Commit 296cc28c authored by Jonathan Marten's avatar Jonathan Marten
Browse files

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:
parent 932ba6b1
Pipeline #57101 passed with stage
in 27 minutes and 25 seconds
......@@ -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;
}
......@@ -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;
};
......
......@@ -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);
......
......@@ -449,6 +449,7 @@ private Q_SLOTS:
void slotForwardInlineMsg();
void slotForwardAttachedMessage();
void slotRedirectMessage();
void slotNewMessageToRecipients();
void slotCustomForwardMsg(const QString &tmpl);
void slotSubjectFilter();
void slotFromFilter();
......
......@@ -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>&amp;File</text>
......@@ -150,6 +150,7 @@
<text>&amp;Message</text>
<Action name="new_message" />
<Action name="post_message" />
<Action name="new_to_recipients" />
<Separator/>
<Action name="reply" />
<Action name="reply_all" />
......
......@@ -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();
......
......@@ -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);
......
<!DOCTYPE gui>
<gui version="531" name="kmreadermainwin" translationDomain="kmail">
<gui version="532" name="kmreadermainwin" translationDomain="kmail">
<MenuBar>
<Menu noMerge="1" name="file" >
<text>&amp;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/>
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment