kmreaderwin.cpp 28.2 KB
Newer Older
Laurent Montel's avatar
Laurent Montel committed
1
/*
2 3
  This file is part of KMail, the KDE mail client.
  Copyright (c) 1997 Markus Wuebben <markus.wuebben@kde.org>
Laurent Montel's avatar
Laurent Montel committed
4
  Copyright (c) 2009-2016 Laurent Montel <montel@kde.org>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
20

21 22
// define this to copy all html that is written to the readerwindow to
// filehtmlwriter.out in the current working directory
23
#include "kmreaderwin.h"
24

Laurent Montel's avatar
Laurent Montel committed
25
#include "settings/kmailsettings.h"
26 27
#include "kmmainwidget.h"
#include "kmreadermainwin.h"
Laurent Montel's avatar
Laurent Montel committed
28
#include "mailcommon/mailkernel.h"
29 30
#include "dialog/addemailtoexistingcontactdialog.h"
#include "job/addemailtoexistingcontactjob.h"
31

32
#include "kdepim-version.h"
33
#include <KEmailAddress>
Laurent Montel's avatar
Laurent Montel committed
34 35 36 37
#include <Libkdepim/AddEmailAddressJob>
#include <Libkdepim/OpenEmailAddressJob>
#include <Libkdepim/AddEmailDisplayJob>
#include <Libkdepim/BroadcastStatus>
38
#include "kmcommands.h"
Laurent Montel's avatar
Laurent Montel committed
39
#include "MailCommon/SendMdnHandler"
Laurent Montel's avatar
Laurent Montel committed
40
#include <QVBoxLayout>
Laurent Montel's avatar
Laurent Montel committed
41 42
#include "messageviewer/headerstrategy.h"
#include "messageviewer/mailwebview.h"
Laurent Montel's avatar
Laurent Montel committed
43
#include "messageviewer/markmessagereadhandler.h"
44
#include "messageviewer/messageviewersettings.h"
45
#include "MessageViewer/CSSHelper"
46
using MessageViewer::CSSHelper;
47
#include "util.h"
48
#include "MessageCore/StringUtil"
Laurent Montel's avatar
Laurent Montel committed
49
#include <QCryptographicHash>
Laurent Montel's avatar
Laurent Montel committed
50
#include <kmime/kmime_mdn.h>
51
#include <akonadi/kmime/messageflags.h>
52

53
#include "messageviewer/viewer.h"
54
using namespace MessageViewer;
55
#include <MessageCore/MessageCoreSettings>
Laurent Montel's avatar
Laurent Montel committed
56

57
#include <MimeTreeParser/AttachmentStrategy>
Laurent Montel's avatar
Laurent Montel committed
58 59 60 61 62
#include "MessageComposer/MessageSender"
#include "MessageComposer/MessageFactory"
#include "MessageComposer/Composer"
#include "MessageComposer/TextPart"
#include "MessageComposer/InfoPart"
63

Laurent Montel's avatar
Laurent Montel committed
64
#include <KIO/JobUiDelegate>
65
using MessageComposer::MessageFactory;
66

Laurent Montel's avatar
Laurent Montel committed
67
#include "messagecore/messagehelpers.h"
68

69
#include <Akonadi/Contact/ContactEditorDialog>
70

Laurent Montel's avatar
Laurent Montel committed
71
#include "kmail_debug.h"
Laurent Montel's avatar
Laurent Montel committed
72
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
73
#include <QAction>
Laurent Montel's avatar
Laurent Montel committed
74
#include <kcodecs.h>
75
#include <ktoggleaction.h>
76
#include <kservice.h>
Laurent Montel's avatar
Laurent Montel committed
77
#include <KActionCollection>
78
#include <KMessageBox>
Laurent Montel's avatar
Laurent Montel committed
79
#include <QMenu>
80

81
#include <QClipboard>
82

83 84 85 86
// X headers...
#undef Never
#undef Always

Stephan Kulow's avatar
Stephan Kulow committed
87
#include <unistd.h>
88 89 90 91 92
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
Laurent Montel's avatar
Laurent Montel committed
93
#include <mailcommon/mailutil.h>
94

95
using namespace KMail;
Andras Mantia's avatar
Andras Mantia committed
96
using namespace MailCommon;
97

98
KMReaderWin::KMReaderWin(QWidget *aParent,
99
                         QWidget *mainWindow,
Laurent Montel's avatar
Laurent Montel committed
100 101 102 103 104
                         KActionCollection *actionCollection,
                         Qt::WindowFlags aFlags)
    : QWidget(aParent, aFlags),
      mMainWindow(mainWindow),
      mActionCollection(actionCollection),
Laurent Montel's avatar
Laurent Montel committed
105 106 107 108 109 110 111 112
      mMailToComposeAction(Q_NULLPTR),
      mMailToReplyAction(Q_NULLPTR),
      mMailToForwardAction(Q_NULLPTR),
      mAddAddrBookAction(Q_NULLPTR),
      mOpenAddrBookAction(Q_NULLPTR),
      mUrlSaveAsAction(Q_NULLPTR),
      mAddBookmarksAction(Q_NULLPTR),
      mAddEmailToExistingContactAction(Q_NULLPTR)
Laurent Montel's avatar
Laurent Montel committed
113 114
{
    createActions();
Laurent Montel's avatar
Laurent Montel committed
115 116 117 118
    QVBoxLayout *vlay = new QVBoxLayout(this);
    vlay->setMargin(0);
    mViewer = new Viewer(this, mainWindow, mActionCollection);
    mViewer->setExternalWindow(true);
Laurent Montel's avatar
Laurent Montel committed
119
    mViewer->setAppName(QStringLiteral("KMail"));
Laurent Montel's avatar
Laurent Montel committed
120
    connect(mViewer, SIGNAL(urlClicked(Akonadi::Item,QUrl)), this, SLOT(slotUrlClicked(Akonadi::Item,QUrl)));
121 122
    connect(mViewer, &Viewer::requestConfigSync, kmkernel, &KMKernel::slotRequestConfigSync, Qt::QueuedConnection);   // happens anyway on shutdown, so we can skip it there with using a queued connection
    connect(mViewer, &Viewer::makeResourceOnline, kmkernel, &KMKernel::makeResourceOnline);
Laurent Montel's avatar
Laurent Montel committed
123 124 125
    connect(mViewer, &MessageViewer::Viewer::showReader, this, &KMReaderWin::slotShowReader);
    connect(mViewer, &MessageViewer::Viewer::showMessage, this, &KMReaderWin::slotShowMessage);
    connect(mViewer, &MessageViewer::Viewer::showStatusBarMessage, this, &KMReaderWin::showStatusBarMessage);
Laurent Montel's avatar
Laurent Montel committed
126
    connect(mViewer, SIGNAL(deleteMessage(Akonadi::Item)), this, SLOT(slotDeleteMessage(Akonadi::Item)));
Laurent Montel's avatar
Laurent Montel committed
127

Laurent Montel's avatar
Laurent Montel committed
128 129
    mViewer->addMessageLoadedHandler(new MessageViewer::MarkMessageReadHandler(this));
    mViewer->addMessageLoadedHandler(new MailCommon::SendMdnHandler(kmkernel, this));
Laurent Montel's avatar
Laurent Montel committed
130

Laurent Montel's avatar
Laurent Montel committed
131
    vlay->addWidget(mViewer);
Laurent Montel's avatar
Laurent Montel committed
132
    readConfig();
133 134

}
Laurent Montel's avatar
Laurent Montel committed
135

136
void KMReaderWin::createActions()
137
{
Laurent Montel's avatar
Laurent Montel committed
138
    KActionCollection *ac = mActionCollection;
Laurent Montel's avatar
Laurent Montel committed
139
    if (!ac) {
Laurent Montel's avatar
Laurent Montel committed
140 141 142 143 144 145
        return;
    }
    //
    // Message Menu
    //
    // new message to
Laurent Montel's avatar
Laurent Montel committed
146
    mMailToComposeAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-message-new")),
Laurent Montel's avatar
Laurent Montel committed
147
                                       i18n("New Message To..."), this);
Laurent Montel's avatar
Laurent Montel committed
148
    ac->addAction(QStringLiteral("mail_new"), mMailToComposeAction);
Laurent Montel's avatar
Laurent Montel committed
149
    ac->setShortcutsConfigurable(mMailToComposeAction, false);
Laurent Montel's avatar
Laurent Montel committed
150
    connect(mMailToComposeAction, &QAction::triggered, this, &KMReaderWin::slotMailtoCompose);
Laurent Montel's avatar
Laurent Montel committed
151 152

    // reply to
Laurent Montel's avatar
Laurent Montel committed
153
    mMailToReplyAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-sender")),
Laurent Montel's avatar
Laurent Montel committed
154
                                     i18n("Reply To..."), this);
Laurent Montel's avatar
Laurent Montel committed
155
    ac->addAction(QStringLiteral("mailto_reply"), mMailToReplyAction);
Laurent Montel's avatar
Laurent Montel committed
156
    ac->setShortcutsConfigurable(mMailToReplyAction, false);
Laurent Montel's avatar
Laurent Montel committed
157
    connect(mMailToReplyAction, &QAction::triggered, this, &KMReaderWin::slotMailtoReply);
Laurent Montel's avatar
Laurent Montel committed
158 159

    // forward to
Laurent Montel's avatar
Laurent Montel committed
160
    mMailToForwardAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-forward")),
Laurent Montel's avatar
Laurent Montel committed
161 162
                                       i18n("Forward To..."), this);
    ac->setShortcutsConfigurable(mMailToForwardAction, false);
Laurent Montel's avatar
Laurent Montel committed
163
    ac->addAction(QStringLiteral("mailto_forward"), mMailToForwardAction);
Laurent Montel's avatar
Laurent Montel committed
164
    connect(mMailToForwardAction, &QAction::triggered, this, &KMReaderWin::slotMailtoForward);
Laurent Montel's avatar
Laurent Montel committed
165 166

    // add to addressbook
Laurent Montel's avatar
Laurent Montel committed
167
    mAddAddrBookAction = new QAction(QIcon::fromTheme(QStringLiteral("contact-new")),
Laurent Montel's avatar
Laurent Montel committed
168 169
                                     i18n("Add to Address Book"), this);
    ac->setShortcutsConfigurable(mAddAddrBookAction, false);
Laurent Montel's avatar
Laurent Montel committed
170
    ac->addAction(QStringLiteral("add_addr_book"), mAddAddrBookAction);
Laurent Montel's avatar
Laurent Montel committed
171
    connect(mAddAddrBookAction, &QAction::triggered, this, &KMReaderWin::slotMailtoAddAddrBook);
Laurent Montel's avatar
Laurent Montel committed
172

Laurent Montel's avatar
Laurent Montel committed
173
    mAddEmailToExistingContactAction = new QAction(QIcon::fromTheme(QStringLiteral("contact-new")),
Laurent Montel's avatar
Laurent Montel committed
174 175
            i18n("Add to Existing Contact"), this);
    ac->setShortcutsConfigurable(mAddEmailToExistingContactAction, false);
Laurent Montel's avatar
Laurent Montel committed
176
    ac->addAction(QStringLiteral("add_to_existing_contact"), mAddAddrBookAction);
Laurent Montel's avatar
Laurent Montel committed
177
    connect(mAddEmailToExistingContactAction, &QAction::triggered, this, &KMReaderWin::slotMailToAddToExistingContact);
Laurent Montel's avatar
Laurent Montel committed
178 179

    // open in addressbook
Laurent Montel's avatar
Laurent Montel committed
180
    mOpenAddrBookAction = new QAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")),
Laurent Montel's avatar
Laurent Montel committed
181 182
                                      i18n("Open in Address Book"), this);
    ac->setShortcutsConfigurable(mOpenAddrBookAction, false);
Laurent Montel's avatar
Laurent Montel committed
183
    ac->addAction(QStringLiteral("openin_addr_book"), mOpenAddrBookAction);
Laurent Montel's avatar
Laurent Montel committed
184
    connect(mOpenAddrBookAction, &QAction::triggered, this, &KMReaderWin::slotMailtoOpenAddrBook);
Laurent Montel's avatar
Laurent Montel committed
185
    // bookmark message
Laurent Montel's avatar
Laurent Montel committed
186
    mAddBookmarksAction = new QAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), i18n("Bookmark This Link"), this);
Laurent Montel's avatar
Laurent Montel committed
187
    ac->setShortcutsConfigurable(mAddBookmarksAction, false);
Laurent Montel's avatar
Laurent Montel committed
188
    ac->addAction(QStringLiteral("add_bookmarks"), mAddBookmarksAction);
Laurent Montel's avatar
Laurent Montel committed
189
    connect(mAddBookmarksAction, &QAction::triggered, this, &KMReaderWin::slotAddBookmarks);
Laurent Montel's avatar
Laurent Montel committed
190

Laurent Montel's avatar
Laurent Montel committed
191
    mEditContactAction = new QAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")),
Laurent Montel's avatar
Laurent Montel committed
192 193
                                     i18n("Edit contact..."), this);
    ac->setShortcutsConfigurable(mEditContactAction, false);
Laurent Montel's avatar
Laurent Montel committed
194
    ac->addAction(QStringLiteral("edit_contact"), mOpenAddrBookAction);
Laurent Montel's avatar
Laurent Montel committed
195
    connect(mEditContactAction, &QAction::triggered, this, &KMReaderWin::slotEditContact);
Laurent Montel's avatar
Laurent Montel committed
196 197

    // save URL as
Laurent Montel's avatar
Laurent Montel committed
198
    mUrlSaveAsAction = new QAction(i18n("Save Link As..."), this);
Laurent Montel's avatar
Laurent Montel committed
199
    ac->addAction(QStringLiteral("saveas_url"), mUrlSaveAsAction);
Laurent Montel's avatar
Laurent Montel committed
200
    ac->setShortcutsConfigurable(mUrlSaveAsAction, false);
Laurent Montel's avatar
Laurent Montel committed
201
    connect(mUrlSaveAsAction, &QAction::triggered, this, &KMReaderWin::slotUrlSave);
Laurent Montel's avatar
Laurent Montel committed
202 203

    // find text
Laurent Montel's avatar
Laurent Montel committed
204
    QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("edit-find")), i18n("&Find in Message..."), this);
Laurent Montel's avatar
Laurent Montel committed
205
    ac->addAction(QStringLiteral("find_in_messages"), action);
Laurent Montel's avatar
Laurent Montel committed
206
    connect(action, &QAction::triggered, this, &KMReaderWin::slotFind);
Laurent Montel's avatar
Laurent Montel committed
207
    ac->setDefaultShortcut(action, KStandardShortcut::find().first());
Laurent Montel's avatar
Laurent Montel committed
208 209

    // save Image On Disk
Laurent Montel's avatar
Laurent Montel committed
210
    mImageUrlSaveAsAction = new QAction(i18n("Save Image On Disk..."), this);
Laurent Montel's avatar
Laurent Montel committed
211
    ac->addAction(QStringLiteral("saveas_imageurl"), mImageUrlSaveAsAction);
Laurent Montel's avatar
Laurent Montel committed
212
    ac->setShortcutsConfigurable(mImageUrlSaveAsAction, false);
Laurent Montel's avatar
Laurent Montel committed
213
    connect(mImageUrlSaveAsAction, &QAction::triggered, this, &KMReaderWin::slotSaveImageOnDisk);
Laurent Montel's avatar
Laurent Montel committed
214 215

    // View html options
Laurent Montel's avatar
Laurent Montel committed
216
    mViewHtmlOptions = new QMenu(i18n("Show HTML Format"));
Laurent Montel's avatar
Laurent Montel committed
217 218
    mViewAsHtml = new QAction(i18n("Show HTML format when mail comes from this contact"), mViewHtmlOptions);
    ac->setShortcutsConfigurable(mViewAsHtml, false);
Laurent Montel's avatar
Laurent Montel committed
219
    connect(mViewAsHtml, &QAction::triggered, this, &KMReaderWin::slotContactHtmlOptions);
Laurent Montel's avatar
Laurent Montel committed
220 221 222
    mViewAsHtml->setCheckable(true);
    mViewHtmlOptions->addAction(mViewAsHtml);

Laurent Montel's avatar
Laurent Montel committed
223 224
    mLoadExternalReference = new QAction(i18n("Load external reference when mail comes for this contact"), mViewHtmlOptions);
    ac->setShortcutsConfigurable(mLoadExternalReference, false);
Laurent Montel's avatar
Laurent Montel committed
225
    connect(mLoadExternalReference, &QAction::triggered, this, &KMReaderWin::slotContactHtmlOptions);
Laurent Montel's avatar
Laurent Montel committed
226 227 228
    mLoadExternalReference->setCheckable(true);
    mViewHtmlOptions->addAction(mLoadExternalReference);

Laurent Montel's avatar
Laurent Montel committed
229
    mShareImage = new QAction(i18n("Share image..."), this);
Laurent Montel's avatar
Laurent Montel committed
230
    ac->addAction(QStringLiteral("share_imageurl"), mShareImage);
Laurent Montel's avatar
Laurent Montel committed
231
    ac->setShortcutsConfigurable(mShareImage, false);
Laurent Montel's avatar
Laurent Montel committed
232
    connect(mShareImage, &QAction::triggered, this, &KMReaderWin::slotShareImage);
Laurent Montel's avatar
Laurent Montel committed
233

Laurent Montel's avatar
Laurent Montel committed
234
}
Markus Wuebben's avatar
Markus Wuebben committed
235

Laurent Montel's avatar
Laurent Montel committed
236
void KMReaderWin::setUseFixedFont(bool useFixedFont)
237
{
Laurent Montel's avatar
Laurent Montel committed
238
    mViewer->setUseFixedFont(useFixedFont);
239 240
}

Laurent Montel's avatar
Laurent Montel committed
241 242 243 244 245
Viewer *KMReaderWin::viewer()
{
    return mViewer;
}

246 247
bool KMReaderWin::isFixedFont() const
{
Laurent Montel's avatar
Laurent Montel committed
248
    return mViewer->isFixedFont();
249 250
}

251 252
KMReaderWin::~KMReaderWin()
{
253 254
}

255 256
void KMReaderWin::readConfig(void)
{
Laurent Montel's avatar
Laurent Montel committed
257
    mViewer->readConfig();
258 259
}

260
void KMReaderWin::setAttachmentStrategy(const MimeTreeParser::AttachmentStrategy *strategy)
Laurent Montel's avatar
Laurent Montel committed
261 262
{
    mViewer->setAttachmentStrategy(strategy);
263
}
Laurent Montel's avatar
Laurent Montel committed
264

Laurent Montel's avatar
Laurent Montel committed
265
void KMReaderWin::setOverrideEncoding(const QString &encoding)
266
{
Laurent Montel's avatar
Laurent Montel committed
267
    mViewer->setOverrideEncoding(encoding);
268 269
}

270 271
void KMReaderWin::clearCache()
{
Laurent Montel's avatar
Laurent Montel committed
272
    clear();
273
}
274

275
// enter items for the "Important changes" list here:
Laurent Montel's avatar
Laurent Montel committed
276 277
static const char *const kmailChanges[] = {
    I18N_NOOP("KMail is now based on the Akonadi Personal Information Management framework, which brings many "
Laurent Montel's avatar
Laurent Montel committed
278
    "changes all around.")
279
};
Marc Mutz's avatar
Marc Mutz committed
280
static const int numKMailChanges =
Laurent Montel's avatar
Laurent Montel committed
281
    sizeof kmailChanges / sizeof * kmailChanges;
282

283 284 285 286
// enter items for the "new features" list here, so the main body of
// the welcome page can be left untouched (probably much easier for
// the translators). Note that the <li>...</li> tags are added
// automatically below:
Laurent Montel's avatar
Laurent Montel committed
287 288 289 290 291 292 293
static const char *const kmailNewFeatures[] = {
    I18N_NOOP("Push email (IMAP IDLE)"),
    I18N_NOOP("Improved virtual folders"),
    I18N_NOOP("Improved searches"),
    I18N_NOOP("Support for adding notes (annotations) to mails"),
    I18N_NOOP("Tag folders"),
    I18N_NOOP("Less GUI freezes, mail checks happen in the background")
294 295
};
static const int numKMailNewFeatures =
Laurent Montel's avatar
Laurent Montel committed
296
    sizeof kmailNewFeatures / sizeof * kmailNewFeatures;
Michael Haeckel's avatar
Michael Haeckel committed
297

298 299 300
//static
QString KMReaderWin::newFeaturesMD5()
{
Laurent Montel's avatar
Laurent Montel committed
301
    QByteArray str;
Laurent Montel's avatar
Laurent Montel committed
302
    for (int i = 0; i < numKMailChanges; ++i) {
Laurent Montel's avatar
Laurent Montel committed
303
        str += kmailChanges[i];
Laurent Montel's avatar
Laurent Montel committed
304
    }
Laurent Montel's avatar
Laurent Montel committed
305
    for (int i = 0; i < numKMailNewFeatures; ++i) {
Laurent Montel's avatar
Laurent Montel committed
306
        str += kmailNewFeatures[i];
Laurent Montel's avatar
Laurent Montel committed
307
    }
Laurent Montel's avatar
Laurent Montel committed
308
    QCryptographicHash md5(QCryptographicHash::Md5);
Laurent Montel's avatar
Laurent Montel committed
309
    md5.addData(str);
Laurent Montel's avatar
Laurent Montel committed
310
    return QLatin1String(md5.result().toBase64());
311 312
}

313
void KMReaderWin::displaySplashPage(const QString &templateName, const QVariantHash &_data)
Michael Haeckel's avatar
Michael Haeckel committed
314
{
315 316
    QVariantHash data = _data;
    if (!data.contains(QStringLiteral("icon"))) {
Laurent Montel's avatar
Laurent Montel committed
317
        data[QStringLiteral("icon")] = QStringLiteral("kmail");
318 319 320 321 322 323 324 325 326
    }
    if (!data.contains(QStringLiteral("name"))) {
        data[QStringLiteral("name")] = i18n("KMail");
    }
    if (!data.contains(QStringLiteral("subtitle"))) {
        data[QStringLiteral("subtitle")] = i18n("The KDE Mail Client");
    }

    mViewer->displaySplashPage(templateName, data);
327 328 329 330
}

void KMReaderWin::displayBusyPage()
{
Laurent Montel's avatar
Laurent Montel committed
331 332 333 334
    displaySplashPage(QStringLiteral("status.html"), {
        { QStringLiteral("title"), i18n("Retrieving Folder Contents") },
        { QStringLiteral("subtext"), i18n("Please wait . . .") }
    });
335 336
}

337 338
void KMReaderWin::displayOfflinePage()
{
Laurent Montel's avatar
Laurent Montel committed
339 340 341 342 343 344 345
    displaySplashPage(QStringLiteral("status.html"), {
        { QStringLiteral("title"), i18n("Offline") },
        {
            QStringLiteral("subtext"), i18n("KMail is currently in offline mode. "
            "Click <a href=\"kmail:goOnline\">here</a> to go online . . .</p>")
        }
    });
346 347
}

348 349
void KMReaderWin::displayResourceOfflinePage()
{
Laurent Montel's avatar
Laurent Montel committed
350 351 352 353 354 355 356
    displaySplashPage(QStringLiteral("status.html"), {
        { QStringLiteral("title"), i18n("Offline") },
        {
            QStringLiteral("subtext"), i18n("Account is currently in offline mode. "
            "Click <a href=\"kmail:goResourceOnline\">here</a> to go online . . .</p>")
        }
    });
357 358
}

359 360
void KMReaderWin::displayAboutPage()
{
361 362 363
    QVariantHash data;
    data[QStringLiteral("version")] = QStringLiteral(KDEPIM_VERSION);
    data[QStringLiteral("firstStart")] = kmkernel->firstStart();
Laurent Montel's avatar
Laurent Montel committed
364

365 366 367 368
    QVariantList features;
    features.reserve(numKMailNewFeatures);
    for (int i = 0; i < numKMailNewFeatures; ++i) {
        features.push_back(i18n(kmailNewFeatures[i]));
Laurent Montel's avatar
Laurent Montel committed
369
    }
370
    data[QStringLiteral("newFeatures")] = features;
Laurent Montel's avatar
Laurent Montel committed
371

372 373 374 375
    QVariantList changes;
    changes.reserve(numKMailChanges);
    for (int i = 0; i < numKMailChanges; ++i) {
        features.push_back(i18n(kmailChanges[i]));
Laurent Montel's avatar
Laurent Montel committed
376
    }
377
    data[QStringLiteral("importantChanges")] = changes;
378

379
    displaySplashPage(QStringLiteral("introduction_kmail.html"), data);
Michael Haeckel's avatar
Michael Haeckel committed
380 381
}

382 383
void KMReaderWin::slotFind()
{
Laurent Montel's avatar
Laurent Montel committed
384
    mViewer->slotFind();
385
}
Laurent Montel's avatar
Laurent Montel committed
386

387 388
void KMReaderWin::slotCopySelectedText()
{
Laurent Montel's avatar
Laurent Montel committed
389
    QString selection = mViewer->selectedText();
Laurent Montel's avatar
Laurent Montel committed
390 391
    selection.replace(QChar::Nbsp, QLatin1Char(' '));
    QApplication::clipboard()->setText(selection);
392
}
393

Laurent Montel's avatar
Laurent Montel committed
394
void KMReaderWin::setMsgPart(KMime::Content *aMsgPart)
395
{
Laurent Montel's avatar
Laurent Montel committed
396
    mViewer->setMessagePart(aMsgPart);
397 398
}

Laurent Montel's avatar
Laurent Montel committed
399
QString KMReaderWin::copyText() const
Markus Wuebben's avatar
Markus Wuebben committed
400
{
Laurent Montel's avatar
Laurent Montel committed
401
    return mViewer->selectedText();
Markus Wuebben's avatar
Markus Wuebben committed
402 403
}

404 405 406 407 408 409 410 411 412 413
MessageViewer::Viewer::DisplayFormatMessage KMReaderWin::displayFormatMessageOverwrite() const
{
    return mViewer->displayFormatMessageOverwrite();
}

void KMReaderWin::setDisplayFormatMessageOverwrite(MessageViewer::Viewer::DisplayFormatMessage format)
{
    mViewer->setDisplayFormatMessageOverwrite(format);
}

Laurent Montel's avatar
Laurent Montel committed
414
void KMReaderWin::setHtmlLoadExtOverride(bool Q_DECL_OVERRIDE)
415
{
Laurent Montel's avatar
Laurent Montel committed
416
    mViewer->setHtmlLoadExtOverride(Q_DECL_OVERRIDE);
417 418
}

Laurent Montel's avatar
Laurent Montel committed
419
bool KMReaderWin::htmlMail() const
420
{
Laurent Montel's avatar
Laurent Montel committed
421
    return mViewer->htmlMail();
422 423
}

424 425
bool KMReaderWin::htmlLoadExternal()
{
Laurent Montel's avatar
Laurent Montel committed
426
    return mViewer->htmlLoadExternal();
427 428
}

Laurent Montel's avatar
Laurent Montel committed
429
Akonadi::Item KMReaderWin::message() const
430
{
Laurent Montel's avatar
Laurent Montel committed
431
    return mViewer->messageItem();
432
}
433

Laurent Montel's avatar
Laurent Montel committed
434 435 436 437 438
QWidget *KMReaderWin::mainWindow()
{
    return mMainWindow;
}

439 440
void KMReaderWin::slotMailtoCompose()
{
Laurent Montel's avatar
Laurent Montel committed
441
    KMCommand *command = new KMMailtoComposeCommand(urlClicked(), message());
Laurent Montel's avatar
Laurent Montel committed
442
    command->start();
443 444 445 446
}

void KMReaderWin::slotMailtoForward()
{
Laurent Montel's avatar
Laurent Montel committed
447 448
    KMCommand *command = new KMMailtoForwardCommand(mMainWindow, urlClicked(),
            message());
Laurent Montel's avatar
Laurent Montel committed
449
    command->start();
450 451 452 453
}

void KMReaderWin::slotMailtoAddAddrBook()
{
Laurent Montel's avatar
Laurent Montel committed
454
    const QUrl url = urlClicked();
Laurent Montel's avatar
Laurent Montel committed
455
    if (url.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
456
        return;
Laurent Montel's avatar
Laurent Montel committed
457
    }
458
    const QString emailString = KEmailAddress::decodeMailtoUrl(url);
459

Laurent Montel's avatar
Laurent Montel committed
460
    KPIM::AddEmailAddressJob *job = new KPIM::AddEmailAddressJob(emailString, mMainWindow, this);
Laurent Montel's avatar
Laurent Montel committed
461
    job->start();
462 463
}

464 465
void KMReaderWin::slotMailToAddToExistingContact()
{
Laurent Montel's avatar
Laurent Montel committed
466
    const QUrl url = urlClicked();
Laurent Montel's avatar
Laurent Montel committed
467
    if (url.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
468
        return;
Laurent Montel's avatar
Laurent Montel committed
469
    }
470
    const QString emailString = KEmailAddress::decodeMailtoUrl(url);
471 472 473 474 475 476 477 478 479 480 481
    QPointer<AddEmailToExistingContactDialog> dlg = new AddEmailToExistingContactDialog(this);
    if (dlg->exec()) {
        Akonadi::Item item = dlg->selectedContact();
        if (item.isValid()) {
            AddEmailToExistingContactJob *job = new AddEmailToExistingContactJob(item, emailString, this);
            job->start();
        }
    }
    delete dlg;
}

482 483
void KMReaderWin::slotMailtoOpenAddrBook()
{
Laurent Montel's avatar
Laurent Montel committed
484
    const QUrl url = urlClicked();
Laurent Montel's avatar
Laurent Montel committed
485
    if (url.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
486
        return;
Laurent Montel's avatar
Laurent Montel committed
487
    }
488
    const QString emailString = KEmailAddress::decodeMailtoUrl(url).toLower();
489

Laurent Montel's avatar
Laurent Montel committed
490
    KPIM::OpenEmailAddressJob *job = new KPIM::OpenEmailAddressJob(emailString, mMainWindow, this);
Laurent Montel's avatar
Laurent Montel committed
491
    job->start();
492 493
}

494 495
void KMReaderWin::slotAddBookmarks()
{
Laurent Montel's avatar
Laurent Montel committed
496
    const QUrl url = urlClicked();
Laurent Montel's avatar
Laurent Montel committed
497
    if (url.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
498
        return;
Laurent Montel's avatar
Laurent Montel committed
499 500
    }
    KMCommand *command = new KMAddBookmarksCommand(url, this);
Laurent Montel's avatar
Laurent Montel committed
501
    command->start();
502 503
}

504 505
void KMReaderWin::slotUrlSave()
{
Laurent Montel's avatar
Laurent Montel committed
506
    const QUrl url = urlClicked();
Laurent Montel's avatar
Laurent Montel committed
507
    if (url.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
508
        return;
Laurent Montel's avatar
Laurent Montel committed
509 510
    }
    KMCommand *command = new KMUrlSaveCommand(url, mMainWindow);
Laurent Montel's avatar
Laurent Montel committed
511
    command->start();
512 513
}

Laurent Montel's avatar
Laurent Montel committed
514
void KMReaderWin::slotSaveImageOnDisk()
515
{
Laurent Montel's avatar
Laurent Montel committed
516
    const QUrl url = imageUrlClicked();
Laurent Montel's avatar
Laurent Montel committed
517
    if (url.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
518
        return;
Laurent Montel's avatar
Laurent Montel committed
519 520
    }
    KMCommand *command = new KMUrlSaveCommand(url, mMainWindow);
Laurent Montel's avatar
Laurent Montel committed
521
    command->start();
522 523
}

524 525
void KMReaderWin::slotMailtoReply()
{
Laurent Montel's avatar
Laurent Montel committed
526 527
    KMCommand *command = new KMMailtoReplyCommand(mMainWindow, urlClicked(),
            message(), copyText());
Laurent Montel's avatar
Laurent Montel committed
528
    command->start();
529 530
}

Laurent Montel's avatar
Laurent Montel committed
531
CSSHelper *KMReaderWin::cssHelper() const
532
{
Laurent Montel's avatar
Laurent Montel committed
533
    return mViewer->cssHelper();
534 535
}

Laurent Montel's avatar
Laurent Montel committed
536 537
bool KMReaderWin::htmlLoadExtOverride() const
{
Laurent Montel's avatar
Laurent Montel committed
538
    return mViewer->htmlLoadExtOverride();
Laurent Montel's avatar
Laurent Montel committed
539
}
Laurent Montel's avatar
Laurent Montel committed
540
void KMReaderWin::setDecryptMessageOverwrite(bool overwrite)
541
{
Laurent Montel's avatar
Laurent Montel committed
542
    mViewer->setDecryptMessageOverwrite(overwrite);
543
}
544
const MimeTreeParser::AttachmentStrategy *KMReaderWin::attachmentStrategy() const
545
{
Laurent Montel's avatar
Laurent Montel committed
546
    return mViewer->attachmentStrategy();
547
}
Laurent Montel's avatar
Port it  
Laurent Montel committed
548 549 550

QString KMReaderWin::overrideEncoding() const
{
Laurent Montel's avatar
Laurent Montel committed
551
    return mViewer->overrideEncoding();
Laurent Montel's avatar
Port it  
Laurent Montel committed
552
}
553

Laurent Montel's avatar
Laurent Montel committed
554
KToggleAction *KMReaderWin::toggleFixFontAction() const
555
{
Laurent Montel's avatar
Laurent Montel committed
556
    return mViewer->toggleFixFontAction();
557
}
Laurent Montel's avatar
Laurent Montel committed
558

Laurent Montel's avatar
Laurent Montel committed
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
QAction *KMReaderWin::mailToComposeAction() const
{
    return mMailToComposeAction;
}

QAction *KMReaderWin::mailToReplyAction() const
{
    return mMailToReplyAction;
}

QAction *KMReaderWin::mailToForwardAction() const
{
    return mMailToForwardAction;
}

QAction *KMReaderWin::addAddrBookAction() const
{
    return mAddAddrBookAction;
}

QAction *KMReaderWin::openAddrBookAction() const
{
    return mOpenAddrBookAction;
}

584 585 586 587 588
bool KMReaderWin::mimePartTreeIsEmpty() const
{
    return mViewer->mimePartTreeIsEmpty();
}

Laurent Montel's avatar
Laurent Montel committed
589
QAction *KMReaderWin::toggleMimePartTreeAction() const
590
{
Laurent Montel's avatar
Laurent Montel committed
591
    return mViewer->toggleMimePartTreeAction();
592 593
}

Laurent Montel's avatar
Laurent Montel committed
594 595 596 597 598
KActionMenu *KMReaderWin::shareServiceUrlMenu() const
{
    return mViewer->shareServiceUrlMenu();
}

599
QList<QAction *> KMReaderWin::viewerPluginActionList(ViewerPluginInterface::SpecificFeatureTypes features)
Laurent Montel's avatar
Laurent Montel committed
600
{
601
    return mViewer->viewerPluginActionList(features);
Laurent Montel's avatar
Laurent Montel committed
602 603
}

Laurent Montel's avatar
Laurent Montel committed
604
QAction *KMReaderWin::selectAllAction() const
Laurent Montel's avatar
Laurent Montel committed
605
{
Laurent Montel's avatar
Laurent Montel committed
606
    return mViewer->selectAllAction();
Laurent Montel's avatar
Laurent Montel committed
607 608
}

Laurent Montel's avatar
Laurent Montel committed
609
QAction *KMReaderWin::copyURLAction() const
610
{
Laurent Montel's avatar
Laurent Montel committed
611
    return mViewer->copyURLAction();
612 613
}

Laurent Montel's avatar
Laurent Montel committed
614
QAction *KMReaderWin::copyImageLocation() const
615
{
Laurent Montel's avatar
Laurent Montel committed
616
    return mViewer->copyImageLocation();
617 618
}

Laurent Montel's avatar
Laurent Montel committed
619
QAction *KMReaderWin::copyAction() const
Laurent Montel's avatar
Laurent Montel committed
620
{
Laurent Montel's avatar
Laurent Montel committed
621
    return mViewer->copyAction();
Laurent Montel's avatar
Laurent Montel committed
622
}
623

Laurent Montel's avatar
Laurent Montel committed
624
QAction *KMReaderWin::viewSourceAction() const
625
{
Laurent Montel's avatar
Laurent Montel committed
626
    return mViewer->viewSourceAction();
627 628
}

Laurent Montel's avatar
Laurent Montel committed
629
QAction *KMReaderWin::saveAsAction() const
630
{
Laurent Montel's avatar
Laurent Montel committed
631
    return mViewer->saveAsAction();
632 633
}

Laurent Montel's avatar
Laurent Montel committed
634
QAction *KMReaderWin::findInMessageAction() const
635
{
Laurent Montel's avatar
Laurent Montel committed
636
    return mViewer->findInMessageAction();
637 638
}

Laurent Montel's avatar
Laurent Montel committed
639
QAction *KMReaderWin::urlOpenAction() const
Laurent Montel's avatar
Laurent Montel committed
640
{
Laurent Montel's avatar
Laurent Montel committed
641
    return mViewer->urlOpenAction();
Laurent Montel's avatar
Laurent Montel committed
642
}
Laurent Montel's avatar
Laurent Montel committed
643 644 645 646 647 648 649 650 651 652

QAction *KMReaderWin::urlSaveAsAction() const
{
    return mUrlSaveAsAction;
}

QAction *KMReaderWin::addBookmarksAction() const
{
    return mAddBookmarksAction;
}
Laurent Montel's avatar
Laurent Montel committed
653 654
void KMReaderWin::setPrinting(bool enable)
{
Laurent Montel's avatar
Laurent Montel committed
655
    mViewer->setPrinting(enable);
Laurent Montel's avatar
Laurent Montel committed
656
}
657

Laurent Montel's avatar
Laurent Montel committed
658
QAction *KMReaderWin::speakTextAction() const
659
{
Laurent Montel's avatar
Laurent Montel committed
660
    return mViewer->speakTextAction();
661 662
}

Laurent Montel's avatar
Laurent Montel committed
663
QAction *KMReaderWin::downloadImageToDiskAction() const
664
{
Laurent Montel's avatar
Laurent Montel committed
665
    return mImageUrlSaveAsAction;
666 667
}

Laurent Montel's avatar
Laurent Montel committed
668
void KMReaderWin::clear(bool force)
Laurent Montel's avatar
Laurent Montel committed
669
{
670
    mViewer->clear(force ? MimeTreeParser::Force : MimeTreeParser::Delayed);
Laurent Montel's avatar
Laurent Montel committed
671 672
}

673
void KMReaderWin::setMessage(const Akonadi::Item &item, MimeTreeParser::UpdateMode updateMode)
674
{
Laurent Montel's avatar
Laurent Montel committed
675
    qCDebug(KMAIL_LOG) << Q_FUNC_INFO << parentWidget();
Laurent Montel's avatar
Laurent Montel committed
676
    mViewer->setMessageItem(item, updateMode);
677
}
Laurent Montel's avatar
Laurent Montel committed
678

Laurent Montel's avatar
Laurent Montel committed
679
void KMReaderWin::setMessage(const KMime::Message::Ptr &message)
680
{
Laurent Montel's avatar
Laurent Montel committed
681
    mViewer->setMessage(message);
682 683
}

Laurent Montel's avatar
Laurent Montel committed
684
QUrl KMReaderWin::urlClicked() const
Laurent Montel's avatar
Laurent Montel committed
685
{
Laurent Montel's avatar
Laurent Montel committed
686
    return mViewer->urlClicked();
Laurent Montel's avatar
Laurent Montel committed
687 688
}

Laurent Montel's avatar
Laurent Montel committed
689
QUrl KMReaderWin::imageUrlClicked() const
690
{
Laurent Montel's avatar
Laurent Montel committed
691
    return mViewer->imageUrlClicked();
692 693
}

Laurent Montel's avatar
Laurent Montel committed
694
void KMReaderWin::update(bool force)
695
{
696
    mViewer->update(force ? MimeTreeParser::Force : MimeTreeParser::Delayed);
697
}
Laurent Montel's avatar
Laurent Montel committed
698

Laurent Montel's avatar
Laurent Montel committed
699
void KMReaderWin::slotUrlClicked(const Akonadi::Item &item, const QUrl &url)
700
{
Laurent Montel's avatar
Laurent Montel committed
701
    if (item.isValid() && item.parentCollection().isValid()) {
Laurent Montel's avatar
Laurent Montel committed
702
        QSharedPointer<FolderCollection> fd = FolderCollection::forCollection(
Laurent Montel's avatar
Laurent Montel committed
703 704
                MailCommon::Util::updatedCollection(item.parentCollection()), false);
        KMail::Util::handleClickedURL(url, fd);
Laurent Montel's avatar
Laurent Montel committed
705 706 707
        return;
    }
    //No folder so we can't have identity and template.
Laurent Montel's avatar
Laurent Montel committed
708
    KMail::Util::handleClickedURL(url);
709 710
}

Laurent Montel's avatar
Laurent Montel committed
711
void KMReaderWin::slotShowReader(KMime::Content *msgPart, bool html, const QString &encoding)
Laurent Montel's avatar
Laurent Montel committed
712
{
713
    const MessageViewer::Viewer::DisplayFormatMessage format = html ? MessageViewer::Viewer::Html : MessageViewer::Viewer::Text;
Laurent Montel's avatar
Laurent Montel committed
714
    KMReaderMainWin *win = new KMReaderMainWin(msgPart, format, encoding);
Laurent Montel's avatar
Laurent Montel committed
715
    win->show();
Laurent Montel's avatar
Laurent Montel committed
716 717
}

Laurent Montel's avatar
Laurent Montel committed
718
void KMReaderWin::slotShowMessage(const KMime::Message::Ptr &message, const QString &encoding)
719
{
Laurent Montel's avatar
Laurent Montel committed
720
    KMReaderMainWin *win = new KMReaderMainWin();
Laurent Montel's avatar
Laurent Montel committed
721
    win->showMessage(encoding, message);
Laurent Montel's avatar
Laurent Montel committed
722
    win->show();
723 724
}

Laurent Montel's avatar
Laurent Montel committed
725
void KMReaderWin::slotDeleteMessage(const Akonadi::Item &item)
726
{
Laurent Montel's avatar
Laurent Montel committed
727
    if (!item.isValid()) {
Laurent Montel's avatar
Laurent Montel committed
728
        return;
Laurent Montel's avatar
Laurent Montel committed
729 730
    }
    KMTrashMsgCommand *command = new KMTrashMsgCommand(item.parentCollection(), item, -1);
Laurent Montel's avatar
Laurent Montel committed
731
    command->start();
732 733
}

734
bool KMReaderWin::printSelectedText(bool preview)
735
{
Laurent Montel's avatar
Laurent Montel committed
736
    const QString str = mViewer->selectedText();
Laurent Montel's avatar
Laurent Montel committed
737
    if (str.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
738
        return false;
Laurent Montel's avatar
Laurent Montel committed
739 740
    }
    ::MessageComposer::Composer *composer = new ::MessageComposer::Composer;
Laurent Montel's avatar
Laurent Montel committed
741 742 743 744
    composer->textPart()->setCleanPlainText(str);
    composer->textPart()->setWrappedPlainText(str);
    KMime::Message::Ptr messagePtr = message().payload<KMime::Message::Ptr>();
    composer->infoPart()->setFrom(messagePtr->from()->asUnicodeString());
Laurent Montel's avatar
Laurent Montel committed
745 746
    composer->infoPart()->setTo(QStringList() << messagePtr->to()->asUnicodeString());
    composer->infoPart()->setCc(QStringList() << messagePtr->cc()->asUnicodeString());
Laurent Montel's avatar
Laurent Montel committed
747
    composer->infoPart()->setSubject(messagePtr->subject()->asUnicodeString());
Laurent Montel's avatar
Laurent Montel committed
748
    composer->setProperty("preview", preview);
Laurent Montel's avatar
Laurent Montel committed
749
    connect(composer, &::MessageComposer::Composer::result, this, &KMReaderWin::slotPrintComposeResult);