Merge remote-tracking branch 'remotes/origin/branches/issue54'
|
@ -27,12 +27,12 @@ add_executable(Pdf4QtDocPageOrganizer
|
|||
pageitemdelegate.h
|
||||
pageitemmodel.cpp
|
||||
pageitemmodel.h
|
||||
selectbookmarkstoregroupdialog.cpp
|
||||
selectbookmarkstoregroupdialog.h
|
||||
selectoutlinetoregroupdialog.cpp
|
||||
selectoutlinetoregroupdialog.h
|
||||
aboutdialog.ui
|
||||
assembleoutputsettingsdialog.ui
|
||||
mainwindow.ui
|
||||
selectbookmarkstoregroupdialog.ui
|
||||
selectoutlinetoregroupdialog.ui
|
||||
resources.qrc
|
||||
icon.rc
|
||||
)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "aboutdialog.h"
|
||||
#include "assembleoutputsettingsdialog.h"
|
||||
#include "selectbookmarkstoregroupdialog.h"
|
||||
#include "selectoutlinetoregroupdialog.h"
|
||||
|
||||
#include "pdfaction.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
|
@ -94,7 +94,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
ui->actionInvert_Selection->setData(int(Operation::InvertSelection));
|
||||
ui->actionRegroup_Even_Odd->setData(int(Operation::RegroupEvenOdd));
|
||||
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_Reversed_Order->setData(int(Operation::RegroupAlternatingPagesReversed));
|
||||
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->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_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_Reversed_Order, ":/pdfdocpage/resources/regroup-alternating-reversed.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 });
|
||||
QToolBar* regroupToolbar = addToolBar(tr("Regroup"));
|
||||
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"));
|
||||
zoomToolbar->setObjectName("zoom_toolbar");
|
||||
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_Reversed_Order);
|
||||
regroupMenu->addAction(ui->actionRegroup_by_Page_Pairs);
|
||||
regroupMenu->addAction(ui->actionRegroup_by_Bookmarks);
|
||||
regroupMenu->addAction(ui->actionRegroup_by_Outline);
|
||||
contextMenu->addSeparator();
|
||||
contextMenu->addAction(ui->actionGroup);
|
||||
contextMenu->addAction(ui->actionUngroup);
|
||||
|
@ -482,7 +482,7 @@ bool MainWindow::canPerformOperation(Operation operation) const
|
|||
case Operation::RegroupPaired:
|
||||
return !isModelEmpty && !selection.isEmpty();
|
||||
|
||||
case Operation::RegroupBookmarks:
|
||||
case Operation::RegroupOutline:
|
||||
{
|
||||
PageItemModel::SelectionInfo info = m_model->getSelectionInfo(selection);
|
||||
return info.isSingleDocument();
|
||||
|
@ -916,7 +916,7 @@ void MainWindow::performOperation(Operation operation)
|
|||
break;
|
||||
}
|
||||
|
||||
case Operation::RegroupBookmarks:
|
||||
case Operation::RegroupOutline:
|
||||
{
|
||||
QModelIndexList indexes = ui->documentItemsView->selectionModel()->selection().indexes();
|
||||
|
||||
|
@ -929,9 +929,9 @@ void MainWindow::performOperation(Operation operation)
|
|||
if (it != documents.end())
|
||||
{
|
||||
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<const pdf::PDFOutlineItem*> outlineItems = dialog.getSelectedOutlineItems();
|
||||
|
@ -972,7 +972,7 @@ void MainWindow::performOperation(Operation operation)
|
|||
std::sort(breakPageIndices.begin(), 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,
|
||||
RegroupPaired,
|
||||
RegroupBookmarks,
|
||||
RegroupOutline,
|
||||
RegroupAlternatingPages,
|
||||
RegroupAlternatingPagesReversed,
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
</property>
|
||||
<addaction name="actionRegroup_Even_Odd"/>
|
||||
<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_Reversed_Order"/>
|
||||
</widget>
|
||||
|
@ -533,13 +533,13 @@
|
|||
<string>Regroup by Page Pairs</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRegroup_by_Bookmarks">
|
||||
<action name="actionRegroup_by_Outline">
|
||||
<property name="icon">
|
||||
<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 name="text">
|
||||
<string>Regroup by Bookmarks</string>
|
||||
<string>Regroup by Outline</string>
|
||||
</property>
|
||||
</action>
|
||||
<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())
|
||||
{
|
||||
|
|
|
@ -191,7 +191,7 @@ public:
|
|||
|
||||
void regroupEvenOdd(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);
|
||||
|
||||
bool canUndo() const { return !m_undoSteps.empty(); }
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
<file>resources/invert-selection.svg</file>
|
||||
<file>resources/regroup-alternating.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-pairs.svg</file>
|
||||
<file>resources/undo.svg</file>
|
||||
<file>resources/redo.svg</file>
|
||||
<file>resources/bookmark.svg</file>
|
||||
<file>resources/wallet.svg</file>
|
||||
<file>resources/regroup-outline.svg</file>
|
||||
</qresource>
|
||||
</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
|
||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "selectbookmarkstoregroupdialog.h"
|
||||
#include "ui_selectbookmarkstoregroupdialog.h"
|
||||
#include "selectoutlinetoregroupdialog.h"
|
||||
#include "ui_selectoutlinetoregroupdialog.h"
|
||||
|
||||
#include "pdfitemmodels.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
|
@ -26,9 +26,9 @@
|
|||
namespace pdfdocpage
|
||||
{
|
||||
|
||||
SelectBookmarksToRegroupDialog::SelectBookmarksToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent) :
|
||||
SelectOutlineToRegroupDialog::SelectOutlineToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SelectBookmarksToRegroupDialog),
|
||||
ui(new Ui::SelectOutlineToRegroupDialog),
|
||||
m_document(document),
|
||||
m_model(nullptr)
|
||||
{
|
||||
|
@ -36,53 +36,53 @@ SelectBookmarksToRegroupDialog::SelectBookmarksToRegroupDialog(const pdf::PDFDoc
|
|||
|
||||
QIcon bookmarkIcon(":/pdfdocpage/resources/bookmark.svg");
|
||||
m_model = new pdf::PDFSelectableOutlineTreeItemModel(qMove(bookmarkIcon), this);
|
||||
ui->bookmarksView->setModel(m_model);
|
||||
ui->bookmarksView->header()->hide();
|
||||
ui->outlineView->setModel(m_model);
|
||||
ui->outlineView->header()->hide();
|
||||
|
||||
m_model->setDocument(pdf::PDFModifiedDocument(const_cast<pdf::PDFDocument*>(document), nullptr));
|
||||
ui->bookmarksView->expandToDepth(2);
|
||||
ui->bookmarksView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->bookmarksView, &QTreeView::customContextMenuRequested, this, &SelectBookmarksToRegroupDialog::onViewContextMenuRequested);
|
||||
ui->outlineView->expandToDepth(2);
|
||||
ui->outlineView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->outlineView, &QTreeView::customContextMenuRequested, this, &SelectOutlineToRegroupDialog::onViewContextMenuRequested);
|
||||
|
||||
QSize size = pdf::PDFWidgetUtils::scaleDPI(this, QSize(400, 600));
|
||||
setMinimumSize(size);
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
SelectBookmarksToRegroupDialog::~SelectBookmarksToRegroupDialog()
|
||||
SelectOutlineToRegroupDialog::~SelectOutlineToRegroupDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
std::vector<const pdf::PDFOutlineItem*> SelectBookmarksToRegroupDialog::getSelectedOutlineItems() const
|
||||
std::vector<const pdf::PDFOutlineItem*> SelectOutlineToRegroupDialog::getSelectedOutlineItems() const
|
||||
{
|
||||
return m_model->getSelectedItems();
|
||||
}
|
||||
|
||||
void SelectBookmarksToRegroupDialog::onViewContextMenuRequested(const QPoint& pos)
|
||||
void SelectOutlineToRegroupDialog::onViewContextMenuRequested(const QPoint& pos)
|
||||
{
|
||||
QMenu menu;
|
||||
menu.addAction(tr("Select All"), this, &SelectBookmarksToRegroupDialog::selectAll);
|
||||
menu.addAction(tr("Deselect All"), this, &SelectBookmarksToRegroupDialog::deselectAll);
|
||||
menu.addAction(tr("Invert Selection"), this, &SelectBookmarksToRegroupDialog::invertSelection);
|
||||
menu.addAction(tr("Select All"), this, &SelectOutlineToRegroupDialog::selectAll);
|
||||
menu.addAction(tr("Deselect All"), this, &SelectOutlineToRegroupDialog::deselectAll);
|
||||
menu.addAction(tr("Invert Selection"), this, &SelectOutlineToRegroupDialog::invertSelection);
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Select Level 1"), this, &SelectBookmarksToRegroupDialog::selectLevel1);
|
||||
menu.addAction(tr("Select Level 2"), this, &SelectBookmarksToRegroupDialog::selectLevel2);
|
||||
menu.addAction(tr("Select Level 1"), this, &SelectOutlineToRegroupDialog::selectLevel1);
|
||||
menu.addAction(tr("Select Level 2"), this, &SelectOutlineToRegroupDialog::selectLevel2);
|
||||
|
||||
QModelIndex index = ui->bookmarksView->indexAt(pos);
|
||||
QModelIndex index = ui->outlineView->indexAt(pos);
|
||||
if (index.isValid())
|
||||
{
|
||||
m_menuIndex = index;
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Select subtree"), this, &SelectBookmarksToRegroupDialog::selectSubtree);
|
||||
menu.addAction(tr("Deselect subtree"), this, &SelectBookmarksToRegroupDialog::deselectSubtree);
|
||||
menu.addAction(tr("Select subtree"), this, &SelectOutlineToRegroupDialog::selectSubtree);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -119,42 +119,42 @@ std::function<void (QModelIndex)> SelectBookmarksToRegroupDialog::createCheckByD
|
|||
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)
|
||||
{
|
||||
const bool isChecked = index.data(Qt::CheckStateRole).toInt() == Qt::Checked;
|
||||
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); });
|
||||
}
|
||||
|
||||
void SelectBookmarksToRegroupDialog::deselectSubtree()
|
||||
void SelectOutlineToRegroupDialog::deselectSubtree()
|
||||
{
|
||||
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
|
||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFDOCPAGEORGANIZER_SELECTBOOKMARKSTOREGROUPDIALOG_H
|
||||
#define PDFDOCPAGEORGANIZER_SELECTBOOKMARKSTOREGROUPDIALOG_H
|
||||
#ifndef PDFDOCPAGEORGANIZER_SELECTOUTLINETOREGROUPDIALOG_H
|
||||
#define PDFDOCPAGEORGANIZER_SELECTOUTLINETOREGROUPDIALOG_H
|
||||
|
||||
#include "pdfdocument.h"
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
|||
|
||||
namespace Ui
|
||||
{
|
||||
class SelectBookmarksToRegroupDialog;
|
||||
class SelectOutlineToRegroupDialog;
|
||||
}
|
||||
|
||||
namespace pdf
|
||||
|
@ -35,13 +35,13 @@ class PDFSelectableOutlineTreeItemModel;
|
|||
namespace pdfdocpage
|
||||
{
|
||||
|
||||
class SelectBookmarksToRegroupDialog : public QDialog
|
||||
class SelectOutlineToRegroupDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SelectBookmarksToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent);
|
||||
virtual ~SelectBookmarksToRegroupDialog() override;
|
||||
explicit SelectOutlineToRegroupDialog(const pdf::PDFDocument* document, QWidget* parent);
|
||||
virtual ~SelectOutlineToRegroupDialog() override;
|
||||
|
||||
std::vector<const pdf::PDFOutlineItem*> getSelectedOutlineItems() const;
|
||||
|
||||
|
@ -62,7 +62,7 @@ private:
|
|||
|
||||
std::function<void (QModelIndex)> createCheckByDepthManipulator(int targetDepth) const;
|
||||
|
||||
Ui::SelectBookmarksToRegroupDialog* ui;
|
||||
Ui::SelectOutlineToRegroupDialog* ui;
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFSelectableOutlineTreeItemModel* m_model;
|
||||
QModelIndex m_menuIndex;
|
||||
|
@ -70,4 +70,4 @@ private:
|
|||
|
||||
} // namespace pdfdocpage
|
||||
|
||||
#endif // PDFDOCPAGEORGANIZER_SELECTBOOKMARKSTOREGROUPDIALOG_H
|
||||
#endif // PDFDOCPAGEORGANIZER_SELECTOUTLINETOREGROUPDIALOG_H
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SelectBookmarksToRegroupDialog</class>
|
||||
<widget class="QDialog" name="SelectBookmarksToRegroupDialog">
|
||||
<class>SelectOutlineToRegroupDialog</class>
|
||||
<widget class="QDialog" name="SelectOutlineToRegroupDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -11,11 +11,11 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Select Bookmarks</string>
|
||||
<string>Select Outline</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeView" name="bookmarksView"/>
|
||||
<widget class="QTreeView" name="outlineView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
|
@ -34,7 +34,7 @@
|
|||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SelectBookmarksToRegroupDialog</receiver>
|
||||
<receiver>SelectOutlineToRegroupDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
|
@ -50,7 +50,7 @@
|
|||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SelectBookmarksToRegroupDialog</receiver>
|
||||
<receiver>SelectOutlineToRegroupDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
|
@ -86,9 +86,9 @@ void PDFDocumentSanitizer::sanitize()
|
|||
performSanitizeMetadata();
|
||||
}
|
||||
|
||||
if (m_flags.testFlag(Bookmarks))
|
||||
if (m_flags.testFlag(Outline))
|
||||
{
|
||||
performSanitizeBookmarks();
|
||||
performSanitizeOutline();
|
||||
}
|
||||
|
||||
if (m_flags.testFlag(FileAttachments))
|
||||
|
@ -163,7 +163,7 @@ void PDFDocumentSanitizer::performSanitizeMetadata()
|
|||
Q_EMIT sanitizationProgress(tr("Metadata streams removed: %1").arg(counter));
|
||||
}
|
||||
|
||||
void PDFDocumentSanitizer::performSanitizeBookmarks()
|
||||
void PDFDocumentSanitizer::performSanitizeOutline()
|
||||
{
|
||||
PDFDocumentBuilder builder(m_storage, PDFVersion(2, 0));
|
||||
PDFObject catalogObject = builder.getObjectByReference(builder.getCatalogReference());
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
None = 0x0000, ///< No sanitization is performed
|
||||
DocumentInfo = 0x0001, ///< Remove document information
|
||||
Metadata = 0x0002, ///< Remove all metadata streams in all objects
|
||||
Bookmarks = 0x0004, ///< Remove bookmarks
|
||||
Outline = 0x0004, ///< Remove outline
|
||||
FileAttachments = 0x0008, ///< Remove file attachments
|
||||
EmbeddedSearchIndex = 0x0010, ///< Remove embedded search index
|
||||
MarkupAnnotations = 0x0020, ///< Remove markup annotations from all pages
|
||||
|
@ -82,7 +82,7 @@ signals:
|
|||
private:
|
||||
void performSanitizeDocumentInfo();
|
||||
void performSanitizeMetadata();
|
||||
void performSanitizeBookmarks();
|
||||
void performSanitizeOutline();
|
||||
void performSanitizeFileAttachments();
|
||||
void performSanitizeEmbeddedSearchIndex();
|
||||
void performSanitizeMarkupAnnotations();
|
||||
|
|
|
@ -69,6 +69,10 @@ add_library(Pdf4QtViewer SHARED
|
|||
pdfcreatebitonaldocumentdialog.cpp
|
||||
pdfcreatebitonaldocumentdialog.h
|
||||
pdf4qtviewer.qrc
|
||||
pdfbookmarkmanager.h
|
||||
pdfbookmarkmanager.cpp
|
||||
pdfbookmarkui.h
|
||||
pdfbookmarkui.cpp
|
||||
)
|
||||
|
||||
add_compile_definitions(QT_INSTALL_DIRECTORY="${QT6_INSTALL_PREFIX}")
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
<file>resources/settings.svg</file>
|
||||
<file>resources/zoom-in.svg</file>
|
||||
<file>resources/zoom-out.svg</file>
|
||||
<file>resources/bookmark.svg</file>
|
||||
<file>resources/security.svg</file>
|
||||
<file>resources/zoom-fit.svg</file>
|
||||
<file>resources/zoom-fit-horizontal.svg</file>
|
||||
|
@ -104,5 +103,10 @@
|
|||
<file>resources/sidebar-speech.svg</file>
|
||||
<file>resources/sidebar-thumbnails.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>
|
||||
</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(GoToNextLine, QKeySequence::MoveToNextLine);
|
||||
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 }))
|
||||
{
|
||||
|
@ -361,6 +364,7 @@ PDFProgramController::PDFProgramController(QObject* parent) :
|
|||
m_toolManager(nullptr),
|
||||
m_annotationManager(nullptr),
|
||||
m_formManager(nullptr),
|
||||
m_bookmarkManager(nullptr),
|
||||
m_isBusy(false),
|
||||
m_isFactorySettingsBeingRestored(false),
|
||||
m_progress(nullptr)
|
||||
|
@ -375,6 +379,9 @@ PDFProgramController::~PDFProgramController()
|
|||
|
||||
delete m_annotationManager;
|
||||
m_annotationManager = nullptr;
|
||||
|
||||
delete m_bookmarkManager;
|
||||
m_bookmarkManager = nullptr;
|
||||
}
|
||||
|
||||
void PDFProgramController::initializeAnnotationManager()
|
||||
|
@ -396,6 +403,13 @@ void PDFProgramController::initializeFormManager()
|
|||
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,
|
||||
QMainWindow* mainWindow,
|
||||
IMainWindow* mainWindowInterface,
|
||||
|
@ -572,6 +586,30 @@ void PDFProgramController::initialize(Features features,
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -605,6 +643,7 @@ void PDFProgramController::initialize(Features features,
|
|||
}
|
||||
|
||||
initializeAnnotationManager();
|
||||
initializeBookmarkManager();
|
||||
|
||||
if (features.testFlag(Forms))
|
||||
{
|
||||
|
@ -1549,6 +1588,8 @@ void PDFProgramController::readSettings(Settings settingsFlags)
|
|||
{
|
||||
m_formManager->setAppearanceFlags(m_settings->getSettings().m_formAppearanceFlags);
|
||||
}
|
||||
|
||||
updateBookmarkSettings();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
|
@ -1915,6 +1963,11 @@ void PDFProgramController::setDocument(pdf::PDFModifiedDocument document, bool i
|
|||
m_annotationManager->setDocument(document);
|
||||
}
|
||||
|
||||
if (m_bookmarkManager)
|
||||
{
|
||||
m_bookmarkManager->setDocument(document);
|
||||
}
|
||||
|
||||
if (m_formManager)
|
||||
{
|
||||
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()
|
||||
{
|
||||
if (m_pdfDocument)
|
||||
|
@ -2535,6 +2604,63 @@ void PDFProgramController::onActionAutomaticDocumentRefresh()
|
|||
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)
|
||||
{
|
||||
if (errorsCount > 0)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "pdfdocumentreader.h"
|
||||
#include "pdfdocumentpropertiesdialog.h"
|
||||
#include "pdfplugin.h"
|
||||
#include "pdfbookmarkmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
|
@ -177,6 +178,12 @@ public:
|
|||
ToolScreenshot,
|
||||
ToolExtractImage,
|
||||
DeveloperCreateInstaller,
|
||||
BookmarkPage,
|
||||
BookmarkGoToNext,
|
||||
BookmarkGoToPrevious,
|
||||
BookmarkExport,
|
||||
BookmarkImport,
|
||||
BookmarkGenerateAutomatically,
|
||||
LastAction
|
||||
};
|
||||
|
||||
|
@ -275,6 +282,7 @@ public:
|
|||
PDFViewerSettings* getSettings() const { return m_settings; }
|
||||
pdf::PDFDocument* getDocument() const { return m_pdfDocument.data(); }
|
||||
pdf::PDFCertificateStore* getCertificateStore() const { return const_cast<pdf::PDFCertificateStore*>(&m_certificateStore); }
|
||||
PDFBookmarkManager* getBookmarkManager() const { return m_bookmarkManager; }
|
||||
PDFTextToSpeech* getTextToSpeech() const { return m_textToSpeech; }
|
||||
const std::vector<pdf::PDFSignatureVerificationResult>* getSignatures() const { return &m_signatures; }
|
||||
|
||||
|
@ -326,6 +334,7 @@ private:
|
|||
void initializeToolManager();
|
||||
void initializeAnnotationManager();
|
||||
void initializeFormManager();
|
||||
void initializeBookmarkManager();
|
||||
|
||||
void onActionGoToDocumentStartTriggered();
|
||||
void onActionGoToDocumentEndTriggered();
|
||||
|
@ -364,6 +373,12 @@ private:
|
|||
void onActionGetSource();
|
||||
void onActionBecomeSponsor();
|
||||
void onActionAutomaticDocumentRefresh();
|
||||
void onActionBookmarkPage();
|
||||
void onActionBookmarkGoToNext();
|
||||
void onActionBookmarkGoToPrevious();
|
||||
void onActionBookmarkExport();
|
||||
void onActionBookmarkImport();
|
||||
void onActionBookmarkGenerateAutomatically(bool checked);
|
||||
|
||||
void onDrawSpaceChanged();
|
||||
void onPageLayoutChanged();
|
||||
|
@ -374,6 +389,7 @@ private:
|
|||
void onViewerSettingsChanged();
|
||||
void onColorManagementSystemChanged();
|
||||
void onFileChanged(const QString& fileName);
|
||||
void onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark);
|
||||
|
||||
void updateMagnifierToolSettings();
|
||||
void updateUndoRedoSettings();
|
||||
|
@ -381,6 +397,7 @@ private:
|
|||
void updateTitle();
|
||||
void updatePageLayoutActions();
|
||||
void updateRenderingOptionActions();
|
||||
void updateBookmarkSettings();
|
||||
|
||||
void setPageLayout(pdf::PageLayout pageLayout);
|
||||
void updateFileInfo(const QString& fileName);
|
||||
|
@ -422,6 +439,7 @@ private:
|
|||
pdf::PDFToolManager* m_toolManager;
|
||||
pdf::PDFWidgetAnnotationManager* m_annotationManager;
|
||||
pdf::PDFWidgetFormManager* m_formManager;
|
||||
PDFBookmarkManager* m_bookmarkManager;
|
||||
|
||||
PDFFileInfo m_fileInfo;
|
||||
QFileSystemWatcher m_fileWatcher;
|
||||
|
|
|
@ -51,7 +51,7 @@ PDFSanitizeDocumentDialog::PDFSanitizeDocumentDialog(const pdf::PDFDocument* doc
|
|||
|
||||
addCheckBox(tr("Remove document info"), pdf::PDFDocumentSanitizer::DocumentInfo);
|
||||
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 embedded search index"), pdf::PDFDocumentSanitizer::EmbeddedSearchIndex);
|
||||
addCheckBox(tr("Remove comments and other markup annotations"), pdf::PDFDocumentSanitizer::MarkupAnnotations);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "pdfdrawspacecontroller.h"
|
||||
#include "pdfdocumentbuilder.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfbookmarkui.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
@ -60,6 +61,7 @@ constexpr const char* STYLESHEET =
|
|||
PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||
PDFTextToSpeech* textToSpeech,
|
||||
pdf::PDFCertificateStore* certificateStore,
|
||||
PDFBookmarkManager* bookmarkManager,
|
||||
PDFViewerSettings* settings,
|
||||
bool editableOutline,
|
||||
QWidget* parent) :
|
||||
|
@ -68,10 +70,12 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
|||
m_proxy(proxy),
|
||||
m_textToSpeech(textToSpeech),
|
||||
m_certificateStore(certificateStore),
|
||||
m_bookmarkManager(bookmarkManager),
|
||||
m_settings(settings),
|
||||
m_outlineTreeModel(nullptr),
|
||||
m_thumbnailsModel(nullptr),
|
||||
m_optionalContentTreeModel(nullptr),
|
||||
m_bookmarkItemModel(nullptr),
|
||||
m_document(nullptr),
|
||||
m_optionalContentActivity(nullptr),
|
||||
m_attachmentsTreeModel(nullptr)
|
||||
|
@ -81,26 +85,26 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
|||
setStyleSheet(STYLESHEET);
|
||||
|
||||
// Outline
|
||||
QIcon bookmarkIcon(":/resources/bookmark.svg");
|
||||
m_outlineTreeModel = new pdf::PDFOutlineTreeItemModel(qMove(bookmarkIcon), editableOutline, this);
|
||||
ui->bookmarksTreeView->setModel(m_outlineTreeModel);
|
||||
ui->bookmarksTreeView->header()->hide();
|
||||
QIcon outlineIcon(":/resources/outline.svg");
|
||||
m_outlineTreeModel = new pdf::PDFOutlineTreeItemModel(qMove(outlineIcon), editableOutline, this);
|
||||
ui->outlineTreeView->setModel(m_outlineTreeModel);
|
||||
ui->outlineTreeView->header()->hide();
|
||||
|
||||
if (editableOutline)
|
||||
{
|
||||
ui->bookmarksTreeView->setDragEnabled(true);
|
||||
ui->bookmarksTreeView->setAcceptDrops(true);
|
||||
ui->bookmarksTreeView->setDropIndicatorShown(true);
|
||||
ui->bookmarksTreeView->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
ui->bookmarksTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->bookmarksTreeView, &QTreeView::customContextMenuRequested, this, &PDFSidebarWidget::onBookmarksTreeViewContextMenuRequested);
|
||||
ui->outlineTreeView->setDragEnabled(true);
|
||||
ui->outlineTreeView->setAcceptDrops(true);
|
||||
ui->outlineTreeView->setDropIndicatorShown(true);
|
||||
ui->outlineTreeView->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
ui->outlineTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->outlineTreeView, &QTreeView::customContextMenuRequested, this, &PDFSidebarWidget::onOutlineTreeViewContextMenuRequested);
|
||||
connect(m_outlineTreeModel, &pdf::PDFOutlineTreeItemModel::dataChanged, 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::rowsMoved, this, &PDFSidebarWidget::onOutlineItemsChanged);
|
||||
}
|
||||
|
||||
connect(ui->bookmarksTreeView, &QTreeView::clicked, this, &PDFSidebarWidget::onOutlineItemClicked);
|
||||
connect(ui->outlineTreeView, &QTreeView::clicked, this, &PDFSidebarWidget::onOutlineItemClicked);
|
||||
|
||||
// Thumbnails
|
||||
m_thumbnailsModel = new pdf::PDFThumbnailsItemModel(proxy, this);
|
||||
|
@ -126,13 +130,22 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
|||
ui->attachmentsTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
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[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[Attachments] = { ui->attachmentsButton, ui->attachmentsPage };
|
||||
m_pageInfo[Speech] = { ui->speechButton, ui->speechPage };
|
||||
m_pageInfo[Signatures] = { ui->signaturesButton, ui->signaturesPage };
|
||||
m_pageInfo[Bookmarks] = { ui->bookmarksButton, ui->bookmarksPage };
|
||||
|
||||
for (const auto& pageInfo : m_pageInfo)
|
||||
{
|
||||
|
@ -189,7 +202,7 @@ void PDFSidebarWidget::setDocument(const pdf::PDFModifiedDocument& document, con
|
|||
switch (pageMode)
|
||||
{
|
||||
case pdf::PageMode::UseOutlines:
|
||||
preferred = Bookmarks;
|
||||
preferred = Outline;
|
||||
break;
|
||||
|
||||
case pdf::PageMode::UseThumbnails:
|
||||
|
@ -210,7 +223,7 @@ void PDFSidebarWidget::setDocument(const pdf::PDFModifiedDocument& document, con
|
|||
switch (nonFullscreenPageMode)
|
||||
{
|
||||
case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseOutline:
|
||||
preferred = Bookmarks;
|
||||
preferred = Outline;
|
||||
break;
|
||||
|
||||
case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseThumbnails:
|
||||
|
@ -259,7 +272,7 @@ bool PDFSidebarWidget::isEmpty(Page page) const
|
|||
case Invalid:
|
||||
return true;
|
||||
|
||||
case Bookmarks:
|
||||
case Outline:
|
||||
return m_outlineTreeModel->isEmpty() && (!m_document || !m_outlineTreeModel->isEditable());
|
||||
|
||||
case Thumbnails:
|
||||
|
@ -271,6 +284,9 @@ bool PDFSidebarWidget::isEmpty(Page page) const
|
|||
case Attachments:
|
||||
return m_attachmentsTreeModel->isEmpty();
|
||||
|
||||
case Bookmarks:
|
||||
return !m_document || !m_bookmarkManager;
|
||||
|
||||
case Speech:
|
||||
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;
|
||||
|
||||
QModelIndex index = ui->bookmarksTreeView->indexAt(pos);
|
||||
QModelIndex index = ui->outlineTreeView->indexAt(pos);
|
||||
|
||||
auto onFollow = [this, index]()
|
||||
{
|
||||
|
@ -779,22 +795,22 @@ void PDFSidebarWidget::onBookmarksTreeViewContextMenuRequested(const QPoint& pos
|
|||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
ui->bookmarksTreeView->model()->insertRow(index.row() + 1, index.parent());
|
||||
ui->outlineTreeView->model()->insertRow(index.row() + 1, index.parent());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->bookmarksTreeView->model()->insertRow(ui->bookmarksTreeView->model()->rowCount());
|
||||
ui->outlineTreeView->model()->insertRow(ui->outlineTreeView->model()->rowCount());
|
||||
}
|
||||
};
|
||||
|
||||
auto onDelete = [this, index]()
|
||||
{
|
||||
ui->bookmarksTreeView->model()->removeRow(index.row(), index.parent());
|
||||
ui->outlineTreeView->model()->removeRow(index.row(), index.parent());
|
||||
};
|
||||
|
||||
auto onRename = [this, index]()
|
||||
{
|
||||
ui->bookmarksTreeView->edit(index);
|
||||
ui->outlineTreeView->edit(index);
|
||||
};
|
||||
|
||||
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("XYZ"), createOnSetTarget(pdf::DestinationType::XYZ));
|
||||
|
||||
contextMenu.exec(ui->bookmarksTreeView->mapToGlobal(pos));
|
||||
contextMenu.exec(ui->outlineTreeView->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define PDFSIDEBARWIDGET_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
#include "pdfbookmarkmanager.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
@ -52,6 +53,7 @@ namespace pdfviewer
|
|||
{
|
||||
class PDFTextToSpeech;
|
||||
class PDFViewerSettings;
|
||||
class PDFBookmarkItemModel;
|
||||
|
||||
class PDFSidebarWidget : public QWidget
|
||||
{
|
||||
|
@ -61,6 +63,7 @@ public:
|
|||
explicit PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
|
||||
PDFTextToSpeech* textToSpeech,
|
||||
pdf::PDFCertificateStore* certificateStore,
|
||||
PDFBookmarkManager* bookmarkManager,
|
||||
PDFViewerSettings* settings,
|
||||
bool editableOutline,
|
||||
QWidget* parent);
|
||||
|
@ -72,12 +75,13 @@ public:
|
|||
{
|
||||
Invalid,
|
||||
_BEGIN,
|
||||
Bookmarks = _BEGIN,
|
||||
Outline = _BEGIN,
|
||||
Thumbnails,
|
||||
OptionalContent,
|
||||
Attachments,
|
||||
Speech,
|
||||
Signatures,
|
||||
Bookmarks,
|
||||
_END
|
||||
};
|
||||
|
||||
|
@ -113,8 +117,11 @@ private:
|
|||
void onAttachmentCustomContextMenuRequested(const QPoint& pos);
|
||||
void onThumbnailClicked(const QModelIndex& index);
|
||||
void onSignatureCustomContextMenuRequested(const QPoint &pos);
|
||||
void onBookmarksTreeViewContextMenuRequested(const QPoint &pos);
|
||||
void onOutlineTreeViewContextMenuRequested(const QPoint &pos);
|
||||
void onOutlineItemsChanged();
|
||||
void onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark);
|
||||
void onBookmarsCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
void onBookmarkClicked(const QModelIndex& index);
|
||||
|
||||
struct PageInfo
|
||||
{
|
||||
|
@ -126,16 +133,19 @@ private:
|
|||
pdf::PDFDrawWidgetProxy* m_proxy;
|
||||
PDFTextToSpeech* m_textToSpeech;
|
||||
pdf::PDFCertificateStore* m_certificateStore;
|
||||
PDFBookmarkManager* m_bookmarkManager;
|
||||
PDFViewerSettings* m_settings;
|
||||
pdf::PDFOutlineTreeItemModel* m_outlineTreeModel;
|
||||
pdf::PDFThumbnailsItemModel* m_thumbnailsModel;
|
||||
pdf::PDFOptionalContentTreeItemModel* m_optionalContentTreeModel;
|
||||
PDFBookmarkItemModel* m_bookmarkItemModel;
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFOptionalContentActivity* m_optionalContentActivity;
|
||||
pdf::PDFAttachmentsTreeItemModel* m_attachmentsTreeModel;
|
||||
std::map<Page, PageInfo> m_pageInfo;
|
||||
std::vector<pdf::PDFSignatureVerificationResult> m_signatures;
|
||||
std::vector<pdf::PDFCertificateInfo> m_certificateInfos;
|
||||
bool m_bookmarkChangeInProgress = false;
|
||||
};
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>339</width>
|
||||
<height>584</height>
|
||||
<width>388</width>
|
||||
<height>681</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="sidebarLayout">
|
||||
|
@ -29,7 +29,7 @@
|
|||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="bookmarksButton">
|
||||
<widget class="QToolButton" name="outlineButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>96</width>
|
||||
|
@ -42,7 +42,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bookmarks</string>
|
||||
<string>Outline</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
|
@ -225,6 +225,35 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<spacer name="buttonSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -243,11 +272,11 @@
|
|||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="emptyPage"/>
|
||||
<widget class="QWidget" name="bookmarksPage">
|
||||
<layout class="QVBoxLayout" name="bookmarksPageLayout">
|
||||
<widget class="QWidget" name="outlinePage">
|
||||
<layout class="QVBoxLayout" name="outlinePageLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -264,7 +293,7 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeView" name="bookmarksTreeView"/>
|
||||
<widget class="QTreeView" name="outlineTreeView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -383,6 +412,32 @@
|
|||
</item>
|
||||
</layout>
|
||||
</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">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
|
|
|
@ -194,6 +194,12 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
|||
m_actionManager->setAction(PDFActionManager::ToolScreenshot, ui->actionScreenshot);
|
||||
m_actionManager->setAction(PDFActionManager::ToolExtractImage, ui->actionExtractImage);
|
||||
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);
|
||||
|
||||
for (QAction* action : m_programController->getRecentFileManager()->getActions())
|
||||
|
@ -269,7 +275,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
|||
setCentralWidget(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->setObjectName("SidebarDockWidget");
|
||||
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
|
|
|
@ -46,12 +46,25 @@
|
|||
<property name="title">
|
||||
<string>Go To</string>
|
||||
</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="actionGoToDocumentEnd"/>
|
||||
<addaction name="actionGoToPreviousPage"/>
|
||||
<addaction name="actionGoToNextPage"/>
|
||||
<addaction name="actionGoToPreviousLine"/>
|
||||
<addaction name="actionGoToNextLine"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionBookmarkPage"/>
|
||||
<addaction name="actionGotoPreviousBookmark"/>
|
||||
<addaction name="actionGotoNextBookmark"/>
|
||||
<addaction name="menuBookmarkSettings"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
|
@ -1051,6 +1064,99 @@
|
|||
<string>Convert the colored images to monochromatic to create a bitonal document.</string>
|
||||
</property>
|
||||
</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>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
|
|
@ -151,6 +151,12 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
|
|||
m_actionManager->setAction(PDFActionManager::PageLayoutTwoPages, ui->actionPageLayoutTwoPages);
|
||||
m_actionManager->setAction(PDFActionManager::PageLayoutTwoColumns, ui->actionPageLayoutTwoColumns);
|
||||
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);
|
||||
|
||||
for (QAction* action : m_programController->getRecentFileManager()->getActions())
|
||||
|
@ -202,7 +208,7 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
|
|||
setCentralWidget(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->setObjectName("SidebarDockWidget");
|
||||
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
|
|
|
@ -42,12 +42,26 @@
|
|||
<property name="title">
|
||||
<string>Go To</string>
|
||||
</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="actionGoToDocumentEnd"/>
|
||||
<addaction name="actionGoToPreviousPage"/>
|
||||
<addaction name="actionGoToNextPage"/>
|
||||
<addaction name="actionGoToPreviousLine"/>
|
||||
<addaction name="actionGoToNextLine"/>
|
||||
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionBookmarkPage"/>
|
||||
<addaction name="actionGotoPreviousBookmark"/>
|
||||
<addaction name="actionGotoNextBookmark"/>
|
||||
<addaction name="menuBookmarkSettings"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
|
@ -543,6 +557,100 @@
|
|||
<string>Become a Sponsor</string>
|
||||
</property>
|
||||
</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>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
|
|
@ -104,6 +104,10 @@ void PDFViewerSettings::readSettings(QSettings& settings, const pdf::PDFCMSSetti
|
|||
m_settings.m_signatureUseSystemStore = settings.value("signatureUseSystemStore", defaultSettings.m_signatureUseSystemStore).toBool();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Bookmarks");
|
||||
m_settings.m_autoGenerateBookmarks = settings.value("autoGenerateBookmarks", defaultSettings.m_autoGenerateBookmarks).toBool();
|
||||
settings.endGroup();
|
||||
|
||||
Q_EMIT settingsChanged();
|
||||
}
|
||||
|
||||
|
@ -174,6 +178,10 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
|
|||
settings.setValue("signatureIgnoreCertificateValidityTime", m_settings.m_signatureIgnoreCertificateValidityTime);
|
||||
settings.setValue("signatureUseSystemStore", m_settings.m_signatureUseSystemStore);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Bookmarks");
|
||||
settings.setValue("autoGenerateBookmarks", m_settings.m_autoGenerateBookmarks);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
QString PDFViewerSettings::getDirectory() const
|
||||
|
@ -287,7 +295,8 @@ PDFViewerSettings::Settings::Settings() :
|
|||
m_signatureVerificationEnabled(true),
|
||||
m_signatureTreatWarningsAsErrors(false),
|
||||
m_signatureIgnoreCertificateValidityTime(false),
|
||||
m_signatureUseSystemStore(true)
|
||||
m_signatureUseSystemStore(true),
|
||||
m_autoGenerateBookmarks(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -91,6 +91,9 @@ public:
|
|||
bool m_signatureTreatWarningsAsErrors;
|
||||
bool m_signatureIgnoreCertificateValidityTime;
|
||||
bool m_signatureUseSystemStore;
|
||||
|
||||
// Bookmarks settings
|
||||
bool m_autoGenerateBookmarks;
|
||||
};
|
||||
|
||||
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"?>
|
||||
<!-- 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>
|
||||
<?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>
|
||||
|
|
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 |