File indexing completed on 2025-03-09 04:54:42

0001 /*
0002   This file is part of KMail, the KDE mail client.
0003   SPDX-FileCopyrightText: 1997 Markus Wuebben <markus.wuebben@kde.org>
0004   SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
0005   SPDX-FileCopyrightText: 2009 Andras Mantia <andras@kdab.net>
0006 
0007   SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "messageviewer/viewerplugininterface.h"
0013 #include "messageviewer_export.h"
0014 #include <MimeTreeParser/Enums>
0015 
0016 #include <KMime/MDN>
0017 #include <KMime/Message>
0018 #include <MessageViewer/MDNWarningWidget>
0019 
0020 #include <QWidget>
0021 #include <memory>
0022 
0023 namespace Akonadi
0024 {
0025 class Item;
0026 class ItemFetchJob;
0027 }
0028 
0029 namespace KIdentityManagementCore
0030 {
0031 class IdentityManager;
0032 }
0033 
0034 class KActionCollection;
0035 class QAction;
0036 class KToggleAction;
0037 class KActionMenu;
0038 
0039 class QAbstractItemModel;
0040 class QCloseEvent;
0041 class QEvent;
0042 class QResizeEvent;
0043 
0044 namespace WebEngineViewer
0045 {
0046 class WebHitTestResult;
0047 }
0048 
0049 namespace MessageViewer
0050 {
0051 class WebHitTestResult;
0052 class DKIMWidgetInfo;
0053 class DKIMViewerMenu;
0054 class AttachmentStrategy;
0055 class HeaderStylePlugin;
0056 class CSSHelper;
0057 class ViewerPrivate;
0058 class Viewer;
0059 class RemoteContentMenu;
0060 class MDNWarningWidget;
0061 
0062 /**
0063  * An interface to plug in a handler that is called when
0064  * an message item has been loaded into the view.
0065  */
0066 class MESSAGEVIEWER_EXPORT AbstractMessageLoadedHandler
0067 {
0068 public:
0069     AbstractMessageLoadedHandler();
0070     virtual ~AbstractMessageLoadedHandler();
0071 
0072     /**
0073      * This method is called whenever a message item has been loaded
0074      * into the view.
0075      *
0076      * @param item The message item that has been loaded.
0077      */
0078     virtual void setItem(const Akonadi::Item &item) = 0;
0079 
0080 protected:
0081     Akonadi::Session *session() const;
0082 
0083 private:
0084     void setSession(Akonadi::Session *session);
0085 
0086     friend class Viewer;
0087     class AbstractMessageLoadedHandlerPrivate;
0088     std::unique_ptr<AbstractMessageLoadedHandlerPrivate> const d;
0089 };
0090 
0091 /**
0092  * This is the main widget for the viewer.
0093  * See the documentation of ViewerPrivate for implementation details.
0094  * See Mainpage.dox for an overview of the classes in the messageviewer library.
0095  */
0096 class MESSAGEVIEWER_EXPORT Viewer : public QWidget
0097 {
0098     Q_OBJECT
0099 
0100     Q_DECLARE_PRIVATE(Viewer)
0101 
0102 public:
0103     /**
0104      * Create a mail viewer widget
0105      * @param parent parent widget
0106      * @param widget the application's main widget
0107      * @param actionCollection the action collection where the widget's actions will belong to
0108      */
0109     explicit Viewer(QWidget *parent, QWidget *widget = nullptr, KActionCollection *actionCollection = nullptr);
0110     ~Viewer() override;
0111 
0112     /**
0113      * Returns the current message displayed in the viewer.
0114      */
0115     [[nodiscard]] KMime::Message::Ptr message() const;
0116 
0117     /**
0118      * Returns the current message item displayed in the viewer.
0119      */
0120     [[nodiscard]] Akonadi::Item messageItem() const;
0121 
0122     enum DisplayFormatMessage {
0123         UseGlobalSetting = 0,
0124         Text = 1,
0125         Html = 2,
0126         Unknown = 3,
0127         ICal = 4,
0128     };
0129 
0130     enum AttachmentAction {
0131         Open = 1,
0132         OpenWith,
0133         View,
0134         Save,
0135         Properties,
0136         Delete,
0137         Copy,
0138         ScrollTo,
0139         ReplyMessageToAuthor,
0140         ReplyMessageToAll,
0141     };
0142 
0143     enum ResourceOnlineMode {
0144         AllResources = 0,
0145         SelectedResource = 1,
0146     };
0147 
0148     /**
0149      * Set the message that shall be shown.
0150      * @param message - the message to be shown. If 0, an empty page is displayed.
0151      * @param updateMode - update the display immediately or not. See UpdateMode.
0152      */
0153     void setMessage(const KMime::Message::Ptr &message, MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
0154 
0155     /**
0156      * Set the Akonadi item that will be displayed.
0157      * @param item - the Akonadi item to be displayed. If it doesn't hold a mail (KMime::Message::Ptr as payload data),
0158      *               an empty page is shown.
0159      * @param updateMode - update the display immediately or not. See UpdateMode.
0160      */
0161     void setMessageItem(const Akonadi::Item &item, MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
0162 
0163     /**
0164      * The path to the message in terms of Akonadi collection hierarchy.
0165      */
0166     [[nodiscard]] QString messagePath() const;
0167 
0168     /**
0169      * Set the path to the message in terms of Akonadi collection hierarchy.
0170      */
0171     void setMessagePath(const QString &path);
0172 
0173     /**
0174      * Instead of settings a message to be shown sets a message part
0175      * to be shown
0176      */
0177     void setMessagePart(KMime::Content *aMsgPart);
0178 
0179     /**
0180      * Convenience method to clear the reader and discard the current message. Sets the internal message pointer
0181      * returned by message() to 0.
0182      * @param updateMode - update the display immediately or not. See UpdateMode.
0183      */
0184     void clear(MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
0185 
0186     void update(MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
0187 
0188     /**
0189      * Sets a message as the current one and print it immediately.
0190      * @param msg the message to display and print
0191      */
0192     void printMessage(const Akonadi::Item &msg);
0193 
0194     void printPreviewMessage(const Akonadi::Item &message);
0195 
0196     /** Print the currently displayed message */
0197     void print();
0198     void printPreview();
0199 
0200     /** Get the html override setting */
0201     [[nodiscard]] Viewer::DisplayFormatMessage displayFormatMessageOverwrite() const;
0202 
0203     /** Override default html mail setting */
0204     void setDisplayFormatMessageOverwrite(Viewer::DisplayFormatMessage format);
0205 
0206     /** Get the load external references override setting */
0207     bool htmlLoadExtOverride() const;
0208 
0209     /** Default behavior for loading external references.
0210      *  Use this for specifying the external reference loading behavior as
0211      *  specified in the user settings.
0212      *  @see setHtmlLoadExtOverride
0213      */
0214     void setHtmlLoadExtDefault(bool loadExtDefault);
0215 
0216     /** Override default load external references setting
0217      *  @warning This must only be called when the user has explicitly
0218      *  been asked to retrieve external references!
0219      *  @see setHtmlLoadExtDefault
0220      */
0221     void setHtmlLoadExtOverride(bool loadExtOverride);
0222 
0223     /** Is html mail to be supported? Takes into account override */
0224     [[nodiscard]] bool htmlMail() const;
0225 
0226     /** Is loading ext. references to be supported? Takes into account override */
0227     [[nodiscard]] bool htmlLoadExternal() const;
0228 
0229     /**
0230      * Display a generic HTML splash page instead of a message.
0231      * @param templateName - the template to be loaded
0232      * @param data - data for the template
0233      * @param domain the domain.
0234      */
0235     void displaySplashPage(const QString &templateName, const QVariantHash &data, const QByteArray &domain = QByteArray());
0236 
0237     /** Enable the displaying of messages again after an splash (or other) page was displayed */
0238     void enableMessageDisplay();
0239 
0240     /** Returns true if the message view is scrolled to the bottom. */
0241     void atBottom();
0242 
0243     [[nodiscard]] bool isFixedFont() const;
0244     void setUseFixedFont(bool useFixedFont);
0245 
0246     [[nodiscard]] QWidget *mainWindow();
0247 
0248     /** Enforce message decryption. */
0249     void setDecryptMessageOverwrite(bool overwrite = true);
0250 
0251     /**
0252      * Initiates a delete, by sending a signal to delete the message item */
0253     void deleteMessage();
0254 
0255     [[nodiscard]] const AttachmentStrategy *attachmentStrategy() const;
0256     void setAttachmentStrategy(const AttachmentStrategy *strategy);
0257 
0258     [[nodiscard]] QString overrideEncoding() const;
0259     void setOverrideEncoding(const QString &encoding);
0260     [[nodiscard]] CSSHelper *cssHelper() const;
0261     void setPrinting(bool enable);
0262 
0263     void selectAll();
0264     void copySelectionToClipboard();
0265 
0266     void setZoomFactor(qreal zoomFactor);
0267 
0268     [[nodiscard]] KToggleAction *toggleFixFontAction() const;
0269 
0270     [[nodiscard]] KToggleAction *toggleMimePartTreeAction() const;
0271 
0272     [[nodiscard]] QAction *selectAllAction() const;
0273     [[nodiscard]] QAction *copyURLAction() const;
0274     [[nodiscard]] QAction *copyAction() const;
0275     [[nodiscard]] QAction *urlOpenAction() const;
0276     [[nodiscard]] QAction *speakTextAction() const;
0277     [[nodiscard]] QAction *copyImageLocation() const;
0278     [[nodiscard]] QAction *viewSourceAction() const;
0279     [[nodiscard]] QAction *findInMessageAction() const;
0280     [[nodiscard]] QAction *saveAsAction() const;
0281     [[nodiscard]] QAction *saveMessageDisplayFormatAction() const;
0282     [[nodiscard]] QAction *resetMessageDisplayFormatAction() const;
0283     [[nodiscard]] QAction *shareTextAction() const;
0284 
0285     [[nodiscard]] QAction *developmentToolsAction() const;
0286     [[nodiscard]] KToggleAction *disableEmoticonAction() const;
0287     [[nodiscard]] KActionMenu *shareServiceUrlMenu() const;
0288     [[nodiscard]] HeaderStylePlugin *headerStylePlugin() const;
0289     [[nodiscard]] MessageViewer::DKIMViewerMenu *dkimViewerMenu();
0290 
0291     [[nodiscard]] MessageViewer::RemoteContentMenu *remoteContentMenu() const;
0292 
0293     void setPluginName(const QString &pluginName);
0294 
0295     void writeConfig(bool withSync = true);
0296 
0297     [[nodiscard]] QUrl urlClicked() const;
0298     [[nodiscard]] QUrl imageUrlClicked() const;
0299 
0300     void readConfig();
0301 
0302     /** A QAIM tree model of the message structure. */
0303     QAbstractItemModel *messageTreeModel() const;
0304 
0305     /**
0306      * Create an item fetch job that is suitable for using to fetch the message item that will
0307      * be displayed on this viewer.
0308      * It will set the correct fetch scope.
0309      * You still need to connect to the job's result signal.
0310      */
0311     Akonadi::ItemFetchJob *createFetchJob(const Akonadi::Item &item);
0312 
0313     /**
0314      * Adds a @p handler for actions that will be executed when the message
0315      * has been loaded into the view.
0316      */
0317     void addMessageLoadedHandler(AbstractMessageLoadedHandler *handler);
0318 
0319     /**
0320      * Removes the @p handler for actions that will be executed when the message
0321      * has been loaded into the view.
0322      */
0323     void removeMessageLoadedHandler(AbstractMessageLoadedHandler *handler);
0324 
0325     [[nodiscard]] QString selectedText() const;
0326 
0327     void saveMainFrameScreenshotInFile(const QString &filename);
0328     bool mimePartTreeIsEmpty() const;
0329 
0330     void showOpenAttachmentFolderWidget(const QList<QUrl> &urls);
0331     [[nodiscard]] QList<QAction *> viewerPluginActionList(MessageViewer::ViewerPluginInterface::SpecificFeatureTypes features);
0332     [[nodiscard]] QList<QAction *> interceptorUrlActions(const WebEngineViewer::WebHitTestResult &result) const;
0333 
0334     void runJavaScript(const QString &code);
0335     void setPrintElementBackground(bool printElementBackground);
0336 
0337     [[nodiscard]] bool printingMode() const;
0338 
0339     [[nodiscard]] bool showSignatureDetails() const;
0340     void setShowSignatureDetails(bool showDetails);
0341 
0342     [[nodiscard]] qreal webViewZoomFactor() const;
0343     void setWebViewZoomFactor(qreal factor);
0344 
0345     [[nodiscard]] bool showEncryptionDetails() const;
0346     void setShowEncryptionDetails(bool showDetails);
0347 
0348     void hasMultiMessages(bool messages);
0349     void updateShowMultiMessagesButton(bool enablePreviousButton, bool enableNextButton);
0350     [[nodiscard]] MessageViewer::DKIMWidgetInfo *dkimWidgetInfo();
0351 
0352     void exportToPdf(const QString &fileName);
0353 
0354     void showDevelopmentTools();
0355 
0356     void setIdentityManager(KIdentityManagementCore::IdentityManager *ident);
0357     void setFolderIdentity(uint folderIdentity);
0358     void showMdnInformations(const QPair<QString, bool> &mdnInfo);
0359     void mdnWarningAnimatedHide();
0360 Q_SIGNALS:
0361     void moveMessageToTrash();
0362     void pageIsScrolledToBottom(bool);
0363 
0364     /**
0365      * Emitted when a status bar message is shown. Note that the status bar message is also set to
0366      * KPIM::BroadcastStatus in addition.
0367      */
0368     void showStatusBarMessage(const QString &message);
0369 
0370     /** The user presses the right mouse button. 'url' may be 0. */
0371     void popupMenu(const Akonadi::Item &msg, const QUrl &url, const QUrl &imageUrl, const QPoint &mousePos);
0372     void displayPopupMenu(const Akonadi::Item &msg, const WebEngineViewer::WebHitTestResult &result, const QPoint &mousePos);
0373     /**
0374      * The message viewer handles some types of urls itself, most notably http(s)
0375      * and ftp(s). When it can't handle the url it will Q_EMIT this signal.
0376      */
0377     void urlClicked(const Akonadi::Item &, const QUrl &);
0378 
0379     void requestConfigSync();
0380 
0381     /// Emitted when the content should be shown in a separate window
0382     void showReader(KMime::Content *aMsgPart, bool aHTML, const QString &encoding);
0383 
0384     /// Emitted when the message should be shown in a separate window
0385     void showMessage(const KMime::Message::Ptr &message, const QString &encoding);
0386 
0387     void replyMessageTo(const KMime::Message::Ptr &message, bool replyToAll);
0388 
0389     void deleteMessage(const Akonadi::Item &);
0390 
0391     /// Emitted when the item, previously set with setMessageItem, has been removed.
0392     void itemRemoved();
0393 
0394     void makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode);
0395 
0396     void printingFinished();
0397     void zoomChanged(qreal zoomFactor);
0398     void showNextMessage();
0399     void showPreviousMessage();
0400     void sendResponse(MessageViewer::MDNWarningWidget::ResponseType type, KMime::MDN::SendingMode sendingMode);
0401 
0402 private:
0403     void initialize();
0404     void slotGeneralPaletteChanged();
0405 
0406 public Q_SLOTS:
0407 
0408     /**
0409      * HTML Widget scrollbar and layout handling.
0410      *
0411      * Scrolling always happens in the direction of the slot that is called. I.e.
0412      * the methods take the absolute value of
0413      */
0414     void slotScrollUp();
0415     void slotScrollDown();
0416     void slotScrollPrior();
0417     void slotScrollNext();
0418     void slotJumpDown();
0419     void slotFind();
0420     void slotSaveMessage();
0421     void slotAttachmentSaveAs();
0422     void slotAttachmentSaveAll();
0423     void slotShowMessageSource();
0424     void slotZoomIn();
0425     void slotZoomOut();
0426     void slotZoomReset();
0427     void slotChangeDisplayMail(Viewer::DisplayFormatMessage, bool);
0428 
0429 protected:
0430     /** Some necessary event handling. */
0431     void closeEvent(QCloseEvent *) override;
0432     void resizeEvent(QResizeEvent *) override;
0433     /** Watch for palette changes */
0434     [[nodiscard]] bool event(QEvent *e) override;
0435     void changeEvent(QEvent *event) override;
0436 
0437     ViewerPrivate *const d_ptr;
0438 };
0439 }