viewer_p.h 28.4 KB
Newer Older
1
/*
2
3
4
  SPDX-FileCopyrightText: 1997 Markus Wuebben <markus.wuebben@kde.org>
  SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
  SPDX-FileCopyrightText: 2009 Andras Mantia <andras@kdab.net>
5

6
  SPDX-License-Identifier: GPL-2.0-or-later
7
8
9
10
11
*/

#ifndef MAILVIEWER_P_H
#define MAILVIEWER_P_H

12
#include "messageviewer_private_export.h"
Laurent Montel's avatar
Laurent Montel committed
13
#include "config-messageviewer.h"
14
#include "viewer.h" //not so nice, it is actually for the enums from MailViewer
15
#include <PimCommon/ShareServiceUrlManager>
16
#include "messageviewer/viewerplugininterface.h"
17
#include "widgets/opensavedfilefolderwidget.h"
18
#include <WebEngineViewer/CheckPhishingUrlUtil>
19
20
21

#include <AkonadiCore/item.h>
#include <AkonadiCore/monitor.h>
22
#include <AkonadiCore/session.h>
23
#include <kio/job.h>
24
#include <KMime/Message>
25
#include <KService>
26
#include <QPointer>
27
#include <QUrl>
28
#include <QVector>
29
30
31
32

#include <QObject>
#include <QTimer>

Laurent Montel's avatar
Laurent Montel committed
33
namespace KIO {
34
35
36
37
38
39
40
41
42
43
44
45
46
class Job;
}

class QAction;
class KActionCollection;
class KSelectAction;
class KToggleAction;
class QMenu;
class KActionMenu;

class QPoint;
class QSplitter;
class QModelIndex;
47
class QPrinter;
48

Laurent Montel's avatar
Laurent Montel committed
49
namespace KPIMTextEdit {
50
51
52
53
class SlideContainer;
class TextToSpeechWidget;
}

