Mailcommon

filteractionrewriteheader.cpp
1 /*
2  * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <[email protected]>
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  *
6  */
7 
8 #include "filteractionrewriteheader.h"
9 
10 #include <KComboBox>
11 #include <KLineEdit>
12 #include <KLocalizedString>
13 
14 #include <QHBoxLayout>
15 #include <QLabel>
16 
17 using namespace MailCommon;
18 
19 FilterAction *FilterActionRewriteHeader::newAction()
20 {
21  return new FilterActionRewriteHeader;
22 }
23 
24 FilterActionRewriteHeader::FilterActionRewriteHeader(QObject *parent)
25  : FilterActionWithStringList(QStringLiteral("rewrite header"), i18n("Rewrite Header"), parent)
26 {
27  mParameterList << QString() << QStringLiteral("Subject") << QStringLiteral("Reply-To") << QStringLiteral("Delivered-To")
28  << QStringLiteral("X-KDE-PR-Message") << QStringLiteral("X-KDE-PR-Package") << QStringLiteral("X-KDE-PR-Keywords");
29 
30  mParameter = mParameterList.at(0);
31 }
32 
33 bool FilterActionRewriteHeader::isEmpty() const
34 {
35  return mParameter.isEmpty() || mRegex.pattern().isEmpty();
36 }
37 
38 QString FilterActionRewriteHeader::informationAboutNotValidAction() const
39 {
40  QString info;
41  if (mParameter.isEmpty()) {
42  info = i18n("Header not defined");
43  }
44  if (mRegex.pattern().isEmpty()) {
45  if (!info.isEmpty()) {
46  info += QLatin1Char('\n');
47  }
48  info += i18n("Search string is empty.");
49  }
50  return info;
51 }
52 
53 FilterAction::ReturnCode FilterActionRewriteHeader::process(ItemContext &context, bool) const
54 {
55  if (isEmpty()) {
56  return ErrorButGoOn;
57  }
58 
59  const auto msg = context.item().payload<KMime::Message::Ptr>();
60 
61  const QByteArray param(mParameter.toLatin1());
62  KMime::Headers::Base *header = msg->headerByType(param.constData());
63  if (!header) {
64  return GoOn; // TODO: Maybe create a new header by type?
65  }
66 
67  QString value = header->asUnicodeString();
68  const QString oldValue = value;
69  const QString newValue = value.replace(mRegex, mReplacementString);
70  if (newValue != oldValue) {
71  msg->removeHeader(param.constData());
72 
73  KMime::Headers::Base *newheader = KMime::Headers::createHeader(param);
74  if (!newheader) {
75  newheader = new KMime::Headers::Generic(param.constData());
76  }
77  newheader->fromUnicodeString(newValue, "utf-8");
78  msg->setHeader(newheader);
79  msg->assemble();
80 
81  context.setNeedsPayloadStore();
82  }
83  return GoOn;
84 }
85 
86 SearchRule::RequiredPart FilterActionRewriteHeader::requiredPart() const
87 {
89 }
90 
91 QWidget *FilterActionRewriteHeader::createParamWidget(QWidget *parent) const
92 {
93  auto widget = new QWidget(parent);
94  auto layout = new QHBoxLayout(widget);
95  layout->setSpacing(4);
96  layout->setContentsMargins({});
97 
98  auto comboBox = new KComboBox(widget);
99  comboBox->setMinimumWidth(50);
100  comboBox->setEditable(true);
101  comboBox->setObjectName(QStringLiteral("combo"));
102  comboBox->setInsertPolicy(QComboBox::InsertAtBottom);
103  layout->addWidget(comboBox, 0 /* stretch */);
104 
105  KCompletion *comp = comboBox->completionObject();
106  comp->setIgnoreCase(true);
107  comp->insertItems(mParameterList);
109 
110  auto label = new QLabel(i18n("Replace:"), widget);
111  label->setObjectName(QStringLiteral("label_replace"));
112  label->setFixedWidth(label->sizeHint().width());
113  layout->addWidget(label, 0);
114 
115  auto regExpLineEdit = new KLineEdit(widget);
116  regExpLineEdit->setClearButtonEnabled(true);
117  regExpLineEdit->setTrapReturnKey(true);
118  regExpLineEdit->setObjectName(QStringLiteral("search"));
119  layout->addWidget(regExpLineEdit, 1);
120 
121  label = new QLabel(i18n("With:"), widget);
122  label->setFixedWidth(label->sizeHint().width());
123  label->setObjectName(QStringLiteral("label_with"));
124  layout->addWidget(label, 0);
125 
126  auto lineEdit = new KLineEdit(widget);
127  lineEdit->setObjectName(QStringLiteral("replace"));
128  lineEdit->setClearButtonEnabled(true);
129  lineEdit->setTrapReturnKey(true);
130  layout->addWidget(lineEdit, 1);
131 
132  setParamWidgetValue(widget);
133  connect(comboBox, &KComboBox::currentIndexChanged, this, &FilterActionRewriteHeader::filterActionModified);
134  connect(comboBox->lineEdit(), &QLineEdit::textChanged, this, &FilterAction::filterActionModified);
135  connect(regExpLineEdit, &KLineEdit::textChanged, this, &FilterActionRewriteHeader::filterActionModified);
136  connect(lineEdit, &KLineEdit::textChanged, this, &FilterActionRewriteHeader::filterActionModified);
137 
138  return widget;
139 }
140 
141 void FilterActionRewriteHeader::setParamWidgetValue(QWidget *paramWidget) const
142 {
143  const int index = mParameterList.indexOf(mParameter);
144  const auto comboBox = paramWidget->findChild<KComboBox *>(QStringLiteral("combo"));
145  Q_ASSERT(comboBox);
146 
147  comboBox->clear();
148  comboBox->addItems(mParameterList);
149  if (index < 0) {
150  comboBox->addItem(mParameter);
151  comboBox->setCurrentIndex(comboBox->count() - 1);
152  } else {
153  comboBox->setCurrentIndex(index);
154  }
155 
156  auto *regExpLineEdit = paramWidget->findChild<KLineEdit *>(QStringLiteral("search"));
157  Q_ASSERT(regExpLineEdit);
158  regExpLineEdit->setText(mRegex.pattern());
159 
160  auto *lineEdit = paramWidget->findChild<KLineEdit *>(QStringLiteral("replace"));
161  Q_ASSERT(lineEdit);
162  lineEdit->setText(mReplacementString);
163 }
164 
165 void FilterActionRewriteHeader::applyParamWidgetValue(QWidget *paramWidget)
166 {
167  const auto comboBox = paramWidget->findChild<KComboBox *>(QStringLiteral("combo"));
168  Q_ASSERT(comboBox);
169  mParameter = comboBox->currentText();
170 
171  const KLineEdit *regExpLineEdit = paramWidget->findChild<KLineEdit *>(QStringLiteral("search"));
172  Q_ASSERT(regExpLineEdit);
173  mRegex.setPattern(regExpLineEdit->text());
174 
175  const KLineEdit *lineEdit = paramWidget->findChild<KLineEdit *>(QStringLiteral("replace"));
176  Q_ASSERT(lineEdit);
177  mReplacementString = lineEdit->text();
178 }
179 
180 void FilterActionRewriteHeader::clearParamWidget(QWidget *paramWidget) const
181 {
182  const auto comboBox = paramWidget->findChild<KComboBox *>(QStringLiteral("combo"));
183  Q_ASSERT(comboBox);
184  comboBox->setCurrentIndex(0);
185 
186  auto *regExpLineEdit = paramWidget->findChild<KLineEdit *>(QStringLiteral("search"));
187  Q_ASSERT(regExpLineEdit);
188  regExpLineEdit->clear();
189 
190  auto *lineEdit = paramWidget->findChild<KLineEdit *>(QStringLiteral("replace"));
191  Q_ASSERT(lineEdit);
192  lineEdit->clear();
193 }
194 
195 QString FilterActionRewriteHeader::argsAsString() const
196 {
197  QString result = mParameter;
198  result += QLatin1Char('\t');
199  result += mRegex.pattern();
200  result += QLatin1Char('\t');
201  result += mReplacementString;
202 
203  return result;
204 }
205 
206 QString FilterActionRewriteHeader::displayString() const
207 {
208  return label() + QStringLiteral(" \"") + argsAsString().toHtmlEscaped() + QStringLiteral("\"");
209 }
210 
211 void FilterActionRewriteHeader::argsFromString(const QString &argsStr)
212 {
213  const QStringList list = argsStr.split(QLatin1Char('\t'));
214  if (list.count() < 3) {
215  return;
216  }
217  QString result;
218 
219  result = list[0];
220  mRegex.setPattern(list[1]);
221  mReplacementString = list[2];
222 
223  int index = mParameterList.indexOf(result);
224  if (index < 0) {
225  mParameterList.append(result);
226  index = mParameterList.count() - 1;
227  }
228 
229  mParameter = mParameterList.at(index);
230 }
QString toHtmlEscaped() const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
int count(const T &value) const const
Abstract base class for filter actions with a fixed set of string parameters.
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
void insertItems(const QStringList &items)
void clear()
Abstract base class for mail filter actions.
Definition: filteraction.h:38
QString i18n(const char *text, const TYPE &arg...)
RequiredPart
Possible required parts.
Definition: searchrule.h:68
void textChanged(const QString &text)
bool isEmpty() const const
void filterActionModified()
Called to notify that the current FilterAction has had some value modification.
virtual void setIgnoreCase(bool ignoreCase)
void setNeedsPayloadStore()
Marks that the item's payload has been changed and needs to be written back.
Definition: itemcontext.cpp:33
int indexOf(QStringView str, int from) const const
virtual void setCompletionMode(CompletionMode mode)
QString & replace(int position, int n, QChar after)
virtual void fromUnicodeString(const QString &s, const QByteArray &b)=0
T findChild(const QString &name, Qt::FindChildOptions options) const const
A helper class for the filtering process.
Definition: itemcontext.h:26
QString label(StandardShortcut id)
ReturnCode
Describes the possible return codes of filter processing:
Definition: filteraction.h:45
@ CompleteMessage
Whole message.
Definition: searchrule.h:71
void currentIndexChanged(int index)
virtual QString asUnicodeString() const=0
Akonadi::Item & item()
Returns the item of the context.
Definition: itemcontext.cpp:18
The filter dialog.
T payload() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Sep 24 2022 03:58:15 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.