7#include "mailcommon_debug.h"
8#include "searchrule/searchruleattachment.h"
9#include "searchrule/searchruledate.h"
10#include "searchrule/searchruleencryption.h"
11#include "searchrule/searchruleinvitation.h"
12#include "searchrule/searchrulenumerical.h"
13#include "searchrule/searchrulestatus.h"
14#include "searchrule/searchrulestring.h"
16#include <KConfigGroup>
24static const char *
const funcConfigNames[] = {
"contains",
35 "is-not-in-addressbook",
47static const int numFuncConfigNames =
sizeof funcConfigNames /
sizeof *funcConfigNames;
72 mField = other.mField;
73 mFunction = other.mFunction;
74 mContents = other.mContents;
82 if (
field ==
"<status>") {
84 }
else if (
field ==
"<age in days>" ||
field ==
"<size>") {
86 }
else if (
field ==
"<date>") {
88 }
else if (
field ==
"<encryption>") {
90 }
else if (
field ==
"<attachment>") {
92 }
else if (
field ==
"<invitation>") {
113 const char cIdx = char(
int(
'A') + aIdx);
116 static const QString func = QStringLiteral(
"func");
123 if (field2 ==
"<To or Cc>") {
150 for (
int i = 0; i < numFuncConfigNames; ++i) {
151 if (qstricmp(funcConfigNames[i], str) == 0) {
152 return static_cast<Function
>(i);
159QString SearchRule::functionToString(Function function)
162 return funcConfigNames[int(
function)];
164 return QStringLiteral(
"invalid");
170 const char cIdx = char(
'A' + aIdx);
172 static const QString func = QStringLiteral(
"func");
176 config.
writeEntry(func + cIdx, functionToString(mFunction));
180QString SearchRule::conditionToString(Function function)
188 str =
i18n(
"not equal");
191 str =
i18n(
"is greater");
193 case FuncIsLessOrEqual:
194 str =
i18n(
"is less or equal");
197 str =
i18n(
"is less");
199 case FuncIsGreaterOrEqual:
200 str =
i18n(
"is greater or equal");
202 case FuncIsInAddressbook:
203 str =
i18n(
"is in addressbook");
205 case FuncIsNotInAddressbook:
206 str =
i18n(
"is not in addressbook");
208 case FuncIsInCategory:
209 str =
i18n(
"is in category");
211 case FuncIsNotInCategory:
212 str =
i18n(
"is in category");
214 case FuncHasAttachment:
215 str =
i18n(
"has an attachment");
217 case FuncHasNoAttachment:
218 str =
i18n(
"has not an attachment");
220 case FuncHasInvitation:
221 str =
i18n(
"has an invitation");
223 case FuncHasNoInvitation:
224 str =
i18n(
"has not an invitation");
227 str =
i18n(
"start with");
229 case FuncNotStartWith:
230 str =
i18n(
"not start with");
233 str =
i18n(
"end with");
236 str =
i18n(
"not end with");
242 str =
i18n(
"contains");
244 case FuncContainsNot:
245 str =
i18n(
"not contains");
248 str =
i18n(
"has regexp");
251 str =
i18n(
"not regexp");
257void SearchRule::generateSieveScript(QStringList &requireModules, QString &code)
259 QString contentStr = mContents;
260 if (mField ==
"<size>") {
265 comparison = QLatin1Char(
'"') +
i18n(
"size equals not supported") + QLatin1Char(
'"');
268 comparison = QLatin1Char(
'"') +
i18n(
"size not equals not supported") + QLatin1Char(
'"');
271 comparison = QStringLiteral(
":over");
273 case FuncIsLessOrEqual:
274 comparison = QStringLiteral(
":under");
278 comparison = QStringLiteral(
":under");
280 case FuncIsGreaterOrEqual:
281 comparison = QStringLiteral(
":over");
284 case FuncIsInAddressbook:
285 case FuncIsNotInAddressbook:
286 case FuncIsInCategory:
287 case FuncIsNotInCategory:
288 case FuncHasAttachment:
289 case FuncHasNoAttachment:
290 case FuncHasInvitation:
291 case FuncHasNoInvitation:
293 case FuncNotStartWith:
298 case FuncContainsNot:
301 code += QLatin1Char(
'"') +
i18n(
"\"%1\" is not supported with condition \"%2\"", QLatin1StringView(mField), conditionToString(mFunction))
305 code += QStringLiteral(
"size %1 %2K").
arg(comparison).
arg(
QString::number(mContents.toInt() + offset));
306 }
else if (mField ==
"<status>") {
308 code += QLatin1Char(
'"') +
i18n(
"<status> not implemented/supported") + QLatin1Char(
'"');
309 }
else if (mField ==
"<any header>") {
311 code += QLatin1Char(
'"') +
i18n(
"<any header> not implemented/supported") + QLatin1Char(
'"');
312 }
else if (mField ==
"contents") {
314 code += QLatin1Char(
'"') +
i18n(
"<contents> not implemented/supported") + QLatin1Char(
'"');
315 }
else if (mField ==
"<age in days>") {
317 code += QLatin1Char(
'"') +
i18n(
"<age in days> not implemented/supported") + QLatin1Char(
'"');
318 }
else if (mField ==
"<date>") {
320 code += QLatin1Char(
'"') +
i18n(
"<date> not implemented/supported") + QLatin1Char(
'"');
321 }
else if (mField ==
"<recipients>") {
323 code += QLatin1Char(
'"') +
i18n(
"<recipients> not implemented/supported") + QLatin1Char(
'"');
324 }
else if (mField ==
"<tag>") {
325 code += QLatin1Char(
'"') +
i18n(
"<Tag> is not supported") + QLatin1Char(
'"');
326 }
else if (mField ==
"<message>") {
328 code +=
i18n(
"<message> not implemented/supported");
329 }
else if (mField ==
"<body>") {
330 if (!requireModules.
contains(QLatin1StringView(
"body"))) {
331 requireModules << QStringLiteral(
"body");
334 bool negative =
false;
339 comparison = QStringLiteral(
":contains");
341 case FuncContainsNot:
343 comparison = QStringLiteral(
":contains");
346 comparison = QStringLiteral(
":is");
349 comparison = QStringLiteral(
":is");
353 comparison = QStringLiteral(
":regex");
354 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
355 requireModules << QStringLiteral(
"regex");
359 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
360 requireModules << QStringLiteral(
"regex");
362 comparison = QStringLiteral(
":regex");
366 comparison = QStringLiteral(
":regex");
367 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
368 requireModules << QStringLiteral(
"regex");
370 contentStr = QLatin1Char(
'^') + contentStr;
372 case FuncNotStartWith:
373 comparison = QStringLiteral(
":regex");
374 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
375 requireModules << QStringLiteral(
"regex");
377 comparison = QStringLiteral(
":regex");
378 contentStr = QLatin1Char(
'^') + contentStr;
382 comparison = QStringLiteral(
":regex");
383 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
384 requireModules << QStringLiteral(
"regex");
386 comparison = QStringLiteral(
":regex");
387 contentStr = contentStr + QLatin1Char(
'$');
390 comparison = QStringLiteral(
":regex");
391 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
392 requireModules << QStringLiteral(
"regex");
394 comparison = QStringLiteral(
":regex");
395 contentStr = contentStr + QLatin1Char(
'$');
399 case FuncIsLessOrEqual:
401 case FuncIsGreaterOrEqual:
402 case FuncIsInAddressbook:
403 case FuncIsNotInAddressbook:
404 case FuncIsInCategory:
405 case FuncIsNotInCategory:
406 case FuncHasAttachment:
407 case FuncHasNoAttachment:
408 case FuncHasInvitation:
409 case FuncHasNoInvitation:
410 code += QLatin1Char(
'"') +
i18n(
"\"%1\" is not supported with condition \"%2\"", QLatin1StringView(mField), conditionToString(mFunction))
414 code += (negative ? QStringLiteral(
"not ") : QString()) + QStringLiteral(
"body :text %1 \"%2\"").arg(comparison, contentStr);
417 bool negative =
false;
422 comparison = QStringLiteral(
":contains");
424 case FuncContainsNot:
426 comparison = QStringLiteral(
":contains");
429 comparison = QStringLiteral(
":is");
432 comparison = QStringLiteral(
":is");
436 comparison = QStringLiteral(
":regex");
437 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
438 requireModules << QStringLiteral(
"regex");
442 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
443 requireModules << QStringLiteral(
"regex");
445 comparison = QStringLiteral(
":regex");
449 comparison = QStringLiteral(
":regex");
450 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
451 requireModules << QStringLiteral(
"regex");
453 contentStr = QLatin1Char(
'^') + contentStr;
455 case FuncNotStartWith:
456 comparison = QStringLiteral(
":regex");
457 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
458 requireModules << QStringLiteral(
"regex");
460 comparison = QStringLiteral(
":regex");
461 contentStr = QLatin1Char(
'^') + contentStr;
465 comparison = QStringLiteral(
":regex");
466 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
467 requireModules << QStringLiteral(
"regex");
469 comparison = QStringLiteral(
":regex");
470 contentStr = contentStr + QLatin1Char(
'$');
473 comparison = QStringLiteral(
":regex");
474 if (!requireModules.
contains(QLatin1StringView(
"regex"))) {
475 requireModules << QStringLiteral(
"regex");
477 comparison = QStringLiteral(
":regex");
478 contentStr = contentStr + QLatin1Char(
'$');
483 case FuncIsLessOrEqual:
485 case FuncIsGreaterOrEqual:
486 case FuncIsInAddressbook:
487 case FuncIsNotInAddressbook:
488 case FuncIsInCategory:
489 case FuncIsNotInCategory:
490 case FuncHasInvitation:
491 case FuncHasNoInvitation:
492 case FuncHasAttachment:
493 case FuncHasNoAttachment:
494 code += QLatin1Char(
'"') +
i18n(
"\"%1\" is not supported with condition \"%2\"", QLatin1StringView(mField), conditionToString(mFunction))
498 code += (negative ? QStringLiteral(
"not ") : QString())
499 + QStringLiteral(
"header %1 \"%2\" \"%3\"").arg(comparison).arg(QLatin1StringView(mField)).arg(contentStr);
536 result += functionToString(mFunction);
545 case SearchRule::FuncContains:
546 case SearchRule::FuncContainsNot:
547 return Akonadi::SearchTerm::CondContains;
549 case SearchRule::FuncEquals:
550 case SearchRule::FuncNotEqual:
551 return Akonadi::SearchTerm::CondEqual;
553 case SearchRule::FuncIsGreater:
554 return Akonadi::SearchTerm::CondGreaterThan;
556 case SearchRule::FuncIsGreaterOrEqual:
557 return Akonadi::SearchTerm::CondGreaterOrEqual;
559 case SearchRule::FuncIsLess:
560 return Akonadi::SearchTerm::CondLessThan;
562 case SearchRule::FuncIsLessOrEqual:
563 return Akonadi::SearchTerm::CondLessOrEqual;
565 case SearchRule::FuncRegExp:
566 case SearchRule::FuncNotRegExp:
568 return Akonadi::SearchTerm::CondContains;
570 case SearchRule::FuncStartWith:
571 case SearchRule::FuncNotStartWith:
572 case SearchRule::FuncEndWith:
573 case SearchRule::FuncNotEndWith:
575 return Akonadi::SearchTerm::CondContains;
577 qCDebug(MAILCOMMON_LOG) <<
"Unhandled function type: " <<
function();
580 return Akonadi::SearchTerm::CondEqual;
587 case SearchRule::FuncContainsNot:
588 case SearchRule::FuncNotEqual:
589 case SearchRule::FuncNotRegExp:
590 case SearchRule::FuncHasNoAttachment:
591 case SearchRule::FuncHasNoInvitation:
592 case SearchRule::FuncIsNotInCategory:
593 case SearchRule::FuncIsNotInAddressbook:
594 case SearchRule::FuncNotStartWith:
595 case SearchRule::FuncNotEndWith:
605 s << mField << functionToString(mFunction) << mContents;
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
This class represents a search pattern rule operating on numerical values.
This class represents a search to be performed against the status of a message.
This class represents one search pattern rule.
QByteArray field() const
Returns the message header field name (without the trailing ':').
static SearchRule::Ptr createInstanceFromConfig(const KConfigGroup &group, int index)
Creates a new search rule from a given config group.
Function function() const
Returns the filter function of the rule.
QString contents() const
Returns the contents of the rule.
void setField(const QByteArray &name)
Sets the message header field name.
std::shared_ptr< SearchRule > Ptr
Defines a pointer to a search rule.
Akonadi::SearchTerm::Condition akonadiComparator() const
Converts the rule function into the corresponding Akonadi query operator.
void setFunction(Function function)
Sets the filter function of the rule.
virtual ~SearchRule()
Destroys the search rule.
Function
Describes operators for comparison of field and contents.
SearchRule(const QByteArray &field=QByteArray(), Function function=FuncContains, const QString &contents=QString())
Creates new new search rule.
bool isNegated() const
Helper that returns whether the rule has a negated function.
const SearchRule & operator=(const SearchRule &other)
Initializes this rule with an other rule.
const QString asString() const
Returns the rule as string for debugging purpose.
void setContents(const QString &contents)
Set the contents of the rule.
void writeConfig(KConfigGroup &group, int index) const
Saves the object into a given config group.
static SearchRule::Ptr createInstance(const QByteArray &field=QByteArray(), Function function=FuncContains, const QString &contents=QString())
Creates a new search rule of a certain type by instantiating the appropriate subclass depending on th...
QString i18n(const char *text, const TYPE &arg...)
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
QString number(double n, char format, int precision)
QByteArray toLatin1() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const