1 /* 2 SPDX-FileCopyrightText: 1997 Markus Wuebben <markus.wuebben@kde.org> 3 SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net 4 SPDX-FileCopyrightText: 2009 Andras Mantia <andras@kdab.net> 5 6 SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #pragma once 10 11 #include "config-messageviewer.h" 12 #include "messageviewer/viewerplugininterface.h" 13 #include "messageviewer_private_export.h" 14 #include "viewer.h" //not so nice, it is actually for the enums from MailViewer 15 #include "widgets/opensavedfilefolderwidget.h" 16 #include <PimCommon/ShareServiceUrlManager> 17 #include <WebEngineViewer/CheckPhishingUrlUtil> 18 19 #include <Akonadi/Item> 20 #include <Akonadi/Monitor> 21 #include <Akonadi/Session> 22 #include <KIO/Job> 23 #include <KMime/Message> 24 #include <KService> 25 #include <QPointer> 26 #include <QUrl> 27 #include <QVector> 28 29 #include <QObject> 30 #include <QTimer> 31 32 namespace KIO 33 { 34 class Job; 35 } 36 37 class QAction; 38 class KActionCollection; 39 class KSelectAction; 40 class KToggleAction; 41 class QMenu; 42 class KActionMenu; 43 44 class QPoint; 45 class QSplitter; 46 class QModelIndex; 47 class QPrinter; 48 49 namespace KIdentityManagement 50 { 51 class IdentityManager; 52 } 53 54 namespace KPIMTextEdit 55 { 56 class SlideContainer; 57 class TextToSpeechWidget; 58 } 59 60 namespace MimeTreeParser 61 { 62 class ObjectTreeParser; 63 class NodeHelper; 64 } 65 namespace MessageViewer 66 { 67 class DKIMWidgetInfo; 68 class DKIMViewerMenu; 69 } 70 namespace WebEngineViewer 71 { 72 class WebHitTestResult; 73 class FindBarWebEngineView; 74 class ZoomActionMenu; 75 class LocalDataBaseManager; 76 class TrackingWarningWidget; 77 class DeveloperToolDialog; 78 class SubmittedFormWarningWidget; 79 } 80 namespace MessageViewer 81 { 82 class AttachmentStrategy; 83 class HeaderStylePlugin; 84 class HtmlWriter; 85 class CSSHelper; 86 class MessageViewerRenderer; 87 class MailWebEngineView; 88 class WebEnginePartHtmlWriter; 89 class HtmlStatusBar; 90 class ScamDetectionWarningWidget; 91 class MimePartTreeView; 92 class HeaderStyleMenuManager; 93 class ViewerPluginToolManager; 94 class MailSourceWebEngineViewer; 95 class ShowNextMessageWidget; 96 class RemoteContentMenu; 97 /** 98 \brief Private class for the Viewer, the main widget in the messageviewer library. 99 100 This class creates all subwidgets, like the MailWebView, the HtmlStatusBar and the FindBarMailWebView. 101 102 Also, ViewerPrivate creates and exposes all actions. 103 104 \par Displaying a message 105 106 Before displaying a message, a message needs to be set. This can be done in two ways, with 107 setMessageItem() and with setMessage(). setMessageItem() is the preferred way, as the viewer can 108 then remember the Akonadi::Item belonging to the message. The Akonadi::Item is needed when modifying 109 the message, for example when editing or deleting an attachment. 110 Sometimes passing an Akonadi::Item to the viewer is not possible, for example when double-clicking 111 an attached message, in which case a new KMime::Message is constructed out of the attachment, and a 112 separate window is opened for it. In this case, the KMime::Message has no associated Akonadi::Item. 113 If there is an Akonadi::Item available, it will be monitored for changes and the viewer 114 automatically updated on external changes. 115 116 Once a message is set, update() is called. update() can also be called after the message has already 117 been displayed. As an example, this is the case when the user decides to decrypt the message. The 118 decryption can happen async, and once the decryption is finished, update() is called to display the 119 now decrypted content. See the documentation of MimeTreeParser::ObjectTreeParser on how exactly decryption is 120 handled. 121 update() is just a thin wrapper that calls updateReaderWin(). The only difference is that update() 122 has a timer that prevents too many slow calls to updateReaderWin() in a short time frame. 123 updateReaderWin() again is only a thin wrapper that resets some state and then calls 124 displayMessage(). 125 displayMessage() itself is again a thin wrapper, which starts the HtmlWriter and then calls 126 parseMsg(). 127 Finally, parseMsg() does the real work. It uses MimeTreeParser::ObjectTreeParser parseObjectTree() to let the 128 MimeTreeParser::ObjectTreeParser parse the message and generate the HTML code for it. 129 As mentioned before, it can happen that the MimeTreeParser::ObjectTreeParser needs to do some operation that happens 130 async, for example decrypting. In this case, the MimeTreeParser::ObjectTreeParser will create a BodyPartMemento, 131 which basically is a wrapper around the job that does the async operation. Once the async operation 132 is finished. the BodyPartMemento will trigger an update() of ViewerPrivate, so that 133 MimeTreeParser::ObjectTreeParser parseObjectTree() gets called again and the MimeTreeParser::ObjectTreeParser then can generate 134 HTML which has the decrypted content of the message. Again, see the documentation of MimeTreeParser::ObjectTreeParser for the details. 135 Additionally, parseMsg() does some evil hack for saving unencrypted messages should the config 136 option for that be set. 137 138 \par Displaying a MIME part of the message 139 140 The viewer can show only a part of the message, for example by clicking on a MIME part in the 141 message structure viewer or by double-clicking an attached message. In this case, setMessagePart() 142 is called. There are two of these functions. One even has special handling for images, special 143 handling for binary attachments and special handling of attached messages. In the last case, a new 144 KMime::Message is constructed and set as the main message with setMessage(). 145 146 \par Attachment Handling 147 148 Some of those actions are actions that operate on a single attachment. For those, there is usually 149 a slot, like slotAttachmentCopy(). These actions are triggered from the attachment context menu, 150 which is shown in showAttachmentPopup(). The actions are connected to slotHandleAttachment() when 151 they are activated. 152 The action to edit an attachment uses the EditorWatcher to detect when editing with an external 153 editor is finished. Upon finishing, slotAttachmentEditDone() is called, which then creates an 154 ItemModifyJob to store the changes of the attachment. A map of currently active EditorWatcher and 155 their KMime::Content is available in mEditorWatchers. 156 For most attachment actions, the attachment is first written to a temp file. The action is then 157 executed on this temp file. Writing the attachment to a temp file is done with 158 MimeTreeParser::NodeHelper::writeNodeToTempFile(). This method is called before opening or copying an attachment or 159 when rendering the attachment list. The MimeTreeParser::ObjectTreeParser also calls MimeTreeParser::NodeHelper::writeNodeToTempFile() 160 in some places. Once the temp file is written, MimeTreeParser::NodeHelper::tempFileUrlFromNode() can be used to get 161 the file name of the temp file for a specific MIME part. This is for example used by the handler for 162 'attachment:' URLs, AttachmentURLHandler. 163 164 Since URLs for attachments are in the "attachment:" scheme, dragging them as-is to outside applications 165 wouldn't work, since other applications don't understand this scheme. Therefore, the viewer has 166 special handling for dragging URLs: In eventFilter(), drags are detected, and the URL handler is 167 called to deal with the drag. The attachment URL handler then starts a drag with the file:// URL 168 of the temp file of the attachment, which it gets with MimeTreeParser::NodeHelper::tempFileUrlFromNode(). 169 170 TODO: How are attachment handled that are loaded on demand? How does prepareHandleAttachment() work? 171 TODO: This temp file handling is a big mess and could use a rewrite, especially in the face of load 172 on demand. There shouldn't be the need to write out tempfiles until really needed. 173 174 Some header styles display an attachment list in the header. The HTML code for the attachment list 175 cannot be generated by the HeaderStyle itself, since that does not know about all attachments. 176 Therefore, the attachment list needs to be created by ViewerPrivate. For this, the HeaderStyle 177 writes out a placeholder for the attachment list when it creates the HTML for the header. Once the 178 MimeTreeParser::ObjectTreeParser is finished with the message, injectAttachments() is called. injectAttachments() 179 searches for the placeholder and replaces that with the real HTML code for the attachments. 180 181 One of the attachment actions is to scroll to the attachment. That action is only available when 182 right-clicking the header. The action scrolls to the attachment in the body and draws a yellow frame 183 around the attachment. This is done in scrollToAttachment(). The attachment in the body and the div 184 which is used for the colored frame are both created by the MimeTreeParser::ObjectTreeParser . 185 186 \par Misc 187 188 ViewerPrivate holds the MimeTreeParser::NodeHelper, which is passed on to the MimeTreeParser::ObjectTreeParser when it needs it. 189 It also holds the HeaderStyle, HeaderStrategy, MimeTreeParser::AttachmentStrategy, CSSHelper, HtmlWriter and more, 190 some of them again passed to the MimeTreeParser::ObjectTreeParser when it needs it. 191 192 @author andras@kdab.net 193 */ 194 class MESSAGEVIEWER_TESTS_EXPORT ViewerPrivate : public QObject 195 { 196 Q_OBJECT 197 public: 198 ViewerPrivate(Viewer *aParent, QWidget *mainWindow, KActionCollection *actionCollection); 199 200 ~ViewerPrivate() override; 201 202 /** Returns message part from given URL or null if invalid. The URL's path is a KMime::ContentIndex path, or an index for the extra nodes, 203 followed by : and the ContentIndex path. */ 204 Q_REQUIRED_RESULT KMime::Content *nodeFromUrl(const QUrl &url) const; 205 206 /** Open the attachment pointed to the node. 207 * @param node the node 208 * @param url - if not empty, use this file to load the attachment content 209 */ 210 void openAttachment(KMime::Content *node, const QUrl &url); 211 212 /** Delete the attachment the @p node points to. Returns false if the user 213 cancelled the deletion, true in all other cases (including failure to delete 214 the attachment!) 215 * @param node the node 216 * @param showWarning whether some warning should be shown 217 */ 218 Q_REQUIRED_RESULT bool deleteAttachment(KMime::Content *node, bool showWarning = true); 219 220 void attachmentProperties(KMime::Content *node); 221 void attachmentCopy(const KMime::Content::List &contents); 222 223 void scrollToAnchor(const QString &anchor); 224 225 void showAttachmentPopup(KMime::Content *node, const QString &name, const QPoint &p); 226 227 /** 228 * Sets the current attachment ID and the current attachment temporary filename 229 * to the given values. 230 * Call this so that slotHandleAttachment() knows which attachment to handle. 231 */ 232 void prepareHandleAttachment(KMime::Content *node); 233 234 Q_REQUIRED_RESULT KService::Ptr getServiceOffer(KMime::Content *content); 235 Q_REQUIRED_RESULT KMime::Content::List selectedContents() const; 236 void attachmentOpenWith(KMime::Content *node, const KService::Ptr &offer = KService::Ptr()); 237 void attachmentOpen(KMime::Content *node); 238 239 /** Return the HtmlWriter connected to the MailWebView we use */ 240 HtmlWriter *htmlWriter() const; 241 242 HeaderStylePlugin *headerStylePlugin() const; 243 244 CSSHelper *cssHelper() const; 245 246 MimeTreeParser::NodeHelper *nodeHelper() const; 247 248 Viewer *viewer() const; 249 250 Q_REQUIRED_RESULT Akonadi::Item messageItem() const; 251 252 Q_REQUIRED_RESULT KMime::Message::Ptr message() const; 253 254 /** Returns whether the message should be decrypted. */ 255 Q_REQUIRED_RESULT bool decryptMessage() const; 256 257 /** Display a generic HTML splash page instead of a message. */ 258 void displaySplashPage(const QString &templateName, const QVariantHash &data, const QByteArray &domain = QByteArray()); 259 260 void displaySplashPage(const QString &message); 261 262 /** Enable the displaying of messages again after an splash (or other) page was displayed */ 263 void enableMessageDisplay(); 264 265 /** Feeds the HTML viewer with the contents of the given message. 266 HTML begin/end parts are written around the message. */ 267 void displayMessage(); 268 269 /** Parse the given content and generate HTML out of it for display */ 270 void parseContent(KMime::Content *content); 271 272 /** Creates a nice mail header depending on the current selected 273 header style. */ 274 Q_REQUIRED_RESULT QString writeMessageHeader(KMime::Message *aMsg, KMime::Content *vCardNode, bool topLevel); 275 276 /** show window containing information about a vCard. */ 277 void showVCard(KMime::Content *msgPart); 278 279 void saveMainFrameScreenshotInFile(const QString &filename); 280 281 void exportToPdf(const QString &fileName); 282 283 private: 284 /** HTML initialization. */ 285 void initHtmlWidget(); 286 void createOpenWithMenu(QMenu *topMenu, const QString &contentTypeStr, bool fromCurrentContent); 287 288 public: 289 void itemFetchResult(KJob *job); 290 291 /** Read settings from app's config file. */ 292 void readConfig(); 293 294 /** Write settings to app's config file. Calls sync() if withSync is true. */ 295 void writeConfig(bool withSync = true); 296 297 /** Get/set the message attachment strategy. */ 298 const AttachmentStrategy *attachmentStrategy() const; 299 void setAttachmentStrategy(const AttachmentStrategy *strategy); 300 301 /** Get selected override character encoding. 302 @return The encoding selected by the user or an empty string if auto-detection 303 is selected. */ 304 Q_REQUIRED_RESULT QString overrideEncoding() const; 305 306 /** Set the override character encoding. */ 307 void setOverrideEncoding(const QString &encoding); 308 309 /** Set printing mode */ 310 void setPrinting(bool enable); 311 Q_REQUIRED_RESULT bool printingMode() const; 312 313 /** Print message. */ 314 void printMessage(const Akonadi::Item &msg); 315 void printPreviewMessage(const Akonadi::Item &message); 316 317 void resetStateForNewMessage(); 318 319 void setMessageInternal(const KMime::Message::Ptr &message, MimeTreeParser::UpdateMode updateMode); 320 321 /** Set the Akonadi item that will be displayed. 322 * @param item - the Akonadi item to be displayed. If it doesn't hold a mail (KMime::Message::Ptr as payload data), 323 * an empty page is shown. 324 * @param updateMode - update the display immediately or not. See MailViewer::UpdateMode. 325 */ 326 void setMessageItem(const Akonadi::Item &item, MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed, bool forceHtmlLoadExtOverride = false); 327 328 /** Set the message that shall be shown. 329 * @param msg - the message to be shown. If 0, an empty page is displayed. 330 * @param updateMode - update the display immediately or not. See MailViewer::UpdateMode. 331 */ 332 void setMessage(const KMime::Message::Ptr &msg, MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed); 333 334 /** Instead of settings a message to be shown sets a message part 335 to be shown */ 336 void setMessagePart(KMime::Content *node); 337 338 /** Show or hide the Mime Tree Viewer if configuration 339 is set to smart mode. */ 340 void showHideMimeTree(); 341 342 /** View message part of type message/RFC822 in extra viewer window. */ 343 void attachmentViewMessage(const KMime::Message::Ptr &message); 344 345 void adjustLayout(); 346 void createWidgets(); 347 void createActions(); 348 349 void showContextMenu(KMime::Content *content, const QPoint &point); 350 351 KToggleAction *actionForAttachmentStrategy(const AttachmentStrategy *); 352 /** Read override codec from configuration */ 353 void readGlobalOverrideCodec(); 354 355 /** Get codec corresponding to the currently selected override character encoding. 356 @return The override codec or 0 if auto-detection is selected. */ 357 const QTextCodec *overrideCodec() const; 358 359 Q_REQUIRED_RESULT QString renderAttachments(KMime::Content *node, const QColor &bgColor) const; 360 361 KMime::Content *findContentByType(KMime::Content *content, const QByteArray &type); // TODO(Andras) move to MimeTreeParser::NodeHelper 362 363 /** Saves the relative position of the scroll view. Call this before calling update() 364 if you want to preserve the current view. */ 365 void saveRelativePosition(); 366 367 Q_REQUIRED_RESULT bool htmlMail() const; 368 Q_REQUIRED_RESULT bool htmlLoadExternal() const; 369 370 Q_REQUIRED_RESULT bool htmlMailGlobalSetting() const; 371 372 /** Get the html override setting */ 373 Q_REQUIRED_RESULT Viewer::DisplayFormatMessage displayFormatMessageOverwrite() const; 374 375 /** Override default html mail setting */ 376 void setDisplayFormatMessageOverwrite(Viewer::DisplayFormatMessage format); 377 378 /** Get the load external references override setting */ 379 Q_REQUIRED_RESULT bool htmlLoadExtOverride() const; 380 381 /** Default behavior for loading external references. 382 * Use this for specifying the external reference loading behavior as 383 * specified in the user settings. 384 * @see setHtmlLoadExtOverride 385 */ 386 void setHtmlLoadExtDefault(bool loadExtDefault); 387 388 /** Override default load external references setting 389 * @warning This must only be called when the user has explicitly 390 * been asked to retrieve external references! 391 * @see setHtmlLoadExtDefault 392 */ 393 void setHtmlLoadExtOverride(bool loadExtOverride); 394 395 /** Enforce message decryption. */ 396 void setDecryptMessageOverwrite(bool overwrite = true); 397 398 /** Show signature details. */ 399 Q_REQUIRED_RESULT bool showSignatureDetails() const; 400 401 /** Show signature details. */ 402 void setShowSignatureDetails(bool showDetails = true); 403 404 /* show or hide encryption details */ 405 void setShowEncryptionDetails(bool showEncDetails); 406 407 Q_REQUIRED_RESULT bool showEncryptionDetails() const; 408 409 void scrollToAttachment(KMime::Content *node); 410 void setUseFixedFont(bool useFixedFont); 411 412 void attachmentView(KMime::Content *atmNode); 413 414 void setZoomFactor(qreal zoomFactor); 415 416 void goOnline(); 417 void goResourceOnline(); 418 419 void showSavedFileFolderWidget(const QList<QUrl> &urls, MessageViewer::OpenSavedFileFolderWidget::FileType fileType); 420 421 Q_REQUIRED_RESULT bool mimePartTreeIsEmpty() const; 422 423 void setPluginName(const QString &pluginName); 424 425 Q_REQUIRED_RESULT QList<QAction *> viewerPluginActionList(MessageViewer::ViewerPluginInterface::SpecificFeatureTypes features); 426 Q_REQUIRED_RESULT QList<QAction *> interceptorUrlActions(const WebEngineViewer::WebHitTestResult &result) const; 427 428 void setPrintElementBackground(bool printElementBackground); 429 Q_REQUIRED_RESULT bool showEmoticons() const; 430 void checkPhishingUrl(); 431 void executeRunner(const QUrl &url); 432 Q_REQUIRED_RESULT QUrl imageUrl() const; 433 Q_REQUIRED_RESULT qreal webViewZoomFactor() const; 434 void setWebViewZoomFactor(qreal factor); 435 void recreateCssHelper(); 436 void hasMultiMessages(bool messages); 437 void updateShowMultiMessagesButton(bool enablePreviousButton, bool enableNextButton); 438 MessageViewer::DKIMViewerMenu *dkimViewerMenu(); 439 440 Q_REQUIRED_RESULT bool isAutocryptEnabled(KMime::Message *message); 441 void setIdentityManager(KIdentityManagement::IdentityManager *ident); 442 void setFolderIdentity(uint folderIdentity); 443 444 RemoteContentMenu *remoteContentMenu() const; 445 446 private Q_SLOTS: 447 void slotActivatePlugin(MessageViewer::ViewerPluginInterface *interface); 448 void slotModifyItemDone(KJob *job); 449 void slotMessageMayBeAScam(); 450 void slotMessageIsNotAScam(); 451 void slotAddToWhiteList(); 452 void slotItemChanged(const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers); 453 void slotItemMoved(const Akonadi::Item &, const Akonadi::Collection &, const Akonadi::Collection &); 454 455 void itemModifiedResult(KJob *job); 456 457 void slotClear(); 458 459 void slotMessageRendered(); 460 461 void slotOpenWithAction(QAction *act); 462 463 void slotOpenWithActionCurrentContent(QAction *act); 464 465 void slotOpenWithDialog(); 466 467 void slotOpenWithDialogCurrentContent(); 468 469 void saveSplitterSizes() const; 470 471 void slotRefreshMessage(const Akonadi::Item &item); 472 void slotServiceUrlSelected(PimCommon::ShareServiceUrlManager::ServiceType serviceType); 473 void slotStyleChanged(MessageViewer::HeaderStylePlugin *plugin); 474 void slotStyleUpdated(); 475 void slotWheelZoomChanged(int numSteps); 476 void slotOpenInBrowser(); 477 void slotExportHtmlPageFailed(); 478 void slotExportHtmlPageSuccess(const QString &filename); 479 void slotHandlePagePrinted(bool result); 480 void slotToggleEmoticons(); 481 482 public Q_SLOTS: 483 /** An URL has been activate with a click. */ 484 void slotUrlOpen(const QUrl &url = QUrl()); 485 void slotOpenUrl(); 486 487 /** The mouse has moved on or off an URL. */ 488 void slotUrlOn(const QString &link); 489 490 /** The user presses the right mouse button on an URL. */ 491 void slotUrlPopup(const WebEngineViewer::WebHitTestResult &result); 492 493 /** The user selected "Find" from the menu. */ 494 void slotFind(); 495 496 /** The user toggled the "Fixed Font" flag from the view menu. */ 497 void slotToggleFixedFont(); 498 void slotToggleMimePartTree(); 499 500 /** Show the message source */ 501 void slotShowMessageSource(); 502 503 /** Refresh the reader window */ 504 void updateReaderWin(); 505 506 void slotMimePartSelected(const QModelIndex &index); 507 508 void slotIconicAttachments(); 509 void slotSmartAttachments(); 510 void slotInlineAttachments(); 511 void slotHideAttachments(); 512 void slotHeaderOnlyAttachments(); 513 514 /** Some attachment operations. */ 515 void slotDelayedResize(); 516 517 /** Print message. Called on as a response of finished() signal of mPartHtmlWriter 518 after rendering is finished. 519 In the very end it deletes the KMReaderWin window that was created 520 for the purpose of rendering. */ 521 void slotPrintMessage(); 522 void slotPrintPreview(); 523 524 void slotSetEncoding(); 525 void executeCustomScriptsAfterLoading(); 526 void slotSettingsChanged(); 527 void slotMimeTreeContextMenuRequested(const QPoint &pos); 528 void slotAttachmentOpenWith(); 529 void slotAttachmentOpen(); 530 void slotAttachmentSaveAs(); 531 void slotAttachmentSaveAll(); 532 void slotAttachmentView(); 533 void slotAttachmentProperties(); 534 void slotAttachmentCopy(); 535 void slotAttachmentDelete(); 536 void slotLevelQuote(int l); 537 538 /** Toggle display mode between HTML and plain text. */ 539 void slotToggleHtmlMode(); 540 void slotLoadExternalReference(); 541 542 /** 543 * Does an action for the current attachment. 544 * The action is defined by the KMHandleAttachmentCommand::AttachmentAction 545 * enum. 546 * prepareHandleAttachment() needs to be called before calling this to set the 547 * correct attachment ID. 548 */ 549 void slotHandleAttachment(int action); 550 /** Copy the selected text to the clipboard */ 551 void slotCopySelectedText(); 552 553 void viewerSelectionChanged(); 554 555 /** Select message body. */ 556 void selectAll(); 557 558 /** Copy URL in mUrlCurrent to clipboard. Removes "mailto:" at 559 beginning of URL before copying. */ 560 void slotUrlCopy(); 561 void slotSaveMessage(); 562 /** Re-parse the current message. */ 563 void update(MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed); 564 565 void slotSpeakText(); 566 void slotCopyImageLocation(); 567 void slotSaveMessageDisplayFormat(); 568 void slotResetMessageDisplayFormat(); 569 570 void slotGeneralFontChanged(); 571 void slotShowDevelopmentTools(); 572 573 Q_SIGNALS: 574 void showStatusBarMessage(const QString &message); 575 void popupMenu(const Akonadi::Item &msg, const QUrl &url, const QUrl &imageUrl, const QPoint &mousePos); 576 void displayPopupMenu(const Akonadi::Item &msg, const WebEngineViewer::WebHitTestResult &result, const QPoint &mousePos); 577 578 void urlClicked(const Akonadi::Item &msg, const QUrl &url); 579 void requestConfigSync(); 580 void showReader(KMime::Content *aMsgPart, bool aHTML, const QString &encoding); 581 void showMessage(const KMime::Message::Ptr &message, const QString &encoding); 582 void replyMessageTo(const KMime::Message::Ptr &message, bool replyToAll); 583 void itemRemoved(); 584 void makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode); 585 586 void changeDisplayMail(Viewer::DisplayFormatMessage, bool); 587 void moveMessageToTrash(); 588 void pageIsScrolledToBottom(bool); 589 void printingFinished(); 590 void zoomChanged(qreal zoomFactor); 591 void showNextMessage(); 592 void showPreviousMessage(); 593 594 private: 595 Q_REQUIRED_RESULT QString attachmentHtml(); 596 void initializeColorFromScheme(); 597 598 void replyMessageToAuthor(KMime::Content *atmNode); 599 void replyMessageToAll(KMime::Content *atmNode); 600 void replyMessage(KMime::Content *atmNode, bool replyToAll); 601 Q_REQUIRED_RESULT bool urlIsAMalwareButContinue(); 602 Q_REQUIRED_RESULT bool messageIsInSpecialFolder() const; 603 604 void slotCheckedUrlFinished(const QUrl &url, WebEngineViewer::CheckPhishingUrlUtil::UrlStatus status); 605 606 void slotDelayPrintPreview(); 607 void applyZoomValue(qreal factor, bool saveConfig = true); 608 void slotZoomChanged(qreal zoom); 609 void assignMessageItem(const Akonadi::Item &item); 610 void slotPdfPrintingFinished(const QString &filePath, bool success); 611 MimeTreeParser::NodeHelper *mNodeHelper = nullptr; 612 bool mHtmlMailGlobalSetting = false; 613 bool mHtmlLoadExternalDefaultSetting = false; 614 bool mHtmlLoadExtOverride = false; 615 void slotUrlBlocked(const QUrl &url); 616 617 public: 618 KMime::Message::Ptr mMessage; // the current message, if it was set manually 619 Akonadi::Item mMessageItem; // the message item from Akonadi 620 // widgets: 621 QSplitter *mSplitter = nullptr; 622 QWidget *mBox = nullptr; 623 HtmlStatusBar *mColorBar = nullptr; 624 MimePartTreeView *mMimePartTree = nullptr; 625 MailWebEngineView *mViewer = nullptr; 626 WebEngineViewer::FindBarWebEngineView *mFindBar = nullptr; 627 628 const AttachmentStrategy *mAttachmentStrategy = nullptr; 629 QTimer mUpdateReaderWinTimer; 630 QTimer mResizeTimer; 631 QString mOverrideEncoding; 632 QString mOldGlobalOverrideEncoding; // used to detect changes of the global override character encoding 633 634 /// This is true if the viewer currently is displaying a message. Can be false, for example when 635 /// the splash/busy page is displayed. 636 bool mMsgDisplay = true; 637 638 bool mUseFixedFont = false; 639 bool mPrinting = false; 640 QWidget *mMainWindow = nullptr; 641 KActionCollection *const mActionCollection; 642 QAction *mCopyAction = nullptr; 643 QAction *mCopyURLAction = nullptr; 644 QAction *mUrlOpenAction = nullptr; 645 QAction *mSelectAllAction = nullptr; 646 QAction *mScrollUpAction = nullptr; 647 QAction *mScrollDownAction = nullptr; 648 QAction *mScrollUpMoreAction = nullptr; 649 QAction *mScrollDownMoreAction = nullptr; 650 QAction *mViewSourceAction = nullptr; 651 QAction *mSaveMessageAction = nullptr; 652 QAction *mFindInMessageAction = nullptr; 653 QAction *mSaveMessageDisplayFormat = nullptr; 654 QAction *mResetMessageDisplayFormat = nullptr; 655 KToggleAction *mDisableEmoticonAction = nullptr; 656 KToggleAction *mHeaderOnlyAttachmentsAction = nullptr; 657 KSelectAction *mSelectEncodingAction = nullptr; 658 KToggleAction *mToggleFixFontAction = nullptr; 659 KToggleAction *mToggleDisplayModeAction = nullptr; 660 KToggleAction *mToggleMimePartTreeAction = nullptr; 661 QAction *mDevelopmentToolsAction = nullptr; 662 QAction *mSpeakTextAction = nullptr; 663 QAction *mCopyImageLocation = nullptr; 664 QAction *mShareTextAction = nullptr; 665 QUrl mClickedUrl; 666 QUrl mImageUrl; 667 HtmlWriter *mHtmlWriter = nullptr; 668 /** Used only to be able to connect and disconnect finished() signal 669 in printMsg() and slotPrintMsg() since mHtmlWriter points only to abstract non-QObject class. */ 670 QPointer<WebEnginePartHtmlWriter> mPartHtmlWriter; 671 QPointer<WebEngineViewer::DeveloperToolDialog> mDeveloperToolDialog; 672 673 int mLevelQuote; 674 bool mDecrytMessageOverwrite = false; 675 bool mShowSignatureDetails = false; 676 bool mShowEncryptionDetails = false; 677 bool mForceEmoticons = true; 678 int mRecursionCountForDisplayMessage = 0; 679 uint mFolderIdentity = 0; 680 KMime::Content *mCurrentContent = nullptr; 681 KMime::Content *mMessagePartNode = nullptr; 682 QString mMessagePath; 683 684 QColor mForegroundError; 685 QColor mBackgroundError; 686 QColor mBackgroundAttachment; 687 688 Viewer *const q; 689 Akonadi::Session *mSession = nullptr; 690 Akonadi::Monitor mMonitor; 691 QSet<AbstractMessageLoadedHandler *> mMessageLoadedHandlers; 692 Akonadi::Item::Id mPreviouslyViewedItemId = -1; 693 694 MessageViewer::ScamDetectionWarningWidget *mScamDetectionWarning = nullptr; 695 MessageViewer::OpenSavedFileFolderWidget *mOpenSavedFileFolderWidget = nullptr; 696 WebEngineViewer::SubmittedFormWarningWidget *mSubmittedFormWarning = nullptr; 697 WebEngineViewer::TrackingWarningWidget *mMailTrackingWarning = nullptr; 698 KPIMTextEdit::TextToSpeechWidget *mTextToSpeechWidget = nullptr; 699 Viewer::DisplayFormatMessage mDisplayFormatMessageOverwrite; 700 KPIMTextEdit::SlideContainer *mSliderContainer = nullptr; 701 PimCommon::ShareServiceUrlManager *mShareServiceManager = nullptr; 702 KActionMenu *mShareServiceUrlMenu = nullptr; 703 MessageViewer::HeaderStylePlugin *mHeaderStylePlugin = nullptr; 704 MessageViewer::HeaderStyleMenuManager *mHeaderStyleMenuManager = nullptr; 705 MessageViewer::ViewerPluginToolManager *mViewerPluginToolManager = nullptr; 706 WebEngineViewer::ZoomActionMenu *mZoomActionMenu = nullptr; 707 QPrinter *mCurrentPrinter = nullptr; 708 QVector<QPointer<MessageViewer::MailSourceWebEngineViewer>> mListMailSourceViewer; 709 WebEngineViewer::LocalDataBaseManager *mPhishingDatabase = nullptr; 710 MessageViewer::ShowNextMessageWidget *mShowNextMessageWidget = nullptr; 711 MessageViewer::DKIMWidgetInfo *mDkimWidgetInfo = nullptr; 712 MessageViewer::DKIMViewerMenu *mDkimViewerMenu = nullptr; 713 MessageViewer::MessageViewerRenderer *mMessageViewerRenderer = nullptr; 714 KIdentityManagement::IdentityManager *mIdentityManager = nullptr; 715 RemoteContentMenu *mRemoteContentMenu = nullptr; 716 }; 717 } 718 719