Mailcommon

filteractionforward.cpp
1/*
2 * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <taferner@kde.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 *
6 */
7
8#include "filteractionforward.h"
9#include "mailcommon_debug.h"
10
11#include "filter/dialog/filteractionmissingtemplatedialog.h"
12#include "kernel/mailkernel.h"
13
14#include <Akonadi/EmailAddressRequester>
15#include <MessageComposer/MessageFactoryNG>
16#include <MessageComposer/MessageSender>
17#include <MessageCore/StringUtil>
18#include <TemplateParser/CustomTemplates>
19#include <templateparser/customtemplates_kfg.h>
20
21#include <KComboBox>
22#include <KLineEdit>
23#include <KLocalizedString>
24
25#include <QHBoxLayout>
26
27using namespace MailCommon;
28
29FilterAction *FilterActionForward::newAction()
30{
31 return new FilterActionForward;
32}
33
34FilterActionForward::FilterActionForward(QObject *parent)
35 : FilterActionWithAddress(QStringLiteral("forward"), i18nc("Forward directly not with a command", "Forward To"), parent)
36{
37}
38
39FilterAction::ReturnCode FilterActionForward::process(ItemContext &context, bool) const
40{
41 if (mParameter.isEmpty()) {
42 return ErrorButGoOn;
43 }
44
45 const auto msg = context.item().payload<KMime::Message::Ptr>();
46 // avoid endless loops when this action is used in a filter
47 // which applies to sent messages
48 if (MessageCore::StringUtil::addressIsInAddressList(mParameter, QStringList(msg->to()->asUnicodeString()))) {
49 qCWarning(MAILCOMMON_LOG) << "Attempt to forward to recipient of original message, ignoring.";
50 return ErrorButGoOn;
51 }
52#if 0 // PORT ME TO ASync
53 MessageComposer::MessageFactoryNG factory(msg, context.item().id());
54 factory.setIdentityManager(KernelIf->identityManager());
55 factory.setFolderIdentity(Util::folderIdentity(context.item()));
56 factory.setTemplate(mTemplate);
57
58 KMime::Message::Ptr fwdMsg = factory.createForward();
59 fwdMsg->to()->fromUnicodeString(fwdMsg->to()->asUnicodeString() + QLatin1Char(',') + mParameter, "utf-8");
60 if (!KernelIf->msgSender()->send(fwdMsg, MessageComposer::MessageSender::SendDefault)) {
61 qCWarning(MAILCOMMON_LOG) << "FilterAction: could not forward message (sending failed)";
62 return ErrorButGoOn; // error: couldn't send
63 } else {
64 sendMDN(context.item(), KMime::MDN::Dispatched);
65 }
66#endif
67 // (the msgSender takes ownership of the message, so don't delete it here)
68 return GoOn;
69}
70
71SearchRule::RequiredPart FilterActionForward::requiredPart() const
72{
74}
75
76QWidget *FilterActionForward::createParamWidget(QWidget *parent) const
77{
78 auto addressAndTemplate = new QWidget(parent);
79 auto layout = new QHBoxLayout(addressAndTemplate);
80 layout->setContentsMargins({});
81
82 QWidget *addressEdit = FilterActionWithAddress::createParamWidget(addressAndTemplate);
83 addressEdit->setObjectName(QLatin1StringView("addressEdit"));
84 layout->addWidget(addressEdit);
85
86 auto addressRequester = qobject_cast<Akonadi::EmailAddressRequester *>(addressEdit);
87 Q_ASSERT(addressRequester);
88 KLineEdit *lineEdit = addressRequester->lineEdit();
89 lineEdit->setClearButtonEnabled(true);
90 lineEdit->setTrapReturnKey(true);
91 lineEdit->setToolTip(i18n("The addressee to whom the message will be forwarded."));
92 lineEdit->setWhatsThis(i18n("The filter will forward the message to the addressee entered here."));
93
94 auto templateCombo = new KComboBox(addressAndTemplate);
95 templateCombo->setMinimumWidth(50);
96 templateCombo->setObjectName(QLatin1StringView("templateCombo"));
97 layout->addWidget(templateCombo);
98
99 templateCombo->addItem(i18n("Default Template"));
100
101 const QStringList templateNames = SettingsIf->customTemplates();
102 for (const QString &templateName : templateNames) {
103 TemplateParser::CTemplates templat(templateName);
104 if (templat.type() == TemplateParser::CustomTemplates::TForward || templat.type() == TemplateParser::CustomTemplates::TUniversal) {
105 templateCombo->addItem(templateName);
106 }
107 }
108
109 templateCombo->setEnabled(templateCombo->count() > 1);
110 templateCombo->setToolTip(i18n("The template used when forwarding"));
111 templateCombo->setWhatsThis(i18n("Set the forwarding template that will be used with this filter."));
114
115 return addressAndTemplate;
116}
117
118void FilterActionForward::applyParamWidgetValue(QWidget *paramWidget)
119{
120 auto addressEdit = paramWidget->findChild<QWidget *>(QStringLiteral("addressEdit"));
121 Q_ASSERT(addressEdit);
123
124 const auto templateCombo = paramWidget->findChild<KComboBox *>(QStringLiteral("templateCombo"));
125 Q_ASSERT(templateCombo);
126
127 if (templateCombo->currentIndex() == 0) {
128 // Default template, so don't use a custom one
129 mTemplate.clear();
130 } else {
131 mTemplate = templateCombo->currentText();
132 }
133}
134
135void FilterActionForward::setParamWidgetValue(QWidget *paramWidget) const
136{
137 auto addressEdit = paramWidget->findChild<QWidget *>(QStringLiteral("addressEdit"));
138 Q_ASSERT(addressEdit);
140
141 const auto templateCombo = paramWidget->findChild<KComboBox *>(QStringLiteral("templateCombo"));
142 Q_ASSERT(templateCombo);
143
144 if (mTemplate.isEmpty()) {
145 templateCombo->setCurrentIndex(0);
146 } else {
147 int templateIndex = templateCombo->findText(mTemplate);
148 if (templateIndex != -1) {
149 templateCombo->setCurrentIndex(templateIndex);
150 } else {
151 mTemplate.clear();
152 }
153 }
154}
155
156void FilterActionForward::clearParamWidget(QWidget *paramWidget) const
157{
158 auto addressEdit = paramWidget->findChild<QWidget *>(QStringLiteral("addressEdit"));
159 Q_ASSERT(addressEdit);
161
162 const auto templateCombo = paramWidget->findChild<KComboBox *>(QStringLiteral("templateCombo"));
163 Q_ASSERT(templateCombo);
164
165 templateCombo->setCurrentIndex(0);
166}
167
168// We simply place a "@$$@" between the two parameters. The template is the last
169// parameter in the string, for compatibility reasons.
170namespace
171{
172inline const QString forwardFilterArgsSeperator()
173{
174 return QStringLiteral("@$$@");
175}
176}
177void FilterActionForward::argsFromString(const QString &argsStr)
178{
179 const int seperatorPos = argsStr.indexOf(forwardFilterArgsSeperator());
180
181 if (seperatorPos == -1) {
182 // Old config, assume that the whole string is the addressee
184 } else {
185 const QString addressee = argsStr.left(seperatorPos);
186 mTemplate = argsStr.mid(seperatorPos + forwardFilterArgsSeperator().length());
188 }
189}
190
191bool FilterActionForward::argsFromStringInteractive(const QString &argsStr, const QString &filterName)
192{
193 bool needUpdate = false;
194 argsFromString(argsStr);
195 if (!mTemplate.isEmpty()) {
196 const QStringList templateNames = SettingsIf->customTemplates();
197 QStringList currentTemplateList;
198 currentTemplateList << i18n("Default Template");
199 for (const QString &templateName : templateNames) {
200 TemplateParser::CTemplates templat(templateName);
201 if (templat.type() == TemplateParser::CustomTemplates::TForward || templat.type() == TemplateParser::CustomTemplates::TUniversal) {
202 if (templateName == mTemplate) {
203 return false;
204 }
205 currentTemplateList << templateName;
206 }
207 }
208 QPointer<MailCommon::FilterActionMissingTemplateDialog> dlg = new MailCommon::FilterActionMissingTemplateDialog(currentTemplateList, filterName);
209 if (dlg->exec()) {
210 mTemplate = dlg->selectedTemplate();
211 needUpdate = true;
212 }
213 delete dlg;
214 }
215 return needUpdate;
216}
217
218QString FilterActionForward::argsAsString() const
219{
220 return FilterActionWithAddress::argsAsString() + forwardFilterArgsSeperator() + mTemplate;
221}
222
223QString FilterActionForward::displayString() const
224{
225 if (mTemplate.isEmpty()) {
226 return i18n("Forward to %1 with default template", mParameter);
227 } else {
228 return i18n("Forward to %1 with template %2", mParameter, mTemplate);
229 }
230}
231
232QString FilterActionForward::informationAboutNotValidAction() const
233{
234 return i18n("Email address was not defined.");
235}
236
237#include "moc_filteractionforward.cpp"
Id id() const
T payload() const
void setTrapReturnKey(bool trap)
Abstract base class for filter actions with a mail address as parameter.
QWidget * createParamWidget(QWidget *parent) const override
Creates a widget for setting the filter action parameter.
void applyParamWidgetValue(QWidget *paramWidget) override
The filter action shall set it's parameter from the widget's contents.
void setParamWidgetValue(QWidget *paramWidget) const override
The filter action shall set it's widget's contents from it's parameter.
void clearParamWidget(QWidget *paramWidget) const override
The filter action shall clear it's parameter widget's contents.
Abstract base class for mail filter actions.
virtual void argsFromString(const QString &argsStr)=0
Read extra arguments from given string.
static void sendMDN(const Akonadi::Item &item, KMime::MDN::DispositionType d, const QList< KMime::MDN::DispositionModifier > &m=QList< KMime::MDN::DispositionModifier >())
Automates the sending of MDNs from filter actions.
virtual QString argsAsString() const =0
Return extra arguments as string.
ReturnCode
Describes the possible return codes of filter processing:
@ ErrorButGoOn
A non-critical error occurred.
@ GoOn
Go on with applying filter actions.
void filterActionModified()
Called to notify that the current FilterAction has had some value modification.
A helper class for the filtering process.
Definition itemcontext.h:27
Akonadi::Item & item()
Returns the item of the context.
RequiredPart
Possible required parts.
Definition searchrule.h:68
@ CompleteMessage
Whole message.
Definition searchrule.h:71
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
MAILCOMMON_EXPORT uint folderIdentity(const Akonadi::Item &item)
Returns the identity of the folder that contains the given Akonadi::Item.
Definition mailutil.cpp:176
The filter dialog.
bool addressIsInAddressList(const QString &address, const QStringList &addresses)
void currentIndexChanged(int index)
void setClearButtonEnabled(bool enable)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T findChild(const QString &name, Qt::FindChildOptions options) const const
QObject * parent() const const
void setObjectName(QAnyStringView name)
void clear()
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
QString mid(qsizetype position, qsizetype n) const const
void setToolTip(const QString &)
void setWhatsThis(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.