Fix Bug 361605 - kmail crash on double click email
[kdepim.git] / kmail / kmreaderwin.cpp
blob55ddee6f655bc3228e73a5ab447fd6469e41d0d5
1 /*
2 This file is part of KMail, the KDE mail client.
3 Copyright (c) 1997 Markus Wuebben <markus.wuebben@kde.org>
4 Copyright (c) 2009-2016 Laurent Montel <montel@kde.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 // define this to copy all html that is written to the readerwindow to
22 // filehtmlwriter.out in the current working directory
23 #include "kmreaderwin.h"
25 #include "settings/kmailsettings.h"
26 #include "kmmainwidget.h"
27 #include "kmreadermainwin.h"
28 #include "mailcommon/mailkernel.h"
29 #include "dialog/addemailtoexistingcontactdialog.h"
30 #include "job/addemailtoexistingcontactjob.h"
32 #include "kdepim-version.h"
33 #include <KEmailAddress>
34 #include <Libkdepim/AddEmailAddressJob>
35 #include <Libkdepim/OpenEmailAddressJob>
36 #include <Libkdepim/AddEmailDisplayJob>
37 #include <Libkdepim/BroadcastStatus>
38 #include "kmcommands.h"
39 #include "MailCommon/SendMdnHandler"
40 #include <QVBoxLayout>
41 #include "messageviewer/headerstrategy.h"
42 #include "messageviewer/mailwebview.h"
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"
49 #include <QCryptographicHash>
50 #include <kmime/kmime_mdn.h>
51 #include <akonadi/kmime/messageflags.h>
53 #include "messageviewer/viewer.h"
54 using namespace MessageViewer;
55 #include <MessageCore/MessageCoreSettings>
57 #include "messageviewer/attachmentstrategy.h"
58 #include "MessageComposer/MessageSender"
59 #include "MessageComposer/MessageFactory"
60 #include "MessageComposer/Composer"
61 #include "MessageComposer/TextPart"
62 #include "MessageComposer/InfoPart"
64 #include <KIO/JobUiDelegate>
65 using MessageComposer::MessageFactory;
67 #include "messagecore/messagehelpers.h"
69 #include <Akonadi/Contact/ContactEditorDialog>
71 #include "kmail_debug.h"
72 #include <KLocalizedString>
73 #include <QAction>
74 #include <kcodecs.h>
75 #include <ktoggleaction.h>
76 #include <kservice.h>
77 #include <KActionCollection>
78 #include <KMessageBox>
79 #include <QMenu>
81 #include <QClipboard>
83 // X headers...
84 #undef Never
85 #undef Always
87 #include <unistd.h>
88 #include <stdlib.h>
89 #include <sys/stat.h>
90 #include <stdio.h>
91 #include <ctype.h>
92 #include <string.h>
93 #include <mailcommon/mailutil.h>
95 using namespace KMail;
96 using namespace MailCommon;
98 KMReaderWin::KMReaderWin(QWidget *aParent,
99 QWidget *mainWindow,
100 KActionCollection *actionCollection,
101 Qt::WindowFlags aFlags)
102 : QWidget(aParent, aFlags),
103 mMainWindow(mainWindow),
104 mActionCollection(actionCollection),
105 mMailToComposeAction(Q_NULLPTR),
106 mMailToReplyAction(Q_NULLPTR),
107 mMailToForwardAction(Q_NULLPTR),
108 mAddAddrBookAction(Q_NULLPTR),
109 mOpenAddrBookAction(Q_NULLPTR),
110 mUrlSaveAsAction(Q_NULLPTR),
111 mAddBookmarksAction(Q_NULLPTR),
112 mAddEmailToExistingContactAction(Q_NULLPTR)
114 createActions();
115 QVBoxLayout *vlay = new QVBoxLayout(this);
116 vlay->setMargin(0);
117 mViewer = new Viewer(this, mainWindow, mActionCollection);
118 mViewer->setExternalWindow(true);
119 mViewer->setAppName(QStringLiteral("KMail"));
120 connect(mViewer, SIGNAL(urlClicked(Akonadi::Item,QUrl)), this, SLOT(slotUrlClicked(Akonadi::Item,QUrl)));
121 connect(mViewer, &Viewer::requestConfigSync, kmkernel, &KMKernel::slotRequestConfigSync, Qt::QueuedConnection); // happens anyway on shutdown, so we can skip it there with using a queued connection
122 connect(mViewer, &Viewer::makeResourceOnline, kmkernel, &KMKernel::makeResourceOnline);
123 connect(mViewer, &MessageViewer::Viewer::showReader, this, &KMReaderWin::slotShowReader);
124 connect(mViewer, &MessageViewer::Viewer::showMessage, this, &KMReaderWin::slotShowMessage);
125 connect(mViewer, &MessageViewer::Viewer::showStatusBarMessage, this, &KMReaderWin::showStatusBarMessage);
126 connect(mViewer, SIGNAL(deleteMessage(Akonadi::Item)), this, SLOT(slotDeleteMessage(Akonadi::Item)));
128 mViewer->addMessageLoadedHandler(new MessageViewer::MarkMessageReadHandler(this));
129 mViewer->addMessageLoadedHandler(new MailCommon::SendMdnHandler(kmkernel, this));
131 vlay->addWidget(mViewer);
132 readConfig();
136 void KMReaderWin::createActions()
138 KActionCollection *ac = mActionCollection;
139 if (!ac) {
140 return;
143 // Message Menu
145 // new message to
146 mMailToComposeAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-message-new")),
147 i18n("New Message To..."), this);
148 ac->addAction(QStringLiteral("mail_new"), mMailToComposeAction);
149 ac->setShortcutsConfigurable(mMailToComposeAction, false);
150 connect(mMailToComposeAction, &QAction::triggered, this, &KMReaderWin::slotMailtoCompose);
152 // reply to
153 mMailToReplyAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-sender")),
154 i18n("Reply To..."), this);
155 ac->addAction(QStringLiteral("mailto_reply"), mMailToReplyAction);
156 ac->setShortcutsConfigurable(mMailToReplyAction, false);
157 connect(mMailToReplyAction, &QAction::triggered, this, &KMReaderWin::slotMailtoReply);
159 // forward to
160 mMailToForwardAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-forward")),
161 i18n("Forward To..."), this);
162 ac->setShortcutsConfigurable(mMailToForwardAction, false);
163 ac->addAction(QStringLiteral("mailto_forward"), mMailToForwardAction);
164 connect(mMailToForwardAction, &QAction::triggered, this, &KMReaderWin::slotMailtoForward);
166 // add to addressbook
167 mAddAddrBookAction = new QAction(QIcon::fromTheme(QStringLiteral("contact-new")),
168 i18n("Add to Address Book"), this);
169 ac->setShortcutsConfigurable(mAddAddrBookAction, false);
170 ac->addAction(QStringLiteral("add_addr_book"), mAddAddrBookAction);
171 connect(mAddAddrBookAction, &QAction::triggered, this, &KMReaderWin::slotMailtoAddAddrBook);
173 mAddEmailToExistingContactAction = new QAction(QIcon::fromTheme(QStringLiteral("contact-new")),
174 i18n("Add to Existing Contact"), this);
175 ac->setShortcutsConfigurable(mAddEmailToExistingContactAction, false);
176 ac->addAction(QStringLiteral("add_to_existing_contact"), mAddAddrBookAction);
177 connect(mAddEmailToExistingContactAction, &QAction::triggered, this, &KMReaderWin::slotMailToAddToExistingContact);
179 // open in addressbook
180 mOpenAddrBookAction = new QAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")),
181 i18n("Open in Address Book"), this);
182 ac->setShortcutsConfigurable(mOpenAddrBookAction, false);
183 ac->addAction(QStringLiteral("openin_addr_book"), mOpenAddrBookAction);
184 connect(mOpenAddrBookAction, &QAction::triggered, this, &KMReaderWin::slotMailtoOpenAddrBook);
185 // bookmark message
186 mAddBookmarksAction = new QAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), i18n("Bookmark This Link"), this);
187 ac->setShortcutsConfigurable(mAddBookmarksAction, false);
188 ac->addAction(QStringLiteral("add_bookmarks"), mAddBookmarksAction);
189 connect(mAddBookmarksAction, &QAction::triggered, this, &KMReaderWin::slotAddBookmarks);
191 mEditContactAction = new QAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")),
192 i18n("Edit contact..."), this);
193 ac->setShortcutsConfigurable(mEditContactAction, false);
194 ac->addAction(QStringLiteral("edit_contact"), mOpenAddrBookAction);
195 connect(mEditContactAction, &QAction::triggered, this, &KMReaderWin::slotEditContact);
197 // save URL as
198 mUrlSaveAsAction = new QAction(i18n("Save Link As..."), this);
199 ac->addAction(QStringLiteral("saveas_url"), mUrlSaveAsAction);
200 ac->setShortcutsConfigurable(mUrlSaveAsAction, false);
201 connect(mUrlSaveAsAction, &QAction::triggered, this, &KMReaderWin::slotUrlSave);
203 // find text
204 QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("edit-find")), i18n("&Find in Message..."), this);
205 ac->addAction(QStringLiteral("find_in_messages"), action);
206 connect(action, &QAction::triggered, this, &KMReaderWin::slotFind);
207 ac->setDefaultShortcut(action, KStandardShortcut::find().first());
209 // save Image On Disk
210 mImageUrlSaveAsAction = new QAction(i18n("Save Image On Disk..."), this);
211 ac->addAction(QStringLiteral("saveas_imageurl"), mImageUrlSaveAsAction);
212 ac->setShortcutsConfigurable(mImageUrlSaveAsAction, false);
213 connect(mImageUrlSaveAsAction, &QAction::triggered, this, &KMReaderWin::slotSaveImageOnDisk);
215 // View html options
216 mViewHtmlOptions = new QMenu(i18n("Show HTML Format"));
217 mViewAsHtml = new QAction(i18n("Show HTML format when mail comes from this contact"), mViewHtmlOptions);
218 ac->setShortcutsConfigurable(mViewAsHtml, false);
219 connect(mViewAsHtml, &QAction::triggered, this, &KMReaderWin::slotContactHtmlOptions);
220 mViewAsHtml->setCheckable(true);
221 mViewHtmlOptions->addAction(mViewAsHtml);
223 mLoadExternalReference = new QAction(i18n("Load external reference when mail comes for this contact"), mViewHtmlOptions);
224 ac->setShortcutsConfigurable(mLoadExternalReference, false);
225 connect(mLoadExternalReference, &QAction::triggered, this, &KMReaderWin::slotContactHtmlOptions);
226 mLoadExternalReference->setCheckable(true);
227 mViewHtmlOptions->addAction(mLoadExternalReference);
229 mShareImage = new QAction(i18n("Share image..."), this);
230 ac->addAction(QStringLiteral("share_imageurl"), mShareImage);
231 ac->setShortcutsConfigurable(mShareImage, false);
232 connect(mShareImage, &QAction::triggered, this, &KMReaderWin::slotShareImage);
236 void KMReaderWin::setUseFixedFont(bool useFixedFont)
238 mViewer->setUseFixedFont(useFixedFont);
241 bool KMReaderWin::isFixedFont() const
243 return mViewer->isFixedFont();
246 KMReaderWin::~KMReaderWin()
250 void KMReaderWin::readConfig(void)
252 mViewer->readConfig();
255 void KMReaderWin::setAttachmentStrategy(const AttachmentStrategy *strategy)
257 mViewer->setAttachmentStrategy(strategy);
260 void KMReaderWin::setOverrideEncoding(const QString &encoding)
262 mViewer->setOverrideEncoding(encoding);
265 void KMReaderWin::clearCache()
267 clear();
270 // enter items for the "Important changes" list here:
271 static const char *const kmailChanges[] = {
272 I18N_NOOP("KMail is now based on the Akonadi Personal Information Management framework, which brings many "
273 "changes all around.")
275 static const int numKMailChanges =
276 sizeof kmailChanges / sizeof * kmailChanges;
278 // enter items for the "new features" list here, so the main body of
279 // the welcome page can be left untouched (probably much easier for
280 // the translators). Note that the <li>...</li> tags are added
281 // automatically below:
282 static const char *const kmailNewFeatures[] = {
283 I18N_NOOP("Push email (IMAP IDLE)"),
284 I18N_NOOP("Improved virtual folders"),
285 I18N_NOOP("Improved searches"),
286 I18N_NOOP("Support for adding notes (annotations) to mails"),
287 I18N_NOOP("Tag folders"),
288 I18N_NOOP("Less GUI freezes, mail checks happen in the background")
290 static const int numKMailNewFeatures =
291 sizeof kmailNewFeatures / sizeof * kmailNewFeatures;
293 //static
294 QString KMReaderWin::newFeaturesMD5()
296 QByteArray str;
297 for (int i = 0; i < numKMailChanges; ++i) {
298 str += kmailChanges[i];
300 for (int i = 0; i < numKMailNewFeatures; ++i) {
301 str += kmailNewFeatures[i];
303 QCryptographicHash md5(QCryptographicHash::Md5);
304 md5.addData(str);
305 return QLatin1String(md5.result().toBase64());
308 void KMReaderWin::displaySplashPage(const QString &templateName, const QVariantHash &_data)
310 QVariantHash data = _data;
311 if (!data.contains(QStringLiteral("icon"))) {
312 data[QStringLiteral("icon")] = QStringLiteral("kmail");
314 if (!data.contains(QStringLiteral("name"))) {
315 data[QStringLiteral("name")] = i18n("KMail");
317 if (!data.contains(QStringLiteral("subtitle"))) {
318 data[QStringLiteral("subtitle")] = i18n("The KDE Mail Client");
321 mViewer->displaySplashPage(templateName, data);
324 void KMReaderWin::displayBusyPage()
326 displaySplashPage(QStringLiteral("status.html"), {
327 { QStringLiteral("title"), i18n("Retrieving Folder Contents") },
328 { QStringLiteral("subtext"), i18n("Please wait . . .") }
332 void KMReaderWin::displayOfflinePage()
334 displaySplashPage(QStringLiteral("status.html"), {
335 { QStringLiteral("title"), i18n("Offline") },
337 QStringLiteral("subtext"), i18n("KMail is currently in offline mode. "
338 "Click <a href=\"kmail:goOnline\">here</a> to go online . . .</p>")
343 void KMReaderWin::displayResourceOfflinePage()
345 displaySplashPage(QStringLiteral("status.html"), {
346 { QStringLiteral("title"), i18n("Offline") },
348 QStringLiteral("subtext"), i18n("Account is currently in offline mode. "
349 "Click <a href=\"kmail:goResourceOnline\">here</a> to go online . . .</p>")
354 void KMReaderWin::displayAboutPage()
356 QVariantHash data;
357 data[QStringLiteral("version")] = QStringLiteral(KDEPIM_VERSION);
358 data[QStringLiteral("firstStart")] = kmkernel->firstStart();
360 QVariantList features;
361 features.reserve(numKMailNewFeatures);
362 for (int i = 0; i < numKMailNewFeatures; ++i) {
363 features.push_back(i18n(kmailNewFeatures[i]));
365 data[QStringLiteral("newFeatures")] = features;
367 QVariantList changes;
368 changes.reserve(numKMailChanges);
369 for (int i = 0; i < numKMailChanges; ++i) {
370 features.push_back(i18n(kmailChanges[i]));
372 data[QStringLiteral("importantChanges")] = changes;
374 displaySplashPage(QStringLiteral("introduction_kmail.html"), data);
377 void KMReaderWin::slotFind()
379 mViewer->slotFind();
382 void KMReaderWin::slotCopySelectedText()
384 QString selection = mViewer->selectedText();
385 selection.replace(QChar::Nbsp, QLatin1Char(' '));
386 QApplication::clipboard()->setText(selection);
389 void KMReaderWin::setMsgPart(KMime::Content *aMsgPart)
391 mViewer->setMessagePart(aMsgPart);
394 QString KMReaderWin::copyText() const
396 return mViewer->selectedText();
399 MessageViewer::Viewer::DisplayFormatMessage KMReaderWin::displayFormatMessageOverwrite() const
401 return mViewer->displayFormatMessageOverwrite();
404 void KMReaderWin::setDisplayFormatMessageOverwrite(MessageViewer::Viewer::DisplayFormatMessage format)
406 mViewer->setDisplayFormatMessageOverwrite(format);
409 void KMReaderWin::setHtmlLoadExtOverride(bool Q_DECL_OVERRIDE)
411 mViewer->setHtmlLoadExtOverride(Q_DECL_OVERRIDE);
414 bool KMReaderWin::htmlMail() const
416 return mViewer->htmlMail();
419 bool KMReaderWin::htmlLoadExternal()
421 return mViewer->htmlLoadExternal();
424 Akonadi::Item KMReaderWin::message() const
426 return mViewer->messageItem();
429 void KMReaderWin::slotMailtoCompose()
431 KMCommand *command = new KMMailtoComposeCommand(urlClicked(), message());
432 command->start();
435 void KMReaderWin::slotMailtoForward()
437 KMCommand *command = new KMMailtoForwardCommand(mMainWindow, urlClicked(),
438 message());
439 command->start();
442 void KMReaderWin::slotMailtoAddAddrBook()
444 const QUrl url = urlClicked();
445 if (url.isEmpty()) {
446 return;
448 const QString emailString = KEmailAddress::decodeMailtoUrl(url);
450 KPIM::AddEmailAddressJob *job = new KPIM::AddEmailAddressJob(emailString, mMainWindow, this);
451 job->start();
454 void KMReaderWin::slotMailToAddToExistingContact()
456 const QUrl url = urlClicked();
457 if (url.isEmpty()) {
458 return;
460 const QString emailString = KEmailAddress::decodeMailtoUrl(url);
461 QPointer<AddEmailToExistingContactDialog> dlg = new AddEmailToExistingContactDialog(this);
462 if (dlg->exec()) {
463 Akonadi::Item item = dlg->selectedContact();
464 if (item.isValid()) {
465 AddEmailToExistingContactJob *job = new AddEmailToExistingContactJob(item, emailString, this);
466 job->start();
469 delete dlg;
472 void KMReaderWin::slotMailtoOpenAddrBook()
474 const QUrl url = urlClicked();
475 if (url.isEmpty()) {
476 return;
478 const QString emailString = KEmailAddress::decodeMailtoUrl(url).toLower();
480 KPIM::OpenEmailAddressJob *job = new KPIM::OpenEmailAddressJob(emailString, mMainWindow, this);
481 job->start();
484 void KMReaderWin::slotAddBookmarks()
486 const QUrl url = urlClicked();
487 if (url.isEmpty()) {
488 return;
490 KMCommand *command = new KMAddBookmarksCommand(url, this);
491 command->start();
494 void KMReaderWin::slotUrlSave()
496 const QUrl url = urlClicked();
497 if (url.isEmpty()) {
498 return;
500 KMCommand *command = new KMUrlSaveCommand(url, mMainWindow);
501 command->start();
504 void KMReaderWin::slotSaveImageOnDisk()
506 const QUrl url = imageUrlClicked();
507 if (url.isEmpty()) {
508 return;
510 KMCommand *command = new KMUrlSaveCommand(url, mMainWindow);
511 command->start();
514 void KMReaderWin::slotMailtoReply()
516 KMCommand *command = new KMMailtoReplyCommand(mMainWindow, urlClicked(),
517 message(), copyText());
518 command->start();
521 CSSHelper *KMReaderWin::cssHelper() const
523 return mViewer->cssHelper();
526 bool KMReaderWin::htmlLoadExtOverride() const
528 return mViewer->htmlLoadExtOverride();
530 void KMReaderWin::setDecryptMessageOverwrite(bool overwrite)
532 mViewer->setDecryptMessageOverwrite(overwrite);
534 const AttachmentStrategy *KMReaderWin::attachmentStrategy() const
536 return mViewer->attachmentStrategy();
539 QString KMReaderWin::overrideEncoding() const
541 return mViewer->overrideEncoding();
544 KToggleAction *KMReaderWin::toggleFixFontAction() const
546 return mViewer->toggleFixFontAction();
549 bool KMReaderWin::mimePartTreeIsEmpty() const
551 return mViewer->mimePartTreeIsEmpty();
554 QAction *KMReaderWin::toggleMimePartTreeAction() const
556 return mViewer->toggleMimePartTreeAction();
559 KActionMenu *KMReaderWin::shareServiceUrlMenu() const
561 return mViewer->shareServiceUrlMenu();
564 QList<QAction *> KMReaderWin::viewerPluginActionList(ViewerPluginInterface::SpecificFeatureTypes features)
566 return mViewer->viewerPluginActionList(features);
569 QAction *KMReaderWin::selectAllAction() const
571 return mViewer->selectAllAction();
574 QAction *KMReaderWin::copyURLAction() const
576 return mViewer->copyURLAction();
579 QAction *KMReaderWin::copyImageLocation() const
581 return mViewer->copyImageLocation();
584 QAction *KMReaderWin::copyAction() const
586 return mViewer->copyAction();
589 QAction *KMReaderWin::viewSourceAction() const
591 return mViewer->viewSourceAction();
594 QAction *KMReaderWin::saveAsAction() const
596 return mViewer->saveAsAction();
599 QAction *KMReaderWin::findInMessageAction() const
601 return mViewer->findInMessageAction();
604 QAction *KMReaderWin::urlOpenAction() const
606 return mViewer->urlOpenAction();
608 void KMReaderWin::setPrinting(bool enable)
610 mViewer->setPrinting(enable);
613 QAction *KMReaderWin::speakTextAction() const
615 return mViewer->speakTextAction();
618 QAction *KMReaderWin::downloadImageToDiskAction() const
620 return mImageUrlSaveAsAction;
623 void KMReaderWin::clear(bool force)
625 mViewer->clear(force ? Force : Delayed);
628 void KMReaderWin::setMessage(const Akonadi::Item &item, UpdateMode updateMode)
630 qCDebug(KMAIL_LOG) << Q_FUNC_INFO << parentWidget();
631 mViewer->setMessageItem(item, updateMode);
634 void KMReaderWin::setMessage(const KMime::Message::Ptr &message)
636 mViewer->setMessage(message);
639 QUrl KMReaderWin::urlClicked() const
641 return mViewer->urlClicked();
644 QUrl KMReaderWin::imageUrlClicked() const
646 return mViewer->imageUrlClicked();
649 void KMReaderWin::update(bool force)
651 mViewer->update(force ? Force : Delayed);
654 void KMReaderWin::slotUrlClicked(const Akonadi::Item &item, const QUrl &url)
656 if (item.isValid() && item.parentCollection().isValid()) {
657 QSharedPointer<FolderCollection> fd = FolderCollection::forCollection(
658 MailCommon::Util::updatedCollection(item.parentCollection()), false);
659 KMail::Util::handleClickedURL(url, fd);
660 return;
662 //No folder so we can't have identity and template.
663 KMail::Util::handleClickedURL(url);
666 void KMReaderWin::slotShowReader(KMime::Content *msgPart, bool html, const QString &encoding)
668 const MessageViewer::Viewer::DisplayFormatMessage format = html ? MessageViewer::Viewer::Html : MessageViewer::Viewer::Text;
669 KMReaderMainWin *win = new KMReaderMainWin(msgPart, format, encoding);
670 win->show();
673 void KMReaderWin::slotShowMessage(const KMime::Message::Ptr &message, const QString &encoding)
675 KMReaderMainWin *win = new KMReaderMainWin();
676 win->showMessage(encoding, message);
677 win->show();
680 void KMReaderWin::slotDeleteMessage(const Akonadi::Item &item)
682 if (!item.isValid()) {
683 return;
685 KMTrashMsgCommand *command = new KMTrashMsgCommand(item.parentCollection(), item, -1);
686 command->start();
689 bool KMReaderWin::printSelectedText(bool preview)
691 const QString str = mViewer->selectedText();
692 if (str.isEmpty()) {
693 return false;
695 ::MessageComposer::Composer *composer = new ::MessageComposer::Composer;
696 composer->textPart()->setCleanPlainText(str);
697 composer->textPart()->setWrappedPlainText(str);
698 KMime::Message::Ptr messagePtr = message().payload<KMime::Message::Ptr>();
699 composer->infoPart()->setFrom(messagePtr->from()->asUnicodeString());
700 composer->infoPart()->setTo(QStringList() << messagePtr->to()->asUnicodeString());
701 composer->infoPart()->setCc(QStringList() << messagePtr->cc()->asUnicodeString());
702 composer->infoPart()->setSubject(messagePtr->subject()->asUnicodeString());
703 composer->setProperty("preview", preview);
704 connect(composer, &::MessageComposer::Composer::result, this, &KMReaderWin::slotPrintComposeResult);
705 composer->start();
706 return true;
709 void KMReaderWin::slotPrintComposeResult(KJob *job)
711 const bool preview = job->property("preview").toBool();
712 ::MessageComposer::Composer *composer = dynamic_cast< ::MessageComposer::Composer * >(job);
713 Q_ASSERT(composer);
714 if (composer->error() == ::MessageComposer::Composer::NoError) {
716 Q_ASSERT(composer->resultMessages().size() == 1);
717 Akonadi::Item printItem;
718 printItem.setPayload<KMime::Message::Ptr>(composer->resultMessages().first());
719 Akonadi::MessageFlags::copyMessageFlags(*(composer->resultMessages().first()), printItem);
720 const bool useFixedFont = MessageViewer::MessageViewerSettings::self()->useFixedFont();
721 const QString overrideEncoding = MessageCore::MessageCoreSettings::self()->overrideCharacterEncoding();
723 KMPrintCommand *command = new KMPrintCommand(this, printItem, mViewer->headerStylePlugin(),
724 mViewer->displayFormatMessageOverwrite(), mViewer->htmlLoadExternal(), useFixedFont, overrideEncoding);
725 command->setPrintPreview(preview);
726 command->start();
727 } else {
728 if (static_cast<KIO::Job *>(job)->ui()) {
729 static_cast<KIO::Job *>(job)->ui()->showErrorMessage();
730 } else {
731 qCWarning(KMAIL_LOG) << "Composer for printing failed:" << composer->errorString();
736 void KMReaderWin::clearContactItem()
738 mSearchedContact = Akonadi::Item();
739 mSearchedAddress = KContacts::Addressee();
740 mLoadExternalReference->setChecked(false);
741 mViewAsHtml->setChecked(false);
744 void KMReaderWin::setContactItem(const Akonadi::Item &contact, const KContacts::Addressee &address)
746 mSearchedContact = contact;
747 mSearchedAddress = address;
748 updateHtmlActions();
751 void KMReaderWin::updateHtmlActions()
753 if (!mSearchedContact.isValid()) {
754 mLoadExternalReference->setChecked(false);
755 mViewAsHtml->setChecked(false);
756 } else {
757 const QStringList customs = mSearchedAddress.customs();
758 Q_FOREACH (const QString &custom, customs) {
759 if (custom.contains(QStringLiteral("MailPreferedFormatting"))) {
760 const QString value = mSearchedAddress.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailPreferedFormatting"));
761 mViewAsHtml->setChecked(value == QLatin1String("HTML"));
762 } else if (custom.contains(QStringLiteral("MailAllowToRemoteContent"))) {
763 const QString value = mSearchedAddress.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailAllowToRemoteContent"));
764 mLoadExternalReference->setChecked((value == QLatin1String("TRUE")));
770 void KMReaderWin::slotContactHtmlOptions()
772 const QUrl url = urlClicked();
773 if (url.isEmpty()) {
774 return;
776 const QString emailString = KEmailAddress::decodeMailtoUrl(url).toLower();
778 KPIM::AddEmailDiplayJob *job = new KPIM::AddEmailDiplayJob(emailString, mMainWindow, this);
779 job->setRemoteContent(mLoadExternalReference->isChecked());
780 job->setShowAsHTML(mViewAsHtml->isChecked());
781 job->setContact(mSearchedContact);
782 job->start();
785 void KMReaderWin::slotEditContact()
787 if (mSearchedContact.isValid()) {
788 QPointer<Akonadi::ContactEditorDialog> dlg =
789 new Akonadi::ContactEditorDialog(Akonadi::ContactEditorDialog::EditMode, this);
790 connect(dlg.data(), &Akonadi::ContactEditorDialog::contactStored, this, &KMReaderWin::contactStored);
791 connect(dlg.data(), &Akonadi::ContactEditorDialog::error, this, &KMReaderWin::slotContactEditorError);
792 dlg->setContact(mSearchedContact);
793 dlg->exec();
794 delete dlg;
798 void KMReaderWin::slotContactEditorError(const QString &error)
800 KMessageBox::error(this, i18n("Contact cannot be stored: %1", error), i18n("Failed to store contact"));
803 void KMReaderWin::contactStored(const Akonadi::Item &item)
805 Q_UNUSED(item);
806 KPIM::BroadcastStatus::instance()->setStatusMsg(i18n("Contact modified successfully"));
809 QAction *KMReaderWin::saveMessageDisplayFormatAction() const
811 return mViewer->saveMessageDisplayFormatAction();
814 QAction *KMReaderWin::resetMessageDisplayFormatAction() const
816 return mViewer->resetMessageDisplayFormatAction();
819 QAction *KMReaderWin::blockImage() const
821 return mViewer->blockImage();
824 bool KMReaderWin::adblockEnabled() const
826 return mViewer->adblockEnabled();
829 QAction *KMReaderWin::openBlockableItems() const
831 return mViewer->openBlockableItems();
834 void KMReaderWin::slotShareImage()
836 KMCommand *command = new KMShareImageCommand(imageUrlClicked(), this);
837 command->start();