File indexing completed on 2024-04-28 04:32:41
0001 /* 0002 SPDX-FileCopyrightText: 2004-2005 Enrico Ros <eros.kde@email.it> 0003 SPDX-FileCopyrightText: 2004-2007 Albert Astals Cid <aacid@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef _OKULAR_DOCUMENT_P_H_ 0009 #define _OKULAR_DOCUMENT_P_H_ 0010 0011 #include "document.h" 0012 #include "script/event_p.h" 0013 0014 #include "synctex/synctex_parser.h" 0015 #include <memory> 0016 0017 // qt/kde/system includes 0018 #include <KConfigDialog> 0019 #include <KPluginMetaData> 0020 #include <QHash> 0021 #include <QMap> 0022 #include <QMutex> 0023 #include <QPointer> 0024 #include <QUrl> 0025 0026 // local includes 0027 #include "fontinfo.h" 0028 #include "generator.h" 0029 0030 class QUndoStack; 0031 class QEventLoop; 0032 class QFile; 0033 class QTimer; 0034 class QTemporaryFile; 0035 class KPluginMetaData; 0036 0037 struct AllocatedPixmap; 0038 struct ArchiveData; 0039 struct RunningSearch; 0040 0041 namespace Okular 0042 { 0043 class ScriptAction; 0044 class ConfigInterface; 0045 class PageController; 0046 class SaveInterface; 0047 class Scripter; 0048 class View; 0049 } 0050 0051 struct GeneratorInfo { 0052 explicit GeneratorInfo(Okular::Generator *g, const KPluginMetaData &data) 0053 : generator(g) 0054 , metadata(data) 0055 , config(nullptr) 0056 , save(nullptr) 0057 , configChecked(false) 0058 , saveChecked(false) 0059 { 0060 } 0061 0062 Okular::Generator *generator; 0063 KPluginMetaData metadata; 0064 Okular::ConfigInterface *config; 0065 Okular::SaveInterface *save; 0066 bool configChecked : 1; 0067 bool saveChecked : 1; 0068 }; 0069 0070 namespace Okular 0071 { 0072 class OKULARCORE_EXPORT BackendConfigDialog : public KConfigDialog 0073 { 0074 Q_OBJECT 0075 public: 0076 BackendConfigDialog(QWidget *parent, const QString &name, KCoreConfigSkeleton *config) 0077 : KConfigDialog(parent, name, config) 0078 { 0079 } 0080 0081 KPageWidget *thePageWidget() 0082 { 0083 return pageWidget(); 0084 } 0085 }; 0086 0087 class FontExtractionThread; 0088 0089 struct DoContinueDirectionMatchSearchStruct { 0090 QSet<int> *pagesToNotify; 0091 RegularAreaRect *match; 0092 int currentPage; 0093 int searchID; 0094 }; 0095 0096 enum LoadDocumentInfoFlag { 0097 LoadNone = 0, 0098 LoadPageInfo = 1, // Load annotations and forms 0099 LoadGeneralInfo = 2, // History, rotation, ... 0100 LoadAllInfo = 0xff 0101 }; 0102 Q_DECLARE_FLAGS(LoadDocumentInfoFlags, LoadDocumentInfoFlag) 0103 0104 class DocumentPrivate 0105 { 0106 public: 0107 explicit DocumentPrivate(Document *parent) 0108 : m_parent(parent) 0109 , m_tempFile(nullptr) 0110 , m_docSize(-1) 0111 , m_allocatedPixmapsTotalMemory(0) 0112 , m_maxAllocatedTextPages(0) 0113 , m_warnedOutOfMemory(false) 0114 , m_rotation(Rotation0) 0115 , m_exportCached(false) 0116 , m_bookmarkManager(nullptr) 0117 , m_memCheckTimer(nullptr) 0118 , m_saveBookmarksTimer(nullptr) 0119 , m_generator(nullptr) 0120 , m_walletGenerator(nullptr) 0121 , m_generatorsLoaded(false) 0122 , m_pageController(nullptr) 0123 , m_closingLoop(nullptr) 0124 , m_scripter(nullptr) 0125 , m_archiveData(nullptr) 0126 , m_fontsCached(false) 0127 , m_annotationEditingEnabled(true) 0128 , m_annotationBeingModified(false) 0129 , m_undoStack(nullptr) 0130 , m_docdataMigrationNeeded(false) 0131 , m_synctex_scanner(nullptr) 0132 { 0133 calculateMaxTextPages(); 0134 } 0135 0136 // private methods 0137 bool updateMetadataXmlNameAndDocSize(); 0138 QString pagesSizeString() const; 0139 QString namePaperSize(double inchesWidth, double inchesHeight) const; 0140 QString localizedSize(const QSizeF size) const; 0141 qulonglong calculateMemoryToFree(); 0142 void cleanupPixmapMemory(); 0143 void cleanupPixmapMemory(qulonglong memoryToFree); 0144 AllocatedPixmap *searchLowestPriorityPixmap(bool unloadableOnly = false, bool thenRemoveIt = false, DocumentObserver *observer = nullptr /* any */); 0145 void calculateMaxTextPages(); 0146 qulonglong getTotalMemory(); 0147 qulonglong getFreeMemory(qulonglong *freeSwap = nullptr); 0148 bool loadDocumentInfo(LoadDocumentInfoFlags loadWhat); 0149 bool loadDocumentInfo(QFile &infoFile, LoadDocumentInfoFlags loadWhat); 0150 void loadViewsInfo(View *view, const QDomElement &e); 0151 void saveViewsInfo(View *view, QDomElement &e) const; 0152 QUrl giveAbsoluteUrl(const QString &fileName) const; 0153 bool openRelativeFile(const QString &fileName); 0154 Generator *loadGeneratorLibrary(const KPluginMetaData &service); 0155 void loadAllGeneratorLibraries(); 0156 void loadServiceList(const QVector<KPluginMetaData> &offers); 0157 void unloadGenerator(const GeneratorInfo &info); 0158 void cacheExportFormats(); 0159 void setRotationInternal(int r, bool notify); 0160 ConfigInterface *generatorConfig(GeneratorInfo &info); 0161 SaveInterface *generatorSave(GeneratorInfo &info); 0162 Document::OpenResult openDocumentInternal(const KPluginMetaData &offer, bool isstdin, const QString &docFile, const QByteArray &filedata, const QString &password); 0163 static ArchiveData *unpackDocumentArchive(const QString &archivePath); 0164 bool savePageDocumentInfo(QTemporaryFile *infoFile, int what) const; 0165 DocumentViewport nextDocumentViewport() const; 0166 void notifyAnnotationChanges(int page); 0167 void notifyFormChanges(int page); 0168 bool canAddAnnotationsNatively() const; 0169 bool canModifyExternalAnnotations() const; 0170 bool canRemoveExternalAnnotations() const; 0171 OKULARCORE_EXPORT static QString docDataFileName(const QUrl &url, qint64 document_size); 0172 bool cancelRenderingBecauseOf(PixmapRequest *executingRequest, PixmapRequest *newRequest); 0173 0174 // Methods that implement functionality needed by undo commands 0175 void performAddPageAnnotation(int page, Annotation *annotation); 0176 void performRemovePageAnnotation(int page, Annotation *annotation); 0177 void performModifyPageAnnotation(int page, Annotation *annotation, bool appearanceChanged); 0178 void performSetAnnotationContents(const QString &newContents, Annotation *annot, int pageNumber); 0179 0180 void recalculateForms(); 0181 0182 // private slots 0183 void saveDocumentInfo() const; 0184 void slotTimedMemoryCheck(); 0185 void sendGeneratorPixmapRequest(); 0186 void rotationFinished(int page, Okular::Page *okularPage); 0187 void slotFontReadingProgress(int page); 0188 void fontReadingGotFont(const Okular::FontInfo &font); 0189 void slotGeneratorConfigChanged(); 0190 void refreshPixmaps(int); 0191 void _o_configChanged(); 0192 void doContinueDirectionMatchSearch(void *doContinueDirectionMatchSearchStruct); 0193 void doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID); 0194 void doContinueGooglesDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QStringList &words); 0195 0196 void doProcessSearchMatch(RegularAreaRect *match, RunningSearch *search, QSet<int> *pagesToNotify, int currentPage, int searchID, bool moveViewport, const QColor &color); 0197 0198 /** 0199 * Executes a JavaScript script from the setInterval function. 0200 * 0201 * @since 1.9 0202 */ 0203 void executeScript(const QString &function); 0204 0205 // generators stuff 0206 /** 0207 * This method is used by the generators to signal the finish of 0208 * the pixmap generation @p request. 0209 */ 0210 void requestDone(PixmapRequest *request); 0211 void textGenerationDone(Page *page); 0212 /** 0213 * Sets the bounding box of the given @p page (in terms of upright orientation, i.e., Rotation0). 0214 */ 0215 void setPageBoundingBox(int page, const NormalizedRect &boundingBox); 0216 0217 /** 0218 * Request a particular metadata of the Document itself (ie, not something 0219 * depending on the document type/backend). 0220 */ 0221 QVariant documentMetaData(const Generator::DocumentMetaDataKey key, const QVariant &option) const; 0222 0223 /** 0224 * Return whether the normalized rectangle @p rectOfInterest on page number @p rectPage 0225 * is fully visible. 0226 */ 0227 bool isNormalizedRectangleFullyVisible(const Okular::NormalizedRect &rectOfInterest, int rectPage); 0228 0229 // For sync files 0230 void loadSyncFile(const QString &filePath); 0231 0232 void clearAndWaitForRequests(); 0233 0234 OKULARCORE_EXPORT static QString diff(const QString &oldVal, const QString &newVal); 0235 0236 /* 0237 * Executes a ScriptAction with the event passed as parameter. 0238 */ 0239 void executeScriptEvent(const std::shared_ptr<Event> &event, const Okular::ScriptAction *linkscript); 0240 0241 /* 0242 * Find the corresponding page number for the form field passed as parameter. 0243 */ 0244 int findFieldPageNumber(Okular::FormField *field); 0245 0246 // member variables 0247 Document *m_parent; 0248 QPointer<QWidget> m_widget; 0249 0250 // find descriptors, mapped by ID (we handle multiple searches) 0251 QMap<int, RunningSearch *> m_searches; 0252 bool m_searchCancelled; 0253 0254 // needed because for remote documents docFileName is a local file and 0255 // we want the remote url when the document refers to relativeNames 0256 QUrl m_url; 0257 0258 // cached stuff 0259 QString m_docFileName; 0260 QString m_xmlFileName; 0261 QTemporaryFile *m_tempFile; 0262 qint64 m_docSize; 0263 0264 // viewport stuff 0265 std::list<DocumentViewport> m_viewportHistory; 0266 std::list<DocumentViewport>::iterator m_viewportIterator; 0267 DocumentViewport m_nextDocumentViewport; // see Link::Goto for an explanation 0268 QString m_nextDocumentDestination; 0269 0270 // observers / requests / allocator stuff 0271 QSet<DocumentObserver *> m_observers; 0272 std::list<PixmapRequest *> m_pixmapRequestsStack; 0273 std::list<PixmapRequest *> m_executingPixmapRequests; 0274 QMutex m_pixmapRequestsMutex; 0275 std::list<AllocatedPixmap *> m_allocatedPixmaps; 0276 qulonglong m_allocatedPixmapsTotalMemory; 0277 QList<int> m_allocatedTextPagesFifo; 0278 int m_maxAllocatedTextPages; 0279 bool m_warnedOutOfMemory; 0280 0281 // the rotation applied to the document 0282 Rotation m_rotation; 0283 0284 // the current size of the pages (if available), and the cache of the 0285 // available page sizes 0286 PageSize m_pageSize; 0287 PageSize::List m_pageSizes; 0288 0289 // cache of the export formats 0290 bool m_exportCached; 0291 ExportFormat::List m_exportFormats; 0292 ExportFormat m_exportToText; 0293 0294 // our bookmark manager 0295 BookmarkManager *m_bookmarkManager; 0296 0297 // timers (memory checking / info saver) 0298 QTimer *m_memCheckTimer; 0299 QTimer *m_saveBookmarksTimer; 0300 0301 QHash<QString, GeneratorInfo> m_loadedGenerators; 0302 Generator *m_generator; 0303 QString m_generatorName; 0304 Generator *m_walletGenerator; 0305 bool m_generatorsLoaded; 0306 QVector<Page *> m_pagesVector; 0307 QVector<VisiblePageRect *> m_pageRects; 0308 0309 // cache of the mimetype we support 0310 QStringList m_supportedMimeTypes; 0311 0312 PageController *m_pageController; 0313 QEventLoop *m_closingLoop; 0314 0315 Scripter *m_scripter; 0316 0317 ArchiveData *m_archiveData; 0318 QString m_archivedFileName; 0319 0320 QPointer<FontExtractionThread> m_fontThread; 0321 bool m_fontsCached; 0322 QSet<DocumentInfo::Key> m_documentInfoAskedKeys; 0323 DocumentInfo m_documentInfo; 0324 FontInfo::List m_fontsCache; 0325 0326 QSet<View *> m_views; 0327 0328 bool m_annotationEditingEnabled; 0329 bool m_annotationBeingModified; // is an annotation currently being moved or resized? 0330 bool m_metadataLoadingCompleted; 0331 0332 QUndoStack *m_undoStack; 0333 QDomNode m_prevPropsOfAnnotBeingModified; 0334 0335 // Since 0.21, we no longer support saving annotations and form data in 0336 // the docdata/ directory and we ask the user to migrate them to an 0337 // external file as soon as possible, otherwise the document will be 0338 // shown in read-only mode. This flag is set if the docdata/ XML file 0339 // for the current document contains any annotation or form. 0340 bool m_docdataMigrationNeeded; 0341 0342 synctex_scanner_p m_synctex_scanner; 0343 0344 QString m_openError; 0345 0346 // generator selection 0347 static QVector<KPluginMetaData> availableGenerators(); 0348 static QVector<KPluginMetaData> configurableGenerators(); 0349 static KPluginMetaData generatorForMimeType(const QMimeType &type, QWidget *widget, const QVector<KPluginMetaData> &triedOffers = QVector<KPluginMetaData>()); 0350 0351 // overrides the editor command (for example with a command from the command line) 0352 QString editorCommandOverride; 0353 }; 0354 0355 class DocumentInfoPrivate 0356 { 0357 public: 0358 QMap<QString, QString> values; // key -> value 0359 QMap<QString, QString> titles; // key -> title For the custom keys 0360 }; 0361 0362 } 0363 0364 #endif 0365 0366 /* kate: replace-tabs on; indent-width 4; */