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; */