[pim/kmail] src: Add a new message operation "New Message to Recipients"

Jonathan Marten null at kde.org
Fri Apr 9 13:11:25 BST 2021


Git commit 296cc28c9e9c88c7e29edf9123e797c31521ec3e by Jonathan Marten.
Committed on 09/04/2021 at 12:04.
Pushed by marten into branch 'master'.

Add a new message operation "New Message to Recipients"

This is equivalent to starting to compose a new message, but the
recipients (To, Cc, Bcc, Reply-To) are copied from the selected message.
Useful for starting a new conversation with the same people which will
not get grouped or threaded with the original.

The operation is available from the "Message" menus in the KMail main
window and the reader window.

Internally this adds a new parameter to ComposeMessageJob to specify the
original message.

GUI:
I18N:

M  +30   -0    src/job/composenewmessagejob.cpp
M  +3    -0    src/job/composenewmessagejob.h
M  +15   -0    src/kmmainwidget.cpp
M  +1    -0    src/kmmainwidget.h
M  +2    -1    src/kmmainwin.rc
M  +19   -0    src/kmreadermainwin.cpp
M  +1    -0    src/kmreadermainwin.h
M  +2    -1    src/kmreadermainwin.rc
M  +9    -0    src/messageactions.cpp
M  +2    -0    src/messageactions.h

https://invent.kde.org/pim/kmail/commit/296cc28c9e9c88c7e29edf9123e797c31521ec3e

diff --git a/src/job/composenewmessagejob.cpp b/src/job/composenewmessagejob.cpp
index d0e9e6aac..4ce06fbc4 100644
--- a/src/job/composenewmessagejob.cpp
+++ b/src/job/composenewmessagejob.cpp
@@ -25,6 +25,18 @@ void ComposeNewMessageJob::setCurrentCollection(const Akonadi::Collection &col)
     mCurrentCollection = col;
 }
 
+static void copyAddresses(const KMime::Headers::Generics::AddressList *from, KMime::Headers::Generics::AddressList *to)
+{
+    if (from == nullptr) { // no such headers to copy from
+        return;
+    }
+
+    const KMime::Types::Mailbox::List mailboxes = from->mailboxes();
+    for (const KMime::Types::Mailbox &mbox : mailboxes) {
+        to->addAddress(mbox);
+    }
+}
+
 void ComposeNewMessageJob::start()
 {
     mMsg = KMime::Message::Ptr(new KMime::Message());
@@ -39,6 +51,19 @@ void ComposeNewMessageJob::start()
     } else {
         parser->process(KMime::Message::Ptr());
     }
+
+    if (mRecipientsFrom.isValid()) {
+        // Copy the recipient list from the original message
+        const KMime::Message::Ptr msg = MessageComposer::Util::message(mRecipientsFrom);
+        if (msg) {
+            copyAddresses(msg->to(false), mMsg->to());
+            copyAddresses(msg->cc(false), mMsg->cc());
+            copyAddresses(msg->bcc(false), mMsg->bcc());
+            copyAddresses(msg->replyTo(false), mMsg->replyTo());
+        } else {
+            qCWarning(KMAIL_LOG) << "Original message" << mRecipientsFrom.id() << "not found";
+        }
+    }
 }
 
 void ComposeNewMessageJob::slotOpenComposer(bool forceCursorPosition)
@@ -57,3 +82,8 @@ void ComposeNewMessageJob::setFolderSettings(const QSharedPointer<MailCommon::Fo
 {
     mFolder = folder;
 }
+
+void ComposeNewMessageJob::setRecipientsFromMessage(const Akonadi::Item &from)
+{
+    mRecipientsFrom = from;
+}
diff --git a/src/job/composenewmessagejob.h b/src/job/composenewmessagejob.h
index f2b3ec6ef..d31f81bd2 100644
--- a/src/job/composenewmessagejob.h
+++ b/src/job/composenewmessagejob.h
@@ -16,16 +16,19 @@ class ComposeNewMessageJob : public QObject
 public:
     explicit ComposeNewMessageJob(QObject *parent = nullptr);
     ~ComposeNewMessageJob() override;
+
     void start();
     void setFolderSettings(const QSharedPointer<MailCommon::FolderSettings> &folder);
 
     void setCurrentCollection(const Akonadi::Collection &col);
+    void setRecipientsFromMessage(const Akonadi::Item &from);
 
 private:
     Q_DISABLE_COPY(ComposeNewMessageJob)
     void slotOpenComposer(bool forceCursorPosition);
     QSharedPointer<MailCommon::FolderSettings> mFolder;
     Akonadi::Collection mCurrentCollection;
+    Akonadi::Item mRecipientsFrom;
     uint mIdentity = 0;
     KMime::Message::Ptr mMsg = nullptr;
 };
