File indexing completed on 2024-04-28 15:51:54
0001 /* 0002 SPDX-FileCopyrightText: 2002 Wilco Greven <greven@kde.org> 0003 SPDX-FileCopyrightText: 2003-2004 Christophe Devriese <Christophe.Devriese@student.kuleuven.ac.be> 0004 SPDX-FileCopyrightText: 2003 Andy Goossens <andygoossens@telenet.be> 0005 SPDX-FileCopyrightText: 2003 Laurent Montel <montel@kde.org> 0006 SPDX-FileCopyrightText: 2004 Dominique Devriese <devriese@kde.org> 0007 SPDX-FileCopyrightText: 2004-2007 Albert Astals Cid <aacid@kde.org> 0008 0009 Work sponsored by the LiMux project of the city of Munich: 0010 SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com> 0011 0012 SPDX-License-Identifier: GPL-2.0-or-later 0013 */ 0014 0015 #ifndef _PART_H_ 0016 #define _PART_H_ 0017 0018 #include <config-okular.h> 0019 0020 #if HAVE_DBUS 0021 #include <QDBusAbstractAdaptor> // for Q_NOREPLY 0022 #else // HAVE_DBUS 0023 #define Q_NOREPLY 0024 #endif // HAVE_DBUS 0025 #include <QIcon> 0026 #include <QList> 0027 #include <QPointer> 0028 #include <QProcess> 0029 #include <QUrl> 0030 0031 #include <KCompressionDevice> 0032 #include <KIO/Job> 0033 #include <KMessageWidget> 0034 #include <KParts/ReadWritePart> 0035 #include <KPluginFactory> 0036 0037 #include "../core/document.h" 0038 #include "../core/observer.h" 0039 #include "../interfaces/viewerinterface.h" 0040 #include "../kdocumentviewer.h" 0041 0042 #include "okularpart_export.h" 0043 0044 class QAction; 0045 class QWidget; 0046 class QPrinter; 0047 class QMenu; 0048 0049 class KConfigDialog; 0050 class KDirWatch; 0051 class KHamburgerMenu; 0052 class KMainWindow; 0053 class KToggleAction; 0054 class KToggleFullScreenAction; 0055 class QTemporaryFile; 0056 class QAction; 0057 class QJsonObject; 0058 namespace KParts 0059 { 0060 class GUIActivateEvent; 0061 } 0062 0063 class FindBar; 0064 class ThumbnailList; 0065 class PageSizeLabel; 0066 class PageView; 0067 class PresentationWidget; 0068 class ProgressWidget; 0069 class SearchWidget; 0070 class Sidebar; 0071 class TOC; 0072 class MiniBar; 0073 class MiniBarLogic; 0074 class FileKeeper; 0075 class Reviews; 0076 class BookmarkList; 0077 class DrawingToolActions; 0078 class Layers; 0079 class SignaturePanel; 0080 0081 #if HAVE_PURPOSE 0082 namespace Purpose 0083 { 0084 class Menu; 0085 } 0086 #endif 0087 0088 namespace Okular 0089 { 0090 class BrowserExtension; 0091 class ExportFormat; 0092 0093 /** 0094 * Describes the possible embedding modes of the part 0095 * 0096 * @since 0.14 (KDE 4.8) 0097 */ 0098 enum EmbedMode { 0099 UnknownEmbedMode, 0100 NativeShellMode, // embedded in the native Okular' shell 0101 PrintPreviewMode, // embedded to show the print preview of a document 0102 ViewerWidgetMode // the part acts as a widget that can display all kinds of documents 0103 }; 0104 0105 /** 0106 * This is a "Part". It that does all the real work in a KPart 0107 * application. 0108 * 0109 * @short Main Part 0110 * @author Wilco Greven <greven@kde.org> 0111 * @version 0.2 0112 */ 0113 class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::DocumentObserver, public KDocumentViewer, public Okular::ViewerInterface 0114 { 0115 Q_OBJECT 0116 Q_CLASSINFO("D-Bus Interface", "org.kde.okular") 0117 Q_INTERFACES(KDocumentViewer) 0118 Q_INTERFACES(Okular::ViewerInterface) 0119 0120 friend class PartTest; 0121 0122 public: 0123 // Default constructor 0124 /** 0125 * If one element of 'args' contains one of the strings "Print/Preview" or "ViewerWidget", 0126 * the part will be set up in the corresponding mode. Additionally, it is possible to specify 0127 * which config file should be used by adding a string containing "ConfigFileName=<file name>" 0128 * to 'args'. 0129 **/ 0130 Part(QObject *parent, const QVariantList &args); 0131 0132 // Destructor 0133 ~Part() override; 0134 0135 // inherited from DocumentObserver 0136 void notifySetup(const QVector<Okular::Page *> &pages, int setupFlags) override; 0137 void notifyViewportChanged(bool smoothMove) override; 0138 void notifyPageChanged(int page, int flags) override; 0139 0140 bool openDocument(const QUrl &url, uint page) override; 0141 void startPresentation() override; 0142 QStringList supportedMimeTypes() const override; 0143 0144 QUrl realUrl() const; 0145 0146 void showSourceLocation(const QString &fileName, int line, int column, bool showGraphically = true) override; 0147 void clearLastShownSourceLocation() override; 0148 bool isWatchFileModeEnabled() const override; 0149 void setWatchFileModeEnabled(bool enable) override; 0150 bool areSourceLocationsShownGraphically() const override; 0151 void setShowSourceLocationsGraphically(bool show) override; 0152 bool openNewFilesInTabs() const override; 0153 QWidget *getSideContainer() const override; 0154 Q_INVOKABLE bool activateTabIfAlreadyOpenFile() const; 0155 0156 void setModified(bool modified) override; 0157 0158 public Q_SLOTS: // dbus 0159 Q_SCRIPTABLE Q_NOREPLY void goToPage(uint page) override; 0160 Q_SCRIPTABLE Q_NOREPLY void openDocument(const QString &doc); 0161 Q_SCRIPTABLE uint pages(); 0162 Q_SCRIPTABLE uint currentPage(); 0163 Q_SCRIPTABLE QString currentDocument(); 0164 Q_SCRIPTABLE QString documentMetaData(const QString &metaData) const; 0165 Q_SCRIPTABLE void slotPreferences(); 0166 Q_SCRIPTABLE void slotFind(); 0167 Q_SCRIPTABLE void slotPrintPreview(); 0168 Q_SCRIPTABLE void slotPreviousPage(); 0169 Q_SCRIPTABLE void slotNextPage(); 0170 Q_SCRIPTABLE void slotGotoFirst(); 0171 Q_SCRIPTABLE void slotGotoLast(); 0172 Q_SCRIPTABLE void slotTogglePresentation(); 0173 Q_SCRIPTABLE void slotToggleChangeColors(); 0174 Q_SCRIPTABLE void slotSetChangeColors(bool active); 0175 Q_SCRIPTABLE Q_NOREPLY void reload(); 0176 Q_SCRIPTABLE Q_NOREPLY void enableStartWithPrint(); 0177 Q_SCRIPTABLE Q_NOREPLY void enableExitAfterPrint(); 0178 Q_SCRIPTABLE Q_NOREPLY void enableStartWithFind(const QString &text); 0179 Q_SCRIPTABLE Q_NOREPLY void setEditorCmd(const QString &editorCmd); 0180 Q_SCRIPTABLE void slotOpenContainingFolder(); 0181 0182 Q_SIGNALS: 0183 void enablePrintAction(bool enable); 0184 void openSourceReference(const QString &absFileName, int line, int column); 0185 void viewerMenuStateChange(bool enabled); 0186 void enableCloseAction(bool enable); 0187 void mimeTypeChanged(const QMimeType &mimeType); 0188 void urlsDropped(const QList<QUrl> &urls); 0189 void fitWindowToPage(const QSize pageViewPortSize, const QSize pageSize); 0190 0191 protected: 0192 // reimplemented from KParts::ReadWritePart 0193 bool openFile() override; 0194 bool openUrl(const QUrl &url) override; 0195 void guiActivateEvent(KParts::GUIActivateEvent *event) override; 0196 void displayInfoMessage(const QString &message, KMessageWidget::MessageType messageType = KMessageWidget::Information, int duration = -1); 0197 0198 public: 0199 bool queryClose() override; 0200 bool closeUrl() override; 0201 bool closeUrl(bool promptToSave) override; 0202 void setReadWrite(bool readwrite) override; 0203 bool saveAs(const QUrl &saveUrl) override; 0204 0205 protected Q_SLOTS: 0206 // connected to actions 0207 void openUrlFromDocument(const QUrl &url); 0208 void openUrlFromBookmarks(const QUrl &url); 0209 void handleDroppedUrls(const QList<QUrl> &urls); 0210 void slotGoToPage(); 0211 void slotHistoryBack(); 0212 void slotHistoryNext(); 0213 void slotAddBookmark(); 0214 void slotRenameBookmarkFromMenu(); 0215 void slotRemoveBookmarkFromMenu(); 0216 void slotRenameCurrentViewportBookmark(); 0217 void slotPreviousBookmark(); 0218 void slotNextBookmark(); 0219 void slotFindNext(); 0220 void slotFindPrev(); 0221 bool slotSaveFileAs(bool showOkularArchiveAsDefaultFormat = false); 0222 void slotNewConfig(); 0223 void slotShowMenu(const Okular::Page *page, const QPoint point); 0224 void slotShowTOCMenu(const Okular::DocumentViewport &vp, const QPoint point, const QString &title); 0225 void slotShowProperties(); 0226 void slotShowEmbeddedFiles(); 0227 void slotShowLeftPanel(); 0228 void slotShowBottomBar(); 0229 void slotShowPresentation(); 0230 void slotHidePresentation(); 0231 0232 /** 0233 * Updates the menu that is by default at the right end of the toolbar. 0234 * In true "simple by default" fashion, the menu only contains the most important actions 0235 * which are needed to use all essential Okular features. More advanced actions can be 0236 * discovered through a sub-menu (@see KConfigWidgets::KHamburgerMenu::setMenuBarAdvertised()). 0237 */ 0238 void slotUpdateHamburgerMenu(); 0239 void slotExportAs(QAction *); 0240 bool slotImportPSFile(); 0241 void slotAboutBackend(); 0242 void slotReload(); 0243 void close(); 0244 void cannotQuit(); 0245 void slotShowFindBar(); 0246 void slotHideFindBar(); 0247 void slotJobStarted(KIO::Job *job); 0248 void slotJobFinished(KJob *job); 0249 void loadCancelled(const QString &reason); 0250 void setWindowTitleFromDocument(); 0251 // can be connected to widget elements 0252 void updateViewActions(); 0253 void updateBookmarksActions(); 0254 void enableTOC(bool enable); 0255 void slotRebuildBookmarkMenu(); 0256 void enableLayers(bool enable); 0257 void enableSidebarSignaturesItem(bool enable); 0258 0259 public Q_SLOTS: 0260 bool saveFile() override; 0261 // connected to Shell action (and browserExtension), not local one 0262 void slotPrint(); 0263 void slotFileDirty(const QString &); 0264 bool slotAttemptReload(bool oneShot = false, const QUrl &newUrl = QUrl()); 0265 void psTransformEnded(int, QProcess::ExitStatus); 0266 KConfigDialog *slotGeneratorPreferences(); 0267 0268 void errorMessage(const QString &message, int duration = 0); 0269 void warningMessage(const QString &message, int duration = -1); 0270 void noticeMessage(const QString &message, int duration = -1); 0271 0272 void moveSplitter(const int sideWidgetSize); 0273 0274 private: 0275 bool aboutToShowContextMenu(QMenu *menu, QAction *action, QMenu *contextMenu); 0276 void showMenu(const Okular::Page *page, const QPoint point, const QString &bookmarkTitle = QString(), const Okular::DocumentViewport &vp = DocumentViewport(), bool showTOCActions = false); 0277 /** 0278 * Searches the actionCollections of all KXMLGUIClients that were created by the same factory() 0279 * as this Part for a QAction that has both the specified name and the specified class. 0280 * @return an action with class @p Action and name @p actionName. nullptr if no such action is found. 0281 */ 0282 template<class Action = QAction> Action *findActionInKPartHierarchy(const QString &actionName); 0283 /** @return the first KMainWindow among the ancestors of this part. nullptr if no KMainWindow is found. */ 0284 KMainWindow *findMainWindow(); 0285 bool eventFilter(QObject *watched, QEvent *event) override; 0286 Document::OpenResult doOpenFile(const QMimeType &mime, const QString &fileNameToOpen, bool *isCompressedFile); 0287 bool openUrl(const QUrl &url, bool swapInsteadOfOpening); 0288 0289 void setupViewerActions(); 0290 void setViewerShortcuts(); 0291 void setupActions(); 0292 0293 void setupPrint(QPrinter &printer); 0294 bool doPrint(QPrinter &printer); 0295 bool handleCompressed(QString &destpath, const QString &path, KCompressionDevice::CompressionType compressionType); 0296 void rebuildBookmarkMenu(bool unplugActions = true); 0297 void updateAboutBackendAction(); 0298 void unsetDummyMode(); 0299 void slotRenameBookmark(const DocumentViewport &viewport); 0300 void slotRemoveBookmark(const DocumentViewport &viewport); 0301 void resetStartArguments(); 0302 void checkNativeSaveDataLoss(bool *out_wontSaveForms, bool *out_wontSaveAnnotations) const; 0303 0304 enum SaveAsFlag { 0305 NoSaveAsFlags = 0, ///< No options 0306 SaveAsOkularArchive = 1 ///< Save as Okular Archive (.okular) instead of document's native format 0307 }; 0308 Q_DECLARE_FLAGS(SaveAsFlags, SaveAsFlag) 0309 0310 bool saveAs(const QUrl &saveUrl, SaveAsFlags flags); 0311 0312 void setFileToWatch(const QString &filePath); 0313 void unsetFileToWatch(); 0314 0315 #if HAVE_PURPOSE 0316 void slotShareActionFinished(const QJsonObject &output, int error, const QString &message); 0317 #endif 0318 0319 bool tryOpeningUrlWithFragmentAsName(); 0320 0321 /** 0322 * Initializes Okular::Settings. 0323 * Determines the config file path, and performs configuration updates not handled by kconf_update. 0324 * 0325 * @param args As passed to Part::Part(). 0326 */ 0327 void setupConfigSkeleton(const QVariantList &args); 0328 0329 static int numberOfParts; 0330 0331 QTemporaryFile *m_tempfile; 0332 0333 // the document 0334 Okular::Document *m_document; 0335 QDateTime m_fileLastModified; 0336 QString m_temporaryLocalFile; 0337 bool isDocumentArchive; 0338 bool m_documentOpenWithPassword; 0339 bool m_swapInsteadOfOpening; // if set, the next open operation will replace the backing file (used when reloading just saved files) 0340 bool m_warnedAboutModifyingUnsaveableDocument = false; 0341 0342 // main widgets 0343 Sidebar *m_sidebar; 0344 SearchWidget *m_searchWidget; 0345 FindBar *m_findBar; 0346 KMessageWidget *m_migrationMessage; 0347 KMessageWidget *m_topMessage; 0348 KMessageWidget *m_formsMessage; 0349 KMessageWidget *m_infoMessage; 0350 KMessageWidget *m_signatureMessage; 0351 QPointer<ThumbnailList> m_thumbnailList; 0352 QPointer<PageView> m_pageView; 0353 QPointer<TOC> m_toc; 0354 bool m_tocEnabled; 0355 QPointer<MiniBarLogic> m_miniBarLogic; 0356 QPointer<MiniBar> m_miniBar; 0357 QPointer<MiniBar> m_pageNumberTool; 0358 QPointer<QWidget> m_bottomBar; 0359 QPointer<PresentationWidget> m_presentationWidget; 0360 QPointer<ProgressWidget> m_progressWidget; 0361 QPointer<PageSizeLabel> m_pageSizeLabel; 0362 QPointer<Reviews> m_reviewsWidget; 0363 QPointer<BookmarkList> m_bookmarkList; 0364 QPointer<Layers> m_layers; 0365 QPointer<SignaturePanel> m_signaturePanel; 0366 0367 // document watcher (and reloader) variables 0368 KDirWatch *m_watcher; 0369 QString m_watchedFilePath, m_watchedFileSymlinkTarget; 0370 QTimer *m_dirtyHandler; 0371 QUrl m_oldUrl; 0372 Okular::DocumentViewport m_viewportDirty; 0373 bool m_isReloading; 0374 bool m_wasPresentationOpen; 0375 QWidget *m_dirtyToolboxItem; 0376 bool m_wasSidebarVisible; 0377 bool m_fileWasRemoved; 0378 Rotation m_dirtyPageRotation; 0379 0380 // Remember the search history 0381 QStringList m_searchHistory; 0382 0383 // actions 0384 QAction *m_gotoPage; 0385 QAction *m_prevPage; 0386 QAction *m_nextPage; 0387 QAction *m_beginningOfDocument; 0388 QAction *m_endOfDocument; 0389 QAction *m_historyBack; 0390 QAction *m_historyNext; 0391 QAction *m_addBookmark; 0392 QAction *m_renameBookmark; 0393 QAction *m_prevBookmark; 0394 QAction *m_nextBookmark; 0395 QAction *m_copy; 0396 QAction *m_selectAll; 0397 QAction *m_selectCurrentPage; 0398 QAction *m_find; 0399 QAction *m_findNext; 0400 QAction *m_findPrev; 0401 QAction *m_save; 0402 QAction *m_saveAs; 0403 QAction *m_saveCopyAs; 0404 QAction *m_printPreview; 0405 QAction *m_showProperties; 0406 QAction *m_showEmbeddedFiles; 0407 QAction *m_exportAs; 0408 QAction *m_exportAsText; 0409 QAction *m_exportAsDocArchive; 0410 #if HAVE_PURPOSE 0411 QAction *m_share; 0412 #endif 0413 QAction *m_showPresentation; 0414 QAction *m_openContainingFolder; 0415 KHamburgerMenu *m_hamburgerMenuAction; 0416 KToggleAction *m_showMenuBarAction; 0417 KToggleAction *m_showLeftPanel; 0418 KToggleAction *m_showBottomBar; 0419 QAction *m_showSignaturePanel; 0420 KToggleFullScreenAction *m_showFullScreenAction; 0421 QAction *m_aboutBackend; 0422 QAction *m_reload; 0423 QMenu *m_exportAsMenu; 0424 #if HAVE_PURPOSE 0425 Purpose::Menu *m_shareMenu; 0426 #endif 0427 QAction *m_closeFindBar; 0428 DrawingToolActions *m_presentationDrawingActions; 0429 0430 BrowserExtension *m_bExtension; 0431 0432 QList<Okular::ExportFormat> m_exportFormats; 0433 QList<QAction *> m_bookmarkActions; 0434 bool m_cliPresentation; 0435 bool m_cliPrint; 0436 bool m_cliPrintAndExit; 0437 QString m_addBookmarkText; 0438 QIcon m_addBookmarkIcon; 0439 0440 EmbedMode m_embedMode; 0441 0442 QUrl m_realUrl; 0443 0444 KXMLGUIClient *m_generatorGuiClient; 0445 FileKeeper *m_keeper; 0446 0447 // Timer for m_infoMessage 0448 QTimer *m_infoTimer; 0449 0450 QString m_registerDbusName; 0451 0452 // String to search in document startup 0453 QString m_textToFindOnOpen; 0454 0455 // Set when opening an url that had fragment so that if it fails opening we try adding the fragment to the filename 0456 // if we're opening http://localhost/foo#bar.pdf and the filename contains an # we can open it after trying to open foo fails 0457 QUrl m_urlWithFragment; 0458 0459 private Q_SLOTS: 0460 void slotAccessibilityPreferences(); 0461 void slotAnnotationPreferences(); 0462 void slotHandleActivatedSourceReference(const QString &absFileName, int line, int col, bool *handled); 0463 }; 0464 0465 } 0466 0467 #endif 0468 0469 /* kate: replace-tabs on; indent-width 4; */