okular/part.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

434 lines
14 KiB
C
Raw Normal View History

/***************************************************************************
* Copyright (C) 2002 by Wilco Greven <greven@kde.org> *
* Copyright (C) 2003-2004 by Christophe Devriese *
* <Christophe.Devriese@student.kuleuven.ac.be> *
* Copyright (C) 2003 by Andy Goossens <andygoossens@telenet.be> *
* Copyright (C) 2003 by Laurent Montel <montel@kde.org> *
* Copyright (C) 2004 by Dominique Devriese <devriese@kde.org> *
* Copyright (C) 2004-2007 by Albert Astals Cid <aacid@kde.org> *
* Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group *
* company, info@kdab.com. Work sponsored by the *
* LiMux project of the city of Munich *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef _PART_H_
#define _PART_H_
#include <QIcon>
#include <QList>
#include <QPointer>
#include <QProcess>
2015-01-29 19:55:57 +00:00
#include <QUrl>
2018-09-01 08:25:57 +00:00
#include <QtDBus> // krazy:exclude=includes
#include <KCompressionDevice>
#include <KIO/Job>
#include <KMessageWidget>
#include <KParts/ReadWritePart>
#include <KPluginFactory>
#include "core/document.h"
#include "core/observer.h"
#include "interfaces/viewerinterface.h"
#include "kdocumentviewer.h"
#include "okularpart_export.h"
#include <config-okular.h>
class QAction;
class QWidget;
class QPrinter;
class QMenu;
class KConfigDialog;
class KDirWatch;
class KToggleAction;
class KToggleFullScreenAction;
2014-09-17 22:30:39 +00:00
class QTemporaryFile;
2014-08-13 10:45:40 +00:00
class QAction;
class QJsonObject;
namespace KParts
{
class GUIActivateEvent;
}
class FindBar;
class ThumbnailList;
class PageSizeLabel;
class PageView;
class PresentationWidget;
class ProgressWidget;
class SearchWidget;
class Sidebar;
class TOC;
class MiniBar;
2012-02-02 18:55:40 +00:00
class MiniBarLogic;
class FileKeeper;
class Reviews;
class BookmarkList;
class DrawingToolActions;
2015-05-27 13:56:56 +00:00
class Layers;
class SignaturePanel;
#if PURPOSE_FOUND
namespace Purpose
{
class Menu;
}
#endif
namespace Okular
{
class BrowserExtension;
class ExportFormat;
/**
* Describes the possible embedding modes of the part
*
* @since 0.14 (KDE 4.8)
*/
enum EmbedMode {
UnknownEmbedMode,
NativeShellMode, // embedded in the native Okular' shell
PrintPreviewMode, // embedded to show the print preview of a document
KHTMLPartMode, // embedded in KHTML
2014-03-02 12:59:49 +00:00
ViewerWidgetMode // the part acts as a widget that can display all kinds of documents
};
/**
* This is a "Part". It that does all the real work in a KPart
* application.
*
* @short Main Part
* @author Wilco Greven <greven@kde.org>
* @version 0.2
*/
class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::DocumentObserver, public KDocumentViewer, public Okular::ViewerInterface
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.okular")
Q_INTERFACES(KDocumentViewer)
Q_INTERFACES(Okular::ViewerInterface)
friend class PartTest;
public:
// Default constructor
/**
* If one element of 'args' contains one of the strings "Print/Preview" or "ViewerWidget",
* the part will be set up in the corresponding mode. Additionally, it is possible to specify
* which config file should be used by adding a string containing "ConfigFileName=<file name>"
* to 'args'.
**/
Part(QWidget *parentWidget, QObject *parent, const QVariantList &args);
// Destructor
~Part() override;
// inherited from DocumentObserver
2017-03-02 19:39:24 +00:00
void notifySetup(const QVector<Okular::Page *> &pages, int setupFlags) override;
void notifyViewportChanged(bool smoothMove) override;
void notifyPageChanged(int page, int flags) override;
2017-03-02 19:39:24 +00:00
bool openDocument(const QUrl &url, uint page) override;
void startPresentation() override;
QStringList supportedMimeTypes() const override;
2015-01-29 19:55:57 +00:00
QUrl realUrl() const;
2017-03-02 19:39:24 +00:00
void showSourceLocation(const QString &fileName, int line, int column, bool showGraphically = true) override;
void clearLastShownSourceLocation() override;
bool isWatchFileModeEnabled() const override;
void setWatchFileModeEnabled(bool enable) override;
bool areSourceLocationsShownGraphically() const override;
void setShowSourceLocationsGraphically(bool show) override;
bool openNewFilesInTabs() const override;
Q_INVOKABLE bool activateTabIfAlreadyOpenFile() const;
public Q_SLOTS: // dbus
2017-03-02 19:39:24 +00:00
Q_SCRIPTABLE Q_NOREPLY void goToPage(uint page) override;
Q_SCRIPTABLE Q_NOREPLY void openDocument(const QString &doc);
Q_SCRIPTABLE uint pages();
Q_SCRIPTABLE uint currentPage();
Q_SCRIPTABLE QString currentDocument();
Q_SCRIPTABLE QString documentMetaData(const QString &metaData) const;
Q_SCRIPTABLE void slotPreferences();
Q_SCRIPTABLE void slotFind();
Q_SCRIPTABLE void slotPrintPreview();
Q_SCRIPTABLE void slotPreviousPage();
Q_SCRIPTABLE void slotNextPage();
Q_SCRIPTABLE void slotGotoFirst();
Q_SCRIPTABLE void slotGotoLast();
Q_SCRIPTABLE void slotTogglePresentation();
Q_SCRIPTABLE void slotToggleChangeColors();
Q_SCRIPTABLE void slotSetChangeColors(bool active);
Q_SCRIPTABLE Q_NOREPLY void reload();
Q_SCRIPTABLE Q_NOREPLY void enableStartWithPrint();
Q_SCRIPTABLE Q_NOREPLY void enableExitAfterPrint();
Q_SCRIPTABLE Q_NOREPLY void enableStartWithFind(const QString &text);
Q_SCRIPTABLE void slotOpenContainingFolder();
Q_SIGNALS:
void enablePrintAction(bool enable);
void openSourceReference(const QString &absFileName, int line, int column);
void viewerMenuStateChange(bool enabled);
void enableCloseAction(bool enable);
2020-02-20 17:45:46 +00:00
void mimeTypeChanged(const QMimeType &mimeType);
2014-08-13 11:07:44 +00:00
void urlsDropped(const QList<QUrl> &urls);
2020-02-20 17:45:46 +00:00
void fitWindowToPage(const QSize pageViewPortSize, const QSize pageSize);
protected:
// reimplemented from KParts::ReadWritePart
2017-03-02 19:39:24 +00:00
bool openFile() override;
bool openUrl(const QUrl &url) override;
void guiActivateEvent(KParts::GUIActivateEvent *event) override;
2014-08-10 18:36:41 +00:00
void displayInfoMessage(const QString &message, KMessageWidget::MessageType messageType = KMessageWidget::Information, int duration = -1);
public:
2017-03-02 19:39:24 +00:00
bool queryClose() override;
bool closeUrl() override;
bool closeUrl(bool promptToSave) override;
void setReadWrite(bool readwrite) override;
bool saveAs(const QUrl &saveUrl) override;
protected Q_SLOTS:
// connected to actions
2015-01-29 19:55:57 +00:00
void openUrlFromDocument(const QUrl &url);
void openUrlFromBookmarks(const QUrl &url);
2014-08-13 11:07:44 +00:00
void handleDroppedUrls(const QList<QUrl> &urls);
void slotGoToPage();
void slotHistoryBack();
void slotHistoryNext();
void slotAddBookmark();
void slotRenameBookmarkFromMenu();
void slotRemoveBookmarkFromMenu();
void slotRenameCurrentViewportBookmark();
void slotPreviousBookmark();
void slotNextBookmark();
void slotFindNext();
void slotFindPrev();
bool slotSaveFileAs(bool showOkularArchiveAsDefaultFormat = false);
void slotGetNewStuff();
void slotNewConfig();
2020-02-20 17:45:46 +00:00
void slotShowMenu(const Okular::Page *page, const QPoint point);
void slotShowTOCMenu(const Okular::DocumentViewport &vp, const QPoint point, const QString &title);
void slotShowProperties();
void slotShowEmbeddedFiles();
void slotShowLeftPanel();
void slotShowBottomBar();
void slotShowPresentation();
void slotHidePresentation();
void slotExportAs(QAction *);
bool slotImportPSFile();
void slotAboutBackend();
void slotReload();
void close();
void cannotQuit();
void slotShowFindBar();
void slotHideFindBar();
void slotJobStarted(KIO::Job *job);
void slotJobFinished(KJob *job);
void loadCancelled(const QString &reason);
void setWindowTitleFromDocument();
// can be connected to widget elements
void updateViewActions();
void updateBookmarksActions();
void enableTOC(bool enable);
void slotRebuildBookmarkMenu();
2015-05-27 13:56:56 +00:00
void enableLayers(bool enable);
Improve the sidebar's navigation and UX Okular's sidebar vertical view chooser toolbar suffers from a few issues: * It's a nonstandard UI not used for category choosers in other pieces of KDE software, and not used in other FOSS document readers * What is shown and what is hidden is simultaneously too configurable while still not offering the desirable UI common to other programs (i.e. no visible category chooser, but a sidebar capable of displaying thumbnails, table of contents, search results, etc.) * With labels on it takes up quite a bit of horizontal space, while with labels off, the categories are less than clear * UX is kind of clunky with nonstandard behaviors (e.g. clicking on the current category to hide that category's view while keeping the view chooser visible, showing mostly disabled items) * It's made with custom painting code, which reduces maintainability and introduces bugs (e.g. https://bugs.kde.org/show_bug.cgi?id=408190) This patch removes the vertical category chooser entirely and replaces it with a tabbed view on the top of the sidebar itself. The tabs are icons-only and have large icons. A button is added on the left side of the default toolbar to quickly hide or show the sidebar. In order to make room for the new button, the Previous and Next buttons on the toolbar are removed, as previous/next buttons are already present on the Page Bar on the bottom of the window so there's no need to duplicate this functionality. This improves the UX, fixes a variety of bugs, and deletes a lot of custom code of dubious long-term maintainability. ![vokoscreenNG-2020-04-16_13-29-24](https://invent.kde.org/graphics/okular/uploads/a1f96a315b69282df51de9993b1befaf/vokoscreenNG-2020-04-16_13-29-24.webm) BUG: 213508 BUG: 334441 BUG: 344599 BUG: 408190 CCBUG: 335189 FIXED-IN: 1.11.0 CHANGELOG: The sidebar can now be easily shown or hidden with a toolbar button, and the category chooser no longer takes up so much space
2020-05-27 13:37:42 +00:00
void enableSidebarSignaturesItem(bool enable);
public Q_SLOTS:
bool saveFile() override;
// connected to Shell action (and browserExtension), not local one
void slotPrint();
void slotFileDirty(const QString &);
bool slotAttemptReload(bool oneShot = false, const QUrl &newUrl = QUrl());
void psTransformEnded(int, QProcess::ExitStatus);
KConfigDialog *slotGeneratorPreferences();
void errorMessage(const QString &message, int duration = 0);
void warningMessage(const QString &message, int duration = -1);
void noticeMessage(const QString &message, int duration = -1);
void moveSplitter(const int sideWidgetSize);
private:
bool aboutToShowContextMenu(QMenu *menu, QAction *action, QMenu *contextMenu);
2020-02-20 17:45:46 +00:00
void showMenu(const Okular::Page *page, const QPoint point, const QString &bookmarkTitle = QString(), const Okular::DocumentViewport &vp = DocumentViewport(), bool showTOCActions = false);
bool eventFilter(QObject *watched, QEvent *event) override;
Document::OpenResult doOpenFile(const QMimeType &mime, const QString &fileNameToOpen, bool *isCompressedFile);
bool openUrl(const QUrl &url, bool swapInsteadOfOpening);
void setupViewerActions();
void setViewerShortcuts();
void setupActions();
void setupPrint(QPrinter &printer);
bool doPrint(QPrinter &printer);
bool handleCompressed(QString &destpath, const QString &path, KCompressionDevice::CompressionType compressionType);
void rebuildBookmarkMenu(bool unplugActions = true);
void updateAboutBackendAction();
void unsetDummyMode();
void slotRenameBookmark(const DocumentViewport &viewport);
void slotRemoveBookmark(const DocumentViewport &viewport);
void resetStartArguments();
void checkNativeSaveDataLoss(bool *out_wontSaveForms, bool *out_wontSaveAnnotations) const;
enum SaveAsFlag {
NoSaveAsFlags = 0, ///< No options
SaveAsOkularArchive = 1 ///< Save as Okular Archive (.okular) instead of document's native format
};
Q_DECLARE_FLAGS(SaveAsFlags, SaveAsFlag)
bool saveAs(const QUrl &saveUrl, SaveAsFlags flags);
void setFileToWatch(const QString &filePath);
void unsetFileToWatch();
#if PURPOSE_FOUND
void slotShareActionFinished(const QJsonObject &output, int error, const QString &message);
#endif
static int numberOfParts;
2014-09-17 22:30:39 +00:00
QTemporaryFile *m_tempfile;
// the document
Okular::Document *m_document;
QDateTime m_fileLastModified;
QString m_temporaryLocalFile;
bool isDocumentArchive;
bool m_documentOpenWithPassword;
bool m_swapInsteadOfOpening; // if set, the next open operation will replace the backing file (used when reloading just saved files)
// main widgets
Sidebar *m_sidebar;
SearchWidget *m_searchWidget;
FindBar *m_findBar;
KMessageWidget *m_migrationMessage;
KMessageWidget *m_topMessage;
KMessageWidget *m_formsMessage;
KMessageWidget *m_infoMessage;
KMessageWidget *m_signatureMessage;
QPointer<ThumbnailList> m_thumbnailList;
QPointer<PageView> m_pageView;
QPointer<TOC> m_toc;
Improve the sidebar's navigation and UX Okular's sidebar vertical view chooser toolbar suffers from a few issues: * It's a nonstandard UI not used for category choosers in other pieces of KDE software, and not used in other FOSS document readers * What is shown and what is hidden is simultaneously too configurable while still not offering the desirable UI common to other programs (i.e. no visible category chooser, but a sidebar capable of displaying thumbnails, table of contents, search results, etc.) * With labels on it takes up quite a bit of horizontal space, while with labels off, the categories are less than clear * UX is kind of clunky with nonstandard behaviors (e.g. clicking on the current category to hide that category's view while keeping the view chooser visible, showing mostly disabled items) * It's made with custom painting code, which reduces maintainability and introduces bugs (e.g. https://bugs.kde.org/show_bug.cgi?id=408190) This patch removes the vertical category chooser entirely and replaces it with a tabbed view on the top of the sidebar itself. The tabs are icons-only and have large icons. A button is added on the left side of the default toolbar to quickly hide or show the sidebar. In order to make room for the new button, the Previous and Next buttons on the toolbar are removed, as previous/next buttons are already present on the Page Bar on the bottom of the window so there's no need to duplicate this functionality. This improves the UX, fixes a variety of bugs, and deletes a lot of custom code of dubious long-term maintainability. ![vokoscreenNG-2020-04-16_13-29-24](https://invent.kde.org/graphics/okular/uploads/a1f96a315b69282df51de9993b1befaf/vokoscreenNG-2020-04-16_13-29-24.webm) BUG: 213508 BUG: 334441 BUG: 344599 BUG: 408190 CCBUG: 335189 FIXED-IN: 1.11.0 CHANGELOG: The sidebar can now be easily shown or hidden with a toolbar button, and the category chooser no longer takes up so much space
2020-05-27 13:37:42 +00:00
bool m_tocEnabled;
2012-02-02 18:55:40 +00:00
QPointer<MiniBarLogic> m_miniBarLogic;
QPointer<MiniBar> m_miniBar;
QPointer<MiniBar> m_pageNumberTool;
QPointer<QWidget> m_bottomBar;
QPointer<PresentationWidget> m_presentationWidget;
QPointer<ProgressWidget> m_progressWidget;
QPointer<PageSizeLabel> m_pageSizeLabel;
QPointer<Reviews> m_reviewsWidget;
QPointer<BookmarkList> m_bookmarkList;
2015-05-27 13:56:56 +00:00
QPointer<Layers> m_layers;
QPointer<SignaturePanel> m_signaturePanel;
// document watcher (and reloader) variables
KDirWatch *m_watcher;
QString m_watchedFilePath, m_watchedFileSymlinkTarget;
QTimer *m_dirtyHandler;
2015-01-29 19:55:57 +00:00
QUrl m_oldUrl;
Okular::DocumentViewport m_viewportDirty;
bool m_isReloading;
bool m_wasPresentationOpen;
QWidget *m_dirtyToolboxItem;
bool m_wasSidebarVisible;
bool m_fileWasRemoved;
Rotation m_dirtyPageRotation;
// Remember the search history
QStringList m_searchHistory;
// actions
2014-08-09 23:08:54 +00:00
QAction *m_gotoPage;
QAction *m_prevPage;
QAction *m_nextPage;
QAction *m_beginningOfDocument;
QAction *m_endOfDocument;
QAction *m_historyBack;
QAction *m_historyNext;
QAction *m_addBookmark;
QAction *m_renameBookmark;
QAction *m_prevBookmark;
QAction *m_nextBookmark;
QAction *m_copy;
QAction *m_selectAll;
QAction *m_selectCurrentPage;
2014-08-09 23:08:54 +00:00
QAction *m_find;
QAction *m_findNext;
QAction *m_findPrev;
QAction *m_save;
2014-08-09 23:08:54 +00:00
QAction *m_saveAs;
QAction *m_saveCopyAs;
QAction *m_printPreview;
QAction *m_showProperties;
QAction *m_showEmbeddedFiles;
QAction *m_exportAs;
QAction *m_exportAsText;
QAction *m_exportAsDocArchive;
#if PURPOSE_FOUND
QAction *m_share;
#endif
2014-08-09 23:08:54 +00:00
QAction *m_showPresentation;
QAction *m_openContainingFolder;
KToggleAction *m_showMenuBarAction;
KToggleAction *m_showLeftPanel;
KToggleAction *m_showBottomBar;
QAction *m_showSignaturePanel;
KToggleFullScreenAction *m_showFullScreenAction;
2014-08-09 23:08:54 +00:00
QAction *m_aboutBackend;
QAction *m_reload;
QMenu *m_exportAsMenu;
#if PURPOSE_FOUND
Purpose::Menu *m_shareMenu;
#endif
2014-08-09 23:08:54 +00:00
QAction *m_closeFindBar;
DrawingToolActions *m_presentationDrawingActions;
bool m_actionsSearched;
BrowserExtension *m_bExtension;
QList<Okular::ExportFormat> m_exportFormats;
QList<QAction *> m_bookmarkActions;
bool m_cliPresentation;
bool m_cliPrint;
bool m_cliPrintAndExit;
QString m_addBookmarkText;
QIcon m_addBookmarkIcon;
EmbedMode m_embedMode;
2015-01-29 19:55:57 +00:00
QUrl m_realUrl;
KXMLGUIClient *m_generatorGuiClient;
FileKeeper *m_keeper;
// Timer for m_infoMessage
QTimer *m_infoTimer;
QString m_registerDbusName;
// String to search in document startup
QString m_textToFindOnOpen;
private Q_SLOTS:
void slotAnnotationPreferences();
2011-10-23 13:22:58 +00:00
void slotHandleActivatedSourceReference(const QString &absFileName, int line, int col, bool *handled);
};
}
#endif
/* kate: replace-tabs on; indent-width 4; */