1 /*
2     SPDX-FileCopyrightText: 2004-2008 Albert Astals Cid <aacid@kde.org>
3     SPDX-FileCopyrightText: 2004 Enrico Ros <eros.kde@email.it>
4 
5     Work sponsored by the LiMux project of the city of Munich:
6     SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com>
7 
8     SPDX-License-Identifier: GPL-2.0-or-later
9 */
10 
11 #ifndef _OKULAR_GENERATOR_PDF_H_
12 #define _OKULAR_GENERATOR_PDF_H_
13 
14 //#include "synctex/synctex_parser.h"
15 #include <config-okular-poppler.h>
16 
17 #include <poppler-qt5.h>
18 
19 #include <QBitArray>
20 #include <QPointer>
21 
22 #include <core/annotations.h>
23 #include <core/document.h>
24 #include <core/generator.h>
25 #include <core/printoptionswidget.h>
26 #include <interfaces/configinterface.h>
27 #include <interfaces/printinterface.h>
28 #include <interfaces/saveinterface.h>
29 
30 #include <unordered_map>
31 
32 class PDFOptionsPage;
33 class PopplerAnnotationProxy;
34 
35 /**
36  * @short A generator that builds contents from a PDF document.
37  *
38  * All Generator features are supported and implemented by this one.
39  * Internally this holds a reference to xpdf's core objects and provides
40  * contents generation using the PDFDoc object and a couple of OutputDevices
41  * called Okular::OutputDev and Okular::TextDev (both defined in gp_outputdev.h).
42  *
43  * For generating page contents we tell PDFDoc to render a page and grab
44  * contents from out OutputDevs when rendering finishes.
45  *
46  */
47 class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, public Okular::PrintInterface, public Okular::SaveInterface
48 {
49     Q_OBJECT
50     Q_INTERFACES(Okular::Generator)
51     Q_INTERFACES(Okular::ConfigInterface)
52     Q_INTERFACES(Okular::PrintInterface)
53     Q_INTERFACES(Okular::SaveInterface)
54 
55 public:
56     PDFGenerator(QObject *parent, const QVariantList &args);
57     ~PDFGenerator() override;
58 
59     // [INHERITED] load a document and fill up the pagesVector
60     Okular::Document::OpenResult loadDocumentWithPassword(const QString &filePath, QVector<Okular::Page *> &pagesVector, const QString &password) override;
61     Okular::Document::OpenResult loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector<Okular::Page *> &pagesVector, const QString &password) override;
62     void loadPages(QVector<Okular::Page *> &pagesVector, int rotation = -1, bool clear = false);
63     // [INHERITED] document information
64     Okular::DocumentInfo generateDocumentInfo(const QSet<Okular::DocumentInfo::Key> &keys) const override;
65     const Okular::DocumentSynopsis *generateDocumentSynopsis() override;
66     Okular::FontInfo::List fontsForPage(int page) override;
67     const QList<Okular::EmbeddedFile *> *embeddedFiles() const override;
pagesSizeMetric()68     PageSizeMetric pagesSizeMetric() const override
69     {
70         return Pixels;
71     }
72     QAbstractItemModel *layersModel() const override;
73     void opaqueAction(const Okular::BackendOpaqueAction *action) override;
74 
75     // [INHERITED] document information
76     bool isAllowed(Okular::Permission permission) const override;
77 
78     // [INHERITED] perform actions on document / pages
79     QImage image(Okular::PixmapRequest *request) override;
80 
81     // [INHERITED] print page using an already configured kprinter
82     bool print(QPrinter &printer) override;
83 
84     // [INHERITED] reply to some metadata requests
85     QVariant metaData(const QString &key, const QVariant &option) const override;
86 
87     // [INHERITED] reparse configuration
88     bool reparseConfig() override;
89     void addPages(KConfigDialog *) override;
90 
91     // [INHERITED] text exporting
92     Okular::ExportFormat::List exportFormats() const override;
93     bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override;
94 
95     // [INHERITED] print interface
96     Okular::PrintOptionsWidget *printConfigurationWidget() const override;
97 
98     // [INHERITED] save interface
99     bool supportsOption(SaveOption) const override;
100     bool save(const QString &fileName, SaveOptions options, QString *errorText) override;
101     Okular::AnnotationProxy *annotationProxy() const override;
102 
103     bool canSign() const override;
104     bool sign(const Okular::NewSignatureData &oData, const QString &rFilename) override;
105 
106     Okular::CertificateStore *certificateStore() const override;
107 
108 protected:
109     SwapBackingFileResult swapBackingFile(QString const &newFileName, QVector<Okular::Page *> &newPagesVector) override;
110     bool doCloseDocument() override;
111     Okular::TextPage *textPage(Okular::TextRequest *request) override;
112     Q_INVOKABLE Okular::Generator::PrintError printError() const;
113 
114 protected Q_SLOTS:
115     void requestFontData(const Okular::FontInfo &font, QByteArray *data);
116 
117 private:
118     Okular::Document::OpenResult init(QVector<Okular::Page *> &pagesVector, const QString &password);
119 
120     // create the document synopsis hierarchy
121     void addSynopsisChildren(const QVector<Poppler::OutlineItem> &outlineItems, QDomNode *parentDestination);
122     // fetch annotations from the pdf file and add they to the page
123     void addAnnotations(Poppler::Page *popplerPage, Okular::Page *page);
124     // fetch the transition information and add it to the page
125     void addTransition(Poppler::Page *pdfPage, Okular::Page *page);
126     // fetch the poppler page form fields
127     QLinkedList<Okular::FormField *> getFormFields(Poppler::Page *popplerPage);
128 
129     Okular::TextPage *abstractTextPage(const QList<Poppler::TextBox *> &text, double height, double width, int rot);
130 
131     void resolveMediaLinkReferences(Okular::Page *page);
132     void resolveMediaLinkReference(Okular::Action *action);
133 
134     bool setDocumentRenderHints();
135 
136     // poppler dependent stuff
137     Poppler::Document *pdfdoc;
138 
139     void xrefReconstructionHandler();
140 
141     // misc variables for document info and synopsis caching
142     bool docSynopsisDirty;
143     bool xrefReconstructed;
144     Okular::DocumentSynopsis docSyn;
145     mutable bool docEmbeddedFilesDirty;
146     mutable QList<Okular::EmbeddedFile *> docEmbeddedFiles;
147     int nextFontPage;
148     PopplerAnnotationProxy *annotProxy;
149     mutable Okular::CertificateStore *certStore;
150     // the hash below only contains annotations that were present on the file at open time
151     // this is enough for what we use it for
152     QHash<Okular::Annotation *, Poppler::Annotation *> annotationsOnOpenHash;
153 
154     QBitArray rectsGenerated;
155 
156     QPointer<PDFOptionsPage> pdfOptionsPage;
157 
158     PrintError lastPrintError;
159 };
160 
161 #endif
162 
163 /* kate: replace-tabs on; indent-width 4; */
164