Laurent Montel's avatar
Laurent Montel committed
54
namespace MimeTreeParser {
55
class ObjectTreeParser;
Laurent Montel's avatar
Laurent Montel committed
56
class NodeHelper;
57
}
58
59
namespace MessageViewer {
class DKIMWidgetInfo;
Laurent Montel's avatar
Laurent Montel committed
60
class DKIMViewerMenu;
61
}
Laurent Montel's avatar
Laurent Montel committed
62
namespace WebEngineViewer {
Laurent Montel's avatar
Laurent Montel committed
63
class WebHitTestResult;
Laurent Montel's avatar
Laurent Montel committed
64
class FindBarWebEngineView;
Laurent Montel's avatar
Laurent Montel committed
65
class ZoomActionMenu;
66
class LocalDataBaseManager;
Laurent Montel's avatar
Laurent Montel committed
67
}
Laurent Montel's avatar
Laurent Montel committed
68
namespace MessageViewer {
69
class AttachmentStrategy;
70
class HeaderStylePlugin;
71
class HtmlWriter;
72
class CSSHelper;
73
class MessageViewerRenderer;
74
75
class MailWebEngineView;
class WebEnginePartHtmlWriter;
76
77
78
79
80
class HtmlStatusBar;
class ScamDetectionWarningWidget;
class MimePartTreeView;
class HeaderStyleMenuManager;
class ViewerPluginToolManager;
81
class SubmittedFormWarningWidget;
82
class MailSourceWebEngineViewer;
Laurent Montel's avatar
Laurent Montel committed
83
class MailTrackingWarningWidget;
84
class ShowNextMessageWidget;
Laurent Montel's avatar
Laurent Montel committed
85
class DeveloperToolDialog;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
\brief Private class for the Viewer, the main widget in the messageviewer library.

This class creates all subwidgets, like the MailWebView, the HtmlStatusBar and the FindBarMailWebView.

Also, ViewerPrivate creates and exposes all actions.

\par Displaying a message

Before displaying a message, a message needs to be set. This can be done in two ways, with
setMessageItem() and with setMessage(). setMessageItem() is the preferred way, as the viewer can
then remember the Akonadi::Item belonging to the message. The Akonadi::Item is needed when modifying
the message, for example when editing or deleting an attachment.
Sometimes passing an Akonadi::Item to the viewer is not possible, for example when double-clicking
an attached message, in which case a new KMime::Message is constructed out of the attachment, and a
separate window is opened for it. In this case, the KMime::Message has no associated Akonadi::Item.
If there is an Akonadi::Item available, it will be monitored for changes and the viewer
automatically updated on external changes.

Once a message is set, update() is called. update() can also be called after the message has already
been displayed. As an example, this is the case when the user decides to decrypt the message. The
decryption can happen async, and once the decryption is finished, update() is called to display the
108
now decrypted content. See the documentation of MimeTreeParser::ObjectTreeParser on how exactly decryption is
109
110
111
112
113
handled.
update() is just a thin wrapper that calls updateReaderWin(). The only difference is that update()
has a timer that prevents too many slow calls to updateReaderWin() in a short time frame.
updateReaderWin() again is only a thin wrapper that resets some state and then calls
displayMessage().
114
displayMessage() itself is again a thin wrapper, which starts the HtmlWriter and then calls
115
parseMsg().
Yuri Chornoivan's avatar
Yuri Chornoivan committed
116
Finally, parseMsg() does the real work. It uses MimeTreeParser::ObjectTreeParser parseObjectTree() to let the
117
118
119
MimeTreeParser::ObjectTreeParser parse the message and generate the HTML code for it.
As mentioned before, it can happen that the MimeTreeParser::ObjectTreeParser needs to do some operation that happens
async, for example decrypting. In this case, the MimeTreeParser::ObjectTreeParser will create a BodyPartMemento,
120
121
which basically is a wrapper around the job that does the async operation. Once the async operation
is finished. the BodyPartMemento will trigger an update() of ViewerPrivate, so that
Yuri Chornoivan's avatar
Yuri Chornoivan committed
122
MimeTreeParser::ObjectTreeParser parseObjectTree() gets called again and the MimeTreeParser::ObjectTreeParser then can generate
123
HTML which has the decrypted content of the message. Again, see the documentation of MimeTreeParser::ObjectTreeParser for the details.
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
Additionally, parseMsg() does some evil hack for saving unencrypted messages should the config
option for that be set.

\par Displaying a MIME part of the message

The viewer can show only a part of the message, for example by clicking on a MIME part in the
message structure viewer or by double-clicking an attached message. In this case, setMessagePart()
is called. There are two of these functions. One even has special handling for images, special
handling for binary attachments and special handling of attached messages. In the last case, a new
KMime::Message is constructed and set as the main message with setMessage().

\par Attachment Handling

Some of those actions are actions that operate on a single attachment. For those, there is usually
a slot, like slotAttachmentCopy(). These actions are triggered from the attachment context menu,
which is shown in showAttachmentPopup(). The actions are connected to slotHandleAttachment() when
they are activated.
The action to edit an attachment uses the EditorWatcher to detect when editing with an external
editor is finished. Upon finishing, slotAttachmentEditDone() is called, which then creates an
ItemModifyJob to store the changes of the attachment. A map of currently active EditorWatcher and
their KMime::Content is available in mEditorWatchers.
For most attachment actions, the attachment is first written to a temp file. The action is then
executed on this temp file. Writing the attachment to a temp file is done with
147
148
149
MimeTreeParser::NodeHelper::writeNodeToTempFile(). This method is called before opening or copying an attachment or
when rendering the attachment list. The MimeTreeParser::ObjectTreeParser also calls MimeTreeParser::NodeHelper::writeNodeToTempFile()
in some places. Once the temp file is written, MimeTreeParser::NodeHelper::tempFileUrlFromNode() can be used to get
150
151
152
153
154
155
156
the file name of the temp file for a specific MIME part. This is for example used by the handler for
'attachment:' URLs, AttachmentURLHandler.

Since URLs for attachments are in the "attachment:" scheme, dragging them as-is to outside applications
wouldn't work, since other applications don't understand this scheme. Therefore, the viewer has
special handling for dragging URLs: In eventFilter(), drags are detected, and the URL handler is
called to deal with the drag. The attachment URL handler then starts a drag with the file:// URL
157
of the temp file of the attachment, which it gets with MimeTreeParser::NodeHelper::tempFileUrlFromNode().
158
159
160
161
162
163
164
165
166

TODO: How are attachment handled that are loaded on demand? How does prepareHandleAttachment() work?
TODO: This temp file handling is a big mess and could use a rewrite, especially in the face of load
      on demand. There shouldn't be the need to write out tempfiles until really needed.

Some header styles display an attachment list in the header. The HTML code for the attachment list
cannot be generated by the HeaderStyle itself, since that does not know about all attachments.
Therefore, the attachment list needs to be created by ViewerPrivate. For this, the HeaderStyle
writes out a placeholder for the attachment list when it creates the HTML for the header. Once the
167
MimeTreeParser::ObjectTreeParser is finished with the message, injectAttachments() is called. injectAttachments()
168
169
170
171
172
searches for the placeholder and replaces that with the real HTML code for the attachments.

One of the attachment actions is to scoll to the attachment. That action is only available when
right-clicking the header. The action scrolls to the attachment in the body and draws a yellow frame
around the attachment. This is done in scrollToAttachment(). The attachment in the body and the div
173
which is used for the colored frame are both created by the MimeTreeParser::ObjectTreeParser .
174
175
176

\par Misc

177
ViewerPrivate holds the MimeTreeParser::NodeHelper, which is passed on to the MimeTreeParser::ObjectTreeParser when it needs it.
178
It also holds the HeaderStyle, HeaderStrategy, MimeTreeParser::AttachmentStrategy, CSSHelper, HtmlWriter and more,
179
some of them again passed to the MimeTreeParser::ObjectTreeParser when it needs it.
180
181
182

@author andras@kdab.net
 */
183
class MESSAGEVIEWER_TESTS_EXPORT ViewerPrivate : public QObject
184
185
186
187
188
189
{
    Q_OBJECT
public:

    ViewerPrivate(Viewer *aParent, QWidget *mainWindow, KActionCollection *actionCollection);

Laurent Montel's avatar
Laurent Montel committed
190
    ~ViewerPrivate() override;
191
192
193

    /** 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,
    followed by : and the ContentIndex path. */
Laurent Montel's avatar
Laurent Montel committed
194
    Q_REQUIRED_RESULT KMime::Content *nodeFromUrl(const QUrl &url) const;
195
196

    /** Open the attachment pointed to the node.
Yuri Chornoivan's avatar
Yuri Chornoivan committed
197
    * @param node the node
198
    * @param url - if not empty, use this file to load the attachment content
199
    */
200
    void openAttachment(KMime::Content *node, const QUrl &url);
201

Yuri Chornoivan's avatar
Yuri Chornoivan committed
202
    /** Delete the attachment the @p node points to. Returns false if the user
203
    cancelled the deletion, true in all other cases (including failure to delete
Yuri Chornoivan's avatar
Yuri Chornoivan committed
204
205
206
207
    the attachment!)
    * @param node the node
    * @param showWarning whether some warning should be shown
    */
Laurent Montel's avatar
Laurent Montel committed
208
    Q_REQUIRED_RESULT bool deleteAttachment(KMime::Content *node, bool showWarning = true);
209
210
211
212

    void attachmentProperties(KMime::Content *node);
    void attachmentCopy(const KMime::Content::List &contents);

Laurent Montel's avatar
Laurent Montel committed
213
    void scrollToAnchor(const QString &anchor);
214
215
216
217
218
219
220
221

    void showAttachmentPopup(KMime::Content *node, const QString &name, const QPoint &p);

    /**
    * Sets the current attachment ID and the current attachment temporary filename
    * to the given values.
    * Call this so that slotHandleAttachment() knows which attachment to handle.
    */
Laurent Montel's avatar
Laurent Montel committed
222
    void prepareHandleAttachment(KMime::Content *node);
223

Laurent Montel's avatar
Laurent Montel committed
224
225
    Q_REQUIRED_RESULT KService::Ptr getServiceOffer(KMime::Content *content);
    Q_REQUIRED_RESULT KMime::Content::List selectedContents() const;
226
227
228
    void attachmentOpenWith(KMime::Content *node, const KService::Ptr &offer = KService::Ptr());
    void attachmentOpen(KMime::Content *node);

229
230
    /** Return the HtmlWriter connected to the MailWebView we use */
    HtmlWriter *htmlWriter() const;
231
232
233
234
235

    HeaderStylePlugin *headerStylePlugin() const;

    CSSHelper *cssHelper() const;

236
    MimeTreeParser::NodeHelper *nodeHelper() const;
237
238
239

    Viewer *viewer() const;

Laurent Montel's avatar
Laurent Montel committed
240
    Q_REQUIRED_RESULT Akonadi::Item messageItem() const;
241

Laurent Montel's avatar
Laurent Montel committed
242
    Q_REQUIRED_RESULT KMime::Message::Ptr message() const;
243

Yuri Chornoivan's avatar
Yuri Chornoivan committed
244
    /** Returns whether the message should be decrypted. */
Laurent Montel's avatar
Laurent Montel committed
245
    Q_REQUIRED_RESULT bool decryptMessage() const;
246
247

    /** Display a generic HTML splash page instead of a message. */
Laurent Montel's avatar
Laurent Montel committed
248
    void displaySplashPage(const QString &templateName, const QVariantHash &data, const QByteArray &domain = QByteArray());
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

    void displaySplashPage(const QString &message);

    /** Enable the displaying of messages again after an splash (or other) page was displayed */
    void enableMessageDisplay();

    /** Feeds the HTML viewer with the contents of the given message.
    HTML begin/end parts are written around the message. */
    void displayMessage();

    /** Parse the given content and generate HTML out of it for display */
    void parseContent(KMime::Content *content);

    /** Creates a nice mail header depending on the current selected
    header style. */
Laurent Montel's avatar
Minor    
Laurent Montel committed
264
    Q_REQUIRED_RESULT QString writeMessageHeader(KMime::Message *aMsg, KMime::Content *vCardNode, bool topLevel);
265
266
267
268
269
270

    /** show window containing information about a vCard. */
    void showVCard(KMime::Content *msgPart);

    void saveMainFrameScreenshotInFile(const QString &filename);

Laurent Montel's avatar
Laurent Montel committed
271
272
    void exportToPdf(const QString &fileName);

273
274
275
276
277
private:
    /** HTML initialization. */
    void initHtmlWidget();
    void createOpenWithMenu(QMenu *topMenu, const QString &contentTypeStr, bool fromCurrentContent);
public:
Laurent Montel's avatar
Laurent Montel committed
278
279
280

    void itemFetchResult(KJob *job);

281
282
283
284
285
286
287
    /** Read settings from app's config file. */
    void readConfig();

    /** Write settings to app's config file. Calls sync() if withSync is true. */
    void writeConfig(bool withSync = true);

    /** Get/set the message attachment strategy. */
288
289
    const AttachmentStrategy *attachmentStrategy() const;
    void setAttachmentStrategy(const AttachmentStrategy *strategy);
290
291
292
293

    /** Get selected override character encoding.
      @return The encoding selected by the user or an empty string if auto-detection
      is selected. */
Laurent Montel's avatar
Laurent Montel committed
294
    Q_REQUIRED_RESULT QString overrideEncoding() const;
295
296
297
298
299

    /** Set the override character encoding. */
    void setOverrideEncoding(const QString &encoding);

    /** Set printing mode */
300
    void setPrinting(bool enable);
Laurent Montel's avatar
Laurent Montel committed
301
    Q_REQUIRED_RESULT bool printingMode() const;
302
303
304
305
306
307
308

    /** Print message. */
    void printMessage(const Akonadi::Item &msg);
    void printPreviewMessage(const Akonadi::Item &message);

    void resetStateForNewMessage();

Laurent Montel's avatar
Laurent Montel committed
309
    void setMessageInternal(const KMime::Message::Ptr &message, MimeTreeParser::UpdateMode updateMode);
310
311
312
313
314
315

    /** Set the Akonadi item that will be displayed.
    *  @param item - the Akonadi item to be displayed. If it doesn't hold a mail (KMime::Message::Ptr as payload data),
    *                an empty page is shown.
    *  @param updateMode - update the display immediately or not. See MailViewer::UpdateMode.
    */
Laurent Montel's avatar
Laurent Montel committed
316
    void setMessageItem(const Akonadi::Item &item, MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
317
318
319
320
321

    /** Set the message that shall be shown.
    * @param msg - the message to be shown. If 0, an empty page is displayed.
    * @param updateMode - update the display immediately or not. See MailViewer::UpdateMode.
    */
Laurent Montel's avatar
Laurent Montel committed
322
    void setMessage(const KMime::Message::Ptr &msg, MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
323
324
325
326
327
328
329
330
331
332

    /** Instead of settings a message to be shown sets a message part
      to be shown */
    void setMessagePart(KMime::Content *node);

    /** Show or hide the Mime Tree Viewer if configuration
      is set to smart mode.  */
    void showHideMimeTree();

    /** View message part of type message/RFC822 in extra viewer window. */
Laurent Montel's avatar
Laurent Montel committed
333
    void attachmentViewMessage(const KMime::Message::Ptr &message);
334
335
336
337
338

    void adjustLayout();
    void createWidgets();
    void createActions();

Laurent Montel's avatar
Laurent Montel committed
339
    void showContextMenu(KMime::Content *content, const QPoint &point);
340

341
    KToggleAction *actionForAttachmentStrategy(const AttachmentStrategy *);
342
343
344
345
346
347
348
    /** Read override codec from configuration */
    void readGlobalOverrideCodec();

    /** Get codec corresponding to the currently selected override character encoding.
      @return The override codec or 0 if auto-detection is selected. */
    const QTextCodec *overrideCodec() const;

Laurent Montel's avatar
Laurent Montel committed
349
    Q_REQUIRED_RESULT QString renderAttachments(KMime::Content *node, const QColor &bgColor) const;
350

351
    KMime::Content *findContentByType(KMime::Content *content, const QByteArray &type); //TODO(Andras) move to MimeTreeParser::NodeHelper
352
353
354
355
356

    /** Saves the relative position of the scroll view. Call this before calling update()
      if you want to preserve the current view. */
    void saveRelativePosition();

Laurent Montel's avatar
Laurent Montel committed
357
358
    Q_REQUIRED_RESULT bool htmlMail() const;
    Q_REQUIRED_RESULT bool htmlLoadExternal() const;
359

Laurent Montel's avatar
Laurent Montel committed
360
    Q_REQUIRED_RESULT bool htmlMailGlobalSetting() const;
361

362
    /** Get the html override setting */
Laurent Montel's avatar
Laurent Montel committed
363
    Q_REQUIRED_RESULT Viewer::DisplayFormatMessage displayFormatMessageOverwrite() const;
364
365
366
367
368

    /** Override default html mail setting */
    void setDisplayFormatMessageOverwrite(Viewer::DisplayFormatMessage format);

    /** Get the load external references override setting */
Laurent Montel's avatar
Laurent Montel committed
369
    Q_REQUIRED_RESULT bool htmlLoadExtOverride() const;
370

371
372
373
374
375
376
377
378
379
380
381
382
383
    /** Default behavior for loading external references.
     *  Use this for specifying the external reference loading behavior as
     *  specified in the user settings.
     *  @see setHtmlLoadExtOverride
     */
    void setHtmlLoadExtDefault(bool loadExtDefault);

    /** Override default load external references setting
     *  @warning This must only be called when the user has explicitly
     *  been asked to retrieve external references!
     *  @see setHtmlLoadExtDefault
     */
    void setHtmlLoadExtOverride(bool loadExtOverride);
384
385
386
387
388

    /** Enforce message decryption. */
    void setDecryptMessageOverwrite(bool overwrite = true);

    /** Show signature details. */
Laurent Montel's avatar
Laurent Montel committed
389
    Q_REQUIRED_RESULT bool showSignatureDetails() const;
390
391
392
393

    /** Show signature details. */
    void setShowSignatureDetails(bool showDetails = true);

394
    /* show or hide encryption details */
395
396
    void setShowEncryptionDetails(bool showEncDetails);

Laurent Montel's avatar
Laurent Montel committed
397
    Q_REQUIRED_RESULT bool showEncryptionDetails() const;
398

399
400
401
402
403
404
405
406
407
408
    void scrollToAttachment(KMime::Content *node);
    void setUseFixedFont(bool useFixedFont);

    void attachmentView(KMime::Content *atmNode);

    void setZoomFactor(qreal zoomFactor);

    void goOnline();
    void goResourceOnline();

409
    void showSavedFileFolderWidget(const QList<QUrl> &urls, MessageViewer::OpenSavedFileFolderWidget::FileType fileType);
410

Laurent Montel's avatar
Laurent Montel committed
411
    Q_REQUIRED_RESULT bool mimePartTreeIsEmpty() const;
412
413
414

    void setPluginName(const QString &pluginName);

Laurent Montel's avatar
Laurent Montel committed
415
    Q_REQUIRED_RESULT QList<QAction *> viewerPluginActionList(
Laurent Montel's avatar
Laurent Montel committed
416
        MessageViewer::ViewerPluginInterface::SpecificFeatureTypes features);
Laurent Montel's avatar
Laurent Montel committed
417
    Q_REQUIRED_RESULT QList<QAction *> interceptorUrlActions(const WebEngineViewer::WebHitTestResult &result) const;
418

Laurent Montel's avatar
Laurent Montel committed
419
    void setPrintElementBackground(bool printElementBackground);
Laurent Montel's avatar
Laurent Montel committed
420
    Q_REQUIRED_RESULT bool showEmoticons() const;
Laurent Montel's avatar
Laurent Montel committed
421
422
    void checkPhishingUrl();
    void executeRunner(const QUrl &url);
Laurent Montel's avatar
Laurent Montel committed
423
    Q_REQUIRED_RESULT QUrl imageUrl() const;
424
425
    Q_REQUIRED_RESULT qreal webViewZoomFactor() const;
    void setWebViewZoomFactor(qreal factor);
Laurent Montel's avatar
Laurent Montel committed
426
    void recreateCssHelper();
427
    void hasMultiMessages(bool messages);
428
    void updateShowMultiMessagesButton(bool enablePreviousButton, bool enableNextButton);
Laurent Montel's avatar
Laurent Montel committed
429
    MessageViewer::DKIMViewerMenu *dkimViewerMenu();
430
431
432
433
434
435
436
private Q_SLOTS:
    void slotActivatePlugin(MessageViewer::ViewerPluginInterface *interface);
    void slotModifyItemDone(KJob *job);
    void slotMessageMayBeAScam();
    void slotMessageIsNotAScam();
    void slotAddToWhiteList();
    void slotItemChanged(const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers);
Laurent Montel's avatar
Laurent Montel committed
437
    void slotItemMoved(const Akonadi::Item &, const Akonadi::Collection &, const Akonadi::Collection &);
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458

    void itemModifiedResult(KJob *job);

    void slotClear();

    void slotMessageRendered();

    void slotOpenWithAction(QAction *act);

    void slotOpenWithActionCurrentContent(QAction *act);

    void slotOpenWithDialog();

    void slotOpenWithDialogCurrentContent();

    void saveSplitterSizes() const;

    void slotRefreshMessage(const Akonadi::Item &item);
    void slotServiceUrlSelected(PimCommon::ShareServiceUrlManager::ServiceType serviceType);
    void slotStyleChanged(MessageViewer::HeaderStylePlugin *plugin);
    void slotStyleUpdated();
459
    void slotWheelZoomChanged(int numSteps);
Laurent Montel's avatar
Laurent Montel committed
460
461
462
    void slotOpenInBrowser();
    void slotExportHtmlPageFailed();
    void slotExportHtmlPageSuccess(const QString &filename);
463
    void slotHandlePagePrinted(bool result);
464
    void slotToggleEmoticons();
465

466
467
468
public Q_SLOTS:
    /** An URL has been activate with a click. */
    void slotUrlOpen(const QUrl &url = QUrl());
Laurent Montel's avatar
Laurent Montel committed
469
    void slotOpenUrl();
470
471

    /** The mouse has moved on or off an URL. */
Laurent Montel's avatar
Laurent Montel committed
472
    void slotUrlOn(const QString &link);
473
474

    /** The user presses the right mouse button on an URL. */
Laurent Montel's avatar
Laurent Montel committed
475
    void slotUrlPopup(const WebEngineViewer::WebHitTestResult &result);
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

    /** The user selected "Find" from the menu. */
    void slotFind();

    /** The user toggled the "Fixed Font" flag from the view menu. */
    void slotToggleFixedFont();
    void slotToggleMimePartTree();

    /** Show the message source */
    void slotShowMessageSource();

    /** Refresh the reader window */
    void updateReaderWin();

    void slotMimePartSelected(const QModelIndex &index);

    void slotIconicAttachments();
    void slotSmartAttachments();
    void slotInlineAttachments();
    void slotHideAttachments();
    void slotHeaderOnlyAttachments();

    /** Some attachment operations. */
    void slotDelayedResize();

    /** Print message. Called on as a response of finished() signal of mPartHtmlWriter
      after rendering is finished.
      In the very end it deletes the KMReaderWin window that was created
      for the purpose of rendering. */
Laurent Montel's avatar
Laurent Montel committed
505
    void slotPrintMessage();
506
507
508
    void slotPrintPreview();

    void slotSetEncoding();
Laurent Montel's avatar
Laurent Montel committed
509
    void executeCustomScriptsAfterLoading();
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
    void slotSettingsChanged();
    void slotMimeTreeContextMenuRequested(const QPoint &pos);
    void slotAttachmentOpenWith();
    void slotAttachmentOpen();
    void slotAttachmentSaveAs();
    void slotAttachmentSaveAll();
    void slotAttachmentView();
    void slotAttachmentProperties();
    void slotAttachmentCopy();
    void slotLevelQuote(int l);

    /** Toggle display mode between HTML and plain text. */
    void slotToggleHtmlMode();
    void slotLoadExternalReference();

    /**
    * Does an action for the current attachment.
    * The action is defined by the KMHandleAttachmentCommand::AttachmentAction
    * enum.
    * prepareHandleAttachment() needs to be called before calling this to set the
    * correct attachment ID.
    */
    void slotHandleAttachment(int action);
    /** Copy the selected text to the clipboard */
    void slotCopySelectedText();

    void viewerSelectionChanged();

    /** Select message body. */
    void selectAll();

    /** Copy URL in mUrlCurrent to clipboard. Removes "mailto:" at
      beginning of URL before copying. */
    void slotUrlCopy();
    void slotSaveMessage();
    /** Re-parse the current message. */
546
    void update(MimeTreeParser::UpdateMode updateMode = MimeTreeParser::Delayed);
547
548
549
550
551
552
553

    void slotSpeakText();
    void slotCopyImageLocation();
    void slotSaveMessageDisplayFormat();
    void slotResetMessageDisplayFormat();

    void slotGeneralFontChanged();
Laurent Montel's avatar
Laurent Montel committed
554
    void slotShowDevelopmentTools();
555
556
557

Q_SIGNALS:
    void showStatusBarMessage(const QString &message);
Laurent Montel's avatar
Laurent Montel committed
558
559
    void popupMenu(const Akonadi::Item &msg, const QUrl &url, const QUrl &imageUrl, const QPoint &mousePos);
    void displayPopupMenu(const Akonadi::Item &msg, const WebEngineViewer::WebHitTestResult &result, const QPoint &mousePos);
560

561
562
563
564
    void urlClicked(const Akonadi::Item &msg, const QUrl &url);
    void requestConfigSync();
    void showReader(KMime::Content *aMsgPart, bool aHTML, const QString &encoding);
    void showMessage(const KMime::Message::Ptr &message, const QString &encoding);
565
    void replyMessageTo(const KMime::Message::Ptr &message, bool replyToAll);
566
567
568
569
570
    void itemRemoved();
    void makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode);

    void changeDisplayMail(Viewer::DisplayFormatMessage, bool);
    void moveMessageToTrash();
571
    void pageIsScrolledToBottom(bool);
572
    void printingFinished();
Laurent Montel's avatar
Laurent Montel committed
573
    void zoomChanged(qreal zoomFactor);
574
575
    void showNextMessage();
    void showPreviousMessage();
576
private:
Laurent Montel's avatar
Laurent Montel committed
577
578
    Q_REQUIRED_RESULT QString attachmentHtml();
    void initializeColorFromScheme();
579

580
581
    void replyMessageToAuthor(KMime::Content *atmNode);
    void replyMessageToAll(KMime::Content *atmNode);
Laurent Montel's avatar
Laurent Montel committed
582
    void replyMessage(KMime::Content *atmNode, bool replyToAll);
Laurent Montel's avatar
Laurent Montel committed
583
584
    Q_REQUIRED_RESULT bool urlIsAMalwareButContinue();
    Q_REQUIRED_RESULT bool messageIsInSpecialFolder() const;
Laurent Montel's avatar
Laurent Montel committed
585

Laurent Montel's avatar
Laurent Montel committed
586
    void slotCheckedUrlFinished(const QUrl &url, WebEngineViewer::CheckPhishingUrlUtil::UrlStatus status);
587

Laurent Montel's avatar
Laurent Montel committed
588
    void slotDelayPrintPreview();
Laurent Montel's avatar
Laurent Montel committed
589
590
    void applyZoomValue(qreal factor, bool saveConfig = true);
    void slotZoomChanged(qreal zoom);
591
    MimeTreeParser::NodeHelper *mNodeHelper = nullptr;
Laurent Montel's avatar
Laurent Montel committed
592
593
594
    bool mHtmlMailGlobalSetting = false;
    bool mHtmlLoadExternalDefaultSetting = false;
    bool mHtmlLoadExtOverride = false;
595
    void assignMessageItem(const Akonadi::Item &item);
596
public:
597
598
599
    KMime::Message::Ptr mMessage; //the current message, if it was set manually
    Akonadi::Item mMessageItem; //the message item from Akonadi
    // widgets:
Laurent Montel's avatar
Laurent Montel committed
600
601
602
603
604
605
    QSplitter *mSplitter = nullptr;
    QWidget *mBox = nullptr;
    HtmlStatusBar *mColorBar = nullptr;
    MimePartTreeView *mMimePartTree = nullptr;
    MailWebEngineView *mViewer = nullptr;
    WebEngineViewer::FindBarWebEngineView *mFindBar = nullptr;
606

607
    const AttachmentStrategy *mAttachmentStrategy = nullptr;
608
609
610
611
612
613
614
    QTimer mUpdateReaderWinTimer;
    QTimer mResizeTimer;
    QString mOverrideEncoding;
    QString mOldGlobalOverrideEncoding; // used to detect changes of the global override character encoding

    /// This is true if the viewer currently is displaying a message. Can be false, for example when
    /// the splash/busy page is displayed.
Laurent Montel's avatar
Laurent Montel committed
615
    bool mMsgDisplay = true;
616

617
    bool mUseFixedFont = false;
Laurent Montel's avatar
Laurent Montel committed
618
    bool mPrinting = false;
Laurent Montel's avatar
Laurent Montel committed
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    QWidget *mMainWindow = nullptr;
    KActionCollection *mActionCollection = nullptr;
    QAction *mCopyAction = nullptr;
    QAction *mCopyURLAction = nullptr;
    QAction *mUrlOpenAction = nullptr;
    QAction *mSelectAllAction = nullptr;
    QAction *mScrollUpAction = nullptr;
    QAction *mScrollDownAction = nullptr;
    QAction *mScrollUpMoreAction = nullptr;
    QAction *mScrollDownMoreAction = nullptr;
    QAction *mViewSourceAction = nullptr;
    QAction *mSaveMessageAction = nullptr;
    QAction *mFindInMessageAction = nullptr;
    QAction *mSaveMessageDisplayFormat = nullptr;
    QAction *mResetMessageDisplayFormat = nullptr;
    KToggleAction *mDisableEmoticonAction = nullptr;
    KToggleAction *mHeaderOnlyAttachmentsAction = nullptr;
    KSelectAction *mSelectEncodingAction = nullptr;
    KToggleAction *mToggleFixFontAction = nullptr;
    KToggleAction *mToggleDisplayModeAction = nullptr;
    KToggleAction *mToggleMimePartTreeAction = nullptr;
640
    QAction *mDevelopmentToolsAction = nullptr;
Laurent Montel's avatar
Laurent Montel committed
641
642
    QAction *mSpeakTextAction = nullptr;
    QAction *mCopyImageLocation = nullptr;
Laurent Montel's avatar
Laurent Montel committed
643
    QAction *mShareTextAction = nullptr;
644
645
    QUrl mClickedUrl;
    QUrl mImageUrl;
646
    HtmlWriter *mHtmlWriter = nullptr;
647
648
    /** Used only to be able to connect and disconnect finished() signal
      in printMsg() and slotPrintMsg() since mHtmlWriter points only to abstract non-QObject class. */
649
    QPointer<WebEnginePartHtmlWriter> mPartHtmlWriter;
Laurent Montel's avatar
Laurent Montel committed
650
    QPointer<DeveloperToolDialog> mDeveloperToolDialog;
651
652

    int mLevelQuote;
653
654
655
656
    bool mDecrytMessageOverwrite = false;
    bool mShowSignatureDetails = false;
    bool mShowEncryptionDetails = false;
    bool mForceEmoticons = true;
Laurent Montel's avatar
Laurent Montel committed
657
    int mRecursionCountForDisplayMessage = 0;
Laurent Montel's avatar
Laurent Montel committed
658
659
    KMime::Content *mCurrentContent = nullptr;
    KMime::Content *mMessagePartNode = nullptr;
660
    QString mMessagePath;
Laurent Montel's avatar
Laurent Montel committed
661
662
663

    QColor mForegroundError;
    QColor mBackgroundError;
Laurent Montel's avatar
Laurent Montel committed
664
    QColor mBackgroundAttachment;
Laurent Montel's avatar
Laurent Montel committed
665

666
    Viewer *const q;
Laurent Montel's avatar
Laurent Montel committed
667
    Akonadi::Session *mSession = nullptr;
668
669
    Akonadi::Monitor mMonitor;
    QSet<AbstractMessageLoadedHandler *> mMessageLoadedHandlers;
Laurent Montel's avatar
Laurent Montel committed
670
    Akonadi::Item::Id mPreviouslyViewedItemId;
671

Laurent Montel's avatar
Laurent Montel committed
672
    MessageViewer::ScamDetectionWarningWidget *mScamDetectionWarning = nullptr;
673
    MessageViewer::OpenSavedFileFolderWidget *mOpenSavedFileFolderWidget = nullptr;
Laurent Montel's avatar
Laurent Montel committed
674
    MessageViewer::SubmittedFormWarningWidget *mSubmittedFormWarning = nullptr;
Laurent Montel's avatar
Laurent Montel committed
675
    MessageViewer::MailTrackingWarningWidget *mMailTrackingWarning = nullptr;
Laurent Montel's avatar
Laurent Montel committed
676
    KPIMTextEdit::TextToSpeechWidget *mTextToSpeechWidget = nullptr;
677
    Viewer::DisplayFormatMessage mDisplayFormatMessageOverwrite;
Laurent Montel's avatar
Laurent Montel committed
678
679
680
681
682
683
684
685
    KPIMTextEdit::SlideContainer *mSliderContainer = nullptr;
    PimCommon::ShareServiceUrlManager *mShareServiceManager = nullptr;
    KActionMenu *mShareServiceUrlMenu = nullptr;
    MessageViewer::HeaderStylePlugin *mHeaderStylePlugin = nullptr;
    MessageViewer::HeaderStyleMenuManager *mHeaderStyleMenuManager = nullptr;
    MessageViewer::ViewerPluginToolManager *mViewerPluginToolManager = nullptr;
    WebEngineViewer::ZoomActionMenu *mZoomActionMenu = nullptr;
    QPrinter *mCurrentPrinter = nullptr;
686
    QVector<QPointer<MessageViewer::MailSourceWebEngineViewer> > mListMailSourceViewer;
Laurent Montel's avatar
Laurent Montel committed
687
    WebEngineViewer::LocalDataBaseManager *mPhishingDatabase = nullptr;
688
    MessageViewer::ShowNextMessageWidget *mShowNextMessageWidget = nullptr;
689
    MessageViewer::DKIMWidgetInfo *mDkimWidgetInfo = nullptr;
Laurent Montel's avatar
Laurent Montel committed
690
    MessageViewer::DKIMViewerMenu *mDkimViewerMenu = nullptr;
691
    MessageViewer::MessageViewerRenderer *mMessageViewerRenderer = nullptr;
692
693
694
695
};
}

#endif