mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Sidebar widget refactoring
This commit is contained in:
		| @@ -67,6 +67,48 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume | ||||
|         catalogObject.m_outlineRoot = PDFOutlineItem::parse(document, catalogDictionary->get("Outlines")); | ||||
|     } | ||||
|  | ||||
|     if (catalogDictionary->hasKey("OpenAction")) | ||||
|     { | ||||
|         PDFObject openAction = document->getObject(catalogDictionary->get("OpenAction")); | ||||
|         if (openAction.isArray()) | ||||
|         { | ||||
|             catalogObject.m_openAction.reset(new PDFActionGoTo(PDFDestination::parse(document, openAction))); | ||||
|         } | ||||
|         if (openAction.isDictionary()) | ||||
|         { | ||||
|             catalogObject.m_openAction = PDFAction::parse(document, openAction); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     PDFDocumentDataLoaderDecorator loader(document); | ||||
|     if (catalogDictionary->hasKey("PageLayout")) | ||||
|     { | ||||
|         constexpr const std::array<std::pair<const char*, PageLayout>, 6> pageLayouts = { | ||||
|             std::pair<const char*, PageLayout>{ "SinglePage", PageLayout::SinglePage }, | ||||
|             std::pair<const char*, PageLayout>{ "OneColumn", PageLayout::OneColumn }, | ||||
|             std::pair<const char*, PageLayout>{ "TwoColumnLeft", PageLayout::TwoColumnLeft }, | ||||
|             std::pair<const char*, PageLayout>{ "TwoColumnRight", PageLayout::TwoColumnRight }, | ||||
|             std::pair<const char*, PageLayout>{ "TwoPageLeft", PageLayout::TwoPagesLeft }, | ||||
|             std::pair<const char*, PageLayout>{ "TwoPageRight", PageLayout::TwoPagesRight } | ||||
|         }; | ||||
|  | ||||
|         catalogObject.m_pageLayout = loader.readEnumByName(catalogDictionary->get("PageLayout"), pageLayouts.begin(), pageLayouts.end(), PageLayout::SinglePage); | ||||
|     } | ||||
|  | ||||
|     if (catalogDictionary->hasKey("PageMode")) | ||||
|     { | ||||
|         constexpr const std::array<std::pair<const char*, PageMode>, 6> pageModes = { | ||||
|             std::pair<const char*, PageMode>{ "UseNone", PageMode::UseNone }, | ||||
|             std::pair<const char*, PageMode>{ "UseOutlines", PageMode::UseOutlines }, | ||||
|             std::pair<const char*, PageMode>{ "UseThumbs", PageMode::UseThumbnails }, | ||||
|             std::pair<const char*, PageMode>{ "FullScreen", PageMode::Fullscreen }, | ||||
|             std::pair<const char*, PageMode>{ "UseOC", PageMode::UseOptionalContent }, | ||||
|             std::pair<const char*, PageMode>{ "UseAttachments", PageMode::UseAttachments } | ||||
|         }; | ||||
|  | ||||
|         catalogObject.m_pageMode = loader.readEnumByName(catalogDictionary->get("PageMode"), pageModes.begin(), pageModes.end(), PageMode::UseNone); | ||||
|     } | ||||
|  | ||||
|     return catalogObject; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
| #include "pdfpage.h" | ||||
| #include "pdfoptionalcontent.h" | ||||
| #include "pdfoutline.h" | ||||
| #include "pdfaction.h" | ||||
|  | ||||
| #include <QtCore> | ||||
|  | ||||
| @@ -219,6 +220,12 @@ public: | ||||
|     /// Returns root pointer for outline items | ||||
|     QSharedPointer<PDFOutlineItem> getOutlineRootPtr() const { return m_outlineRoot; } | ||||
|  | ||||
|     /// Returns action, which should be performed | ||||
|     const PDFAction* getOpenAction() const { return m_openAction.data(); } | ||||
|  | ||||
|     PageLayout getPageLayout() const { return m_pageLayout; } | ||||
|     PageMode getPageMode() const { return m_pageMode; } | ||||
|  | ||||
|     /// Parses catalog from catalog dictionary. If object cannot be parsed, or error occurs, | ||||
|     /// then exception is thrown. | ||||
|     static PDFCatalog parse(const PDFObject& catalog, const PDFDocument* document); | ||||
| @@ -229,6 +236,9 @@ private: | ||||
|     std::vector<PDFPageLabel> m_pageLabels; | ||||
|     PDFOptionalContentProperties m_optionalContentProperties; | ||||
|     QSharedPointer<PDFOutlineItem> m_outlineRoot; | ||||
|     PDFActionPtr m_openAction; | ||||
|     PageLayout m_pageLayout = PageLayout::SinglePage; | ||||
|     PageMode m_pageMode = PageMode::UseNone; | ||||
| }; | ||||
|  | ||||
| }   // namespace pdf | ||||
|   | ||||
| @@ -364,16 +364,26 @@ QVariant PDFOutlineTreeItemModel::data(const QModelIndex& index, int role) const | ||||
|         case Qt::FontRole: | ||||
|         { | ||||
|             QFont font = QApplication::font(); | ||||
|             font.setPointSize(10); | ||||
|             font.setBold(outlineItem->isFontBold()); | ||||
|             font.setItalic(outlineItem->isFontItalics()); | ||||
|             return font; | ||||
|         } | ||||
|  | ||||
|         case Qt::DecorationRole: | ||||
|         { | ||||
|             if (!m_icon.isNull()) | ||||
|             { | ||||
|                 return m_icon; | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     return QString(); | ||||
|     return QVariant(); | ||||
| } | ||||
|  | ||||
| void PDFOutlineTreeItemModel::update() | ||||
| @@ -415,4 +425,16 @@ Qt::ItemFlags PDFOutlineTreeItemModel::flags(const QModelIndex& index) const | ||||
|     return flags; | ||||
| } | ||||
|  | ||||
| const PDFAction* PDFOutlineTreeItemModel::getAction(const QModelIndex& index) const | ||||
| { | ||||
|     if (index.isValid()) | ||||
|     { | ||||
|         const PDFOutlineTreeItem* item = static_cast<const PDFOutlineTreeItem*>(index.internalPointer()); | ||||
|         const PDFOutlineItem* outlineItem = item->getOutlineItem(); | ||||
|         return outlineItem->getAction(); | ||||
|     } | ||||
|  | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
| }   // namespace pdf | ||||
|   | ||||
| @@ -21,10 +21,12 @@ | ||||
| #include "pdfglobal.h" | ||||
| #include "pdfobject.h" | ||||
|  | ||||
| #include <QIcon> | ||||
| #include <QAbstractItemModel> | ||||
|  | ||||
| namespace pdf | ||||
| { | ||||
| class PDFAction; | ||||
| class PDFDocument; | ||||
| class PDFOutlineItem; | ||||
| class PDFOptionalContentActivity; | ||||
| @@ -107,6 +109,7 @@ private: | ||||
|  | ||||
| class PDFFORQTLIBSHARED_EXPORT PDFOptionalContentTreeItemModel : public PDFTreeItemModel | ||||
| { | ||||
|     Q_OBJECT | ||||
| public: | ||||
|     inline explicit PDFOptionalContentTreeItemModel(QObject* parent) : | ||||
|         PDFTreeItemModel(parent), | ||||
| @@ -140,13 +143,27 @@ private: | ||||
|  | ||||
| class PDFFORQTLIBSHARED_EXPORT PDFOutlineTreeItemModel : public PDFTreeItemModel | ||||
| { | ||||
|     Q_OBJECT | ||||
| public: | ||||
|     using PDFTreeItemModel::PDFTreeItemModel; | ||||
|     PDFOutlineTreeItemModel(QIcon icon, QObject* parent) : | ||||
|         PDFTreeItemModel(parent), | ||||
|         m_icon(qMove(icon)) | ||||
|     { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     virtual int columnCount(const QModelIndex& parent) const override; | ||||
|     virtual QVariant data(const QModelIndex& index, int role) const override; | ||||
|     virtual void update() override; | ||||
|     virtual Qt::ItemFlags flags(const QModelIndex& index) const override; | ||||
|  | ||||
|     /// Returns action assigned to the index. If index is invalid, or | ||||
|     /// points to the invalid item, nullptr is returned. | ||||
|     /// \param index Index of the outline item | ||||
|     const PDFAction* getAction(const QModelIndex& index) const; | ||||
|  | ||||
| private: | ||||
|     QIcon m_icon; | ||||
| }; | ||||
|  | ||||
| }   // namespace pdf | ||||
|   | ||||
| @@ -16,5 +16,6 @@ | ||||
|         <file>resources/settings.svg</file> | ||||
|         <file>resources/zoom-in.svg</file> | ||||
|         <file>resources/zoom-out.svg</file> | ||||
|         <file>resources/bookmark.svg</file> | ||||
|     </qresource> | ||||
| </RCC> | ||||
|   | ||||
| @@ -35,9 +35,11 @@ PDFSidebarWidget::PDFSidebarWidget(QWidget* parent) : | ||||
|     ui->setupUi(this); | ||||
|  | ||||
|     // Outline | ||||
|     m_outlineTreeModel = new pdf::PDFOutlineTreeItemModel(this); | ||||
|     QIcon bookmarkIcon(":/resources/bookmark.svg"); | ||||
|     m_outlineTreeModel = new pdf::PDFOutlineTreeItemModel(qMove(bookmarkIcon), this); | ||||
|     ui->bookmarksTreeView->setModel(m_outlineTreeModel); | ||||
|     ui->bookmarksTreeView->header()->hide(); | ||||
|     connect(ui->bookmarksTreeView, &QTreeView::clicked, this, &PDFSidebarWidget::onOutlineItemClicked); | ||||
|  | ||||
|     // Optional content | ||||
|     ui->optionalContentTreeView->header()->hide(); | ||||
| @@ -75,18 +77,18 @@ void PDFSidebarWidget::setDocument(const pdf::PDFDocument* document, pdf::PDFOpt | ||||
|     Page preferred = Invalid; | ||||
|     if (m_document) | ||||
|     { | ||||
|         const pdf::PDFViewerPreferences::NonFullScreenPageMode pageMode = m_document->getCatalog()->getViewerPreferences()->getNonFullScreenPageMode(); | ||||
|         const pdf::PageMode pageMode = m_document->getCatalog()->getPageMode(); | ||||
|         switch (pageMode) | ||||
|         { | ||||
|             case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseOutline: | ||||
|             case pdf::PageMode::UseOutlines: | ||||
|                 preferred = Bookmarks; | ||||
|                 break; | ||||
|  | ||||
|             case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseThumbnails: | ||||
|             case pdf::PageMode::UseThumbnails: | ||||
|                 preferred = Thumbnails; | ||||
|                 break; | ||||
|  | ||||
|             case pdf::PDFViewerPreferences::NonFullScreenPageMode::UseOptionalContent: | ||||
|             case pdf::PageMode::UseOptionalContent: | ||||
|                 preferred = OptionalContent; | ||||
|                 break; | ||||
|  | ||||
| @@ -202,4 +204,12 @@ void PDFSidebarWidget::updateButtons() | ||||
|     } | ||||
| } | ||||
|  | ||||
| void PDFSidebarWidget::onOutlineItemClicked(const QModelIndex& index) | ||||
| { | ||||
|     if (const pdf::PDFAction* action = m_outlineTreeModel->getAction(index)) | ||||
|     { | ||||
|         emit actionTriggered(action); | ||||
|     } | ||||
| } | ||||
|  | ||||
| }   // namespace pdfviewer | ||||
|   | ||||
| @@ -31,6 +31,7 @@ class PDFSidebarWidget; | ||||
|  | ||||
| namespace pdf | ||||
| { | ||||
| class PDFAction; | ||||
| class PDFDocument; | ||||
| class PDFOutlineTreeItemModel; | ||||
| class PDFOptionalContentActivity; | ||||
| @@ -72,10 +73,15 @@ public: | ||||
|     /// Returns list of valid pages (nonempty pages) | ||||
|     std::vector<Page> getValidPages() const; | ||||
|  | ||||
| signals: | ||||
|     void actionTriggered(const pdf::PDFAction* action); | ||||
|  | ||||
| private: | ||||
|     void updateGUI(Page preferredPage); | ||||
|     void updateButtons(); | ||||
|  | ||||
|     void onOutlineItemClicked(const QModelIndex& index); | ||||
|  | ||||
|     struct PageInfo | ||||
|     { | ||||
|         QPushButton* button = nullptr; | ||||
|   | ||||
| @@ -149,6 +149,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget *parent) : | ||||
|     m_sidebarDockWidget->setWidget(m_sidebarWidget); | ||||
|     addDockWidget(Qt::LeftDockWidgetArea, m_sidebarDockWidget); | ||||
|     m_sidebarDockWidget->hide(); | ||||
|     connect(m_sidebarWidget, &PDFSidebarWidget::actionTriggered, this, &PDFViewerMainWindow::onActionTriggered); | ||||
|  | ||||
|     ui->actionRenderOptionAntialiasing->setData(pdf::PDFRenderer::Antialiasing); | ||||
|     ui->actionRenderOptionTextAntialiasing->setData(pdf::PDFRenderer::TextAntialiasing); | ||||
| @@ -248,6 +249,11 @@ void PDFViewerMainWindow::onPageZoomSpinboxEditingFinished() | ||||
|     m_pdfWidget->getDrawWidgetProxy()->zoom(m_pageZoomSpinBox->value() / 100.0); | ||||
| } | ||||
|  | ||||
| void PDFViewerMainWindow::onActionTriggered(const pdf::PDFAction* action) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void PDFViewerMainWindow::onProgressStarted() | ||||
| { | ||||
|     m_progressTaskbarIndicator->setRange(0, 100); | ||||
| @@ -486,6 +492,18 @@ void PDFViewerMainWindow::setDocument(const pdf::PDFDocument* document) | ||||
|  | ||||
|     updateTitle(); | ||||
|     updateUI(true); | ||||
|  | ||||
|     if (m_pdfDocument) | ||||
|     { | ||||
|         const pdf::PDFCatalog* catalog = m_pdfDocument->getCatalog(); | ||||
|         setPageLayout(catalog->getPageLayout()); | ||||
|         updatePageLayoutActions(); | ||||
|  | ||||
|         if (const pdf::PDFAction* action = catalog->getOpenAction()) | ||||
|         { | ||||
|             onActionTriggered(action); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void PDFViewerMainWindow::closeDocument() | ||||
|   | ||||
| @@ -41,6 +41,7 @@ class PDFViewerMainWindow; | ||||
|  | ||||
| namespace pdf | ||||
| { | ||||
| class PDFAction; | ||||
| class PDFWidget; | ||||
| class PDFDocument; | ||||
| class PDFOptionalContentTreeItemModel; | ||||
| @@ -82,6 +83,7 @@ private: | ||||
|     void onPageLayoutChanged(); | ||||
|     void onPageNumberSpinboxEditingFinished(); | ||||
|     void onPageZoomSpinboxEditingFinished(); | ||||
|     void onActionTriggered(const pdf::PDFAction* action); | ||||
|  | ||||
|     void onProgressStarted(); | ||||
|     void onProgressStep(int percentage); | ||||
|   | ||||
							
								
								
									
										84
									
								
								PdfForQtViewer/resources/bookmark.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								PdfForQtViewer/resources/bookmark.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| <?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" | ||||
|    width="30mm" | ||||
|    height="30mm" | ||||
|    viewBox="0 0 30 30" | ||||
|    version="1.1" | ||||
|    id="svg5291" | ||||
|    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||
|    sodipodi:docname="bookmark.svg"> | ||||
|   <defs | ||||
|      id="defs5285" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="0.35" | ||||
|      inkscape:cx="-278.8134" | ||||
|      inkscape:cy="145.70776" | ||||
|      inkscape:document-units="mm" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="3840" | ||||
|      inkscape:window-height="2035" | ||||
|      inkscape:window-x="-13" | ||||
|      inkscape:window-y="-13" | ||||
|      inkscape:window-maximized="1" /> | ||||
|   <metadata | ||||
|      id="metadata5288"> | ||||
|     <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> | ||||
|         <dc:creator> | ||||
|           <cc:Agent> | ||||
|             <dc:title>Jakub Melka</dc:title> | ||||
|           </cc:Agent> | ||||
|         </dc:creator> | ||||
|         <cc:license | ||||
|            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||
|       </cc:Work> | ||||
|       <cc:License | ||||
|          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||
|       </cc:License> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Vrstva 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-267)"> | ||||
|     <path | ||||
|        style="fill:#000000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:0.1545139;stroke-miterlimit:4;stroke-dasharray:none" | ||||
|        d="m 5.8113839,294.11793 v -0.3071 l 0.07087,-23.95425 18.8279381,-0.11811 0.09449,24.68657 -9.307663,-10.08724 z" | ||||
|        id="path831" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.8 KiB | 
		Reference in New Issue
	
	Block a user