2 Copyright (c) 2007 Volker Krause <vkrause@kde.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "messageactions.h"
21 #include "settings/globalsettings.h"
22 #include "kmreaderwin.h"
24 #include "kernel/mailkernel.h"
25 #include "kmmainwidget.h"
27 #include "kmcommands.h"
28 #include "customtemplatesmenu.h"
30 #include "pimcommon/widgets/annotationdialog.h"
31 #include "pimcommon/webshortcut/webshortcutmenumanager.h"
32 #include "messagecore/settings/globalsettings.h"
33 #include "messagecore/misc/mailinglist.h"
34 #include "messagecore/helpers/messagehelpers.h"
35 #include "messageviewer/viewer/csshelper.h"
36 #include "messageviewer/settings/globalsettings.h"
38 #include <AkonadiCore/itemfetchjob.h>
39 #include <Akonadi/KMime/MessageParts>
40 #include <AkonadiCore/ChangeRecorder>
42 #include "pimcommon/baloodebug/baloodebugdialog.h"
44 #include "followupreminder/followupreminderselectdatedialog.h"
45 #include "job/createfollowupreminderonexistingmessagejob.h"
47 #include <AkonadiCore/ItemFetchJob>
48 #include <KActionMenu>
49 #include <KActionCollection>
50 #include "kmail_debug.h"
51 #include <KLocalizedString>
52 #include <KXMLGUIClient>
55 #include <KUriFilterData>
56 #include <KToolInvocation>
58 #include <KStringHandler>
59 #include <KPrintPreview>
64 #include <AkonadiCore/collection.h>
65 #include <AkonadiCore/entityannotationsattribute.h>
66 #include <util/mailutil.h>
68 using namespace KMail
;
70 MessageActions::MessageActions(KActionCollection
*ac
, QWidget
*parent
)
73 mMessageView(Q_NULLPTR
),
74 mRedirectAction(Q_NULLPTR
),
75 mPrintPreviewAction(Q_NULLPTR
),
76 mCustomTemplatesMenu(Q_NULLPTR
),
77 mAddFollowupReminderAction(Q_NULLPTR
),
78 mDebugBalooAction(Q_NULLPTR
)
80 mWebShortcutMenuManager
= new PimCommon::WebShortcutMenuManager(this);
81 mReplyActionMenu
= new KActionMenu(QIcon::fromTheme(QStringLiteral("mail-reply-sender")), i18nc("Message->", "&Reply"), this);
82 ac
->addAction(QStringLiteral("message_reply_menu"), mReplyActionMenu
);
83 connect(mReplyActionMenu
, &KActionMenu::triggered
, this, &MessageActions::slotReplyToMsg
);
85 mReplyAction
= new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-sender")), i18n("&Reply..."), this);
86 ac
->addAction(QStringLiteral("reply"), mReplyAction
);
87 ac
->setDefaultShortcut(mReplyAction
, Qt::Key_R
);
88 connect(mReplyAction
, &QAction::triggered
, this, &MessageActions::slotReplyToMsg
);
89 mReplyActionMenu
->addAction(mReplyAction
);
91 mReplyAuthorAction
= new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-sender")), i18n("Reply to A&uthor..."), this);
92 ac
->addAction(QStringLiteral("reply_author"), mReplyAuthorAction
);
93 ac
->setDefaultShortcut(mReplyAuthorAction
, Qt::SHIFT
+ Qt::Key_A
);
94 connect(mReplyAuthorAction
, &QAction::triggered
, this, &MessageActions::slotReplyAuthorToMsg
);
95 mReplyActionMenu
->addAction(mReplyAuthorAction
);
97 mReplyAllAction
= new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-all")), i18n("Reply to &All..."), this);
98 ac
->addAction(QStringLiteral("reply_all"), mReplyAllAction
);
99 ac
->setDefaultShortcut(mReplyAllAction
, Qt::Key_A
);
100 connect(mReplyAllAction
, &QAction::triggered
, this, &MessageActions::slotReplyAllToMsg
);
101 mReplyActionMenu
->addAction(mReplyAllAction
);
103 mReplyListAction
= new QAction(QIcon::fromTheme(QStringLiteral("mail-reply-list")), i18n("Reply to Mailing-&List..."), this);
104 ac
->addAction(QStringLiteral("reply_list"), mReplyListAction
);
106 ac
->setDefaultShortcut(mReplyListAction
, Qt::Key_L
);
107 connect(mReplyListAction
, &QAction::triggered
, this, &MessageActions::slotReplyListToMsg
);
108 mReplyActionMenu
->addAction(mReplyListAction
);
110 mNoQuoteReplyAction
= new QAction(i18n("Reply Without &Quote..."), this);
111 ac
->addAction(QStringLiteral("noquotereply"), mNoQuoteReplyAction
);
112 ac
->setDefaultShortcut(mNoQuoteReplyAction
, Qt::SHIFT
+ Qt::Key_R
);
113 connect(mNoQuoteReplyAction
, &QAction::triggered
, this, &MessageActions::slotNoQuoteReplyToMsg
);
115 mListFilterAction
= new QAction(i18n("Filter on Mailing-&List..."), this);
116 ac
->addAction(QStringLiteral("mlist_filter"), mListFilterAction
);
117 connect(mListFilterAction
, &QAction::triggered
, this, &MessageActions::slotMailingListFilter
);
119 mStatusMenu
= new KActionMenu(i18n("Mar&k Message"), this);
120 ac
->addAction(QStringLiteral("set_status"), mStatusMenu
);
122 KMMainWidget
*mainwin
= kmkernel
->getKMMainWidget();
124 QAction
*action
= mainwin
->akonadiStandardAction(Akonadi::StandardMailActionManager::MarkMailAsRead
);
125 mStatusMenu
->addAction(action
);
127 action
= mainwin
->akonadiStandardAction(Akonadi::StandardMailActionManager::MarkMailAsUnread
);
128 mStatusMenu
->addAction(action
);
130 mStatusMenu
->addSeparator();
131 action
= mainwin
->akonadiStandardAction(Akonadi::StandardMailActionManager::MarkMailAsImportant
);
132 mStatusMenu
->addAction(action
);
134 action
= mainwin
->akonadiStandardAction(Akonadi::StandardMailActionManager::MarkMailAsActionItem
);
135 mStatusMenu
->addAction(action
);
139 mEditAction
= new QAction(QIcon::fromTheme(QStringLiteral("accessories-text-editor")), i18n("&Edit Message"), this);
140 ac
->addAction(QStringLiteral("edit"), mEditAction
);
141 connect(mEditAction
, &QAction::triggered
, this, &MessageActions::editCurrentMessage
);
142 ac
->setDefaultShortcut(mEditAction
, Qt::Key_T
);
144 mAnnotateAction
= new QAction(QIcon::fromTheme(QStringLiteral("view-pim-notes")), i18n("Add Note..."), this);
145 ac
->addAction(QStringLiteral("annotate"), mAnnotateAction
);
146 connect(mAnnotateAction
, &QAction::triggered
, this, &MessageActions::annotateMessage
);
148 mPrintAction
= KStandardAction::print(this, SLOT(slotPrintMsg()), ac
);
149 if (KPrintPreview::isAvailable()) {
150 mPrintPreviewAction
= KStandardAction::printPreview(this, SLOT(slotPrintPreviewMsg()), ac
);
153 mForwardActionMenu
= new KActionMenu(QIcon::fromTheme(QStringLiteral("mail-forward")), i18nc("Message->", "&Forward"), this);
154 ac
->addAction(QStringLiteral("message_forward"), mForwardActionMenu
);
156 mForwardAttachedAction
= new QAction(QIcon::fromTheme(QStringLiteral("mail-forward")),
157 i18nc("@action:inmenu Message->Forward->",
158 "As &Attachment..."),
160 connect(mForwardAttachedAction
, SIGNAL(triggered(bool)), parent
, SLOT(slotForwardAttachedMsg()));
162 ac
->addAction(QStringLiteral("message_forward_as_attachment"), mForwardAttachedAction
);
164 mForwardInlineAction
= new QAction(QIcon::fromTheme(QStringLiteral("mail-forward")),
165 i18nc("@action:inmenu Message->Forward->",
168 connect(mForwardInlineAction
, SIGNAL(triggered(bool)), parent
, SLOT(slotForwardInlineMsg()));
170 ac
->addAction(QStringLiteral("message_forward_inline"), mForwardInlineAction
);
172 setupForwardActions(ac
);
174 mRedirectAction
= new QAction(i18nc("Message->Forward->", "&Redirect..."), this);
175 ac
->addAction(QStringLiteral("message_forward_redirect"), mRedirectAction
);
176 connect(mRedirectAction
, SIGNAL(triggered(bool)), parent
, SLOT(slotRedirectMsg()));
178 ac
->setDefaultShortcut(mRedirectAction
, QKeySequence(Qt::Key_E
));
179 mForwardActionMenu
->addAction(mRedirectAction
);
181 //FIXME add QIcon::fromTheme("mail-list") as first arguement. Icon can be derived from
182 // mail-reply-list icon by removing top layers off svg
183 mMailingListActionMenu
= new KActionMenu(i18nc("Message->", "Mailing-&List"), this);
184 connect(mMailingListActionMenu
->menu(), &QMenu::triggered
, this, &MessageActions::slotRunUrl
);
185 ac
->addAction(QStringLiteral("mailing_list"), mMailingListActionMenu
);
186 mMailingListActionMenu
->setEnabled(false);
188 connect(kmkernel
->folderCollectionMonitor(), SIGNAL(itemChanged(Akonadi::Item
,QSet
<QByteArray
>)), SLOT(slotItemModified(Akonadi::Item
,QSet
<QByteArray
>)));
189 connect(kmkernel
->folderCollectionMonitor(), SIGNAL(itemRemoved(Akonadi::Item
)), SLOT(slotItemRemoved(Akonadi::Item
)));
191 mCustomTemplatesMenu
= new TemplateParser::CustomTemplatesMenu(parent
, ac
);
193 connect(mCustomTemplatesMenu
, SIGNAL(replyTemplateSelected(QString
)), parent
, SLOT(slotCustomReplyToMsg(QString
)));
194 connect(mCustomTemplatesMenu
, SIGNAL(replyAllTemplateSelected(QString
)), parent
, SLOT(slotCustomReplyAllToMsg(QString
)));
195 connect(mCustomTemplatesMenu
, SIGNAL(forwardTemplateSelected(QString
)), parent
, SLOT(slotCustomForwardMsg(QString
)));
196 connect(KMKernel::self(), &KMKernel::customTemplatesChanged
, mCustomTemplatesMenu
, &TemplateParser::CustomTemplatesMenu::update
);
198 forwardMenu()->addSeparator();
199 forwardMenu()->addAction(mCustomTemplatesMenu
->forwardActionMenu());
200 replyMenu()->addSeparator();
201 replyMenu()->addAction(mCustomTemplatesMenu
->replyActionMenu());
202 replyMenu()->addAction(mCustomTemplatesMenu
->replyAllActionMenu());
204 //Don't translate it. Shown only when we set env variable KDEPIM_BALOO_DEBUG
205 mDebugBalooAction
= new QAction(QStringLiteral("Debug Baloo..."), this);
206 connect(mDebugBalooAction
, SIGNAL(triggered(bool)), this, SLOT(slotDebugBaloo()));
208 mAddFollowupReminderAction
= new QAction(i18n("Add Followup Reminder..."), this);
209 ac
->addAction(QStringLiteral("message_followup_reminder"), mAddFollowupReminderAction
);
210 connect(mAddFollowupReminderAction
, SIGNAL(triggered(bool)), this, SLOT(slotAddFollowupReminder()));
215 MessageActions::~MessageActions()
217 delete mCustomTemplatesMenu
;
220 TemplateParser::CustomTemplatesMenu
*MessageActions::customTemplatesMenu() const
222 return mCustomTemplatesMenu
;
225 void MessageActions::setCurrentMessage(const Akonadi::Item
&msg
, const Akonadi::Item::List
&items
)
229 if (!items
.isEmpty()) {
231 mVisibleItems
= items
;
233 mVisibleItems
.clear();
237 if (!msg
.isValid()) {
238 mVisibleItems
.clear();
239 clearMailingListActions();
245 void MessageActions::slotItemRemoved(const Akonadi::Item
&item
)
247 if (item
== mCurrentItem
) {
248 mCurrentItem
= Akonadi::Item();
253 void MessageActions::slotItemModified(const Akonadi::Item
&item
, const QSet
< QByteArray
> &partIdentifiers
)
255 Q_UNUSED(partIdentifiers
);
256 if (item
== mCurrentItem
) {
258 const int numberOfVisibleItems
= mVisibleItems
.count();
259 for (int i
= 0; i
< numberOfVisibleItems
; ++i
) {
260 Akonadi::Item it
= mVisibleItems
.at(i
);
262 mVisibleItems
[i
] = item
;
269 void MessageActions::updateActions()
271 const bool hasPayload
= mCurrentItem
.hasPayload
<KMime::Message::Ptr
>();
272 bool itemValid
= mCurrentItem
.isValid();
273 Akonadi::Collection parent
;
274 if (itemValid
) { //=> valid
275 parent
= mCurrentItem
.parentCollection();
277 if (parent
.isValid()) {
278 if (CommonKernel
->folderIsTemplates(parent
)) {
283 const bool multiVisible
= mVisibleItems
.count() > 0 || mCurrentItem
.isValid();
284 const bool uniqItem
= (itemValid
|| hasPayload
) && (mVisibleItems
.count() <= 1);
285 mReplyActionMenu
->setEnabled(hasPayload
);
286 mReplyAction
->setEnabled(hasPayload
);
287 mNoQuoteReplyAction
->setEnabled(hasPayload
);
288 mReplyAuthorAction
->setEnabled(hasPayload
);
289 mReplyAllAction
->setEnabled(hasPayload
);
290 mReplyListAction
->setEnabled(hasPayload
);
291 mNoQuoteReplyAction
->setEnabled(hasPayload
);
293 mAnnotateAction
->setEnabled(uniqItem
);
294 if (!mCurrentItem
.hasAttribute
<Akonadi::EntityAnnotationsAttribute
>()) {
295 mAnnotateAction
->setText(i18n("Add Note..."));
297 mAnnotateAction
->setText(i18n("Edit Note..."));
300 mStatusMenu
->setEnabled(multiVisible
);
302 if (mCurrentItem
.hasPayload
<KMime::Message::Ptr
>()) {
303 if (mCurrentItem
.loadedPayloadParts().contains("RFC822")) {
304 updateMailingListActions(mCurrentItem
);
306 Akonadi::ItemFetchJob
*job
= new Akonadi::ItemFetchJob(mCurrentItem
);
307 job
->fetchScope().fetchAllAttributes();
308 job
->fetchScope().fetchFullPayload(true);
309 job
->fetchScope().fetchPayloadPart(Akonadi::MessagePart::Header
);
310 job
->fetchScope().fetchAttribute
<Akonadi::EntityAnnotationsAttribute
>();
311 connect(job
, &Akonadi::ItemFetchJob::result
, this, &MessageActions::slotUpdateActionsFetchDone
);
314 mEditAction
->setEnabled(uniqItem
);
317 void MessageActions::slotUpdateActionsFetchDone(KJob
*job
)
323 Akonadi::ItemFetchJob
*fetchJob
= static_cast<Akonadi::ItemFetchJob
*>(job
);
324 if (fetchJob
->items().isEmpty()) {
327 Akonadi::Item messageItem
= fetchJob
->items().first();
328 if (messageItem
== mCurrentItem
) {
329 mCurrentItem
= messageItem
;
330 updateMailingListActions(messageItem
);
334 void MessageActions::clearMailingListActions()
336 mMailingListActionMenu
->setEnabled(false);
337 mListFilterAction
->setEnabled(false);
338 mListFilterAction
->setText(i18n("Filter on Mailing-List..."));
341 void MessageActions::updateMailingListActions(const Akonadi::Item
&messageItem
)
343 KMime::Message::Ptr message
= messageItem
.payload
<KMime::Message::Ptr
>();
344 const MessageCore::MailingList mailList
= MessageCore::MailingList::detect(message
);
346 if (mailList
.features() == MessageCore::MailingList::None
) {
347 clearMailingListActions();
349 // A mailing list menu with only a title is pretty boring
350 // so make sure theres at least some content
352 if (mailList
.features() & MessageCore::MailingList::Id
) {
353 // From a list-id in the form, "Birds of France <bof.yahoo.com>",
354 // take "Birds of France" if it exists otherwise "bof.yahoo.com".
355 listId
= mailList
.id();
356 const int start
= listId
.indexOf(QLatin1Char('<'));
358 listId
.truncate(start
- 1);
359 } else if (start
== 0) {
360 const int end
= listId
.lastIndexOf(QLatin1Char('>'));
361 if (end
< 1) { // shouldn't happen but account for it anyway
364 listId
= listId
.mid(1, end
- 1);
368 mMailingListActionMenu
->menu()->clear();
369 qDeleteAll(mMailListActionList
);
370 mMailListActionList
.clear();
371 if (!listId
.isEmpty()) {
372 mMailingListActionMenu
->menu()->setTitle(listId
);
374 if (mailList
.features() & MessageCore::MailingList::ArchivedAt
)
375 // IDEA: this may be something you want to copy - "Copy in submenu"?
377 addMailingListActions(i18n("Open Message in List Archive"), mailList
.archivedAtUrls());
379 if (mailList
.features() & MessageCore::MailingList::Post
) {
380 addMailingListActions(i18n("Post New Message"), mailList
.postUrls());
382 if (mailList
.features() & MessageCore::MailingList::Archive
) {
383 addMailingListActions(i18n("Go to Archive"), mailList
.archiveUrls());
385 if (mailList
.features() & MessageCore::MailingList::Help
) {
386 addMailingListActions(i18n("Request Help"), mailList
.helpUrls());
388 if (mailList
.features() & MessageCore::MailingList::Owner
) {
389 addMailingListActions(i18nc("Contact the owner of the mailing list", "Contact Owner"), mailList
.ownerUrls());
391 if (mailList
.features() & MessageCore::MailingList::Subscribe
) {
392 addMailingListActions(i18n("Subscribe to List"), mailList
.subscribeUrls());
394 if (mailList
.features() & MessageCore::MailingList::Unsubscribe
) {
395 addMailingListActions(i18n("Unsubscribe from List"), mailList
.unsubscribeUrls());
397 mMailingListActionMenu
->setEnabled(true);
401 const QString lname
= MailingList::name(message
, name
, value
);
402 if (!lname
.isEmpty()) {
403 mListFilterAction
->setEnabled(true);
404 mListFilterAction
->setText(i18n("Filter on Mailing-List %1...", lname
));
409 void MessageActions::replyCommand(MessageComposer::ReplyStrategy strategy
)
411 if (!mCurrentItem
.hasPayload
<KMime::Message::Ptr
>()) {
415 const QString text
= mMessageView
? mMessageView
->copyText() : QString();
416 KMCommand
*command
= new KMReplyCommand(mParent
, mCurrentItem
, strategy
, text
);
417 connect(command
, &KMCommand::completed
, this, &MessageActions::replyActionFinished
);
421 void MessageActions::setMessageView(KMReaderWin
*msgView
)
423 mMessageView
= msgView
;
426 void MessageActions::setupForwardActions(KActionCollection
*ac
)
428 disconnect(mForwardActionMenu
, SIGNAL(triggered(bool)), Q_NULLPTR
, Q_NULLPTR
);
429 mForwardActionMenu
->removeAction(mForwardInlineAction
);
430 mForwardActionMenu
->removeAction(mForwardAttachedAction
);
432 if (GlobalSettings::self()->forwardingInlineByDefault()) {
433 mForwardActionMenu
->insertAction(mRedirectAction
, mForwardInlineAction
);
434 mForwardActionMenu
->insertAction(mRedirectAction
, mForwardAttachedAction
);
435 ac
->setDefaultShortcut(mForwardInlineAction
, QKeySequence(Qt::Key_F
));
436 ac
->setDefaultShortcut(mForwardAttachedAction
, QKeySequence(Qt::SHIFT
+ Qt::Key_F
));
437 QObject::connect(mForwardActionMenu
, SIGNAL(triggered(bool)),
438 mParent
, SLOT(slotForwardInlineMsg()));
440 mForwardActionMenu
->insertAction(mRedirectAction
, mForwardAttachedAction
);
441 mForwardActionMenu
->insertAction(mRedirectAction
, mForwardInlineAction
);
442 ac
->setDefaultShortcut(mForwardInlineAction
, QKeySequence(Qt::Key_F
));
443 ac
->setDefaultShortcut(mForwardAttachedAction
, QKeySequence(Qt::SHIFT
+ Qt::Key_F
));
444 QObject::connect(mForwardActionMenu
, SIGNAL(triggered(bool)),
445 mParent
, SLOT(slotForwardAttachedMsg()));
449 void MessageActions::setupForwardingActionsList(KXMLGUIClient
*guiClient
)
451 QList
<QAction
*> forwardActionList
;
452 guiClient
->unplugActionList(QStringLiteral("forward_action_list"));
453 if (GlobalSettings::self()->forwardingInlineByDefault()) {
454 forwardActionList
.append(mForwardInlineAction
);
455 forwardActionList
.append(mForwardAttachedAction
);
457 forwardActionList
.append(mForwardAttachedAction
);
458 forwardActionList
.append(mForwardInlineAction
);
460 forwardActionList
.append(mRedirectAction
);
461 guiClient
->plugActionList(QStringLiteral("forward_action_list"), forwardActionList
);
464 void MessageActions::slotReplyToMsg()
466 replyCommand(MessageComposer::ReplySmart
);
469 void MessageActions::slotReplyAuthorToMsg()
471 replyCommand(MessageComposer::ReplyAuthor
);
474 void MessageActions::slotReplyListToMsg()
476 replyCommand(MessageComposer::ReplyList
);
479 void MessageActions::slotReplyAllToMsg()
481 replyCommand(MessageComposer::ReplyAll
);
484 void MessageActions::slotNoQuoteReplyToMsg()
486 if (!mCurrentItem
.hasPayload
<KMime::Message::Ptr
>()) {
489 KMCommand
*command
= new KMReplyCommand(mParent
, mCurrentItem
, MessageComposer::ReplySmart
, QString(), true);
493 void MessageActions::slotRunUrl(QAction
*urlAction
)
495 const QVariant q
= urlAction
->data();
496 if (q
.type() == QVariant::Url
) {
497 new KRun(q
.toUrl(), mParent
);
501 void MessageActions::slotMailingListFilter()
503 if (!mCurrentItem
.hasPayload
<KMime::Message::Ptr
>()) {
507 KMCommand
*command
= new KMMailingListFilterCommand(mParent
, mCurrentItem
);
511 void MessageActions::printMessage(bool preview
)
515 if (MessageViewer::GlobalSettings::self()->printSelectedText()) {
516 result
= mMessageView
->printSelectedText(preview
);
520 const bool useFixedFont
= MessageViewer::GlobalSettings::self()->useFixedFont();
521 const QString overrideEncoding
= MessageCore::GlobalSettings::self()->overrideCharacterEncoding();
523 const Akonadi::Item message
= mCurrentItem
;
524 KMPrintCommand
*command
=
525 new KMPrintCommand(mParent
, message
,
526 mMessageView
->viewer()->headerStyle(), mMessageView
->viewer()->headerStrategy(),
527 mMessageView
->viewer()->displayFormatMessageOverwrite(), mMessageView
->viewer()->htmlLoadExternal(),
528 useFixedFont
, overrideEncoding
);
529 command
->setPrintPreview(preview
);
534 void MessageActions::slotPrintPreviewMsg()
539 void MessageActions::slotPrintMsg()
545 * This adds a list of actions to mMailingListActionMenu mapping the identifier item to
548 * e.g.: item = "Contact Owner"
549 * "Contact Owner (email)" -> KRun( "mailto:bob@arthouseflowers.example.com" )
550 * "Contact Owner (web)" -> KRun( "http://arthouseflowers.example.com/contact-owner.php" )
552 void MessageActions::addMailingListActions(const QString
&item
, const QList
<QUrl
> &list
)
554 foreach (const QUrl
&url
, list
) {
555 addMailingListAction(item
, url
);
560 * This adds a action to mMailingListActionMenu mapping the identifier item to
561 * the url. See addMailingListActions above.
563 void MessageActions::addMailingListAction(const QString
&item
, const QUrl
&url
)
565 QString protocol
= url
.scheme().toLower();
566 QString prettyUrl
= url
.toDisplayString();
567 if (protocol
== QLatin1String("mailto")) {
568 protocol
= i18n("email");
569 prettyUrl
.remove(0, 7); // length( "mailto:" )
570 } else if (protocol
.startsWith(QStringLiteral("http"))) {
571 protocol
= i18n("web");
573 // item is a mailing list url description passed from the updateActions method above.
574 QAction
*act
= new QAction(i18nc("%1 is a 'Contact Owner' or similar action. %2 is a protocol normally web or email though could be irc/ftp or other url variant", "%1 (%2)", item
, protocol
) , this);
575 mMailListActionList
.append(act
);
576 const QVariant
v(url
);
578 KMail::Util::addQActionHelpText(act
, prettyUrl
);
579 mMailingListActionMenu
->addAction(act
);
582 void MessageActions::editCurrentMessage()
584 KMCommand
*command
= Q_NULLPTR
;
585 if (mCurrentItem
.isValid()) {
586 Akonadi::Collection col
= mCurrentItem
.parentCollection();
587 qCDebug(KMAIL_LOG
) << " mCurrentItem.parentCollection()" << mCurrentItem
.parentCollection();
588 // edit, unlike send again, removes the message from the folder
589 // we only want that for templates and drafts folders
591 && (CommonKernel
->folderIsDraftOrOutbox(col
) ||
592 CommonKernel
->folderIsTemplates(col
))
594 command
= new KMEditItemCommand(mParent
, mCurrentItem
, true);
596 command
= new KMEditItemCommand(mParent
, mCurrentItem
, false);
599 } else if (mCurrentItem
.hasPayload
<KMime::Message::Ptr
>()) {
600 command
= new KMEditMessageCommand(mParent
, mCurrentItem
.payload
<KMime::Message::Ptr
>());
605 void MessageActions::annotateMessage()
607 if (!mCurrentItem
.isValid()) {
611 PimCommon::AnnotationEditDialog
*dialog
= new PimCommon::AnnotationEditDialog(mCurrentItem
);
612 dialog
->setAttribute(Qt::WA_DeleteOnClose
);
616 void MessageActions::addWebShortcutsMenu(QMenu
*menu
, const QString
&text
)
618 mWebShortcutMenuManager
->setSelectedText(text
);
619 mWebShortcutMenuManager
->addWebShortcutsMenu(menu
);
622 void MessageActions::slotDebugBaloo()
624 if (!mCurrentItem
.isValid()) {
627 QPointer
<PimCommon::BalooDebugDialog
> dlg
= new PimCommon::BalooDebugDialog
;
628 dlg
->setAkonadiId(mCurrentItem
.id());
629 dlg
->setAttribute(Qt::WA_DeleteOnClose
);
630 dlg
->setSearchType(PimCommon::BalooDebugSearchPathComboBox::Emails
);
635 void MessageActions::slotAddFollowupReminder()
637 if (!mCurrentItem
.isValid()) {
641 QPointer
<MessageComposer::FollowUpReminderSelectDateDialog
> dlg
= new MessageComposer::FollowUpReminderSelectDateDialog
;
643 const QDate date
= dlg
->selectedDate();
644 CreateFollowupReminderOnExistingMessageJob
*job
= new CreateFollowupReminderOnExistingMessageJob(this);
646 job
->setCollection(dlg
->collection());
647 job
->setMessageItem(mCurrentItem
);