diff --git a/messagecomposer/src/sender/akonadisender.cpp b/messagecomposer/src/sender/akonadisender.cpp index 9f2deaab..30cb383b 100644 --- a/messagecomposer/src/sender/akonadisender.cpp +++ b/messagecomposer/src/sender/akonadisender.cpp @@ -1,211 +1,210 @@ /* * This file is part of KMail. * Copyright (c) 2009 Constantin Berzan * * 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. */ #include "akonadisender.h" #include "messagecomposer_debug.h" #include "helper/messagehelper.h" #include "settings/messagecomposersettings.h" #include "MessageComposer/Util" #include "utils/util_p.h" #include #include #include #include #include #include #include using namespace KMime::Types; using namespace KPIM; using namespace MailTransport; using namespace MessageComposer; static QStringList addrSpecListToStringList(const AddrSpecList &l, bool allowEmpty = false) { QStringList result; for (AddrSpecList::const_iterator it = l.constBegin(), end = l.constEnd(); it != end; ++it) { const QString s = (*it).asString(); if (allowEmpty || !s.isEmpty()) { result.push_back(s); } } return result; } static void extractSenderToCCAndBcc(const KMime::Message::Ptr &aMsg, QString &sender, QStringList &to, QStringList &cc, QStringList &bcc) { sender = aMsg->sender()->asUnicodeString(); if (aMsg->headerByType("X-KMail-Recipients")) { // extended BCC handling to prevent TOs and CCs from seeing // BBC information by looking at source of an OpenPGP encrypted mail to = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "X-KMail-Recipients")); aMsg->removeHeader("X-KMail-Recipients"); } else if (aMsg->headerByType("Resent-To")) { to = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "Resent-To")); cc = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "Resent-Cc")); bcc = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "Resent-Bcc")); } else { to = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "To")); cc = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "Cc")); bcc = addrSpecListToStringList(MessageHelper::extractAddrSpecs(aMsg, "Bcc")); } } class MessageComposer::AkonadiSenderPrivate { public: AkonadiSenderPrivate() - : mCustomTransportId(-1) { } QSet mPendingJobs; - int mCustomTransportId; + int mCustomTransportId = -1; }; AkonadiSender::AkonadiSender(QObject *parent) : QObject(parent) , d(new MessageComposer::AkonadiSenderPrivate) { } AkonadiSender::~AkonadiSender() { delete d; } bool AkonadiSender::doSend(const KMime::Message::Ptr &aMsg, short sendNow) { if (sendNow == -1) { sendNow = MessageComposer::MessageComposerSettings::self()->sendImmediate(); // -1 == use default setting } if (sendNow) { sendOrQueueMessage(aMsg, MessageComposer::MessageSender::SendImmediate); } else { sendOrQueueMessage(aMsg, MessageComposer::MessageSender::SendLater); } return true; } bool AkonadiSender::doSendQueued(int customTransportId) { qCDebug(MESSAGECOMPOSER_LOG) << "Sending queued message with custom transport:" << customTransportId; if (!MessageComposer::Util::sendMailDispatcherIsOnline()) { return false; } d->mCustomTransportId = customTransportId; DispatcherInterface *dispatcher = new DispatcherInterface(); if (d->mCustomTransportId == -1) { dispatcher->dispatchManually(); } else { dispatcher->dispatchManualTransport(d->mCustomTransportId); } delete dispatcher; return true; } void AkonadiSender::sendOrQueueMessage(const KMime::Message::Ptr &message, MessageComposer::MessageSender::SendMethod method) { Q_ASSERT(message); qCDebug(MESSAGECOMPOSER_LOG) << "KMime::Message: \n[\n" << message->encodedContent().left(1000) << "\n]\n"; MessageQueueJob *qjob = new MessageQueueJob(this); if (message->hasHeader("X-KMail-FccDisabled")) { qjob->sentBehaviourAttribute().setSentBehaviour(MailTransport::SentBehaviourAttribute::Delete); } else if (auto hrd = message->headerByType("X-KMail-Fcc")) { qjob->sentBehaviourAttribute().setSentBehaviour( SentBehaviourAttribute::MoveToCollection); const int sentCollectionId = hrd->asUnicodeString().toInt(); qjob->sentBehaviourAttribute().setMoveToCollection( Akonadi::Collection(sentCollectionId)); } else { qjob->sentBehaviourAttribute().setSentBehaviour( MailTransport::SentBehaviourAttribute::MoveToDefaultSentCollection); } qjob->setMessage(message); // Get transport. int transportId = -1; if (d->mCustomTransportId != -1) { transportId = d->mCustomTransportId; } else { if (auto hrd = message->headerByType("X-KMail-Transport")) { transportId = hrd->asUnicodeString().toInt(); } } const Transport *transport = TransportManager::self()->transportById(transportId); if (!transport) { qCDebug(MESSAGECOMPOSER_LOG) << " No transport defined. Need to create it"; return; } if ((method == MessageComposer::MessageSender::SendImmediate) && !MessageComposer::Util::sendMailDispatcherIsOnline()) { return; } qCDebug(MESSAGECOMPOSER_LOG) << "Using transport (" << transport->name() << "," << transport->id() << ")"; qjob->transportAttribute().setTransportId(transport->id()); // if we want to manually queue it for sending later, then do it if (method == MessageComposer::MessageSender::SendLater) { qjob->dispatchModeAttribute().setDispatchMode(MailTransport::DispatchModeAttribute::Manual); } // Get addresses. QStringList to, cc, bcc; QString from; extractSenderToCCAndBcc(message, from, to, cc, bcc); qjob->addressAttribute().setFrom(from); qjob->addressAttribute().setTo(to); qjob->addressAttribute().setCc(cc); qjob->addressAttribute().setBcc(bcc); MessageComposer::Util::addSendReplyForwardAction(message, qjob); MessageCore::StringUtil::removePrivateHeaderFields(message, false); message->assemble(); // Queue the message. connect(qjob, &MessageQueueJob::result, this, &AkonadiSender::queueJobResult); d->mPendingJobs.insert(qjob); qjob->start(); qCDebug(MESSAGECOMPOSER_LOG) << "QueueJob started."; // TODO potential problem: // The MDA finishes sending a message before I queue the next one, and // thinking it is finished, the progress item deletes itself. // Turn the MDA offline until everything is queued? } void AkonadiSender::queueJobResult(KJob *job) { Q_ASSERT(d->mPendingJobs.contains(job)); d->mPendingJobs.remove(job); if (job->error()) { qCDebug(MESSAGECOMPOSER_LOG) << "QueueJob failed with error" << job->errorString(); } else { qCDebug(MESSAGECOMPOSER_LOG) << "QueueJob success."; } } diff --git a/messagecomposer/src/snippet/autotests/convertvariablesjobtest.cpp b/messagecomposer/src/snippet/autotests/convertvariablesjobtest.cpp index 9d09eca3..86fce4d8 100644 --- a/messagecomposer/src/snippet/autotests/convertvariablesjobtest.cpp +++ b/messagecomposer/src/snippet/autotests/convertvariablesjobtest.cpp @@ -1,75 +1,75 @@ /* Copyright (C) 2019 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "convertvariablesjobtest.h" #include "snippet/convertsnippetvariablesjob.h" #include #include "composer/composerviewbase.h" #include "composer/composerviewinterface.h" QTEST_GUILESS_MAIN(ConvertVariablesJobTest) ConvertVariablesJobTest::ConvertVariablesJobTest(QObject *parent) : QObject(parent) { } void ConvertVariablesJobTest::shouldHaveDefaultValues() { MessageComposer::ConvertSnippetVariablesJob job; QVERIFY(job.text().isEmpty()); QVERIFY(!job.composerViewInterface()); QVERIFY(!job.canStart()); } void ConvertVariablesJobTest::shouldCanStart() { MessageComposer::ConvertSnippetVariablesJob job; QVERIFY(!job.canStart()); job.setText(QStringLiteral("bla")); QVERIFY(!job.canStart()); MessageComposer::ComposerViewBase b; MessageComposer::ComposerViewInterface *interface = new MessageComposer::ComposerViewInterface(&b); job.setComposerViewInterface(interface); QVERIFY(job.canStart()); } void ConvertVariablesJobTest::shouldConvertVariables() { QFETCH(QString, original); QFETCH(QString, expected); MessageComposer::ComposerViewBase b; MessageComposer::ComposerViewInterface *interface = new MessageComposer::ComposerViewInterface(&b); MessageComposer::ConvertSnippetVariablesJob job; job.setComposerViewInterface(interface); b.setSubject(QStringLiteral("Subject!!!!")); b.setFrom(QStringLiteral("from!!")); //TOOD add CC/BCC/TO job.setText(original); - QCOMPARE(job.convertVariables(), expected); + QCOMPARE(job.convertVariables(interface, original), expected); } void ConvertVariablesJobTest::shouldConvertVariables_data() { QTest::addColumn("original"); QTest::addColumn("expected"); QTest::newRow("empty") << QString() << QString(); QTest::newRow("novariable") << QStringLiteral("bla bli blo") << QStringLiteral("bla bli blo"); QTest::newRow("subject") << QStringLiteral("bla bli blo %FULLSUBJECT") << QStringLiteral("bla bli blo Subject!!!!"); } diff --git a/messagecomposer/src/snippet/convertsnippetvariablesjob.cpp b/messagecomposer/src/snippet/convertsnippetvariablesjob.cpp index f070c8eb..32fce483 100644 --- a/messagecomposer/src/snippet/convertsnippetvariablesjob.cpp +++ b/messagecomposer/src/snippet/convertsnippetvariablesjob.cpp @@ -1,150 +1,150 @@ /* Copyright (C) 2019 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "convertsnippetvariablesjob.h" #include "messagecomposer_debug.h" #include "composer/composerviewinterface.h" #include using namespace MessageComposer; ConvertSnippetVariablesJob::ConvertSnippetVariablesJob(QObject *parent) : QObject(parent) { } ConvertSnippetVariablesJob::~ConvertSnippetVariablesJob() { delete mComposerViewInterface; } void ConvertSnippetVariablesJob::setText(const QString &str) { mText = str; } bool ConvertSnippetVariablesJob::canStart() const { if (mText.isEmpty() || !mComposerViewInterface) { return false; } return true; } void ConvertSnippetVariablesJob::start() { if (!canStart()) { Q_EMIT textConverted(QString()); deleteLater(); return; } - Q_EMIT textConverted(convertVariables()); + Q_EMIT textConverted(convertVariables(mComposerViewInterface, mText)); deleteLater(); } QString ConvertSnippetVariablesJob::text() const { return mText; } MessageComposer::ComposerViewInterface *ConvertSnippetVariablesJob::composerViewInterface() const { return mComposerViewInterface; } void ConvertSnippetVariablesJob::setComposerViewInterface(MessageComposer::ComposerViewInterface *composerViewInterface) { mComposerViewInterface = composerViewInterface; } -QString ConvertSnippetVariablesJob::convertVariables() const +QString ConvertSnippetVariablesJob::convertVariables(MessageComposer::ComposerViewInterface *composerView, const QString &text) { QString result; - const int tmpl_len = mText.length(); + const int tmpl_len = text.length(); for (int i = 0; i < tmpl_len; ++i) { - const QChar c = mText[i]; + const QChar c = text[i]; if (c == QLatin1Char('%')) { - const QString cmd = mText.mid(i + 1); + const QString cmd = text.mid(i + 1); if (cmd.startsWith(QLatin1String("CCADDR"))) { i += strlen("CCADDR"); - const QString str = mComposerViewInterface->cc(); + const QString str = composerView->cc(); result.append(str); } else if (cmd.startsWith(QLatin1String("FULLSUBJECT"))) { i += strlen("FULLSUBJECT"); - const QString str = mComposerViewInterface->subject(); + const QString str = composerView->subject(); result.append(str); } else if (cmd.startsWith(QLatin1String("TOADDR"))) { i += strlen("TOADDR"); - const QString str = mComposerViewInterface->to(); + const QString str = composerView->to(); result.append(str); } else if (cmd.startsWith(QLatin1String("TOFNAME"))) { i += strlen("TOFNAME"); - const QString str = TemplateParser::Util::getFirstNameFromEmail(mComposerViewInterface->to()); + const QString str = TemplateParser::Util::getFirstNameFromEmail(composerView->to()); result.append(str); } else if (cmd.startsWith(QLatin1String("TOLNAME"))) { i += strlen("TOLNAME"); - const QString str = TemplateParser::Util::getLastNameFromEmail(mComposerViewInterface->to()); + const QString str = TemplateParser::Util::getLastNameFromEmail(composerView->to()); result.append(str); } else if (cmd.startsWith(QLatin1String("FROMADDR"))) { i += strlen("FROMADDR"); - const QString str = mComposerViewInterface->from(); + const QString str = composerView->from(); result.append(str); } else if (cmd.startsWith(QLatin1String("DOW"))) { i += strlen("DOW"); - const QString str = mComposerViewInterface->insertDayOfWeek(); + const QString str = composerView->insertDayOfWeek(); result.append(str); } else if (cmd.startsWith(QLatin1String("DATE"))) { i += strlen("DATE"); - const QString str = mComposerViewInterface->longDate(); + const QString str = composerView->longDate(); result.append(str); } else if (cmd.startsWith(QLatin1String("SHORTDATE"))) { i += strlen("SHORTDATE"); - const QString str = mComposerViewInterface->shortDate(); + const QString str = composerView->shortDate(); result.append(str); } else if (cmd.startsWith(QLatin1String("TIME"))) { i += strlen("TIME"); - const QString str = mComposerViewInterface->shortTime(); + const QString str = composerView->shortTime(); result.append(str); } else if (cmd.startsWith(QLatin1String("TIMELONG"))) { i += strlen("TIMELONG"); - const QString str = mComposerViewInterface->longTime(); + const QString str = composerView->longTime(); result.append(str); } else if (cmd.startsWith(QLatin1String("ATTACHMENTCOUNT"))) { i += strlen("ATTACHMENTCOUNT"); - const QString str = QString::number(mComposerViewInterface->attachments().count()); + const QString str = QString::number(composerView->attachments().count()); result.append(str); } else if (cmd.startsWith(QLatin1String("ATTACHMENTNAMES"))) { i += strlen("ATTACHMENTNAMES"); - const QString str = mComposerViewInterface->attachments().names().join(QLatin1Char(',')); + const QString str = composerView->attachments().names().join(QLatin1Char(',')); result.append(str); } else if (cmd.startsWith(QLatin1String("ATTACHMENTFILENAMES"))) { i += strlen("ATTACHMENTFILENAMES"); - const QString str = mComposerViewInterface->attachments().fileNames().join(QLatin1Char(',')); + const QString str = composerView->attachments().fileNames().join(QLatin1Char(',')); result.append(str); } else if (cmd.startsWith(QLatin1String("ATTACHMENTNAMESANDSIZES"))) { i += strlen("ATTACHMENTNAMESANDSIZES"); - const QString str = mComposerViewInterface->attachments().namesAndSize().join(QLatin1Char(',')); + const QString str = composerView->attachments().namesAndSize().join(QLatin1Char(',')); result.append(str); } else { result.append(c); } } else { result.append(c); } } return result; } diff --git a/messagecomposer/src/snippet/convertsnippetvariablesjob.h b/messagecomposer/src/snippet/convertsnippetvariablesjob.h index 911c8692..7ee3b593 100644 --- a/messagecomposer/src/snippet/convertsnippetvariablesjob.h +++ b/messagecomposer/src/snippet/convertsnippetvariablesjob.h @@ -1,51 +1,51 @@ /* Copyright (C) 2019 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CONVERTSNIPPETVARIABLESJOB_H #define CONVERTSNIPPETVARIABLESJOB_H #include #include "messagecomposer_export.h" namespace MessageComposer { class ComposerViewInterface; class MESSAGECOMPOSER_EXPORT ConvertSnippetVariablesJob : public QObject { Q_OBJECT public: explicit ConvertSnippetVariablesJob(QObject *parent = nullptr); ~ConvertSnippetVariablesJob(); void start(); void setText(const QString &str); Q_REQUIRED_RESULT QString text() const; MessageComposer::ComposerViewInterface *composerViewInterface() const; void setComposerViewInterface(MessageComposer::ComposerViewInterface *composerViewInterface); - Q_REQUIRED_RESULT QString convertVariables() const; + static Q_REQUIRED_RESULT QString convertVariables(MessageComposer::ComposerViewInterface *composerView, const QString &text); Q_REQUIRED_RESULT bool canStart() const; Q_SIGNALS: void textConverted(const QString &str); private: QString mText; MessageComposer::ComposerViewInterface *mComposerViewInterface = nullptr; }; } #endif // CONVERTVARIABLESJOB_H