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 }