diff --git a/src/kmmainwidget.cpp b/src/kmmainwidget.cpp
index 8b1efa7f7..3b6e6a3f9 100644
--- a/src/kmmainwidget.cpp
+++ b/src/kmmainwidget.cpp
@@ -2012,6 +2012,20 @@ void KMMainWidget::slotRedirectMessage()
     command->start();
 }
 
+void KMMainWidget::slotNewMessageToRecipients()
+{
+    const Akonadi::Item::List selectedMessages = mMessagePane->selectionAsMessageItemList();
+    if (selectedMessages.count() != 1) {
+        return;
+    }
+
+    ComposeNewMessageJob *job = new ComposeNewMessageJob;
+    job->setFolderSettings(mCurrentFolderSettings);
+    job->setCurrentCollection(mCurrentCollection);
+    job->setRecipientsFromMessage(selectedMessages.constFirst());
+    job->start();
+}
+
 //-----------------------------------------------------------------------------
 void KMMainWidget::slotCustomReplyToMsg(const QString &tmpl)
 {
@@ -3709,6 +3723,7 @@ void KMMainWidget::updateMessageActionsDelayed()
     mMsgActions->newMessageFromTemplateAction()->setEnabled(single_actions && CommonKernel->folderIsTemplates(mCurrentCollection));
     filterMenu()->setEnabled(single_actions);
     mMsgActions->redirectAction()->setEnabled(/*single_actions &&*/ mass_actions && !CommonKernel->folderIsTemplates(mCurrentCollection));
+    mMsgActions->newToRecipientsAction()->setEnabled(single_actions);
 
     if (auto *menuCustom = mMsgActions->customTemplatesMenu()) {
         menuCustom->forwardActionMenu()->setEnabled(mass_actions);
diff --git a/src/kmmainwidget.h b/src/kmmainwidget.h
index 9143d60b5..ef269be42 100644
--- a/src/kmmainwidget.h
+++ b/src/kmmainwidget.h
@@ -449,6 +449,7 @@ private Q_SLOTS:
     void slotForwardInlineMsg();
     void slotForwardAttachedMessage();
     void slotRedirectMessage();
+    void slotNewMessageToRecipients();
     void slotCustomForwardMsg(const QString &tmpl);
     void slotSubjectFilter();
     void slotFromFilter();
diff --git a/src/kmmainwin.rc b/src/kmmainwin.rc
index e1c6df7a3..b7c860d79 100644
--- a/src/kmmainwin.rc
+++ b/src/kmmainwin.rc
@@ -2,7 +2,7 @@
      the same menu entries at the same place in KMail and Kontact  -->
 
 <!DOCTYPE gui>
-<gui version="546" name="kmmainwin" translationDomain="kmail">
+<gui version="547" name="kmmainwin" translationDomain="kmail">
  <MenuBar>
   <Menu noMerge="1" name="file" >
    <text>&File</text>
@@ -150,6 +150,7 @@
    <text>&Message</text>
    <Action name="new_message" />
    <Action name="post_message" />
+   <Action name="new_to_recipients" />
    <Separator/>
    <Action name="reply" />
    <Action name="reply_all" />
diff --git a/src/kmreadermainwin.cpp b/src/kmreadermainwin.cpp
index 8fd8e6c51..f8ef8287f 100644
--- a/src/kmreadermainwin.cpp
+++ b/src/kmreadermainwin.cpp
@@ -14,6 +14,7 @@
 // widgets like a toolbar.
 
 #include "kmreadermainwin.h"
+#include "job/composenewmessagejob.h"
 #include "kmmainwidget.h"
 #include "kmreaderwin.h"
 #include "widgets/zoomlabelwidget.h"
@@ -359,6 +360,24 @@ void KMReaderMainWin::slotForwardAttachedMessage()
     command->start();
 }
 
+void KMReaderMainWin::slotNewMessageToRecipients()
+{
+    ComposeNewMessageJob *job = new ComposeNewMessageJob;
+
+    const Akonadi::Collection parentCol = mReaderWin->messageItem().parentCollection();
+    if (parentCol.isValid()) {
+        job->setCurrentCollection(parentCol);
+
+        QSharedPointer<FolderSettings> fd = FolderSettings::forCollection(parentCol, false);
+        if (fd) {
+            job->setFolderSettings(fd);
+        }
+    }
+
+    job->setRecipientsFromMessage(mReaderWin->messageItem());
+    job->start();
+}
+
 void KMReaderMainWin::slotRedirectMessage()
 {
     const Akonadi::Item currentItem = mReaderWin->messageItem();
diff --git a/src/kmreadermainwin.h b/src/kmreadermainwin.h
index bf32e8dc4..2aa3614ec 100644
--- a/src/kmreadermainwin.h
+++ b/src/kmreadermainwin.h
@@ -75,6 +75,7 @@ public Q_SLOTS:
     void slotForwardInlineMsg();
     void slotForwardAttachedMessage();
     void slotRedirectMessage();
+    void slotNewMessageToRecipients();
     void slotCustomReplyToMsg(const QString &tmpl);
     void slotCustomReplyAllToMsg(const QString &tmpl);
     void slotCustomForwardMsg(const QString &tmpl);
diff --git a/src/kmreadermainwin.rc b/src/kmreadermainwin.rc
index 23b32d0d7..093e02069 100644
--- a/src/kmreadermainwin.rc
+++ b/src/kmreadermainwin.rc
@@ -1,5 +1,5 @@
 <!DOCTYPE gui>
-<gui version="531" name="kmreadermainwin" translationDomain="kmail">
+<gui version="532" name="kmreadermainwin" translationDomain="kmail">
  <MenuBar>
   <Menu noMerge="1" name="file" >
    <text>&File</text>
@@ -58,6 +58,7 @@
      <Separator/>
      <Action name="custom_forward" />
    </Menu>
+   <Action name="new_to_recipients" />
    <Action name="send_again" />
    <Action name="mailing_list"/>
    <Separator/>
diff --git a/src/messageactions.cpp b/src/messageactions.cpp
index 9c71a4621..1b51a4c0c 100644
--- a/src/messageactions.cpp
+++ b/src/messageactions.cpp
@@ -129,6 +129,10 @@ MessageActions::MessageActions(KActionCollection *ac, QWidget *parent)
 
     setupForwardActions(ac);
 
+    mNewToRecipientsAction = new QAction(i18n("New Message to Recipients..."), this);
+    ac->addAction(QStringLiteral("new_to_recipients"), mNewToRecipientsAction);
+    connect(mNewToRecipientsAction, SIGNAL(triggered(bool)), parent, SLOT(slotNewMessageToRecipients()));
+
     mRedirectAction = new QAction(i18nc("Message->Forward->", "&Redirect..."), this);
     ac->addAction(QStringLiteral("message_forward_redirect"), mRedirectAction);
     connect(mRedirectAction, SIGNAL(triggered(bool)), parent, SLOT(slotRedirectMessage()));
@@ -266,6 +270,11 @@ QAction *MessageActions::redirectAction() const
     return mRedirectAction;
 }
 
+QAction *MessageActions::newToRecipientsAction() const
+{
+    return mNewToRecipientsAction;
+}
+
 KActionMenu *MessageActions::messageStatusMenu() const
 {
     return mStatusMenu;
diff --git a/src/messageactions.h b/src/messageactions.h
index 29491e277..970062383 100644
--- a/src/messageactions.h
+++ b/src/messageactions.h
@@ -68,6 +68,7 @@ public:
     QAction *forwardInlineAction() const;
     QAction *forwardAttachedAction() const;
     QAction *redirectAction() const;
+    QAction *newToRecipientsAction() const;
 
     KActionMenu *messageStatusMenu() const;
     KActionMenu *forwardMenu() const;
@@ -156,6 +157,7 @@ private:
     QAction *mForwardInlineAction = nullptr;
     QAction *mForwardAttachedAction = nullptr;
     QAction *mRedirectAction = nullptr;
+    QAction *mNewToRecipientsAction = nullptr;
     KActionMenu *mStatusMenu = nullptr;
     KActionMenu *mForwardActionMenu = nullptr;
     KActionMenu *mMailingListActionMenu = nullptr;


More information about the kde-doc-english mailing list