You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
917 lines
29 KiB
917 lines
29 KiB
/* |
|
This file is part of KMail, the KDE mail client. |
|
Copyright (c) 1997 Markus Wuebben <markus.wuebben@kde.org> |
|
Copyright (c) 2009-2019 Laurent Montel <montel@kde.org> |
|
|
|
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. |
|
*/ |
|
|
|
// define this to copy all html that is written to the readerwindow to |
|
// filehtmlwriter.out in the current working directory |
|
#include "kmreaderwin.h" |
|
|
|
#include "settings/kmailsettings.h" |
|
#include "kmmainwidget.h" |
|
#include "kmreadermainwin.h" |
|
#include "mailcommon/mailkernel.h" |
|
#include "dialog/addemailtoexistingcontactdialog.h" |
|
#include "job/addemailtoexistingcontactjob.h" |
|
|
|
#include "kmail-version.h" |
|
#include <KEmailAddress> |
|
#include <LibkdepimAkonadi/AddEmailAddressJob> |
|
#include <LibkdepimAkonadi/OpenEmailAddressJob> |
|
#include <LibkdepimAkonadi/AddEmailDisplayJob> |
|
#include <Libkdepim/BroadcastStatus> |
|
#include "kmcommands.h" |
|
#include "MailCommon/SendMdnHandler" |
|
#include <QVBoxLayout> |
|
#include "messageviewer/headerstrategy.h" |
|
#include "messageviewer/markmessagereadhandler.h" |
|
#include "messageviewer/messageviewersettings.h" |
|
#include <MessageViewer/CSSHelper> |
|
using MessageViewer::CSSHelper; |
|
#include "util.h" |
|
#include <MessageCore/StringUtil> |
|
#include <QCryptographicHash> |
|
#include <kmime/kmime_mdn.h> |
|
#include <akonadi/kmime/messageflags.h> |
|
|
|
#include "messageviewer/viewer.h" |
|
using namespace MessageViewer; |
|
#include <MessageCore/MessageCoreSettings> |
|
|
|
#include <MessageViewer/AttachmentStrategy> |
|
#include <MessageComposer/MessageSender> |
|
#include "MessageComposer/Composer" |
|
#include "MessageComposer/TextPart" |
|
#include "MessageComposer/InfoPart" |
|
|
|
#include <KIO/JobUiDelegate> |
|
|
|
#include <Akonadi/Contact/ContactEditorDialog> |
|
|
|
#include "kmail_debug.h" |
|
#include <KLocalizedString> |
|
#include <QAction> |
|
#include <KCodecs> |
|
#include <KToggleAction> |
|
#include <KService> |
|
#include <KActionCollection> |
|
#include <KMessageBox> |
|
#include <QMenu> |
|
|
|
#include <QClipboard> |
|
|
|
// X headers... |
|
#undef Never |
|
#undef Always |
|
|
|
#include <mailcommon/mailutil.h> |
|
|
|
using namespace KMail; |
|
using namespace MailCommon; |
|
|
|
KMReaderWin::KMReaderWin(QWidget *aParent, QWidget *mainWindow, KActionCollection *actionCollection) |
|
: QWidget(aParent) |
|
, mMainWindow(mainWindow) |
|
, mActionCollection(actionCollection) |
|
{ |
|
createActions(); |
|
QVBoxLayout *vlay = new QVBoxLayout(this); |
|
vlay->setContentsMargins(0, 4, 0, 0); |
|
mViewer = new Viewer(this, mainWindow, mActionCollection); |
|
connect(mViewer, qOverload<const Akonadi::Item &, const QUrl &>(&Viewer::urlClicked), this, &KMReaderWin::slotUrlClicked); |
|
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); |
|
connect(mViewer, &MessageViewer::Viewer::showReader, this, &KMReaderWin::slotShowReader); |
|
connect(mViewer, &MessageViewer::Viewer::showMessage, this, &KMReaderWin::slotShowMessage); |
|
connect(mViewer, &MessageViewer::Viewer::showStatusBarMessage, this, &KMReaderWin::showStatusBarMessage); |
|
connect(mViewer, &MessageViewer::Viewer::printingFinished, this, &KMReaderWin::slotPrintingFinished); |
|
connect(mViewer, &MessageViewer::Viewer::zoomChanged, this, &KMReaderWin::zoomChanged); |
|
connect(mViewer, qOverload<const Akonadi::Item &>(&Viewer::deleteMessage), this, &KMReaderWin::slotDeleteMessage); |
|
connect(mViewer, &MessageViewer::Viewer::showNextMessage, this, &KMReaderWin::showNextMessage); |
|
connect(mViewer, &MessageViewer::Viewer::showPreviousMessage, this, &KMReaderWin::showPreviousMessage); |
|
|
|
mViewer->addMessageLoadedHandler(new MessageViewer::MarkMessageReadHandler(this)); |
|
mViewer->addMessageLoadedHandler(new MailCommon::SendMdnHandler(kmkernel, this)); |
|
|
|
vlay->addWidget(mViewer); |
|
readConfig(); |
|
} |
|
|
|
void KMReaderWin::createActions() |
|
{ |
|
KActionCollection *ac = mActionCollection; |
|
if (!ac) { |
|
return; |
|
} |
|
// |
|
// Message Menu |
|
// |
|
// new message to |
|
mMailToComposeAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-message-new")), |
|
i18n("New Message To..."), this); |
|
ac->addAction(QStringLiteral("mail_new"), mMailToComposeAction); |
|
ac->setShortcutsConfigurable(mMailToComposeAction, false); |
|
connect(mMailToComposeAction, &QAction::triggered, this, &KMReaderWin::slotMailtoCompose); |
|
|
|
// reply to |
|
mMailToReplyAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-sender")), |
|
i18n("Reply To..."), this); |
|
ac->addAction(QStringLiteral("mailto_reply"), mMailToReplyAction); |
|
ac->setShortcutsConfigurable(mMailToReplyAction, false); |
|
connect(mMailToReplyAction, &QAction::triggered, this, &KMReaderWin::slotMailtoReply); |
|
|
|
// forward to |
|
mMailToForwardAction = new QAction(QIcon::fromTheme(QStringLiteral("mail-forward")), |
|
i18n("Forward To..."), this); |
|
ac->setShortcutsConfigurable(mMailToForwardAction, false); |
|
ac->addAction(QStringLiteral("mailto_forward"), mMailToForwardAction); |
|
connect(mMailToForwardAction, &QAction::triggered, this, &KMReaderWin::slotMailtoForward); |
|
|
|
// add to addressbook |
|
mAddAddrBookAction = new QAction(QIcon::fromTheme(QStringLiteral("contact-new")), |
|
i18n("Add to Address Book"), this); |
|
ac->setShortcutsConfigurable(mAddAddrBookAction, false); |
|
ac->addAction(QStringLiteral("add_addr_book"), mAddAddrBookAction); |
|
connect(mAddAddrBookAction, &QAction::triggered, this, &KMReaderWin::slotMailtoAddAddrBook); |
|
|
|
mAddEmailToExistingContactAction = new QAction(QIcon::fromTheme(QStringLiteral("contact-new")), |
|
i18n("Add to Existing Contact"), this); |
|
ac->setShortcutsConfigurable(mAddEmailToExistingContactAction, false); |
|
ac->addAction(QStringLiteral("add_to_existing_contact"), mAddAddrBookAction); |
|
connect(mAddEmailToExistingContactAction, &QAction::triggered, this, &KMReaderWin::slotMailToAddToExistingContact); |
|
|
|
// open in addressbook |
|
mOpenAddrBookAction = new QAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")), |
|
i18n("Open in Address Book"), this); |
|
ac->setShortcutsConfigurable(mOpenAddrBookAction, false); |
|
ac->addAction(QStringLiteral("openin_addr_book"), mOpenAddrBookAction); |
|
connect(mOpenAddrBookAction, &QAction::triggered, this, &KMReaderWin::slotMailtoOpenAddrBook); |
|
// bookmark message |
|
mAddBookmarksAction = new QAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), i18n("Bookmark This Link"), this); |
|
ac->setShortcutsConfigurable(mAddBookmarksAction, false); |
|
ac->addAction(QStringLiteral("add_bookmarks"), mAddBookmarksAction); |
|
connect(mAddBookmarksAction, &QAction::triggered, this, &KMReaderWin::slotAddBookmarks); |
|
|
|
mEditContactAction = new QAction(QIcon::fromTheme(QStringLiteral("view-pim-contacts")), |
|
i18n("Edit contact..."), this); |
|
ac->setShortcutsConfigurable(mEditContactAction, false); |
|
ac->addAction(QStringLiteral("edit_contact"), mOpenAddrBookAction); |
|
connect(mEditContactAction, &QAction::triggered, this, &KMReaderWin::slotEditContact); |
|
|
|
// save URL as |
|
mUrlSaveAsAction = new QAction(i18n("Save Link As..."), this); |
|
ac->addAction(QStringLiteral("saveas_url"), mUrlSaveAsAction); |
|
ac->setShortcutsConfigurable(mUrlSaveAsAction, false); |
|
connect(mUrlSaveAsAction, &QAction::triggered, this, &KMReaderWin::slotUrlSave); |
|
|
|
// find text |
|
QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("edit-find")), i18n("&Find in Message..."), this); |
|
ac->addAction(QStringLiteral("find_in_messages"), action); |
|
connect(action, &QAction::triggered, this, &KMReaderWin::slotFind); |
|
ac->setDefaultShortcut(action, KStandardShortcut::find().first()); |
|
|
|
// save Image On Disk |
|
mImageUrlSaveAsAction = new QAction(i18n("Save Image On Disk..."), this); |
|
ac->addAction(QStringLiteral("saveas_imageurl"), mImageUrlSaveAsAction); |
|
ac->setShortcutsConfigurable(mImageUrlSaveAsAction, false); |
|
connect(mImageUrlSaveAsAction, &QAction::triggered, this, &KMReaderWin::slotSaveImageOnDisk); |
|
|
|
// View html options |
|
mViewHtmlOptions = new QMenu(i18n("Show HTML Format"), this); |
|
mViewAsHtml = new QAction(i18n("Show HTML format when mail comes from this contact"), mViewHtmlOptions); |
|
ac->setShortcutsConfigurable(mViewAsHtml, false); |
|
connect(mViewAsHtml, &QAction::triggered, this, &KMReaderWin::slotContactHtmlOptions); |
|
mViewAsHtml->setCheckable(true); |
|
mViewHtmlOptions->addAction(mViewAsHtml); |
|
|
|
mLoadExternalReference = new QAction(i18n("Load external reference when mail comes for this contact"), mViewHtmlOptions); |
|
ac->setShortcutsConfigurable(mLoadExternalReference, false); |
|
connect(mLoadExternalReference, &QAction::triggered, this, &KMReaderWin::slotContactHtmlOptions); |
|
mLoadExternalReference->setCheckable(true); |
|
mViewHtmlOptions->addAction(mLoadExternalReference); |
|
|
|
mShareImage = new QAction(i18n("Share image..."), this); |
|
ac->addAction(QStringLiteral("share_imageurl"), mShareImage); |
|
ac->setShortcutsConfigurable(mShareImage, false); |
|
connect(mShareImage, &QAction::triggered, this, &KMReaderWin::slotShareImage); |
|
} |
|
|
|
void KMReaderWin::setUseFixedFont(bool useFixedFont) |
|
{ |
|
mViewer->setUseFixedFont(useFixedFont); |
|
} |
|
|
|
Viewer *KMReaderWin::viewer() const |
|
{ |
|
return mViewer; |
|
} |
|
|
|
bool KMReaderWin::isFixedFont() const |
|
{ |
|
return mViewer->isFixedFont(); |
|
} |
|
|
|
KMReaderWin::~KMReaderWin() |
|
{ |
|
} |
|
|
|
void KMReaderWin::readConfig() |
|
{ |
|
mViewer->readConfig(); |
|
} |
|
|
|
void KMReaderWin::setAttachmentStrategy(const MessageViewer::AttachmentStrategy *strategy) |
|
{ |
|
mViewer->setAttachmentStrategy(strategy); |
|
} |
|
|
|
void KMReaderWin::setOverrideEncoding(const QString &encoding) |
|
{ |
|
mViewer->setOverrideEncoding(encoding); |
|
} |
|
|
|
void KMReaderWin::clearCache() |
|
{ |
|
clear(); |
|
} |
|
|
|
void KMReaderWin::updateShowMultiMessagesButton(bool enablePreviousButton, bool enableNextButton) |
|
{ |
|
mViewer->updateShowMultiMessagesButton(enablePreviousButton, enableNextButton); |
|
} |
|
|
|
void KMReaderWin::hasMultiMessages(bool multi) |
|
{ |
|
mViewer->hasMultiMessages(multi); |
|
} |
|
|
|
// enter items for the "Important changes" list here: |
|
static const char *const kmailChanges[] = { |
|
I18N_NOOP("KMail is now based on the Akonadi Personal Information Management framework, which brings many " |
|
"changes all around.") |
|
}; |
|
static const int numKMailChanges |
|
= sizeof kmailChanges / sizeof *kmailChanges; |
|
|
|
// 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: |
|
static const char *const kmailNewFeatures[] = { |
|
I18N_NOOP("Push email (IMAP IDLE)"), |
|
I18N_NOOP("Improved searches"), |
|
I18N_NOOP("Support for adding notes (annotations) to mails"), |
|
I18N_NOOP("Less GUI freezes, mail checks happen in the background"), |
|
I18N_NOOP("Plugins support"), |
|
I18N_NOOP("New HTML renderer (QtWebEngine)"), |
|
I18N_NOOP("Added Check for Phishing URL"), |
|
}; |
|
static const int numKMailNewFeatures |
|
= sizeof kmailNewFeatures / sizeof *kmailNewFeatures; |
|
|
|
//static |
|
QString KMReaderWin::newFeaturesMD5() |
|
{ |
|
QByteArray str; |
|
for (int i = 0; i < numKMailChanges; ++i) { |
|
str += kmailChanges[i]; |
|
} |
|
for (int i = 0; i < numKMailNewFeatures; ++i) { |
|
str += kmailNewFeatures[i]; |
|
} |
|
QCryptographicHash md5(QCryptographicHash::Md5); |
|
md5.addData(str); |
|
return QLatin1String(md5.result().toBase64()); |
|
} |
|
|
|
void KMReaderWin::displaySplashPage(const QString &templateName, const QVariantHash &_data) |
|
{ |
|
QVariantHash data = _data; |
|
if (!data.contains(QLatin1String("icon"))) { |
|
data[QStringLiteral("icon")] = QStringLiteral("kmail"); |
|
} |
|
if (!data.contains(QLatin1String("name"))) { |
|
data[QStringLiteral("name")] = i18n("KMail"); |
|
} |
|
if (!data.contains(QLatin1String("subtitle"))) { |
|
data[QStringLiteral("subtitle")] = i18n("The KDE Mail Client"); |
|
} |
|
|
|
mViewer->displaySplashPage(templateName, data, QByteArrayLiteral("kmail")); |
|
} |
|
|
|
void KMReaderWin::displayBusyPage() |
|
{ |
|
displaySplashPage(QStringLiteral("status.html"), { |
|
{ QStringLiteral("title"), i18n("Retrieving Folder Contents") }, |
|
{ QStringLiteral("subtext"), i18n("Please wait . . .") } |
|
}); |
|
} |
|
|
|
void KMReaderWin::displayOfflinePage() |
|
{ |
|
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>") |
|
} |
|
}); |
|
} |
|
|
|
void KMReaderWin::displayResourceOfflinePage() |
|
{ |
|
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>") |
|
} |
|
}); |
|
} |
|
|
|
void KMReaderWin::displayAboutPage() |
|
{ |
|
QVariantHash data; |
|
data[QStringLiteral("version")] = QStringLiteral(KDEPIM_VERSION); |
|
data[QStringLiteral("firstStart")] = kmkernel->firstStart(); |
|
|
|
QVariantList features; |
|
features.reserve(numKMailNewFeatures); |
|
for (int i = 0; i < numKMailNewFeatures; ++i) { |
|
features.push_back(i18n(kmailNewFeatures[i])); |
|
} |
|
data[QStringLiteral("newFeatures")] = features; |
|
|
|
QVariantList changes; |
|
changes.reserve(numKMailChanges); |
|
for (int i = 0; i < numKMailChanges; ++i) { |
|
features.push_back(i18n(kmailChanges[i])); |
|
} |
|
data[QStringLiteral("importantChanges")] = changes; |
|
|
|
displaySplashPage(QStringLiteral(":/about/introduction_kmail.html"), data); |
|
} |
|
|
|
void KMReaderWin::slotFind() |
|
{ |
|
mViewer->slotFind(); |
|
} |
|
|
|
void KMReaderWin::slotCopySelectedText() |
|
{ |
|
QString selection = mViewer->selectedText(); |
|
selection.replace(QChar::Nbsp, QLatin1Char(' ')); |
|
QApplication::clipboard()->setText(selection); |
|
} |
|
|
|
void KMReaderWin::setMsgPart(KMime::Content *aMsgPart) |
|
{ |
|
mViewer->setMessagePart(aMsgPart); |
|
} |
|
|
|
QString KMReaderWin::copyText() const |
|
{ |
|
return mViewer->selectedText(); |
|
} |
|
|
|
MessageViewer::Viewer::DisplayFormatMessage KMReaderWin::displayFormatMessageOverwrite() const |
|
{ |
|
return mViewer->displayFormatMessageOverwrite(); |
|
} |
|
|
|
void KMReaderWin::setPrintElementBackground(bool printElementBackground) |
|
{ |
|
mViewer->setPrintElementBackground(printElementBackground); |
|
} |
|
|
|
void KMReaderWin::setDisplayFormatMessageOverwrite(MessageViewer::Viewer::DisplayFormatMessage format) |
|
{ |
|
mViewer->setDisplayFormatMessageOverwrite(format); |
|
} |
|
|
|
void KMReaderWin::setHtmlLoadExtDefault(bool loadExtDefault) |
|
{ |
|
mViewer->setHtmlLoadExtDefault(loadExtDefault); |
|
} |
|
|
|
void KMReaderWin::setHtmlLoadExtOverride(bool loadExtOverride) |
|
{ |
|
mViewer->setHtmlLoadExtOverride(loadExtOverride); |
|
} |
|
|
|
bool KMReaderWin::htmlMail() const |
|
{ |
|
return mViewer->htmlMail(); |
|
} |
|
|
|
bool KMReaderWin::htmlLoadExternal() |
|
{ |
|
return mViewer->htmlLoadExternal(); |
|
} |
|
|
|
Akonadi::Item KMReaderWin::message() const |
|
{ |
|
return mViewer->messageItem(); |
|
} |
|
|
|
QWidget *KMReaderWin::mainWindow() const |
|
{ |
|
return mMainWindow; |
|
} |
|
|
|
void KMReaderWin::slotMailtoCompose() |
|
{ |
|
KMCommand *command = new KMMailtoComposeCommand(urlClicked(), message()); |
|
command->start(); |
|
} |
|
|
|
void KMReaderWin::slotMailtoForward() |
|
{ |
|
KMCommand *command = new KMMailtoForwardCommand(mMainWindow, urlClicked(), |
|
message()); |
|
command->start(); |
|
} |
|
|
|
void KMReaderWin::slotMailtoAddAddrBook() |
|
{ |
|
const QUrl url = urlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
const QString emailString = KEmailAddress::decodeMailtoUrl(url); |
|
|
|
KPIM::AddEmailAddressJob *job = new KPIM::AddEmailAddressJob(emailString, mMainWindow, this); |
|
job->start(); |
|
} |
|
|
|
void KMReaderWin::slotMailToAddToExistingContact() |
|
{ |
|
const QUrl url = urlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
const QString emailString = KEmailAddress::decodeMailtoUrl(url); |
|
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; |
|
} |
|
|
|
void KMReaderWin::slotMailtoOpenAddrBook() |
|
{ |
|
const QUrl url = urlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
const QString emailString = KEmailAddress::decodeMailtoUrl(url).toLower(); |
|
|
|
KPIM::OpenEmailAddressJob *job = new KPIM::OpenEmailAddressJob(emailString, mMainWindow, this); |
|
job->start(); |
|
} |
|
|
|
void KMReaderWin::slotAddBookmarks() |
|
{ |
|
const QUrl url = urlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
KMCommand *command = new KMAddBookmarksCommand(url, this); |
|
command->start(); |
|
} |
|
|
|
void KMReaderWin::slotUrlSave() |
|
{ |
|
const QUrl url = urlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
KMCommand *command = new KMUrlSaveCommand(url, mMainWindow); |
|
command->start(); |
|
} |
|
|
|
void KMReaderWin::slotSaveImageOnDisk() |
|
{ |
|
const QUrl url = imageUrlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
KMCommand *command = new KMUrlSaveCommand(url, mMainWindow); |
|
command->start(); |
|
} |
|
|
|
void KMReaderWin::slotMailtoReply() |
|
{ |
|
KMCommand *command = new KMMailtoReplyCommand(mMainWindow, urlClicked(), |
|
message(), copyText()); |
|
command->start(); |
|
} |
|
|
|
CSSHelper *KMReaderWin::cssHelper() const |
|
{ |
|
return mViewer->cssHelper(); |
|
} |
|
|
|
bool KMReaderWin::htmlLoadExtOverride() const |
|
{ |
|
return mViewer->htmlLoadExtOverride(); |
|
} |
|
|
|
void KMReaderWin::setDecryptMessageOverwrite(bool overwrite) |
|
{ |
|
mViewer->setDecryptMessageOverwrite(overwrite); |
|
} |
|
|
|
const MessageViewer::AttachmentStrategy *KMReaderWin::attachmentStrategy() const |
|
{ |
|
return mViewer->attachmentStrategy(); |
|
} |
|
|
|
QString KMReaderWin::overrideEncoding() const |
|
{ |
|
return mViewer->overrideEncoding(); |
|
} |
|
|
|
KToggleAction *KMReaderWin::toggleFixFontAction() const |
|
{ |
|
return mViewer->toggleFixFontAction(); |
|
} |
|
|
|
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; |
|
} |
|
|
|
bool KMReaderWin::mimePartTreeIsEmpty() const |
|
{ |
|
return mViewer->mimePartTreeIsEmpty(); |
|
} |
|
|
|
QAction *KMReaderWin::toggleMimePartTreeAction() const |
|
{ |
|
return mViewer->toggleMimePartTreeAction(); |
|
} |
|
|
|
KActionMenu *KMReaderWin::shareServiceUrlMenu() const |
|
{ |
|
return mViewer->shareServiceUrlMenu(); |
|
} |
|
|
|
#ifdef USE_DKIM_CHECKER |
|
DKIMViewerMenu *KMReaderWin::dkimViewerMenu() |
|
{ |
|
return mViewer->dkimViewerMenu(); |
|
} |
|
#endif |
|
|
|
QList<QAction *> KMReaderWin::viewerPluginActionList(ViewerPluginInterface::SpecificFeatureTypes features) |
|
{ |
|
return mViewer->viewerPluginActionList(features); |
|
} |
|
|
|
QAction *KMReaderWin::selectAllAction() const |
|
{ |
|
return mViewer->selectAllAction(); |
|
} |
|
|
|
QAction *KMReaderWin::copyURLAction() const |
|
{ |
|
return mViewer->copyURLAction(); |
|
} |
|
|
|
QAction *KMReaderWin::copyImageLocation() const |
|
{ |
|
return mViewer->copyImageLocation(); |
|
} |
|
|
|
QAction *KMReaderWin::copyAction() const |
|
{ |
|
return mViewer->copyAction(); |
|
} |
|
|
|
QAction *KMReaderWin::viewSourceAction() const |
|
{ |
|
return mViewer->viewSourceAction(); |
|
} |
|
|
|
QAction *KMReaderWin::saveAsAction() const |
|
{ |
|
return mViewer->saveAsAction(); |
|
} |
|
|
|
QAction *KMReaderWin::findInMessageAction() const |
|
{ |
|
return mViewer->findInMessageAction(); |
|
} |
|
|
|
QAction *KMReaderWin::urlOpenAction() const |
|
{ |
|
return mViewer->urlOpenAction(); |
|
} |
|
|
|
QAction *KMReaderWin::urlSaveAsAction() const |
|
{ |
|
return mUrlSaveAsAction; |
|
} |
|
|
|
QAction *KMReaderWin::addBookmarksAction() const |
|
{ |
|
return mAddBookmarksAction; |
|
} |
|
|
|
void KMReaderWin::setPrinting(bool enable) |
|
{ |
|
mViewer->setPrinting(enable); |
|
} |
|
|
|
QAction *KMReaderWin::speakTextAction() const |
|
{ |
|
return mViewer->speakTextAction(); |
|
} |
|
|
|
QAction *KMReaderWin::downloadImageToDiskAction() const |
|
{ |
|
return mImageUrlSaveAsAction; |
|
} |
|
|
|
void KMReaderWin::clear(bool force) |
|
{ |
|
mViewer->clear(force ? MimeTreeParser::Force : MimeTreeParser::Delayed); |
|
} |
|
|
|
void KMReaderWin::setMessage(const Akonadi::Item &item, MimeTreeParser::UpdateMode updateMode) |
|
{ |
|
qCDebug(KMAIL_LOG) << Q_FUNC_INFO << parentWidget(); |
|
mViewer->setMessageItem(item, updateMode); |
|
} |
|
|
|
void KMReaderWin::setMessage(const KMime::Message::Ptr &message) |
|
{ |
|
mViewer->setMessage(message); |
|
} |
|
|
|
QUrl KMReaderWin::urlClicked() const |
|
{ |
|
return mViewer->urlClicked(); |
|
} |
|
|
|
QUrl KMReaderWin::imageUrlClicked() const |
|
{ |
|
return mViewer->imageUrlClicked(); |
|
} |
|
|
|
void KMReaderWin::update(bool force) |
|
{ |
|
mViewer->update(force ? MimeTreeParser::Force : MimeTreeParser::Delayed); |
|
} |
|
|
|
void KMReaderWin::slotUrlClicked(const Akonadi::Item &item, const QUrl &url) |
|
{ |
|
if (item.isValid() && item.parentCollection().isValid()) { |
|
const auto col = CommonKernel->collectionFromId(item.parentCollection().id()); |
|
QSharedPointer<FolderSettings> fd = FolderSettings::forCollection(col, false); |
|
KMail::Util::handleClickedURL(url, fd, item.parentCollection()); |
|
return; |
|
} |
|
//No folder so we can't have identity and template. |
|
KMail::Util::handleClickedURL(url); |
|
} |
|
|
|
void KMReaderWin::slotShowReader(KMime::Content *msgPart, bool html, const QString &encoding) |
|
{ |
|
const MessageViewer::Viewer::DisplayFormatMessage format = html ? MessageViewer::Viewer::Html : MessageViewer::Viewer::Text; |
|
KMReaderMainWin *win = new KMReaderMainWin(msgPart, format, encoding); |
|
win->show(); |
|
} |
|
|
|
void KMReaderWin::slotShowMessage(const KMime::Message::Ptr &message, const QString &encoding) |
|
{ |
|
KMReaderMainWin *win = new KMReaderMainWin(); |
|
win->showMessage(encoding, message); |
|
win->show(); |
|
} |
|
|
|
void KMReaderWin::slotDeleteMessage(const Akonadi::Item &item) |
|
{ |
|
if (!item.isValid()) { |
|
return; |
|
} |
|
KMTrashMsgCommand *command = new KMTrashMsgCommand(item.parentCollection(), item, -1); |
|
command->start(); |
|
} |
|
|
|
bool KMReaderWin::printSelectedText(bool preview) |
|
{ |
|
const QString str = mViewer->selectedText(); |
|
if (str.isEmpty()) { |
|
return false; |
|
} |
|
::MessageComposer::Composer *composer = new ::MessageComposer::Composer; |
|
composer->textPart()->setCleanPlainText(str); |
|
composer->textPart()->setWrappedPlainText(str); |
|
KMime::Message::Ptr messagePtr = message().payload<KMime::Message::Ptr>(); |
|
composer->infoPart()->setFrom(messagePtr->from()->asUnicodeString()); |
|
composer->infoPart()->setTo(QStringList() << messagePtr->to()->asUnicodeString()); |
|
composer->infoPart()->setCc(QStringList() << messagePtr->cc()->asUnicodeString()); |
|
composer->infoPart()->setSubject(messagePtr->subject()->asUnicodeString()); |
|
composer->setProperty("preview", preview); |
|
connect(composer, &::MessageComposer::Composer::result, this, &KMReaderWin::slotPrintComposeResult); |
|
composer->start(); |
|
return true; |
|
} |
|
|
|
void KMReaderWin::slotPrintComposeResult(KJob *job) |
|
{ |
|
const bool preview = job->property("preview").toBool(); |
|
::MessageComposer::Composer *composer = dynamic_cast< ::MessageComposer::Composer * >(job); |
|
Q_ASSERT(composer); |
|
if (composer->error() == ::MessageComposer::Composer::NoError) { |
|
Q_ASSERT(composer->resultMessages().size() == 1); |
|
Akonadi::Item printItem; |
|
printItem.setPayload<KMime::Message::Ptr>(composer->resultMessages().constFirst()); |
|
Akonadi::MessageFlags::copyMessageFlags(*(composer->resultMessages().constFirst()), printItem); |
|
const bool useFixedFont = MessageViewer::MessageViewerSettings::self()->useFixedFont(); |
|
const QString overrideEncoding = MessageCore::MessageCoreSettings::self()->overrideCharacterEncoding(); |
|
|
|
KMPrintCommandInfo commandInfo; |
|
commandInfo.mMsg = printItem; |
|
commandInfo.mHeaderStylePlugin = mViewer->headerStylePlugin(); |
|
commandInfo.mFormat = mViewer->displayFormatMessageOverwrite(); |
|
commandInfo.mHtmlLoadExtOverride = mViewer->htmlLoadExternal(); |
|
commandInfo.mPrintPreview = preview; |
|
commandInfo.mUseFixedFont = useFixedFont; |
|
commandInfo.mOverrideFont = overrideEncoding; |
|
commandInfo.mShowSignatureDetails = mViewer->showSignatureDetails() || MessageViewer::MessageViewerSettings::self()->alwaysShowEncryptionSignatureDetails(); |
|
commandInfo.mShowEncryptionDetails = mViewer->showEncryptionDetails() || MessageViewer::MessageViewerSettings::self()->alwaysShowEncryptionSignatureDetails(); |
|
|
|
KMPrintCommand *command = new KMPrintCommand(this, commandInfo); |
|
command->start(); |
|
} else { |
|
if (static_cast<KIO::Job *>(job)->uiDelegate()) { |
|
static_cast<KIO::Job *>(job)->uiDelegate()->showErrorMessage(); |
|
} else { |
|
qCWarning(KMAIL_LOG) << "Composer for printing failed:" << composer->errorString(); |
|
} |
|
} |
|
} |
|
|
|
void KMReaderWin::clearContactItem() |
|
{ |
|
mSearchedContact = Akonadi::Item(); |
|
mSearchedAddress = KContacts::Addressee(); |
|
mLoadExternalReference->setChecked(false); |
|
mViewAsHtml->setChecked(false); |
|
} |
|
|
|
void KMReaderWin::setContactItem(const Akonadi::Item &contact, const KContacts::Addressee &address) |
|
{ |
|
mSearchedContact = contact; |
|
mSearchedAddress = address; |
|
updateHtmlActions(); |
|
} |
|
|
|
void KMReaderWin::updateHtmlActions() |
|
{ |
|
if (!mSearchedContact.isValid()) { |
|
mLoadExternalReference->setChecked(false); |
|
mViewAsHtml->setChecked(false); |
|
} else { |
|
const QStringList customs = mSearchedAddress.customs(); |
|
for (const QString &custom : customs) { |
|
if (custom.contains(QLatin1String("MailPreferedFormatting"))) { |
|
const QString value = mSearchedAddress.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailPreferedFormatting")); |
|
mViewAsHtml->setChecked(value == QLatin1String("HTML")); |
|
} else if (custom.contains(QLatin1String("MailAllowToRemoteContent"))) { |
|
const QString value = mSearchedAddress.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailAllowToRemoteContent")); |
|
mLoadExternalReference->setChecked((value == QLatin1String("TRUE"))); |
|
} |
|
} |
|
} |
|
} |
|
|
|
void KMReaderWin::slotContactHtmlOptions() |
|
{ |
|
const QUrl url = urlClicked(); |
|
if (url.isEmpty()) { |
|
return; |
|
} |
|
const QString emailString = KEmailAddress::decodeMailtoUrl(url).toLower(); |
|
|
|
KPIM::AddEmailDiplayJob *job = new KPIM::AddEmailDiplayJob(emailString, mMainWindow, this); |
|
job->setRemoteContent(mLoadExternalReference->isChecked()); |
|
job->setShowAsHTML(mViewAsHtml->isChecked()); |
|
job->setContact(mSearchedContact); |
|
job->start(); |
|
} |
|
|
|
void KMReaderWin::slotEditContact() |
|
{ |
|
if (mSearchedContact.isValid()) { |
|
QPointer<Akonadi::ContactEditorDialog> dlg |
|
= new Akonadi::ContactEditorDialog(Akonadi::ContactEditorDialog::EditMode, this); |
|
connect(dlg.data(), &Akonadi::ContactEditorDialog::contactStored, this, &KMReaderWin::contactStored); |
|
connect(dlg.data(), &Akonadi::ContactEditorDialog::error, this, &KMReaderWin::slotContactEditorError); |
|
dlg->setContact(mSearchedContact); |
|
dlg->exec(); |
|
delete dlg; |
|
} |
|
} |
|
|
|
void KMReaderWin::slotContactEditorError(const QString &error) |
|
{ |
|
KMessageBox::error(this, i18n("Contact cannot be stored: %1", error), i18n("Failed to store contact")); |
|
} |
|
|
|
void KMReaderWin::contactStored(const Akonadi::Item &item) |
|
{ |
|
Q_UNUSED(item); |
|
KPIM::BroadcastStatus::instance()->setStatusMsg(i18n("Contact modified successfully")); |
|
} |
|
|
|
QAction *KMReaderWin::saveMessageDisplayFormatAction() const |
|
{ |
|
return mViewer->saveMessageDisplayFormatAction(); |
|
} |
|
|
|
QAction *KMReaderWin::resetMessageDisplayFormatAction() const |
|
{ |
|
return mViewer->resetMessageDisplayFormatAction(); |
|
} |
|
|
|
QAction *KMReaderWin::editContactAction() const |
|
{ |
|
return mEditContactAction; |
|
} |
|
|
|
QMenu *KMReaderWin::viewHtmlOption() const |
|
{ |
|
return mViewHtmlOptions; |
|
} |
|
|
|
QAction *KMReaderWin::shareImage() const |
|
{ |
|
return mShareImage; |
|
} |
|
|
|
QAction *KMReaderWin::addToExistingContactAction() const |
|
{ |
|
return mAddEmailToExistingContactAction; |
|
} |
|
|
|
void KMReaderWin::slotShareImage() |
|
{ |
|
KMCommand *command = new KMShareImageCommand(imageUrlClicked(), this); |
|
command->start(); |
|
} |
|
|
|
QList<QAction *> KMReaderWin::interceptorUrlActions(const WebEngineViewer::WebHitTestResult &result) const |
|
{ |
|
return mViewer->interceptorUrlActions(result); |
|
} |
|
|
|
void KMReaderWin::slotPrintingFinished() |
|
{ |
|
if (mViewer->printingMode()) { |
|
deleteLater(); |
|
} |
|
}
|
|
|