Merge remote-tracking branch 'remotes/origin/branches/issue54'
|
@ -27,12 +27,12 @@ add_executable(Pdf4QtDocPageOrganizer
|
||||||
pageitemdelegate.h
|
pageitemdelegate.h
|
||||||
pageitemmodel.cpp
|
pageitemmodel.cpp
|
||||||
pageitemmodel.h
|
pageitemmodel.h
|
||||||
selectbookmarkstoregroupdialog.cpp
|
selectoutlinetoregroupdialog.cpp
|
||||||
selectbookmarkstoregroupdialog.h
|
selectoutlinetoregroupdialog.h
|
||||||
aboutdialog.ui
|
aboutdialog.ui
|
||||||
assembleoutputsettingsdialog.ui
|
assembleoutputsettingsdialog.ui
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
selectbookmarkstoregroupdialog.ui
|
selectoutlinetoregroupdialog.ui
|
||||||
resources.qrc
|
resources.qrc
|
||||||
icon.rc
|
icon.rc
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "aboutdialog.h"
|
#include "aboutdialog.h"
|
||||||
#include "assembleoutputsettingsdialog.h"
|
#include "assembleoutputsettingsdialog.h"
|
||||||
#include "selectbookmarkstoregroupdialog.h"
|
#include "selectoutlinetoregroupdialog.h"
|
||||||
|
|
||||||
#include "pdfaction.h"
|
#include "pdfaction.h"
|
||||||
#include "pdfwidgetutils.h"
|
#include "pdfwidgetutils.h"
|
||||||
|
@ -94,7 +94,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||||
ui->actionInvert_Selection->setData(int(Operation::InvertSelection));
|
ui->actionInvert_Selection->setData(int(Operation::InvertSelection));
|
||||||
ui->actionRegroup_Even_Odd->setData(int(Operation::RegroupEvenOdd));
|
ui->actionRegroup_Even_Odd->setData(int(Operation::RegroupEvenOdd));
|
||||||
ui->actionRegroup_by_Page_Pairs->setData(int(Operation::RegroupPaired));
|
ui->actionRegroup_by_Page_Pairs->setData(int(Operation::RegroupPaired));
|
||||||
ui->actionRegroup_by_Bookmarks->setData(int(Operation::RegroupBookmarks));
|
ui->actionRegroup_by_Outline->setData(int(Operation::RegroupOutline));
|
||||||
ui->actionRegroup_by_Alternating_Pages->setData(int(Operation::RegroupAlternatingPages));
|
ui->actionRegroup_by_Alternating_Pages->setData(int(Operation::RegroupAlternatingPages));
|
||||||
ui->actionRegroup_by_Alternating_Pages_Reversed_Order->setData(int(Operation::RegroupAlternatingPagesReversed));
|
ui->actionRegroup_by_Alternating_Pages_Reversed_Order->setData(int(Operation::RegroupAlternatingPagesReversed));
|
||||||
ui->actionPrepare_Icon_Theme->setData(int(Operation::PrepareIconTheme));
|
ui->actionPrepare_Icon_Theme->setData(int(Operation::PrepareIconTheme));
|
||||||
|
@ -132,7 +132,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||||
m_iconTheme.registerAction(ui->actionClear, ":/pdfdocpage/resources/clear.svg");
|
m_iconTheme.registerAction(ui->actionClear, ":/pdfdocpage/resources/clear.svg");
|
||||||
m_iconTheme.registerAction(ui->actionRegroup_Even_Odd, ":/pdfdocpage/resources/regroup-even-odd.svg");
|
m_iconTheme.registerAction(ui->actionRegroup_Even_Odd, ":/pdfdocpage/resources/regroup-even-odd.svg");
|
||||||
m_iconTheme.registerAction(ui->actionRegroup_by_Page_Pairs, ":/pdfdocpage/resources/regroup-pairs.svg");
|
m_iconTheme.registerAction(ui->actionRegroup_by_Page_Pairs, ":/pdfdocpage/resources/regroup-pairs.svg");
|
||||||
m_iconTheme.registerAction(ui->actionRegroup_by_Bookmarks, ":/pdfdocpage/resources/regroup-bookmarks.svg");
|
m_iconTheme.registerAction(ui->actionRegroup_by_Outline, ":/pdfdocpage/resources/regroup-outline.svg");
|
||||||
m_iconTheme.registerAction(ui->actionRegroup_by_Alternating_Pages, ":/pdfdocpage/resources/regroup-alternating.svg");
|
m_iconTheme.registerAction(ui->actionRegroup_by_Alternating_Pages, ":/pdfdocpage/resources/regroup-alternating.svg");
|
||||||
m_iconTheme.registerAction(ui->actionRegroup_by_Alternating_Pages_Reversed_Order, ":/pdfdocpage/resources/regroup-alternating-reversed.svg");
|
m_iconTheme.registerAction(ui->actionRegroup_by_Alternating_Pages_Reversed_Order, ":/pdfdocpage/resources/regroup-alternating-reversed.svg");
|
||||||
m_iconTheme.registerAction(ui->actionInvert_Selection, ":/pdfdocpage/resources/invert-selection.svg");
|
m_iconTheme.registerAction(ui->actionInvert_Selection, ":/pdfdocpage/resources/invert-selection.svg");
|
||||||
|
@ -162,7 +162,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||||
selectToolbar->addActions({ ui->actionSelect_None, ui->actionSelect_All, ui->actionSelect_Even, ui->actionSelect_Odd, ui->actionSelect_Portrait, ui->actionSelect_Landscape, ui->actionInvert_Selection });
|
selectToolbar->addActions({ ui->actionSelect_None, ui->actionSelect_All, ui->actionSelect_Even, ui->actionSelect_Odd, ui->actionSelect_Portrait, ui->actionSelect_Landscape, ui->actionInvert_Selection });
|
||||||
QToolBar* regroupToolbar = addToolBar(tr("Regroup"));
|
QToolBar* regroupToolbar = addToolBar(tr("Regroup"));
|
||||||
regroupToolbar->setObjectName("regroup_toolbar");
|
regroupToolbar->setObjectName("regroup_toolbar");
|
||||||
regroupToolbar->addActions({ ui->actionRegroup_Even_Odd, ui->actionRegroup_by_Page_Pairs, ui->actionRegroup_by_Bookmarks, ui->actionRegroup_by_Alternating_Pages, ui->actionRegroup_by_Alternating_Pages_Reversed_Order });
|
regroupToolbar->addActions({ ui->actionRegroup_Even_Odd, ui->actionRegroup_by_Page_Pairs, ui->actionRegroup_by_Outline, ui->actionRegroup_by_Alternating_Pages, ui->actionRegroup_by_Alternating_Pages_Reversed_Order });
|
||||||
QToolBar* zoomToolbar = addToolBar(tr("Zoom"));
|
QToolBar* zoomToolbar = addToolBar(tr("Zoom"));
|
||||||
zoomToolbar->setObjectName("zoom_toolbar");
|
zoomToolbar->setObjectName("zoom_toolbar");
|
||||||
zoomToolbar->addActions({ ui->actionZoom_In, ui->actionZoom_Out });
|
zoomToolbar->addActions({ ui->actionZoom_In, ui->actionZoom_Out });
|
||||||
|
@ -283,7 +283,7 @@ void MainWindow::onWorkspaceCustomContextMenuRequested(const QPoint& point)
|
||||||
regroupMenu->addAction(ui->actionRegroup_by_Alternating_Pages);
|
regroupMenu->addAction(ui->actionRegroup_by_Alternating_Pages);
|
||||||
regroupMenu->addAction(ui->actionRegroup_by_Alternating_Pages_Reversed_Order);
|
regroupMenu->addAction(ui->actionRegroup_by_Alternating_Pages_Reversed_Order);
|
||||||
regroupMenu->addAction(ui->actionRegroup_by_Page_Pairs);
|
regroupMenu->addAction(ui->actionRegroup_by_Page_Pairs);
|
||||||
regroupMenu->addAction(ui->actionRegroup_by_Bookmarks);
|
regroupMenu->addAction(ui->actionRegroup_by_Outline);
|
||||||
contextMenu->addSeparator();
|
contextMenu->addSeparator();
|
||||||
contextMenu->addAction(ui->actionGroup);
|
contextMenu->addAction(ui->actionGroup);
|
||||||
contextMenu->addAction(ui->actionUngroup);
|
contextMenu->addAction(ui->actionUngroup);
|
||||||
|
@ -482,7 +482,7 @@ bool MainWindow::canPerformOperation(Operation operation) const
|
||||||
case Operation::RegroupPaired:
|
case Operation::RegroupPaired:
|
||||||
return !isModelEmpty && !selection.isEmpty();
|
return !isModelEmpty && !selection.isEmpty();
|
||||||
|
|
||||||
case Operation::RegroupBookmarks:
|
case Operation::RegroupOutline:
|
||||||
{
|
{
|
||||||
PageItemModel::SelectionInfo info = m_model->getSelectionInfo(selection);
|
PageItemModel::SelectionInfo info = m_model->getSelectionInfo(selection);
|
||||||
return info.isSingleDocument();
|
return info.isSingleDocument();
|
||||||
|
@ -916,7 +916,7 @@ void MainWindow::performOperation(Operation operation)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Operation::RegroupBookmarks:
|
case Operation::RegroupOutline:
|
||||||
{
|
{
|
||||||
QModelIndexList indexes = ui->documentItemsView->selectionModel()->selection().indexes();
|
QModelIndexList indexes = ui->documentItemsView->selectionModel()->selection().indexes();
|
||||||
|
|
||||||
|
@ -929,9 +929,9 @@ void MainWindow::performOperation(Operation operation)
|
||||||
if (it != documents.end())
|
if (it != documents.end())
|
||||||
{
|
{
|
||||||
const pdf::PDFDocument* document = &it->second.document;
|
const pdf::PDFDocument* document = &it->second.document;
|
||||||
SelectBookmarksToRegroupDialog dialog(document, this);
|
SelectOutlineToRegroupDialog dialog(document, this);
|
||||||
|
|
||||||
if (dialog.exec() == SelectBookmarksToRegroupDialog::Accepted)
|
if (dialog.exec() == SelectOutlineToRegroupDialog::Accepted)
|
||||||
{
|
{
|
||||||
std::vector<pdf::PDFInteger> breakPageIndices;
|
std::vector<pdf::PDFInteger> breakPageIndices;
|
||||||
std::vector<const pdf::PDFOutlineItem*> outlineItems = dialog.getSelectedOutlineItems();
|
std::vector<const pdf::PDFOutlineItem*> outlineItems = dialog.getSelectedOutlineItems();
|
||||||
|
@ -972,7 +972,7 @@ void MainWindow::performOperation(Operation operation)
|
||||||
std::sort(breakPageIndices.begin(), breakPageIndices.end());
|
std::sort(breakPageIndices.begin(), breakPageIndices.end());
|
||||||
breakPageIndices.erase(std::unique(breakPageIndices.begin(), breakPageIndices.end()), breakPageIndices.end());
|
breakPageIndices.erase(std::unique(breakPageIndices.begin(), breakPageIndices.end()), breakPageIndices.end());
|
||||||
|
|
||||||
m_model->regroupBookmarks(indexes, breakPageIndices);
|
m_model->regroupOutline(indexes, breakPageIndices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
|
|
||||||
RegroupEvenOdd,
|
RegroupEvenOdd,
|
||||||
RegroupPaired,
|
RegroupPaired,
|
||||||
RegroupBookmarks,
|
RegroupOutline,
|
||||||
RegroupAlternatingPages,
|
RegroupAlternatingPages,
|
||||||
RegroupAlternatingPagesReversed,
|
RegroupAlternatingPagesReversed,
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionRegroup_Even_Odd"/>
|
<addaction name="actionRegroup_Even_Odd"/>
|
||||||
<addaction name="actionRegroup_by_Page_Pairs"/>
|
<addaction name="actionRegroup_by_Page_Pairs"/>
|
||||||
<addaction name="actionRegroup_by_Bookmarks"/>
|
<addaction name="actionRegroup_by_Outline"/>
|
||||||
<addaction name="actionRegroup_by_Alternating_Pages"/>
|
<addaction name="actionRegroup_by_Alternating_Pages"/>
|
||||||
<addaction name="actionRegroup_by_Alternating_Pages_Reversed_Order"/>
|
<addaction name="actionRegroup_by_Alternating_Pages_Reversed_Order"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -533,13 +533,13 @@
|
||||||
<string>Regroup by Page Pairs</string>
|
<string>Regroup by Page Pairs</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionRegroup_by_Bookmarks">
|
<action name="actionRegroup_by_Outline">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="resources.qrc">
|
<iconset resource="resources.qrc">
|
||||||
<normaloff>:/pdfdocpage/resources/regroup-bookmarks.svg</normaloff>:/pdfdocpage/resources/regroup-bookmarks.svg</iconset>
|
<normaloff>:/pdfdocpage/resources/regroup-outline.svg</normaloff>:/pdfdocpage/resources/regroup-outline.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Regroup by Bookmarks</string>
|
<string>Regroup by Outline</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionRegroup_by_Alternating_Pages">
|
<action name="actionRegroup_by_Alternating_Pages">
|
||||||
|
|
|
@ -703,7 +703,7 @@ void PageItemModel::regroupPaired(const QModelIndexList& list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageItemModel::regroupBookmarks(const QModelIndexList& list, const std::vector<pdf::PDFInteger>& indices)
|
void PageItemModel::regroupOutline(const QModelIndexList& list, const std::vector<pdf::PDFInteger>& indices)
|
||||||
{
|
{
|
||||||
if (list.empty())
|
if (list.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -191,7 +191,7 @@ public:
|
||||||
|
|
||||||
void regroupEvenOdd(const QModelIndexList& list);
|
void regroupEvenOdd(const QModelIndexList& list);
|
||||||
void regroupPaired(const QModelIndexList& list);
|
void regroupPaired(const QModelIndexList& list);
|
||||||
void regroupBookmarks(const QModelIndexList& list, const std::vector<pdf::PDFInteger>& indices);
|
void regroupOutline(const QModelIndexList& list, const std::vector<pdf::PDFInteger>& indices);
|
||||||
void regroupAlternatingPages(const QModelIndexList& list, bool reversed);
|
void regroupAlternatingPages(const QModelIndexList& list, bool reversed);
|
||||||
|
|
||||||
bool canUndo() const { return !m_undoSteps.empty(); }
|
bool canUndo() const { return !m_undoSteps.empty(); }
|
||||||
|
|
|
@ -33,12 +33,12 @@
|
||||||
<file>resources/invert-selection.svg</file>
|
<file>resources/invert-selection.svg</file>
|
||||||
<file>resources/regroup-alternating.svg</file>
|
<file>resources/regroup-alternating.svg</file>
|
||||||
<file>resources/regroup-alternating-reversed.svg</file>
|
<file>resources/regroup-alternating-reversed.svg</file>
|
||||||
<file>resources/regroup-bookmarks.svg</file>
|
|
||||||
<file>resources/regroup-even-odd.svg</file>
|
<file>resources/regroup-even-odd.svg</file>
|
||||||
<file>resources/regroup-pairs.svg</file>
|
<file>resources/regroup-pairs.svg</file>
|
||||||
<file>resources/undo.svg</file>
|
<file>resources/undo.svg</file>
|
||||||
<file>resources/redo.svg</file>
|
<file>resources/redo.svg</file>
|
||||||
<file>resources/bookmark.svg</file>
|
<file>resources/bookmark.svg</file>
|
||||||
<file>resources/wallet.svg</file>
|
<file>resources/wallet.svg</file>
|
||||||
|
<file>resources/regroup-outline.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
@ -15,8 +15,8 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "selectbookmarkstoregroupdialog.h"
|
#include "selectoutlinetoregroupdialog.h"
|
||||||
#include "ui_selectbookmarkstoregroupdialog.h"
|
#include "ui_selectoutlinetoregroupdialog.h"
|
||||||
|
|
||||||
#include "pdfitemmodels.h"
|
#include "pdfitemmodels.h"
|
||||||
#include "pdfwidgetutils.h"
|
#include "pdfwidgetutils.h"
|
||||||
|
@ -26,9 +26,9 @@
|
||||||
namespace pdfdocpage
|
namespace pdfdocpage
|
||||||
{
|
{
|
||||||
|
|
||||||
SelectBookmarksToRegroupDialog::SelectBookmarksToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent) :
|
SelectOutlineToRegroupDialog::SelectOutlineToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::SelectBookmarksToRegroupDialog),
|
ui(new Ui::SelectOutlineToRegroupDialog),
|
||||||
m_document(document),
|
m_document(document),
|
||||||
m_model(nullptr)
|
m_model(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -36,53 +36,53 @@ SelectBookmarksToRegroupDialog::SelectBookmarksToRegroupDialog(const pdf::PDFDoc
|
||||||
|
|
||||||
QIcon bookmarkIcon(":/pdfdocpage/resources/bookmark.svg");
|
QIcon bookmarkIcon(":/pdfdocpage/resources/bookmark.svg");
|
||||||
m_model = new pdf::PDFSelectableOutlineTreeItemModel(qMove(bookmarkIcon), this);
|
m_model = new pdf::PDFSelectableOutlineTreeItemModel(qMove(bookmarkIcon), this);
|
||||||
ui->bookmarksView->setModel(m_model);
|
ui->outlineView->setModel(m_model);
|
||||||
ui->bookmarksView->header()->hide();
|
ui->outlineView->header()->hide();
|
||||||
|
|
||||||
m_model->setDocument(pdf::PDFModifiedDocument(const_cast<pdf::PDFDocument*>(document), nullptr));
|
m_model->setDocument(pdf::PDFModifiedDocument(const_cast<pdf::PDFDocument*>(document), nullptr));
|
||||||
ui->bookmarksView->expandToDepth(2);
|
ui->outlineView->expandToDepth(2);
|
||||||
ui->bookmarksView->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->outlineView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(ui->bookmarksView, &QTreeView::customContextMenuRequested, this, &SelectBookmarksToRegroupDialog::onViewContextMenuRequested);
|
connect(ui->outlineView, &QTreeView::customContextMenuRequested, this, &SelectOutlineToRegroupDialog::onViewContextMenuRequested);
|
||||||
|
|
||||||
QSize size = pdf::PDFWidgetUtils::scaleDPI(this, QSize(400, 600));
|
QSize size = pdf::PDFWidgetUtils::scaleDPI(this, QSize(400, 600));
|
||||||
setMinimumSize(size);
|
setMinimumSize(size);
|
||||||
pdf::PDFWidgetUtils::style(this);
|
pdf::PDFWidgetUtils::style(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectBookmarksToRegroupDialog::~SelectBookmarksToRegroupDialog()
|
SelectOutlineToRegroupDialog::~SelectOutlineToRegroupDialog()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const pdf::PDFOutlineItem*> SelectBookmarksToRegroupDialog::getSelectedOutlineItems() const
|
std::vector<const pdf::PDFOutlineItem*> SelectOutlineToRegroupDialog::getSelectedOutlineItems() const
|
||||||
{
|
{
|
||||||
return m_model->getSelectedItems();
|
return m_model->getSelectedItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::onViewContextMenuRequested(const QPoint& pos)
|
void SelectOutlineToRegroupDialog::onViewContextMenuRequested(const QPoint& pos)
|
||||||
{
|
{
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction(tr("Select All"), this, &SelectBookmarksToRegroupDialog::selectAll);
|
menu.addAction(tr("Select All"), this, &SelectOutlineToRegroupDialog::selectAll);
|
||||||
menu.addAction(tr("Deselect All"), this, &SelectBookmarksToRegroupDialog::deselectAll);
|
menu.addAction(tr("Deselect All"), this, &SelectOutlineToRegroupDialog::deselectAll);
|
||||||
menu.addAction(tr("Invert Selection"), this, &SelectBookmarksToRegroupDialog::invertSelection);
|
menu.addAction(tr("Invert Selection"), this, &SelectOutlineToRegroupDialog::invertSelection);
|
||||||
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(tr("Select Level 1"), this, &SelectBookmarksToRegroupDialog::selectLevel1);
|
menu.addAction(tr("Select Level 1"), this, &SelectOutlineToRegroupDialog::selectLevel1);
|
||||||
menu.addAction(tr("Select Level 2"), this, &SelectBookmarksToRegroupDialog::selectLevel2);
|
menu.addAction(tr("Select Level 2"), this, &SelectOutlineToRegroupDialog::selectLevel2);
|
||||||
|
|
||||||
QModelIndex index = ui->bookmarksView->indexAt(pos);
|
QModelIndex index = ui->outlineView->indexAt(pos);
|
||||||
if (index.isValid())
|
if (index.isValid())
|
||||||
{
|
{
|
||||||
m_menuIndex = index;
|
m_menuIndex = index;
|
||||||
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(tr("Select subtree"), this, &SelectBookmarksToRegroupDialog::selectSubtree);
|
menu.addAction(tr("Select subtree"), this, &SelectOutlineToRegroupDialog::selectSubtree);
|
||||||
menu.addAction(tr("Deselect subtree"), this, &SelectBookmarksToRegroupDialog::deselectSubtree);
|
menu.addAction(tr("Deselect subtree"), this, &SelectOutlineToRegroupDialog::deselectSubtree);
|
||||||
}
|
}
|
||||||
menu.exec(ui->bookmarksView->mapToGlobal(pos));
|
menu.exec(ui->outlineView->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::manipulateTree(const QModelIndex& index,
|
void SelectOutlineToRegroupDialog::manipulateTree(const QModelIndex& index,
|
||||||
const std::function<void (QModelIndex)>& manipulator)
|
const std::function<void (QModelIndex)>& manipulator)
|
||||||
{
|
{
|
||||||
if (index.isValid())
|
if (index.isValid())
|
||||||
|
@ -98,7 +98,7 @@ void SelectBookmarksToRegroupDialog::manipulateTree(const QModelIndex& index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void (QModelIndex)> SelectBookmarksToRegroupDialog::createCheckByDepthManipulator(int targetDepth) const
|
std::function<void (QModelIndex)> SelectOutlineToRegroupDialog::createCheckByDepthManipulator(int targetDepth) const
|
||||||
{
|
{
|
||||||
auto manipulator = [this, targetDepth](QModelIndex index)
|
auto manipulator = [this, targetDepth](QModelIndex index)
|
||||||
{
|
{
|
||||||
|
@ -119,42 +119,42 @@ std::function<void (QModelIndex)> SelectBookmarksToRegroupDialog::createCheckByD
|
||||||
return manipulator;
|
return manipulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::selectAll()
|
void SelectOutlineToRegroupDialog::selectAll()
|
||||||
{
|
{
|
||||||
manipulateTree(ui->bookmarksView->rootIndex(), [this](QModelIndex index) { m_model->setData(index, Qt::Checked, Qt::CheckStateRole); });
|
manipulateTree(ui->outlineView->rootIndex(), [this](QModelIndex index) { m_model->setData(index, Qt::Checked, Qt::CheckStateRole); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::deselectAll()
|
void SelectOutlineToRegroupDialog::deselectAll()
|
||||||
{
|
{
|
||||||
manipulateTree(ui->bookmarksView->rootIndex(), [this](QModelIndex index) { m_model->setData(index, Qt::Unchecked, Qt::CheckStateRole); });
|
manipulateTree(ui->outlineView->rootIndex(), [this](QModelIndex index) { m_model->setData(index, Qt::Unchecked, Qt::CheckStateRole); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::invertSelection()
|
void SelectOutlineToRegroupDialog::invertSelection()
|
||||||
{
|
{
|
||||||
auto manipulator = [this](QModelIndex index)
|
auto manipulator = [this](QModelIndex index)
|
||||||
{
|
{
|
||||||
const bool isChecked = index.data(Qt::CheckStateRole).toInt() == Qt::Checked;
|
const bool isChecked = index.data(Qt::CheckStateRole).toInt() == Qt::Checked;
|
||||||
m_model->setData(index, isChecked ? Qt::Unchecked : Qt::Checked, Qt::CheckStateRole);
|
m_model->setData(index, isChecked ? Qt::Unchecked : Qt::Checked, Qt::CheckStateRole);
|
||||||
};
|
};
|
||||||
manipulateTree(ui->bookmarksView->rootIndex(), manipulator);
|
manipulateTree(ui->outlineView->rootIndex(), manipulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::selectLevel1()
|
void SelectOutlineToRegroupDialog::selectLevel1()
|
||||||
{
|
{
|
||||||
manipulateTree(ui->bookmarksView->rootIndex(), createCheckByDepthManipulator(1));
|
manipulateTree(ui->outlineView->rootIndex(), createCheckByDepthManipulator(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::selectLevel2()
|
void SelectOutlineToRegroupDialog::selectLevel2()
|
||||||
{
|
{
|
||||||
manipulateTree(ui->bookmarksView->rootIndex(), createCheckByDepthManipulator(2));
|
manipulateTree(ui->outlineView->rootIndex(), createCheckByDepthManipulator(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::selectSubtree()
|
void SelectOutlineToRegroupDialog::selectSubtree()
|
||||||
{
|
{
|
||||||
manipulateTree(m_menuIndex, [this](QModelIndex index) { m_model->setData(index, Qt::Checked, Qt::CheckStateRole); });
|
manipulateTree(m_menuIndex, [this](QModelIndex index) { m_model->setData(index, Qt::Checked, Qt::CheckStateRole); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBookmarksToRegroupDialog::deselectSubtree()
|
void SelectOutlineToRegroupDialog::deselectSubtree()
|
||||||
{
|
{
|
||||||
manipulateTree(m_menuIndex, [this](QModelIndex index) { m_model->setData(index, Qt::Unchecked, Qt::CheckStateRole); });
|
manipulateTree(m_menuIndex, [this](QModelIndex index) { m_model->setData(index, Qt::Unchecked, Qt::CheckStateRole); });
|
||||||
}
|
}
|
|
@ -15,8 +15,8 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef PDFDOCPAGEORGANIZER_SELECTBOOKMARKSTOREGROUPDIALOG_H
|
#ifndef PDFDOCPAGEORGANIZER_SELECTOUTLINETOREGROUPDIALOG_H
|
||||||
#define PDFDOCPAGEORGANIZER_SELECTBOOKMARKSTOREGROUPDIALOG_H
|
#define PDFDOCPAGEORGANIZER_SELECTOUTLINETOREGROUPDIALOG_H
|
||||||
|
|
||||||
#include "pdfdocument.h"
|
#include "pdfdocument.h"
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class SelectBookmarksToRegroupDialog;
|
class SelectOutlineToRegroupDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
|
@ -35,13 +35,13 @@ class PDFSelectableOutlineTreeItemModel;
|
||||||
namespace pdfdocpage
|
namespace pdfdocpage
|
||||||
{
|
{
|
||||||
|
|
||||||
class SelectBookmarksToRegroupDialog : public QDialog
|
class SelectOutlineToRegroupDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SelectBookmarksToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent);
|
explicit SelectOutlineToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent);
|
||||||
virtual ~SelectBookmarksToRegroupDialog() override;
|
virtual ~SelectOutlineToRegroupDialog() override;
|
||||||
|
|
||||||
std::vector<const pdf::PDFOutlineItem*> getSelectedOutlineItems() const;
|
std::vector<const pdf::PDFOutlineItem*> getSelectedOutlineItems() const;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ private:
|
||||||
|
|
||||||
std::function<void (QModelIndex)> createCheckByDepthManipulator(int targetDepth) const;
|
std::function<void (QModelIndex)> createCheckByDepthManipulator(int targetDepth) const;
|
||||||
|
|
||||||
Ui::SelectBookmarksToRegroupDialog* ui;
|
Ui::SelectOutlineToRegroupDialog* ui;
|
||||||
const pdf::PDFDocument* m_document;
|
const pdf::PDFDocument* m_document;
|
||||||
pdf::PDFSelectableOutlineTreeItemModel* m_model;
|
pdf::PDFSelectableOutlineTreeItemModel* m_model;
|
||||||
QModelIndex m_menuIndex;
|
QModelIndex m_menuIndex;
|
||||||
|
@ -70,4 +70,4 @@ private:
|
||||||
|
|
||||||
} // namespace pdfdocpage
|
} // namespace pdfdocpage
|
||||||
|
|
||||||
#endif // PDFDOCPAGEORGANIZER_SELECTBOOKMARKSTOREGROUPDIALOG_H
|
#endif // PDFDOCPAGEORGANIZER_SELECTOUTLINETOREGROUPDIALOG_H
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>SelectBookmarksToRegroupDialog</class>
|
<class>SelectOutlineToRegroupDialog</class>
|
||||||
<widget class="QDialog" name="SelectBookmarksToRegroupDialog">
|
<widget class="QDialog" name="SelectOutlineToRegroupDialog">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
@ -11,11 +11,11 @@
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Select Bookmarks</string>
|
<string>Select Outline</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="bookmarksView"/>
|
<widget class="QTreeView" name="outlineView"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
<signal>accepted()</signal>
|
<signal>accepted()</signal>
|
||||||
<receiver>SelectBookmarksToRegroupDialog</receiver>
|
<receiver>SelectOutlineToRegroupDialog</receiver>
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
<signal>rejected()</signal>
|
<signal>rejected()</signal>
|
||||||
<receiver>SelectBookmarksToRegroupDialog</receiver>
|
<receiver>SelectOutlineToRegroupDialog</receiver>
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
|
@ -86,9 +86,9 @@ void PDFDocumentSanitizer::sanitize()
|
||||||
performSanitizeMetadata();
|
performSanitizeMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_flags.testFlag(Bookmarks))
|
if (m_flags.testFlag(Outline))
|
||||||
{
|
{
|
||||||
performSanitizeBookmarks();
|
performSanitizeOutline();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_flags.testFlag(FileAttachments))
|
if (m_flags.testFlag(FileAttachments))
|
||||||
|
@ -163,7 +163,7 @@ void PDFDocumentSanitizer::performSanitizeMetadata()
|
||||||
Q_EMIT sanitizationProgress(tr("Metadata streams removed: %1").arg(counter));
|
Q_EMIT sanitizationProgress(tr("Metadata streams removed: %1").arg(counter));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFDocumentSanitizer::performSanitizeBookmarks()
|
void PDFDocumentSanitizer::performSanitizeOutline()
|
||||||
{
|
{
|
||||||
PDFDocumentBuilder builder(m_storage, PDFVersion(2, 0));
|
PDFDocumentBuilder builder(m_storage, PDFVersion(2, 0));
|
||||||
PDFObject catalogObject = builder.getObjectByReference(builder.getCatalogReference());
|
PDFObject catalogObject = builder.getObjectByReference(builder.getCatalogReference());
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
None = 0x0000, ///< No sanitization is performed
|
None = 0x0000, ///< No sanitization is performed
|
||||||
DocumentInfo = 0x0001, ///< Remove document information
|
DocumentInfo = 0x0001, ///< Remove document information
|
||||||
Metadata = 0x0002, ///< Remove all metadata streams in all objects
|
Metadata = 0x0002, ///< Remove all metadata streams in all objects
|
||||||
Bookmarks = 0x0004, ///< Remove bookmarks
|
Outline = 0x0004, ///< Remove outline
|
||||||
FileAttachments = 0x0008, ///< Remove file attachments
|
FileAttachments = 0x0008, ///< Remove file attachments
|
||||||
EmbeddedSearchIndex = 0x0010, ///< Remove embedded search index
|
EmbeddedSearchIndex = 0x0010, ///< Remove embedded search index
|
||||||
MarkupAnnotations = 0x0020, ///< Remove markup annotations from all pages
|
MarkupAnnotations = 0x0020, ///< Remove markup annotations from all pages
|
||||||
|
@ -82,7 +82,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
void performSanitizeDocumentInfo();
|
void performSanitizeDocumentInfo();
|
||||||
void performSanitizeMetadata();
|
void performSanitizeMetadata();
|
||||||
void performSanitizeBookmarks();
|
void performSanitizeOutline();
|
||||||
void performSanitizeFileAttachments();
|
void performSanitizeFileAttachments();
|
||||||
void performSanitizeEmbeddedSearchIndex();
|
void performSanitizeEmbeddedSearchIndex();
|
||||||
void performSanitizeMarkupAnnotations();
|
void performSanitizeMarkupAnnotations();
|
||||||
|
|
|
@ -69,6 +69,10 @@ add_library(Pdf4QtViewer SHARED
|
||||||
pdfcreatebitonaldocumentdialog.cpp
|
pdfcreatebitonaldocumentdialog.cpp
|
||||||
pdfcreatebitonaldocumentdialog.h
|
pdfcreatebitonaldocumentdialog.h
|
||||||
pdf4qtviewer.qrc
|
pdf4qtviewer.qrc
|
||||||
|
pdfbookmarkmanager.h
|
||||||
|
pdfbookmarkmanager.cpp
|
||||||
|
pdfbookmarkui.h
|
||||||
|
pdfbookmarkui.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_compile_definitions(QT_INSTALL_DIRECTORY="${QT6_INSTALL_PREFIX}")
|
add_compile_definitions(QT_INSTALL_DIRECTORY="${QT6_INSTALL_PREFIX}")
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
<file>resources/settings.svg</file>
|
<file>resources/settings.svg</file>
|
||||||
<file>resources/zoom-in.svg</file>
|
<file>resources/zoom-in.svg</file>
|
||||||
<file>resources/zoom-out.svg</file>
|
<file>resources/zoom-out.svg</file>
|
||||||
<file>resources/bookmark.svg</file>
|
|
||||||
<file>resources/security.svg</file>
|
<file>resources/security.svg</file>
|
||||||
<file>resources/zoom-fit.svg</file>
|
<file>resources/zoom-fit.svg</file>
|
||||||
<file>resources/zoom-fit-horizontal.svg</file>
|
<file>resources/zoom-fit-horizontal.svg</file>
|
||||||
|
@ -104,5 +103,10 @@
|
||||||
<file>resources/sidebar-speech.svg</file>
|
<file>resources/sidebar-speech.svg</file>
|
||||||
<file>resources/sidebar-thumbnails.svg</file>
|
<file>resources/sidebar-thumbnails.svg</file>
|
||||||
<file>resources/sidebar-visibility.svg</file>
|
<file>resources/sidebar-visibility.svg</file>
|
||||||
|
<file>resources/outline.svg</file>
|
||||||
|
<file>resources/sidebar-favourites.svg</file>
|
||||||
|
<file>resources/bookmark.svg</file>
|
||||||
|
<file>resources/bookmark-next.svg</file>
|
||||||
|
<file>resources/bookmark-previous.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -0,0 +1,353 @@
|
||||||
|
// Copyright (C) 2023 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of PDF4QT.
|
||||||
|
//
|
||||||
|
// PDF4QT is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// with the written consent of the copyright owner, any later version.
|
||||||
|
//
|
||||||
|
// PDF4QT is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "pdfbookmarkmanager.h"
|
||||||
|
#include "pdfaction.h"
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
namespace pdfviewer
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFBookmarkManagerHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr PDFBookmarkManagerHelper() = delete;
|
||||||
|
|
||||||
|
static QJsonObject convertBookmarkToJson(const PDFBookmarkManager::Bookmark& bookmark)
|
||||||
|
{
|
||||||
|
QJsonObject json;
|
||||||
|
json["isAuto"] = bookmark.isAuto;
|
||||||
|
json["name"] = bookmark.name;
|
||||||
|
json["pageIndex"] = static_cast<qint64>(bookmark.pageIndex);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PDFBookmarkManager::Bookmark convertJsonToBookmark(const QJsonObject& json)
|
||||||
|
{
|
||||||
|
PDFBookmarkManager::Bookmark bookmark;
|
||||||
|
bookmark.isAuto = json["isAuto"].toBool();
|
||||||
|
bookmark.name = json["name"].toString();
|
||||||
|
bookmark.pageIndex = json["pageIndex"].toInteger();
|
||||||
|
return bookmark;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QJsonObject convertBookmarksToJson(const PDFBookmarkManager::Bookmarks& bookmarks)
|
||||||
|
{
|
||||||
|
QJsonArray jsonArray;
|
||||||
|
|
||||||
|
for (const auto& bookmark : bookmarks.bookmarks)
|
||||||
|
{
|
||||||
|
jsonArray.append(convertBookmarkToJson(bookmark));
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject jsonObject;
|
||||||
|
jsonObject["bookmarks"] = jsonArray;
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PDFBookmarkManager::Bookmarks convertBookmarksFromJson(const QJsonObject& object)
|
||||||
|
{
|
||||||
|
PDFBookmarkManager::Bookmarks bookmarks;
|
||||||
|
|
||||||
|
QJsonArray jsonArray = object["bookmarks"].toArray();
|
||||||
|
|
||||||
|
for (const auto& jsonValue : jsonArray)
|
||||||
|
{
|
||||||
|
bookmarks.bookmarks.push_back(convertJsonToBookmark(jsonValue.toObject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return bookmarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QJsonDocument convertBookmarksMapToJsonDocument(const std::map<QString, PDFBookmarkManager::Bookmarks>& bookmarksMap)
|
||||||
|
{
|
||||||
|
QJsonObject mainObject;
|
||||||
|
for (const auto& pair : bookmarksMap)
|
||||||
|
{
|
||||||
|
mainObject[pair.first] = convertBookmarksToJson(pair.second);
|
||||||
|
}
|
||||||
|
return QJsonDocument(mainObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<QString, PDFBookmarkManager::Bookmarks> convertBookmarksMapFromJsonDocument(const QJsonDocument &doc)
|
||||||
|
{
|
||||||
|
std::map<QString, PDFBookmarkManager::Bookmarks> container;
|
||||||
|
QJsonObject mainObject = doc.object();
|
||||||
|
|
||||||
|
for (auto it = mainObject.begin(); it != mainObject.end(); ++it)
|
||||||
|
{
|
||||||
|
container[it.key()] = convertBookmarksFromJson(it.value().toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PDFBookmarkManager::PDFBookmarkManager(QObject* parent) :
|
||||||
|
BaseClass(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::setDocument(const pdf::PDFModifiedDocument& document)
|
||||||
|
{
|
||||||
|
Q_EMIT bookmarksAboutToBeChanged();
|
||||||
|
|
||||||
|
m_document = document.getDocument();
|
||||||
|
|
||||||
|
if (document.hasReset())
|
||||||
|
{
|
||||||
|
if (!document.hasPreserveView())
|
||||||
|
{
|
||||||
|
m_bookmarks.bookmarks.clear();
|
||||||
|
regenerateAutoBookmarks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT bookmarksChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::saveToFile(QString fileName)
|
||||||
|
{
|
||||||
|
QJsonDocument doc(PDFBookmarkManagerHelper::convertBookmarksToJson(m_bookmarks));
|
||||||
|
|
||||||
|
// Příklad zápisu do souboru
|
||||||
|
QFile file(fileName);
|
||||||
|
if (file.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
file.write(doc.toJson());
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PDFBookmarkManager::loadFromFile(QString fileName)
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
if (file.open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
|
QJsonDocument loadedDoc = QJsonDocument::fromJson(file.readAll());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
Q_EMIT bookmarksAboutToBeChanged();
|
||||||
|
m_bookmarks = PDFBookmarkManagerHelper::convertBookmarksFromJson(loadedDoc.object());
|
||||||
|
Q_EMIT bookmarksChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PDFBookmarkManager::isEmpty() const
|
||||||
|
{
|
||||||
|
return m_bookmarks.bookmarks.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PDFBookmarkManager::getBookmarkCount() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_bookmarks.bookmarks.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFBookmarkManager::Bookmark PDFBookmarkManager::getBookmark(int index) const
|
||||||
|
{
|
||||||
|
return m_bookmarks.bookmarks.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::toggleBookmark(pdf::PDFInteger pageIndex)
|
||||||
|
{
|
||||||
|
Q_EMIT bookmarksAboutToBeChanged();
|
||||||
|
|
||||||
|
auto it = std::find_if(m_bookmarks.bookmarks.begin(), m_bookmarks.bookmarks.end(), [pageIndex](const auto& bookmark) { return bookmark.pageIndex == pageIndex; });
|
||||||
|
if (it != m_bookmarks.bookmarks.cend())
|
||||||
|
{
|
||||||
|
Bookmark& bookmark = *it;
|
||||||
|
if (bookmark.isAuto)
|
||||||
|
{
|
||||||
|
bookmark.isAuto = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_bookmarks.bookmarks.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bookmark bookmark;
|
||||||
|
bookmark.isAuto = false;
|
||||||
|
bookmark.name = tr("User bookmark for page %1").arg(pageIndex + 1);
|
||||||
|
bookmark.pageIndex = pageIndex;
|
||||||
|
m_bookmarks.bookmarks.push_back(bookmark);
|
||||||
|
sortBookmarks();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT bookmarksChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::setGenerateBookmarksAutomatically(bool generateBookmarksAutomatically)
|
||||||
|
{
|
||||||
|
if (m_generateBookmarksAutomatically != generateBookmarksAutomatically)
|
||||||
|
{
|
||||||
|
Q_EMIT bookmarksAboutToBeChanged();
|
||||||
|
m_generateBookmarksAutomatically = generateBookmarksAutomatically;
|
||||||
|
regenerateAutoBookmarks();
|
||||||
|
Q_EMIT bookmarksChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::goToNextBookmark()
|
||||||
|
{
|
||||||
|
if (isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentBookmark = (m_currentBookmark + 1) % getBookmarkCount();
|
||||||
|
goToCurrentBookmark();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::goToPreviousBookmark()
|
||||||
|
{
|
||||||
|
if (isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_currentBookmark <= 0)
|
||||||
|
{
|
||||||
|
m_currentBookmark = getBookmarkCount() - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--m_currentBookmark;
|
||||||
|
}
|
||||||
|
|
||||||
|
goToCurrentBookmark();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::goToCurrentBookmark()
|
||||||
|
{
|
||||||
|
if (isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_currentBookmark >= 0 && m_currentBookmark < getBookmarkCount())
|
||||||
|
{
|
||||||
|
Q_EMIT bookmarkActivated(m_currentBookmark, m_bookmarks.bookmarks.at(m_currentBookmark));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::goToBookmark(int index, bool force)
|
||||||
|
{
|
||||||
|
if (m_currentBookmark != index || force)
|
||||||
|
{
|
||||||
|
m_currentBookmark = index;
|
||||||
|
goToCurrentBookmark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::sortBookmarks()
|
||||||
|
{
|
||||||
|
auto predicate = [](const auto& l, const auto& r)
|
||||||
|
{
|
||||||
|
return l.pageIndex < r.pageIndex;
|
||||||
|
};
|
||||||
|
std::sort(m_bookmarks.bookmarks.begin(), m_bookmarks.bookmarks.end(), predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkManager::regenerateAutoBookmarks()
|
||||||
|
{
|
||||||
|
if (!m_document)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create bookmarks for all main chapters
|
||||||
|
Bookmarks& bookmarks = m_bookmarks;
|
||||||
|
|
||||||
|
for (auto it = bookmarks.bookmarks.begin(); it != bookmarks.bookmarks.end();)
|
||||||
|
{
|
||||||
|
if (it->isAuto)
|
||||||
|
{
|
||||||
|
it = bookmarks.bookmarks.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_generateBookmarksAutomatically)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto outlineRoot = m_document->getCatalog()->getOutlineRootPtr())
|
||||||
|
{
|
||||||
|
size_t childCount = outlineRoot->getChildCount();
|
||||||
|
for (size_t i = 0; i < childCount; ++i)
|
||||||
|
{
|
||||||
|
Bookmark bookmark;
|
||||||
|
bookmark.isAuto = true;
|
||||||
|
bookmark.pageIndex = pdf::PDFCatalog::INVALID_PAGE_INDEX;
|
||||||
|
|
||||||
|
const pdf::PDFOutlineItem* child = outlineRoot->getChild(i);
|
||||||
|
const pdf::PDFAction* action = child->getAction();
|
||||||
|
|
||||||
|
if (action)
|
||||||
|
{
|
||||||
|
for (const pdf::PDFAction* currentAction : action->getActionList())
|
||||||
|
{
|
||||||
|
if (currentAction->getType() != pdf::ActionType::GoTo)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pdf::PDFActionGoTo* typedAction = dynamic_cast<const pdf::PDFActionGoTo*>(currentAction);
|
||||||
|
pdf::PDFDestination destination = typedAction->getDestination();
|
||||||
|
if (destination.getDestinationType() == pdf::DestinationType::Named)
|
||||||
|
{
|
||||||
|
if (const pdf::PDFDestination* targetDestination = m_document->getCatalog()->getNamedDestination(destination.getName()))
|
||||||
|
{
|
||||||
|
destination = *targetDestination;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destination.getDestinationType() != pdf::DestinationType::Invalid &&
|
||||||
|
destination.getPageReference() != pdf::PDFObjectReference())
|
||||||
|
{
|
||||||
|
const size_t pageIndex = m_document->getCatalog()->getPageIndexFromPageReference(destination.getPageReference());
|
||||||
|
if (pageIndex != pdf::PDFCatalog::INVALID_PAGE_INDEX)
|
||||||
|
{
|
||||||
|
bookmark.pageIndex = pageIndex;
|
||||||
|
bookmark.name = child->getTitle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bookmark.pageIndex != pdf::PDFCatalog::INVALID_PAGE_INDEX)
|
||||||
|
{
|
||||||
|
bookmarks.bookmarks.emplace_back(std::move(bookmark));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pdf
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (C) 2023 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of PDF4QT.
|
||||||
|
//
|
||||||
|
// PDF4QT is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// with the written consent of the copyright owner, any later version.
|
||||||
|
//
|
||||||
|
// PDF4QT is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PDFBOOKMARKMANAGER_H
|
||||||
|
#define PDFBOOKMARKMANAGER_H
|
||||||
|
|
||||||
|
#include "pdfdocument.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace pdfviewer
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFBookmarkManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BaseClass = QObject;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PDFBookmarkManager(QObject* parent);
|
||||||
|
|
||||||
|
void setDocument(const pdf::PDFModifiedDocument& document);
|
||||||
|
|
||||||
|
void saveToFile(QString fileName);
|
||||||
|
bool loadFromFile(QString fileName);
|
||||||
|
|
||||||
|
struct Bookmark
|
||||||
|
{
|
||||||
|
bool isAuto = false;
|
||||||
|
QString name;
|
||||||
|
pdf::PDFInteger pageIndex = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isEmpty() const;
|
||||||
|
int getBookmarkCount() const;
|
||||||
|
Bookmark getBookmark(int index) const;
|
||||||
|
void toggleBookmark(pdf::PDFInteger pageIndex);
|
||||||
|
void setGenerateBookmarksAutomatically(bool generateBookmarksAutomatically);
|
||||||
|
|
||||||
|
void goToNextBookmark();
|
||||||
|
void goToPreviousBookmark();
|
||||||
|
void goToCurrentBookmark();
|
||||||
|
void goToBookmark(int index, bool force);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void bookmarksAboutToBeChanged();
|
||||||
|
void bookmarksChanged();
|
||||||
|
void bookmarkActivated(int index, Bookmark bookmark);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class PDFBookmarkManagerHelper;
|
||||||
|
|
||||||
|
void sortBookmarks();
|
||||||
|
void regenerateAutoBookmarks();
|
||||||
|
|
||||||
|
struct Bookmarks
|
||||||
|
{
|
||||||
|
std::vector<Bookmark> bookmarks;
|
||||||
|
};
|
||||||
|
|
||||||
|
pdf::PDFDocument* m_document;
|
||||||
|
Bookmarks m_bookmarks;
|
||||||
|
int m_currentBookmark = -1;
|
||||||
|
bool m_generateBookmarksAutomatically = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdf
|
||||||
|
|
||||||
|
#endif // PDFBOOKMARKMANAGER_H
|
|
@ -0,0 +1,198 @@
|
||||||
|
// Copyright (C) 2023 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of PDF4QT.
|
||||||
|
//
|
||||||
|
// PDF4QT is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// with the written consent of the copyright owner, any later version.
|
||||||
|
//
|
||||||
|
// PDF4QT is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "pdfbookmarkui.h"
|
||||||
|
#include "pdfwidgetutils.h"
|
||||||
|
#include "pdfpainterutils.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
|
namespace pdfviewer
|
||||||
|
{
|
||||||
|
|
||||||
|
PDFBookmarkItemModel::PDFBookmarkItemModel(PDFBookmarkManager* bookmarkManager, QObject* parent) :
|
||||||
|
BaseClass(parent),
|
||||||
|
m_bookmarkManager(bookmarkManager)
|
||||||
|
{
|
||||||
|
connect(m_bookmarkManager, &PDFBookmarkManager::bookmarksAboutToBeChanged, this, &PDFBookmarkItemModel::beginResetModel);
|
||||||
|
connect(m_bookmarkManager, &PDFBookmarkManager::bookmarksChanged, this, &PDFBookmarkItemModel::endResetModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex PDFBookmarkItemModel::index(int row, int column, const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
{
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return createIndex(row, column, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex PDFBookmarkItemModel::parent(const QModelIndex& child) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(child);
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PDFBookmarkItemModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_bookmarkManager ? m_bookmarkManager->getBookmarkCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PDFBookmarkItemModel::columnCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PDFBookmarkItemModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
return m_bookmarkManager->getBookmark(index.row()).name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFBookmarkItemDelegate::PDFBookmarkItemDelegate(PDFBookmarkManager* bookmarkManager, QObject* parent) :
|
||||||
|
BaseClass(parent),
|
||||||
|
m_bookmarkManager(bookmarkManager)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkItemDelegate::paint(QPainter* painter,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QStyleOptionViewItem options = option;
|
||||||
|
initStyleOption(&options, index);
|
||||||
|
|
||||||
|
PDFBookmarkManager::Bookmark bookmark = m_bookmarkManager->getBookmark(index.row());
|
||||||
|
|
||||||
|
options.text = QString();
|
||||||
|
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
|
||||||
|
|
||||||
|
const int margin = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, MARGIN);
|
||||||
|
const int iconSize = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, ICON_SIZE);
|
||||||
|
|
||||||
|
QRect rect = options.rect;
|
||||||
|
rect.marginsRemoved(QMargins(margin, margin, margin, margin));
|
||||||
|
|
||||||
|
QColor color = bookmark.isAuto ? QColor(0, 123, 255) : QColor(255, 159, 0);
|
||||||
|
|
||||||
|
if (options.state.testFlag(QStyle::State_Selected))
|
||||||
|
{
|
||||||
|
color = Qt::yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect iconRect = rect;
|
||||||
|
iconRect.setWidth(iconSize);
|
||||||
|
iconRect.setHeight(iconSize);
|
||||||
|
iconRect.moveCenter(QPoint(rect.left() + iconSize / 2, rect.center().y()));
|
||||||
|
drawStar(*painter, iconRect.center(), iconRect.width() * 0.5, color);
|
||||||
|
|
||||||
|
QRect textRect = rect;
|
||||||
|
textRect.setLeft(iconRect.right() + margin);
|
||||||
|
textRect.moveTop(rect.top() + (rect.height() - 2 * options.fontMetrics.lineSpacing()) / 2);
|
||||||
|
|
||||||
|
textRect.setHeight(options.fontMetrics.lineSpacing());
|
||||||
|
|
||||||
|
QFont font = options.font;
|
||||||
|
font.setBold(true);
|
||||||
|
|
||||||
|
painter->setFont(font);
|
||||||
|
painter->drawText(textRect, getPageText(bookmark));
|
||||||
|
|
||||||
|
textRect.translate(0, textRect.height());
|
||||||
|
|
||||||
|
painter->setFont(options.font);
|
||||||
|
painter->drawText(textRect, bookmark.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize PDFBookmarkItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
PDFBookmarkManager::Bookmark bookmark = m_bookmarkManager->getBookmark(index.row());
|
||||||
|
|
||||||
|
const int textWidthLine1 = option.fontMetrics.horizontalAdvance(getPageText(bookmark));
|
||||||
|
const int textWidthLine2 = option.fontMetrics.horizontalAdvance(option.text);
|
||||||
|
const int textWidth = qMax(textWidthLine1, textWidthLine2);
|
||||||
|
const int textHeight = option.fontMetrics.lineSpacing() * 2;
|
||||||
|
|
||||||
|
const int margin = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, MARGIN);
|
||||||
|
const int iconSize = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, ICON_SIZE);
|
||||||
|
|
||||||
|
const int requiredWidth = 3 * margin + iconSize + textWidth;
|
||||||
|
const int requiredHeight = 2 * margin + qMax(iconSize, textHeight);
|
||||||
|
|
||||||
|
return QSize(requiredWidth, requiredHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFBookmarkItemDelegate::drawStar(QPainter& painter, const QPointF& center, double size, const QColor& color) const
|
||||||
|
{
|
||||||
|
pdf::PDFPainterStateGuard guard(&painter);
|
||||||
|
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.setBrush(color);
|
||||||
|
|
||||||
|
QPainterPath path;
|
||||||
|
double angle = M_PI / 5;
|
||||||
|
double phase = -M_PI / 10;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
double radius = (i % 2 == 0) ? size : size / 2.5;
|
||||||
|
QPointF point(radius * cos(i * angle + phase), radius * sin(i * angle + phase));
|
||||||
|
point += center;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
path.moveTo(point);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path.lineTo(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path.closeSubpath();
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PDFBookmarkItemDelegate::getPageText(const PDFBookmarkManager::Bookmark& bookmark) const
|
||||||
|
{
|
||||||
|
if (bookmark.isAuto)
|
||||||
|
{
|
||||||
|
return tr("Page %1 | Generated").arg(bookmark.pageIndex + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tr("Page %1").arg(bookmark.pageIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pdfviewer
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright (C) 2023 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of PDF4QT.
|
||||||
|
//
|
||||||
|
// PDF4QT is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// with the written consent of the copyright owner, any later version.
|
||||||
|
//
|
||||||
|
// PDF4QT is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PDFBOOKMARKUI_H
|
||||||
|
#define PDFBOOKMARKUI_H
|
||||||
|
|
||||||
|
#include "pdfviewerglobal.h"
|
||||||
|
#include "pdfbookmarkmanager.h"
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
namespace pdfviewer
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFBookmarkItemModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BaseClass = QAbstractItemModel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PDFBookmarkItemModel(PDFBookmarkManager* bookmarkManager, QObject* parent);
|
||||||
|
|
||||||
|
virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override;
|
||||||
|
virtual QModelIndex parent(const QModelIndex& child) const override;
|
||||||
|
virtual int rowCount(const QModelIndex& parent) const override;
|
||||||
|
virtual int columnCount(const QModelIndex& parent) const override;
|
||||||
|
virtual QVariant data(const QModelIndex& index, int role) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PDFBookmarkManager* m_bookmarkManager = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PDFBookmarkItemDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BaseClass = QStyledItemDelegate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PDFBookmarkItemDelegate(PDFBookmarkManager* bookmarkManager, QObject* parent);
|
||||||
|
|
||||||
|
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
|
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr int MARGIN = 6;
|
||||||
|
static constexpr int ICON_SIZE = 32;
|
||||||
|
|
||||||
|
void drawStar(QPainter& painter, const QPointF& center, double size, const QColor& color) const;
|
||||||
|
|
||||||
|
QString getPageText(const PDFBookmarkManager::Bookmark& bookmark) const;
|
||||||
|
|
||||||
|
PDFBookmarkManager* m_bookmarkManager = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdfviewer
|
||||||
|
|
||||||
|
#endif // PDFBOOKMARKUI_H
|
|
@ -210,6 +210,9 @@ void PDFActionManager::initActions(QSize iconSize, bool initializeStampActions)
|
||||||
setShortcut(GoToPreviousPage, QKeySequence::MoveToPreviousPage);
|
setShortcut(GoToPreviousPage, QKeySequence::MoveToPreviousPage);
|
||||||
setShortcut(GoToNextLine, QKeySequence::MoveToNextLine);
|
setShortcut(GoToNextLine, QKeySequence::MoveToNextLine);
|
||||||
setShortcut(GoToPreviousLine, QKeySequence::MoveToPreviousLine);
|
setShortcut(GoToPreviousLine, QKeySequence::MoveToPreviousLine);
|
||||||
|
setShortcut(BookmarkPage, QKeySequence("Ctrl+M"));
|
||||||
|
setShortcut(BookmarkGoToNext, QKeySequence("Ctrl+."));
|
||||||
|
setShortcut(BookmarkGoToPrevious, QKeySequence("Ctrl+,"));
|
||||||
|
|
||||||
if (hasActions({ CreateStickyNoteComment, CreateStickyNoteHelp, CreateStickyNoteInsert, CreateStickyNoteKey, CreateStickyNoteNewParagraph, CreateStickyNoteNote, CreateStickyNoteParagraph }))
|
if (hasActions({ CreateStickyNoteComment, CreateStickyNoteHelp, CreateStickyNoteInsert, CreateStickyNoteKey, CreateStickyNoteNewParagraph, CreateStickyNoteNote, CreateStickyNoteParagraph }))
|
||||||
{
|
{
|
||||||
|
@ -361,6 +364,7 @@ PDFProgramController::PDFProgramController(QObject* parent) :
|
||||||
m_toolManager(nullptr),
|
m_toolManager(nullptr),
|
||||||
m_annotationManager(nullptr),
|
m_annotationManager(nullptr),
|
||||||
m_formManager(nullptr),
|
m_formManager(nullptr),
|
||||||
|
m_bookmarkManager(nullptr),
|
||||||
m_isBusy(false),
|
m_isBusy(false),
|
||||||
m_isFactorySettingsBeingRestored(false),
|
m_isFactorySettingsBeingRestored(false),
|
||||||
m_progress(nullptr)
|
m_progress(nullptr)
|
||||||
|
@ -375,6 +379,9 @@ PDFProgramController::~PDFProgramController()
|
||||||
|
|
||||||
delete m_annotationManager;
|
delete m_annotationManager;
|
||||||
m_annotationManager = nullptr;
|
m_annotationManager = nullptr;
|
||||||
|
|
||||||
|
delete m_bookmarkManager;
|
||||||
|
m_bookmarkManager = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFProgramController::initializeAnnotationManager()
|
void PDFProgramController::initializeAnnotationManager()
|
||||||
|
@ -396,6 +403,13 @@ void PDFProgramController::initializeFormManager()
|
||||||
connect(m_formManager, &pdf::PDFFormManager::documentModified, this, &PDFProgramController::onDocumentModified);
|
connect(m_formManager, &pdf::PDFFormManager::documentModified, this, &PDFProgramController::onDocumentModified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::initializeBookmarkManager()
|
||||||
|
{
|
||||||
|
m_bookmarkManager = new PDFBookmarkManager(this);
|
||||||
|
connect(m_bookmarkManager, &PDFBookmarkManager::bookmarkActivated, this, &PDFProgramController::onBookmarkActivated);
|
||||||
|
updateBookmarkSettings();
|
||||||
|
}
|
||||||
|
|
||||||
void PDFProgramController::initialize(Features features,
|
void PDFProgramController::initialize(Features features,
|
||||||
QMainWindow* mainWindow,
|
QMainWindow* mainWindow,
|
||||||
IMainWindow* mainWindowInterface,
|
IMainWindow* mainWindowInterface,
|
||||||
|
@ -572,6 +586,30 @@ void PDFProgramController::initialize(Features features,
|
||||||
{
|
{
|
||||||
connect(action, &QAction::triggered, this, &PDFProgramController::onActionAutomaticDocumentRefresh);
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionAutomaticDocumentRefresh);
|
||||||
}
|
}
|
||||||
|
if (QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkPage))
|
||||||
|
{
|
||||||
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionBookmarkPage);
|
||||||
|
}
|
||||||
|
if (QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkGoToNext))
|
||||||
|
{
|
||||||
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionBookmarkGoToNext);
|
||||||
|
}
|
||||||
|
if (QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkGoToPrevious))
|
||||||
|
{
|
||||||
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionBookmarkGoToPrevious);
|
||||||
|
}
|
||||||
|
if (QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkExport))
|
||||||
|
{
|
||||||
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionBookmarkExport);
|
||||||
|
}
|
||||||
|
if (QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkImport))
|
||||||
|
{
|
||||||
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionBookmarkImport);
|
||||||
|
}
|
||||||
|
if (QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkGenerateAutomatically))
|
||||||
|
{
|
||||||
|
connect(action, &QAction::triggered, this, &PDFProgramController::onActionBookmarkGenerateAutomatically);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_recentFileManager)
|
if (m_recentFileManager)
|
||||||
{
|
{
|
||||||
|
@ -605,6 +643,7 @@ void PDFProgramController::initialize(Features features,
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeAnnotationManager();
|
initializeAnnotationManager();
|
||||||
|
initializeBookmarkManager();
|
||||||
|
|
||||||
if (features.testFlag(Forms))
|
if (features.testFlag(Forms))
|
||||||
{
|
{
|
||||||
|
@ -1549,6 +1588,8 @@ void PDFProgramController::readSettings(Settings settingsFlags)
|
||||||
{
|
{
|
||||||
m_formManager->setAppearanceFlags(m_settings->getSettings().m_formAppearanceFlags);
|
m_formManager->setAppearanceFlags(m_settings->getSettings().m_formAppearanceFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateBookmarkSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settingsFlags.testFlag(PluginsSettings))
|
if (settingsFlags.testFlag(PluginsSettings))
|
||||||
|
@ -1702,6 +1743,13 @@ void PDFProgramController::onFileChanged(const QString& fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark)
|
||||||
|
{
|
||||||
|
Q_UNUSED(index);
|
||||||
|
|
||||||
|
m_pdfWidget->getDrawWidgetProxy()->goToPage(bookmark.pageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFProgramController::updateFileInfo(const QString& fileName)
|
void PDFProgramController::updateFileInfo(const QString& fileName)
|
||||||
{
|
{
|
||||||
QFileInfo fileInfo(fileName);
|
QFileInfo fileInfo(fileName);
|
||||||
|
@ -1915,6 +1963,11 @@ void PDFProgramController::setDocument(pdf::PDFModifiedDocument document, bool i
|
||||||
m_annotationManager->setDocument(document);
|
m_annotationManager->setDocument(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_bookmarkManager)
|
||||||
|
{
|
||||||
|
m_bookmarkManager->setDocument(document);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_formManager)
|
if (m_formManager)
|
||||||
{
|
{
|
||||||
m_formManager->setDocument(document);
|
m_formManager->setDocument(document);
|
||||||
|
@ -1981,6 +2034,22 @@ void PDFProgramController::updateRenderingOptionActions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::updateBookmarkSettings()
|
||||||
|
{
|
||||||
|
const bool enable = m_settings->getSettings().m_autoGenerateBookmarks;
|
||||||
|
|
||||||
|
if (m_bookmarkManager)
|
||||||
|
{
|
||||||
|
m_bookmarkManager->setGenerateBookmarksAutomatically(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction* action = m_actionManager->getAction(PDFActionManager::BookmarkGenerateAutomatically);
|
||||||
|
if (action)
|
||||||
|
{
|
||||||
|
action->setChecked(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFProgramController::updateTitle()
|
void PDFProgramController::updateTitle()
|
||||||
{
|
{
|
||||||
if (m_pdfDocument)
|
if (m_pdfDocument)
|
||||||
|
@ -2535,6 +2604,63 @@ void PDFProgramController::onActionAutomaticDocumentRefresh()
|
||||||
updateFileWatcher();
|
updateFileWatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onActionBookmarkPage()
|
||||||
|
{
|
||||||
|
std::vector<pdf::PDFInteger> currentPages = m_pdfWidget->getDrawWidget()->getCurrentPages();
|
||||||
|
if (!currentPages.empty())
|
||||||
|
{
|
||||||
|
m_bookmarkManager->toggleBookmark(currentPages.front());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onActionBookmarkGoToNext()
|
||||||
|
{
|
||||||
|
m_bookmarkManager->goToNextBookmark();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onActionBookmarkGoToPrevious()
|
||||||
|
{
|
||||||
|
m_bookmarkManager->goToPreviousBookmark();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onActionBookmarkExport()
|
||||||
|
{
|
||||||
|
if (!m_pdfDocument)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo fileInfo(m_fileInfo.originalFileName);
|
||||||
|
QString saveFileName = QFileDialog::getSaveFileName(m_mainWindow, tr("Export Bookmarks As"), fileInfo.dir().absoluteFilePath(m_fileInfo.originalFileName).replace(".pdf", ".json"), tr("JSON (*.json);;All files (*.*)"));
|
||||||
|
if (!saveFileName.isEmpty())
|
||||||
|
{
|
||||||
|
m_bookmarkManager->saveToFile(saveFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onActionBookmarkImport()
|
||||||
|
{
|
||||||
|
if (!m_pdfDocument)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo fileInfo(m_fileInfo.originalFileName);
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(m_mainWindow, tr("Select PDF document"), fileInfo.dir().absolutePath(), tr("JSON (*.json)"));
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
m_bookmarkManager->loadFromFile(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::onActionBookmarkGenerateAutomatically(bool checked)
|
||||||
|
{
|
||||||
|
auto settings = m_settings->getSettings();
|
||||||
|
settings.m_autoGenerateBookmarks = checked;
|
||||||
|
m_settings->setSettings(settings);
|
||||||
|
m_bookmarkManager->setGenerateBookmarksAutomatically(checked);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFProgramController::onPageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount)
|
void PDFProgramController::onPageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount)
|
||||||
{
|
{
|
||||||
if (errorsCount > 0)
|
if (errorsCount > 0)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "pdfdocumentreader.h"
|
#include "pdfdocumentreader.h"
|
||||||
#include "pdfdocumentpropertiesdialog.h"
|
#include "pdfdocumentpropertiesdialog.h"
|
||||||
#include "pdfplugin.h"
|
#include "pdfplugin.h"
|
||||||
|
#include "pdfbookmarkmanager.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
@ -177,6 +178,12 @@ public:
|
||||||
ToolScreenshot,
|
ToolScreenshot,
|
||||||
ToolExtractImage,
|
ToolExtractImage,
|
||||||
DeveloperCreateInstaller,
|
DeveloperCreateInstaller,
|
||||||
|
BookmarkPage,
|
||||||
|
BookmarkGoToNext,
|
||||||
|
BookmarkGoToPrevious,
|
||||||
|
BookmarkExport,
|
||||||
|
BookmarkImport,
|
||||||
|
BookmarkGenerateAutomatically,
|
||||||
LastAction
|
LastAction
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -275,6 +282,7 @@ public:
|
||||||
PDFViewerSettings* getSettings() const { return m_settings; }
|
PDFViewerSettings* getSettings() const { return m_settings; }
|
||||||
pdf::PDFDocument* getDocument() const { return m_pdfDocument.data(); }
|
pdf::PDFDocument* getDocument() const { return m_pdfDocument.data(); }
|
||||||
pdf::PDFCertificateStore* getCertificateStore() const { return const_cast<pdf::PDFCertificateStore*>(&m_certificateStore); }
|
pdf::PDFCertificateStore* getCertificateStore() const { return const_cast<pdf::PDFCertificateStore*>(&m_certificateStore); }
|
||||||
|
PDFBookmarkManager* getBookmarkManager() const { return m_bookmarkManager; }
|
||||||
PDFTextToSpeech* getTextToSpeech() const { return m_textToSpeech; }
|
PDFTextToSpeech* getTextToSpeech() const { return m_textToSpeech; }
|
||||||
const std::vector<pdf::PDFSignatureVerificationResult>* getSignatures() const { return &m_signatures; }
|
const std::vector<pdf::PDFSignatureVerificationResult>* getSignatures() const { return &m_signatures; }
|
||||||
|
|
||||||
|
@ -326,6 +334,7 @@ private:
|
||||||
void initializeToolManager();
|
void initializeToolManager();
|
||||||
void initializeAnnotationManager();
|
void initializeAnnotationManager();
|
||||||
void initializeFormManager();
|
void initializeFormManager();
|
||||||
|
void initializeBookmarkManager();
|
||||||
|
|
||||||
void onActionGoToDocumentStartTriggered();
|
void onActionGoToDocumentStartTriggered();
|
||||||
void onActionGoToDocumentEndTriggered();
|
void onActionGoToDocumentEndTriggered();
|
||||||
|
@ -364,6 +373,12 @@ private:
|
||||||
void onActionGetSource();
|
void onActionGetSource();
|
||||||
void onActionBecomeSponsor();
|
void onActionBecomeSponsor();
|
||||||
void onActionAutomaticDocumentRefresh();
|
void onActionAutomaticDocumentRefresh();
|
||||||
|
void onActionBookmarkPage();
|
||||||
|
void onActionBookmarkGoToNext();
|
||||||
|
void onActionBookmarkGoToPrevious();
|
||||||
|
void onActionBookmarkExport();
|
||||||
|
void onActionBookmarkImport();
|
||||||
|
void onActionBookmarkGenerateAutomatically(bool checked);
|
||||||
|
|
||||||
void onDrawSpaceChanged();
|
void onDrawSpaceChanged();
|
||||||
void onPageLayoutChanged();
|
void onPageLayoutChanged();
|
||||||
|
@ -374,6 +389,7 @@ private:
|
||||||
void onViewerSettingsChanged();
|
void onViewerSettingsChanged();
|
||||||
void onColorManagementSystemChanged();
|
void onColorManagementSystemChanged();
|
||||||
void onFileChanged(const QString& fileName);
|
void onFileChanged(const QString& fileName);
|
||||||
|
void onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark);
|
||||||
|
|
||||||
void updateMagnifierToolSettings();
|
void updateMagnifierToolSettings();
|
||||||
void updateUndoRedoSettings();
|
void updateUndoRedoSettings();
|
||||||
|
@ -381,6 +397,7 @@ private:
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
void updatePageLayoutActions();
|
void updatePageLayoutActions();
|
||||||
void updateRenderingOptionActions();
|
void updateRenderingOptionActions();
|
||||||
|
void updateBookmarkSettings();
|
||||||
|
|
||||||
void setPageLayout(pdf::PageLayout pageLayout);
|
void setPageLayout(pdf::PageLayout pageLayout);
|
||||||
void updateFileInfo(const QString& fileName);
|
void updateFileInfo(const QString& fileName);
|
||||||
|
@ -422,6 +439,7 @@ private:
|
||||||
pdf::PDFToolManager* m_toolManager;
|
pdf::PDFToolManager* m_toolManager;
|
||||||
pdf::PDFWidgetAnnotationManager* m_annotationManager;
|
pdf::PDFWidgetAnnotationManager* m_annotationManager;
|
||||||
pdf::PDFWidgetFormManager* m_formManager;
|
pdf::PDFWidgetFormManager* m_formManager;
|
||||||
|
PDFBookmarkManager* m_bookmarkManager;
|
||||||
|
|
||||||
PDFFileInfo m_fileInfo;
|
PDFFileInfo m_fileInfo;
|
||||||
QFileSystemWatcher m_fileWatcher;
|
QFileSystemWatcher m_fileWatcher;
|
||||||
|
|
|
@ -51,7 +51,7 @@ PDFSanitizeDocumentDialog::PDFSanitizeDocumentDialog(const pdf::PDFDocument* doc
|
||||||
|
|
||||||
addCheckBox(tr("Remove document info"), pdf::PDFDocumentSanitizer::DocumentInfo);
|
addCheckBox(tr("Remove document info"), pdf::PDFDocumentSanitizer::DocumentInfo);
|
||||||
addCheckBox(tr("Remove all metadata"), pdf::PDFDocumentSanitizer::Metadata);
|
addCheckBox(tr("Remove all metadata"), pdf::PDFDocumentSanitizer::Metadata);
|
||||||
addCheckBox(tr("Remove outline (bookmarks)"), pdf::PDFDocumentSanitizer::Bookmarks);
|
addCheckBox(tr("Remove outline"), pdf::PDFDocumentSanitizer::Outline);
|
||||||
addCheckBox(tr("Remove file attachments"), pdf::PDFDocumentSanitizer::FileAttachments);
|
addCheckBox(tr("Remove file attachments"), pdf::PDFDocumentSanitizer::FileAttachments);
|
||||||
addCheckBox(tr("Remove embedded search index"), pdf::PDFDocumentSanitizer::EmbeddedSearchIndex);
|
addCheckBox(tr("Remove embedded search index"), pdf::PDFDocumentSanitizer::EmbeddedSearchIndex);
|
||||||
addCheckBox(tr("Remove comments and other markup annotations"), pdf::PDFDocumentSanitizer::MarkupAnnotations);
|
addCheckBox(tr("Remove comments and other markup annotations"), pdf::PDFDocumentSanitizer::MarkupAnnotations);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "pdfdrawspacecontroller.h"
|
#include "pdfdrawspacecontroller.h"
|
||||||
#include "pdfdocumentbuilder.h"
|
#include "pdfdocumentbuilder.h"
|
||||||
#include "pdfwidgetutils.h"
|
#include "pdfwidgetutils.h"
|
||||||
|
#include "pdfbookmarkui.h"
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
@ -60,6 +61,7 @@ constexpr const char* STYLESHEET =
|
||||||
PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||||
PDFTextToSpeech* textToSpeech,
|
PDFTextToSpeech* textToSpeech,
|
||||||
pdf::PDFCertificateStore* certificateStore,
|
pdf::PDFCertificateStore* certificateStore,
|
||||||
|
PDFBookmarkManager* bookmarkManager,
|
||||||
PDFViewerSettings* settings,
|
PDFViewerSettings* settings,
|
||||||
bool editableOutline,
|
bool editableOutline,
|
||||||
QWidget* parent) :
|
QWidget* parent) :
|
||||||
|
@ -68,10 +70,12 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||||
m_proxy(proxy),
|
m_proxy(proxy),
|
||||||
m_textToSpeech(textToSpeech),
|
m_textToSpeech(textToSpeech),
|
||||||
m_certificateStore(certificateStore),
|
m_certificateStore(certificateStore),
|
||||||
|
m_bookmarkManager(bookmarkManager),
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
m_outlineTreeModel(nullptr),
|
m_outlineTreeModel(nullptr),
|
||||||
m_thumbnailsModel(nullptr),
|
m_thumbnailsModel(nullptr),
|
||||||
m_optionalContentTreeModel(nullptr),
|
m_optionalContentTreeModel(nullptr),
|
||||||
|
m_bookmarkItemModel(nullptr),
|
||||||
m_document(nullptr),
|
m_document(nullptr),
|
||||||
m_optionalContentActivity(nullptr),
|
m_optionalContentActivity(nullptr),
|
||||||
m_attachmentsTreeModel(nullptr)
|
m_attachmentsTreeModel(nullptr)
|
||||||
|
@ -81,26 +85,26 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||||
setStyleSheet(STYLESHEET);
|
setStyleSheet(STYLESHEET);
|
||||||
|
|
||||||
// Outline
|
// Outline
|
||||||
QIcon bookmarkIcon(":/resources/bookmark.svg");
|
QIcon outlineIcon(":/resources/outline.svg");
|
||||||
m_outlineTreeModel = new pdf::PDFOutlineTreeItemModel(qMove(bookmarkIcon), editableOutline, this);
|
m_outlineTreeModel = new pdf::PDFOutlineTreeItemModel(qMove(outlineIcon), editableOutline, this);
|
||||||
ui->bookmarksTreeView->setModel(m_outlineTreeModel);
|
ui->outlineTreeView->setModel(m_outlineTreeModel);
|
||||||
ui->bookmarksTreeView->header()->hide();
|
ui->outlineTreeView->header()->hide();
|
||||||
|
|
||||||
if (editableOutline)
|
if (editableOutline)
|
||||||
{
|
{
|
||||||
ui->bookmarksTreeView->setDragEnabled(true);
|
ui->outlineTreeView->setDragEnabled(true);
|
||||||
ui->bookmarksTreeView->setAcceptDrops(true);
|
ui->outlineTreeView->setAcceptDrops(true);
|
||||||
ui->bookmarksTreeView->setDropIndicatorShown(true);
|
ui->outlineTreeView->setDropIndicatorShown(true);
|
||||||
ui->bookmarksTreeView->setDragDropMode(QAbstractItemView::InternalMove);
|
ui->outlineTreeView->setDragDropMode(QAbstractItemView::InternalMove);
|
||||||
ui->bookmarksTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->outlineTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(ui->bookmarksTreeView, &QTreeView::customContextMenuRequested, this, &PDFSidebarWidget::onBookmarksTreeViewContextMenuRequested);
|
connect(ui->outlineTreeView, &QTreeView::customContextMenuRequested, this, &PDFSidebarWidget::onOutlineTreeViewContextMenuRequested);
|
||||||
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::dataChanged, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::dataChanged, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
||||||
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::rowsInserted, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::rowsInserted, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
||||||
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::rowsRemoved, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::rowsRemoved, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
||||||
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::rowsMoved, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::rowsMoved, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->bookmarksTreeView, &QTreeView::clicked, this, &PDFSidebarWidget::onOutlineItemClicked);
|
connect(ui->outlineTreeView, &QTreeView::clicked, this, &PDFSidebarWidget::onOutlineItemClicked);
|
||||||
|
|
||||||
// Thumbnails
|
// Thumbnails
|
||||||
m_thumbnailsModel = new pdf::PDFThumbnailsItemModel(proxy, this);
|
m_thumbnailsModel = new pdf::PDFThumbnailsItemModel(proxy, this);
|
||||||
|
@ -126,13 +130,22 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||||
ui->attachmentsTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->attachmentsTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(ui->attachmentsTreeView, &QTreeView::customContextMenuRequested, this, &PDFSidebarWidget::onAttachmentCustomContextMenuRequested);
|
connect(ui->attachmentsTreeView, &QTreeView::customContextMenuRequested, this, &PDFSidebarWidget::onAttachmentCustomContextMenuRequested);
|
||||||
|
|
||||||
|
// Bookmarks
|
||||||
|
m_bookmarkItemModel = new PDFBookmarkItemModel(bookmarkManager, this);
|
||||||
|
ui->bookmarksView->setModel(m_bookmarkItemModel);
|
||||||
|
ui->bookmarksView->setItemDelegate(new PDFBookmarkItemDelegate(bookmarkManager, this));
|
||||||
|
connect(m_bookmarkManager, &PDFBookmarkManager::bookmarkActivated, this, &PDFSidebarWidget::onBookmarkActivated);
|
||||||
|
connect(ui->bookmarksView->selectionModel(), &QItemSelectionModel::currentChanged, this, &PDFSidebarWidget::onBookmarsCurrentIndexChanged);
|
||||||
|
connect(ui->bookmarksView, &QListView::clicked, this, &PDFSidebarWidget::onBookmarkClicked);
|
||||||
|
|
||||||
m_pageInfo[Invalid] = { nullptr, ui->emptyPage };
|
m_pageInfo[Invalid] = { nullptr, ui->emptyPage };
|
||||||
m_pageInfo[OptionalContent] = { ui->optionalContentButton, ui->optionalContentPage };
|
m_pageInfo[OptionalContent] = { ui->optionalContentButton, ui->optionalContentPage };
|
||||||
m_pageInfo[Bookmarks] = { ui->bookmarksButton, ui->bookmarksPage };
|
m_pageInfo[Outline] = { ui->outlineButton, ui->outlinePage };
|
||||||
m_pageInfo[Thumbnails] = { ui->thumbnailsButton, ui->thumbnailsPage };
|
m_pageInfo[Thumbnails] = { ui->thumbnailsButton, ui->thumbnailsPage };
|
||||||
m_pageInfo[Attachments] = { ui->attachmentsButton, ui->attachmentsPage };
|
m_pageInfo[Attachments] = { ui->attachmentsButton, ui->attachmentsPage };
|
||||||
m_pageInfo[Speech] = { ui->speechButton, ui->speechPage };
|
m_pageInfo[Speech] = { ui->speechButton, ui->speechPage };
|
||||||
m_pageInfo[Signatures] = { ui->signaturesButton, ui->signaturesPage };
|
m_pageInfo[Signatures] = { ui->signaturesButton, ui->signaturesPage };
|
||||||
|
m_pageInfo[Bookmarks] = { ui->bookmarksButton, ui->bookmarksPage };
|
||||||
|
|
||||||
for (const auto& pageInfo : m_pageInfo)
|
for (const auto& pageInfo : m_pageInfo)
|
||||||
{
|
{
|
||||||
|
@ -189,7 +202,7 @@ void PDFSidebarWidget::setDocument(const pdf::PDFModifiedDocument& document, con
|
||||||
switch (pageMode)
|
switch (pageMode)
|
||||||
{
|
{
|
||||||
case pdf::PageMode::UseOutlines:
|
case pdf::PageMode::UseOutlines:
|
||||||
preferred = Bookmarks;
|
preferred = Outline;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case pdf::PageMode::UseThumbnails:
|
case pdf::PageMode::UseThumbnails:
|
||||||
|
@ -210,7 +223,7 @@ void PDFSidebarWidget::setDocument(const pdf::PDFModifiedDocument& document, con
|
||||||
switch (nonFullscreenPageMode)
|
switch (nonFullscreenPageMode)
|
||||||
{
|
{
|
||||||
case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseOutline:
|
case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseOutline:
|
||||||
preferred = Bookmarks;
|
preferred = Outline;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseThumbnails:
|
case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseThumbnails:
|
||||||
|
@ -259,7 +272,7 @@ bool PDFSidebarWidget::isEmpty(Page page) const
|
||||||
case Invalid:
|
case Invalid:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Bookmarks:
|
case Outline:
|
||||||
return m_outlineTreeModel->isEmpty() && (!m_document || !m_outlineTreeModel->isEditable());
|
return m_outlineTreeModel->isEmpty() && (!m_document || !m_outlineTreeModel->isEditable());
|
||||||
|
|
||||||
case Thumbnails:
|
case Thumbnails:
|
||||||
|
@ -271,6 +284,9 @@ bool PDFSidebarWidget::isEmpty(Page page) const
|
||||||
case Attachments:
|
case Attachments:
|
||||||
return m_attachmentsTreeModel->isEmpty();
|
return m_attachmentsTreeModel->isEmpty();
|
||||||
|
|
||||||
|
case Bookmarks:
|
||||||
|
return !m_document || !m_bookmarkManager;
|
||||||
|
|
||||||
case Speech:
|
case Speech:
|
||||||
return !m_textToSpeech->isValid();
|
return !m_textToSpeech->isValid();
|
||||||
|
|
||||||
|
@ -764,11 +780,11 @@ void PDFSidebarWidget::onSignatureCustomContextMenuRequested(const QPoint& pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFSidebarWidget::onBookmarksTreeViewContextMenuRequested(const QPoint& pos)
|
void PDFSidebarWidget::onOutlineTreeViewContextMenuRequested(const QPoint& pos)
|
||||||
{
|
{
|
||||||
QMenu contextMenu;
|
QMenu contextMenu;
|
||||||
|
|
||||||
QModelIndex index = ui->bookmarksTreeView->indexAt(pos);
|
QModelIndex index = ui->outlineTreeView->indexAt(pos);
|
||||||
|
|
||||||
auto onFollow = [this, index]()
|
auto onFollow = [this, index]()
|
||||||
{
|
{
|
||||||
|
@ -779,22 +795,22 @@ void PDFSidebarWidget::onBookmarksTreeViewContextMenuRequested(const QPoint& pos
|
||||||
{
|
{
|
||||||
if (index.isValid())
|
if (index.isValid())
|
||||||
{
|
{
|
||||||
ui->bookmarksTreeView->model()->insertRow(index.row() + 1, index.parent());
|
ui->outlineTreeView->model()->insertRow(index.row() + 1, index.parent());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ui->bookmarksTreeView->model()->insertRow(ui->bookmarksTreeView->model()->rowCount());
|
ui->outlineTreeView->model()->insertRow(ui->outlineTreeView->model()->rowCount());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto onDelete = [this, index]()
|
auto onDelete = [this, index]()
|
||||||
{
|
{
|
||||||
ui->bookmarksTreeView->model()->removeRow(index.row(), index.parent());
|
ui->outlineTreeView->model()->removeRow(index.row(), index.parent());
|
||||||
};
|
};
|
||||||
|
|
||||||
auto onRename = [this, index]()
|
auto onRename = [this, index]()
|
||||||
{
|
{
|
||||||
ui->bookmarksTreeView->edit(index);
|
ui->outlineTreeView->edit(index);
|
||||||
};
|
};
|
||||||
|
|
||||||
QAction* followAction = contextMenu.addAction(tr("Follow"), onFollow);
|
QAction* followAction = contextMenu.addAction(tr("Follow"), onFollow);
|
||||||
|
@ -927,7 +943,7 @@ void PDFSidebarWidget::onBookmarksTreeViewContextMenuRequested(const QPoint& pos
|
||||||
submenu->addAction(tr("Fit Bounding Box Vertically"), createOnSetTarget(pdf::DestinationType::FitBV));
|
submenu->addAction(tr("Fit Bounding Box Vertically"), createOnSetTarget(pdf::DestinationType::FitBV));
|
||||||
submenu->addAction(tr("XYZ"), createOnSetTarget(pdf::DestinationType::XYZ));
|
submenu->addAction(tr("XYZ"), createOnSetTarget(pdf::DestinationType::XYZ));
|
||||||
|
|
||||||
contextMenu.exec(ui->bookmarksTreeView->mapToGlobal(pos));
|
contextMenu.exec(ui->outlineTreeView->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFSidebarWidget::onOutlineItemsChanged()
|
void PDFSidebarWidget::onOutlineItemsChanged()
|
||||||
|
@ -943,6 +959,46 @@ void PDFSidebarWidget::onOutlineItemsChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFSidebarWidget::onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark)
|
||||||
|
{
|
||||||
|
if (m_bookmarkChangeInProgress)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf::PDFTemporaryValueChange<bool> guard(&m_bookmarkChangeInProgress, true);
|
||||||
|
QModelIndex currentIndex = m_bookmarkItemModel->index(index, 0, QModelIndex());
|
||||||
|
ui->bookmarksView->selectionModel()->select(currentIndex, QItemSelectionModel::SelectCurrent);
|
||||||
|
ui->bookmarksView->setCurrentIndex(currentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFSidebarWidget::onBookmarsCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||||
|
{
|
||||||
|
Q_UNUSED(previous);
|
||||||
|
|
||||||
|
if (m_bookmarkChangeInProgress)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf::PDFTemporaryValueChange<bool> guard(&m_bookmarkChangeInProgress, true);
|
||||||
|
m_bookmarkManager->goToBookmark(current.row(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFSidebarWidget::onBookmarkClicked(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
if (m_bookmarkChangeInProgress)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == ui->bookmarksView->currentIndex())
|
||||||
|
{
|
||||||
|
pdf::PDFTemporaryValueChange<bool> guard(&m_bookmarkChangeInProgress, true);
|
||||||
|
m_bookmarkManager->goToCurrentBookmark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFSidebarWidget::paintEvent(QPaintEvent* event)
|
void PDFSidebarWidget::paintEvent(QPaintEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define PDFSIDEBARWIDGET_H
|
#define PDFSIDEBARWIDGET_H
|
||||||
|
|
||||||
#include "pdfglobal.h"
|
#include "pdfglobal.h"
|
||||||
|
#include "pdfbookmarkmanager.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ namespace pdfviewer
|
||||||
{
|
{
|
||||||
class PDFTextToSpeech;
|
class PDFTextToSpeech;
|
||||||
class PDFViewerSettings;
|
class PDFViewerSettings;
|
||||||
|
class PDFBookmarkItemModel;
|
||||||
|
|
||||||
class PDFSidebarWidget : public QWidget
|
class PDFSidebarWidget : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -61,6 +63,7 @@ public:
|
||||||
explicit PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
explicit PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||||
PDFTextToSpeech* textToSpeech,
|
PDFTextToSpeech* textToSpeech,
|
||||||
pdf::PDFCertificateStore* certificateStore,
|
pdf::PDFCertificateStore* certificateStore,
|
||||||
|
PDFBookmarkManager* bookmarkManager,
|
||||||
PDFViewerSettings* settings,
|
PDFViewerSettings* settings,
|
||||||
bool editableOutline,
|
bool editableOutline,
|
||||||
QWidget* parent);
|
QWidget* parent);
|
||||||
|
@ -72,12 +75,13 @@ public:
|
||||||
{
|
{
|
||||||
Invalid,
|
Invalid,
|
||||||
_BEGIN,
|
_BEGIN,
|
||||||
Bookmarks = _BEGIN,
|
Outline = _BEGIN,
|
||||||
Thumbnails,
|
Thumbnails,
|
||||||
OptionalContent,
|
OptionalContent,
|
||||||
Attachments,
|
Attachments,
|
||||||
Speech,
|
Speech,
|
||||||
Signatures,
|
Signatures,
|
||||||
|
Bookmarks,
|
||||||
_END
|
_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,8 +117,11 @@ private:
|
||||||
void onAttachmentCustomContextMenuRequested(const QPoint& pos);
|
void onAttachmentCustomContextMenuRequested(const QPoint& pos);
|
||||||
void onThumbnailClicked(const QModelIndex& index);
|
void onThumbnailClicked(const QModelIndex& index);
|
||||||
void onSignatureCustomContextMenuRequested(const QPoint &pos);
|
void onSignatureCustomContextMenuRequested(const QPoint &pos);
|
||||||
void onBookmarksTreeViewContextMenuRequested(const QPoint &pos);
|
void onOutlineTreeViewContextMenuRequested(const QPoint &pos);
|
||||||
void onOutlineItemsChanged();
|
void onOutlineItemsChanged();
|
||||||
|
void onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark);
|
||||||
|
void onBookmarsCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
|
void onBookmarkClicked(const QModelIndex& index);
|
||||||
|
|
||||||
struct PageInfo
|
struct PageInfo
|
||||||
{
|
{
|
||||||
|
@ -126,16 +133,19 @@ private:
|
||||||
pdf::PDFDrawWidgetProxy* m_proxy;
|
pdf::PDFDrawWidgetProxy* m_proxy;
|
||||||
PDFTextToSpeech* m_textToSpeech;
|
PDFTextToSpeech* m_textToSpeech;
|
||||||
pdf::PDFCertificateStore* m_certificateStore;
|
pdf::PDFCertificateStore* m_certificateStore;
|
||||||
|
PDFBookmarkManager* m_bookmarkManager;
|
||||||
PDFViewerSettings* m_settings;
|
PDFViewerSettings* m_settings;
|
||||||
pdf::PDFOutlineTreeItemModel* m_outlineTreeModel;
|
pdf::PDFOutlineTreeItemModel* m_outlineTreeModel;
|
||||||
pdf::PDFThumbnailsItemModel* m_thumbnailsModel;
|
pdf::PDFThumbnailsItemModel* m_thumbnailsModel;
|
||||||
pdf::PDFOptionalContentTreeItemModel* m_optionalContentTreeModel;
|
pdf::PDFOptionalContentTreeItemModel* m_optionalContentTreeModel;
|
||||||
|
PDFBookmarkItemModel* m_bookmarkItemModel;
|
||||||
const pdf::PDFDocument* m_document;
|
const pdf::PDFDocument* m_document;
|
||||||
pdf::PDFOptionalContentActivity* m_optionalContentActivity;
|
pdf::PDFOptionalContentActivity* m_optionalContentActivity;
|
||||||
pdf::PDFAttachmentsTreeItemModel* m_attachmentsTreeModel;
|
pdf::PDFAttachmentsTreeItemModel* m_attachmentsTreeModel;
|
||||||
std::map<Page, PageInfo> m_pageInfo;
|
std::map<Page, PageInfo> m_pageInfo;
|
||||||
std::vector<pdf::PDFSignatureVerificationResult> m_signatures;
|
std::vector<pdf::PDFSignatureVerificationResult> m_signatures;
|
||||||
std::vector<pdf::PDFCertificateInfo> m_certificateInfos;
|
std::vector<pdf::PDFCertificateInfo> m_certificateInfos;
|
||||||
|
bool m_bookmarkChangeInProgress = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdfviewer
|
} // namespace pdfviewer
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>339</width>
|
<width>388</width>
|
||||||
<height>584</height>
|
<height>681</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="sidebarLayout">
|
<layout class="QHBoxLayout" name="sidebarLayout">
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="bookmarksButton">
|
<widget class="QToolButton" name="outlineButton">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>96</width>
|
<width>96</width>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Bookmarks</string>
|
<string>Outline</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="pdf4qtviewer.qrc">
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
@ -225,6 +225,35 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="bookmarksButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>96</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/sidebar-favourites.svg</normaloff>:/resources/sidebar-favourites.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="buttonSpacer">
|
<spacer name="buttonSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -243,11 +272,11 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="emptyPage"/>
|
<widget class="QWidget" name="emptyPage"/>
|
||||||
<widget class="QWidget" name="bookmarksPage">
|
<widget class="QWidget" name="outlinePage">
|
||||||
<layout class="QVBoxLayout" name="bookmarksPageLayout">
|
<layout class="QVBoxLayout" name="outlinePageLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -264,7 +293,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="bookmarksTreeView"/>
|
<widget class="QTreeView" name="outlineTreeView"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -383,6 +412,32 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="bookmarksPage">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="bookmarksView">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="speechPage">
|
<widget class="QWidget" name="speechPage">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -194,6 +194,12 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||||
m_actionManager->setAction(PDFActionManager::ToolScreenshot, ui->actionScreenshot);
|
m_actionManager->setAction(PDFActionManager::ToolScreenshot, ui->actionScreenshot);
|
||||||
m_actionManager->setAction(PDFActionManager::ToolExtractImage, ui->actionExtractImage);
|
m_actionManager->setAction(PDFActionManager::ToolExtractImage, ui->actionExtractImage);
|
||||||
m_actionManager->setAction(PDFActionManager::DeveloperCreateInstaller, ui->actionDeveloperCreateInstaller);
|
m_actionManager->setAction(PDFActionManager::DeveloperCreateInstaller, ui->actionDeveloperCreateInstaller);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkPage, ui->actionBookmarkPage);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkGoToNext, ui->actionGotoNextBookmark);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkGoToPrevious, ui->actionGotoPreviousBookmark);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkExport, ui->actionBookmarkExport);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkImport, ui->actionBookmarkImport);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkGenerateAutomatically, ui->actionBookmarkAutoGenerate);
|
||||||
m_actionManager->initActions(pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)), true);
|
m_actionManager->initActions(pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)), true);
|
||||||
|
|
||||||
for (QAction* action : m_programController->getRecentFileManager()->getActions())
|
for (QAction* action : m_programController->getRecentFileManager()->getActions())
|
||||||
|
@ -269,7 +275,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||||
setCentralWidget(m_programController->getPdfWidget());
|
setCentralWidget(m_programController->getPdfWidget());
|
||||||
setFocusProxy(m_programController->getPdfWidget());
|
setFocusProxy(m_programController->getPdfWidget());
|
||||||
|
|
||||||
m_sidebarWidget = new PDFSidebarWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), m_programController->getTextToSpeech(), m_programController->getCertificateStore(), m_programController->getSettings(), true, this);
|
m_sidebarWidget = new PDFSidebarWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), m_programController->getTextToSpeech(), m_programController->getCertificateStore(), m_programController->getBookmarkManager(), m_programController->getSettings(), true, this);
|
||||||
m_sidebarDockWidget = new QDockWidget(tr("Sidebar"), this);
|
m_sidebarDockWidget = new QDockWidget(tr("Sidebar"), this);
|
||||||
m_sidebarDockWidget->setObjectName("SidebarDockWidget");
|
m_sidebarDockWidget->setObjectName("SidebarDockWidget");
|
||||||
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
|
|
@ -46,12 +46,25 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Go To</string>
|
<string>Go To</string>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menuBookmarkSettings">
|
||||||
|
<property name="title">
|
||||||
|
<string>Bookmark Settings</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionBookmarkExport"/>
|
||||||
|
<addaction name="actionBookmarkImport"/>
|
||||||
|
<addaction name="actionBookmarkAutoGenerate"/>
|
||||||
|
</widget>
|
||||||
<addaction name="actionGoToDocumentStart"/>
|
<addaction name="actionGoToDocumentStart"/>
|
||||||
<addaction name="actionGoToDocumentEnd"/>
|
<addaction name="actionGoToDocumentEnd"/>
|
||||||
<addaction name="actionGoToPreviousPage"/>
|
<addaction name="actionGoToPreviousPage"/>
|
||||||
<addaction name="actionGoToNextPage"/>
|
<addaction name="actionGoToNextPage"/>
|
||||||
<addaction name="actionGoToPreviousLine"/>
|
<addaction name="actionGoToPreviousLine"/>
|
||||||
<addaction name="actionGoToNextLine"/>
|
<addaction name="actionGoToNextLine"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionBookmarkPage"/>
|
||||||
|
<addaction name="actionGotoPreviousBookmark"/>
|
||||||
|
<addaction name="actionGotoNextBookmark"/>
|
||||||
|
<addaction name="menuBookmarkSettings"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuView">
|
<widget class="QMenu" name="menuView">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -1051,6 +1064,99 @@
|
||||||
<string>Convert the colored images to monochromatic to create a bitonal document.</string>
|
<string>Convert the colored images to monochromatic to create a bitonal document.</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionBookmarkPage">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Bookmark Page</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Bookmark Page</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Bookmark page for fast navigation.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGotoNextBookmark">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark-next.svg</normaloff>:/resources/bookmark-next.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go to Next Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go to Next Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Navigates to the next bookmarked page.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGotoPreviousBookmark">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark-previous.svg</normaloff>:/resources/bookmark-previous.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go to Previous Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go to Previous Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Navigates to the previous bookmarked page.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionBookmarkExport">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Export Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Export Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Export bookmarks to the file.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionBookmarkImport">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Import Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Import bookmarks from the file.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionBookmarkAutoGenerate">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Generate Bookmarks Automatically</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Generate Bookmarks Automatically</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>If checked, bookmarks for main document chapters are generated automatically.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
|
@ -151,6 +151,12 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
|
||||||
m_actionManager->setAction(PDFActionManager::PageLayoutTwoPages, ui->actionPageLayoutTwoPages);
|
m_actionManager->setAction(PDFActionManager::PageLayoutTwoPages, ui->actionPageLayoutTwoPages);
|
||||||
m_actionManager->setAction(PDFActionManager::PageLayoutTwoColumns, ui->actionPageLayoutTwoColumns);
|
m_actionManager->setAction(PDFActionManager::PageLayoutTwoColumns, ui->actionPageLayoutTwoColumns);
|
||||||
m_actionManager->setAction(PDFActionManager::PageLayoutFirstPageOnRightSide, ui->actionFirstPageOnRightSide);
|
m_actionManager->setAction(PDFActionManager::PageLayoutFirstPageOnRightSide, ui->actionFirstPageOnRightSide);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkPage, ui->actionBookmarkPage);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkGoToNext, ui->actionGotoNextBookmark);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkGoToPrevious, ui->actionGotoPreviousBookmark);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkExport, ui->actionBookmarkExport);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkImport, ui->actionBookmarkImport);
|
||||||
|
m_actionManager->setAction(PDFActionManager::BookmarkGenerateAutomatically, ui->actionBookmarkAutoGenerate);
|
||||||
m_actionManager->initActions(pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)), true);
|
m_actionManager->initActions(pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)), true);
|
||||||
|
|
||||||
for (QAction* action : m_programController->getRecentFileManager()->getActions())
|
for (QAction* action : m_programController->getRecentFileManager()->getActions())
|
||||||
|
@ -202,7 +208,7 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
|
||||||
setCentralWidget(m_programController->getPdfWidget());
|
setCentralWidget(m_programController->getPdfWidget());
|
||||||
setFocusProxy(m_programController->getPdfWidget());
|
setFocusProxy(m_programController->getPdfWidget());
|
||||||
|
|
||||||
m_sidebarWidget = new PDFSidebarWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), m_programController->getTextToSpeech(), m_programController->getCertificateStore(), m_programController->getSettings(), false, this);
|
m_sidebarWidget = new PDFSidebarWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), m_programController->getTextToSpeech(), m_programController->getCertificateStore(), m_programController->getBookmarkManager(), m_programController->getSettings(), false, this);
|
||||||
m_sidebarDockWidget = new QDockWidget(tr("Sidebar"), this);
|
m_sidebarDockWidget = new QDockWidget(tr("Sidebar"), this);
|
||||||
m_sidebarDockWidget->setObjectName("SidebarDockWidget");
|
m_sidebarDockWidget->setObjectName("SidebarDockWidget");
|
||||||
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
|
|
@ -42,12 +42,26 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Go To</string>
|
<string>Go To</string>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menuBookmarkSettings">
|
||||||
|
<property name="title">
|
||||||
|
<string>Bookmark Settings</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionBookmarkExport"/>
|
||||||
|
<addaction name="actionBookmarkImport"/>
|
||||||
|
<addaction name="actionBookmarkAutoGenerate"/>
|
||||||
|
</widget>
|
||||||
<addaction name="actionGoToDocumentStart"/>
|
<addaction name="actionGoToDocumentStart"/>
|
||||||
<addaction name="actionGoToDocumentEnd"/>
|
<addaction name="actionGoToDocumentEnd"/>
|
||||||
<addaction name="actionGoToPreviousPage"/>
|
<addaction name="actionGoToPreviousPage"/>
|
||||||
<addaction name="actionGoToNextPage"/>
|
<addaction name="actionGoToNextPage"/>
|
||||||
<addaction name="actionGoToPreviousLine"/>
|
<addaction name="actionGoToPreviousLine"/>
|
||||||
<addaction name="actionGoToNextLine"/>
|
<addaction name="actionGoToNextLine"/>
|
||||||
|
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionBookmarkPage"/>
|
||||||
|
<addaction name="actionGotoPreviousBookmark"/>
|
||||||
|
<addaction name="actionGotoNextBookmark"/>
|
||||||
|
<addaction name="menuBookmarkSettings"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuView">
|
<widget class="QMenu" name="menuView">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -543,6 +557,100 @@
|
||||||
<string>Become a Sponsor</string>
|
<string>Become a Sponsor</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action name="actionBookmarkPage">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Bookmark Page</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Bookmark Page</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Bookmark page for fast navigation.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGotoNextBookmark">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark-next.svg</normaloff>:/resources/bookmark-next.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go to Next Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go to Next Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Navigates to the next bookmarked page.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGotoPreviousBookmark">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark-previous.svg</normaloff>:/resources/bookmark-previous.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go to Previous Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go to Previous Bookmark</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Navigates to the previous bookmarked page.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionBookmarkExport">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Export Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Export Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Export bookmarks to the file.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionBookmarkImport">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Import Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Import bookmarks from the file.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionBookmarkAutoGenerate">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="pdf4qtviewer.qrc">
|
||||||
|
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Generate Bookmarks Automatically</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Generate Bookmarks Automatically</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>If checked, bookmarks for main document chapters are generated automatically.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
|
@ -104,6 +104,10 @@ void PDFViewerSettings::readSettings(QSettings& settings, const pdf::PDFCMSSetti
|
||||||
m_settings.m_signatureUseSystemStore = settings.value("signatureUseSystemStore", defaultSettings.m_signatureUseSystemStore).toBool();
|
m_settings.m_signatureUseSystemStore = settings.value("signatureUseSystemStore", defaultSettings.m_signatureUseSystemStore).toBool();
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Bookmarks");
|
||||||
|
m_settings.m_autoGenerateBookmarks = settings.value("autoGenerateBookmarks", defaultSettings.m_autoGenerateBookmarks).toBool();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
Q_EMIT settingsChanged();
|
Q_EMIT settingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +178,10 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
|
||||||
settings.setValue("signatureIgnoreCertificateValidityTime", m_settings.m_signatureIgnoreCertificateValidityTime);
|
settings.setValue("signatureIgnoreCertificateValidityTime", m_settings.m_signatureIgnoreCertificateValidityTime);
|
||||||
settings.setValue("signatureUseSystemStore", m_settings.m_signatureUseSystemStore);
|
settings.setValue("signatureUseSystemStore", m_settings.m_signatureUseSystemStore);
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Bookmarks");
|
||||||
|
settings.setValue("autoGenerateBookmarks", m_settings.m_autoGenerateBookmarks);
|
||||||
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PDFViewerSettings::getDirectory() const
|
QString PDFViewerSettings::getDirectory() const
|
||||||
|
@ -287,7 +295,8 @@ PDFViewerSettings::Settings::Settings() :
|
||||||
m_signatureVerificationEnabled(true),
|
m_signatureVerificationEnabled(true),
|
||||||
m_signatureTreatWarningsAsErrors(false),
|
m_signatureTreatWarningsAsErrors(false),
|
||||||
m_signatureIgnoreCertificateValidityTime(false),
|
m_signatureIgnoreCertificateValidityTime(false),
|
||||||
m_signatureUseSystemStore(true)
|
m_signatureUseSystemStore(true),
|
||||||
|
m_autoGenerateBookmarks(true)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,9 @@ public:
|
||||||
bool m_signatureTreatWarningsAsErrors;
|
bool m_signatureTreatWarningsAsErrors;
|
||||||
bool m_signatureIgnoreCertificateValidityTime;
|
bool m_signatureIgnoreCertificateValidityTime;
|
||||||
bool m_signatureUseSystemStore;
|
bool m_signatureUseSystemStore;
|
||||||
|
|
||||||
|
// Bookmarks settings
|
||||||
|
bool m_autoGenerateBookmarks;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Settings& getSettings() const { return m_settings; }
|
const Settings& getSettings() const { return m_settings; }
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg815"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
sodipodi:docname="bookmark-next.svg"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||||
|
<metadata
|
||||||
|
id="metadata821">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs819" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2035"
|
||||||
|
id="namedview817"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.4279174"
|
||||||
|
inkscape:cx="137.55859"
|
||||||
|
inkscape:cy="137.21551"
|
||||||
|
inkscape:window-x="-13"
|
||||||
|
inkscape:window-y="-13"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg815" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path839"
|
||||||
|
sodipodi:sides="5"
|
||||||
|
sodipodi:cx="259.20364"
|
||||||
|
sodipodi:cy="269.65189"
|
||||||
|
sodipodi:r1="203.30641"
|
||||||
|
sodipodi:r2="101.65321"
|
||||||
|
sodipodi:arg1="-1.585122"
|
||||||
|
sodipodi:arg2="-0.95680346"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
|
||||||
|
inkscape:transform-center-x="0.89998123"
|
||||||
|
inkscape:transform-center-y="-18.55611" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:31.68950462;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 220.58404,237.11509 v 70.93287 c 0,14.53213 13.81864,23.63982 24.86768,16.38716 l 26.95074,-17.71983 26.95662,-17.78679 c 11.03729,-7.24597 11.03729,-25.42788 0,-32.68725 l -26.95662,-17.7734 -26.95074,-17.72652 c -11.04904,-7.27945 -24.86768,1.76127 -24.86768,16.37376 z"
|
||||||
|
id="path1701" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg815"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
sodipodi:docname="bookmark-previous.svg"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||||
|
<metadata
|
||||||
|
id="metadata821">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs819" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2035"
|
||||||
|
id="namedview817"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.21459961"
|
||||||
|
inkscape:cx="-2504.7782"
|
||||||
|
inkscape:cy="317.10796"
|
||||||
|
inkscape:window-x="-13"
|
||||||
|
inkscape:window-y="-13"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg815" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path839"
|
||||||
|
sodipodi:sides="5"
|
||||||
|
sodipodi:cx="259.20364"
|
||||||
|
sodipodi:cy="269.65189"
|
||||||
|
sodipodi:r1="203.30641"
|
||||||
|
sodipodi:r2="101.65321"
|
||||||
|
sodipodi:arg1="-1.585122"
|
||||||
|
sodipodi:arg2="-0.95680346"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
|
||||||
|
inkscape:transform-center-x="0.89998123"
|
||||||
|
inkscape:transform-center-y="-18.55611" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:31.68950462;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 292.61298,235.87946 v 70.93287 c 0,14.53213 -13.81864,23.63982 -24.86768,16.38716 l -26.95074,-17.71983 -26.95662,-17.78679 c -11.03729,-7.24597 -11.03729,-25.42788 0,-32.68725 l 26.95662,-17.7734 26.95074,-17.72652 c 11.04904,-7.27945 24.86768,1.76127 24.86768,16.37376 z"
|
||||||
|
id="path1701" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -1,10 +1,70 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg
|
||||||
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
<g>
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
<path fill="#CCCED0" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M20.264,22.624
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
L12,16.722l-8.264,5.902V3.737c0-1.304,1.057-2.361,2.361-2.361h11.805c1.305,0,2.361,1.057,2.361,2.361V22.624z"/>
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
</g>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg815"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
sodipodi:docname="sidebar-favourites.svg"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||||
|
<metadata
|
||||||
|
id="metadata821">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs819" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2035"
|
||||||
|
id="namedview817"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.2139587"
|
||||||
|
inkscape:cx="535.31725"
|
||||||
|
inkscape:cy="132.65123"
|
||||||
|
inkscape:window-x="-13"
|
||||||
|
inkscape:window-y="-13"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg815" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path839"
|
||||||
|
sodipodi:sides="5"
|
||||||
|
sodipodi:cx="259.20364"
|
||||||
|
sodipodi:cy="269.65189"
|
||||||
|
sodipodi:r1="203.30641"
|
||||||
|
sodipodi:r2="101.65321"
|
||||||
|
sodipodi:arg1="-1.585122"
|
||||||
|
sodipodi:arg2="-0.95680346"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
|
||||||
|
inkscape:transform-center-x="0.89998123"
|
||||||
|
inkscape:transform-center-y="-18.55611" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 718 B After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path fill="#CCCED0" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M20.264,22.624
|
||||||
|
L12,16.722l-8.264,5.902V3.737c0-1.304,1.057-2.361,2.361-2.361h11.805c1.305,0,2.361,1.057,2.361,2.361V22.624z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 718 B |
|
@ -0,0 +1,70 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg815"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
sodipodi:docname="sidebar-favourites.svg"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||||
|
<metadata
|
||||||
|
id="metadata821">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs819" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2035"
|
||||||
|
id="namedview817"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.2139587"
|
||||||
|
inkscape:cx="535.31725"
|
||||||
|
inkscape:cy="132.65123"
|
||||||
|
inkscape:window-x="-13"
|
||||||
|
inkscape:window-y="-13"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg815" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path839"
|
||||||
|
sodipodi:sides="5"
|
||||||
|
sodipodi:cx="259.20364"
|
||||||
|
sodipodi:cy="269.65189"
|
||||||
|
sodipodi:r1="203.30641"
|
||||||
|
sodipodi:r2="101.65321"
|
||||||
|
sodipodi:arg1="-1.585122"
|
||||||
|
sodipodi:arg2="-0.95680346"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
|
||||||
|
inkscape:transform-center-x="0.89998123"
|
||||||
|
inkscape:transform-center-y="-18.55611" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |