Mailcommon

mailfilter.cpp
1/*
2 * kmail: KDE mail client
3 * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <taferner@kde.org>
4 * SPDX-FileCopyrightText: 2012 Andras Mantia <amantia@kde.org>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 *
8 */
9
10// my header
11#include "mailfilter.h"
12
13// other kmail headers
14#include "dialog/filteractionmissingaccountdialog.h"
15#include "filteractions/filteraction.h"
16#include "filteractions/filteractiondict.h"
17#include "filterlog.h"
18#include "filtermanager.h"
20
21#include <PimCommon/PimUtil>
22
23// KDEPIMLIBS headers
24#include <Akonadi/AgentManager>
25
26// other KDE headers
27#include <KConfig>
28#include <KConfigGroup>
29#include <KLocalizedString>
30#include <KMessageBox>
31#include <KRandom>
32#include <QPointer>
33
34#include <algorithm>
35
36using namespace MailCommon;
37
39{
40 generateRandomIdentifier();
41 bApplyOnInbound = true;
42 bApplyBeforeOutbound = false;
43 bApplyOnOutbound = false;
44 bApplyOnExplicit = true;
45 bApplyOnAllFolders = false;
46 bStopProcessingHere = true;
47 bConfigureShortcut = false;
48 bConfigureToolbar = false;
49 bAutoNaming = true;
50 mApplicability = All;
51 bEnabled = true;
52}
53
54MailFilter::MailFilter(const KConfigGroup &aConfig, bool interactive, bool &needUpdate)
55{
56 needUpdate = readConfig(aConfig, interactive);
57}
58
60{
61 mIdentifier = aFilter.mIdentifier;
62 mPattern = aFilter.mPattern;
63
64 bApplyOnInbound = aFilter.applyOnInbound();
65 bApplyBeforeOutbound = aFilter.applyBeforeOutbound();
66 bApplyOnOutbound = aFilter.applyOnOutbound();
67 bApplyOnExplicit = aFilter.applyOnExplicit();
68 bApplyOnAllFolders = aFilter.applyOnAllFoldersInbound();
69 bStopProcessingHere = aFilter.stopProcessingHere();
70 bConfigureShortcut = aFilter.configureShortcut();
71 bConfigureToolbar = aFilter.configureToolbar();
72 mToolbarName = aFilter.toolbarName();
73 mApplicability = aFilter.applicability();
74 bAutoNaming = aFilter.isAutoNaming();
75 bEnabled = aFilter.isEnabled();
76 mIcon = aFilter.icon();
77 mShortcut = aFilter.shortcut();
78
79 QListIterator<FilterAction *> it(aFilter.mActions);
80 while (it.hasNext()) {
81 FilterAction *action = it.next();
83 if (desc) {
84 FilterAction *f = desc->create();
85 if (f) {
86 f->argsFromString(action->argsAsString());
87 mActions.append(f);
88 }
89 }
90 }
91
92 mAccounts.clear();
94 QStringList::ConstIterator end2 = aFilter.mAccounts.constEnd();
95 for (it2 = aFilter.mAccounts.constBegin(); it2 != end2; ++it2) {
96 mAccounts.append(*it2);
97 }
98}
99
101{
102 qDeleteAll(mActions);
103}
104
105int MailFilter::filterActionsMaximumSize()
106{
107 return 8;
108}
109
110void MailFilter::generateRandomIdentifier()
111{
112 mIdentifier = KRandom::randomString(16);
113}
114
116{
117 return mIdentifier;
118}
119
121{
122 return mPattern.name();
123}
124
125MailFilter::ReturnCode MailFilter::execActions(ItemContext &context, bool &stopIt, bool applyOnOutbound) const
126{
127 QList<FilterAction *>::const_iterator it(mActions.constBegin());
128 QList<FilterAction *>::const_iterator end(mActions.constEnd());
129 for (; it != end; ++it) {
130 if (FilterLog::instance()->isLogging()) {
131 const QString logText(i18n("<b>Applying filter action:</b> %1", (*it)->displayString()));
133 }
134
135 const FilterAction::ReturnCode result = (*it)->process(context, applyOnOutbound);
136
137 switch (result) {
139 if (FilterLog::instance()->isLogging()) {
140 const QString logText = QStringLiteral("<font color=#FF0000>%1</font>").arg(i18n("A critical error occurred. Processing stops here."));
142 }
143 // in case it's a critical error: return immediately!
144 return CriticalError;
146 if (FilterLog::instance()->isLogging()) {
147 const QString logText = QStringLiteral("<font color=#FF0000>%1</font>").arg(i18n("A problem was found while applying this action."));
149 }
152 break;
153 }
154 }
155
156 stopIt = stopProcessingHere();
157
158 return GoOn;
159}
160
162{
163 return &mActions;
164}
165
167{
168 return &mActions;
169}
170
172{
173 return &mPattern;
174}
175
177{
178 return &mPattern;
179}
180
182{
183 bApplyOnOutbound = aApply;
184}
185
187{
188 bApplyBeforeOutbound = aApply;
189}
190
192{
193 return bApplyOnOutbound;
194}
195
197{
198 return bApplyBeforeOutbound;
199}
200
202{
203 bApplyOnInbound = aApply;
204}
205
207{
208 return bApplyOnInbound;
209}
210
212{
213 bApplyOnExplicit = aApply;
214}
215
217{
218 return bApplyOnExplicit;
219}
220
222{
223 bApplyOnAllFolders = aApply;
224}
225
227{
228 return bApplyOnAllFolders;
229}
230
232{
233 mApplicability = aApply;
234}
235
237{
238 return mApplicability;
239}
240
242{
243 // find the required message part needed for the filter
244 // this can be either only the Envelope, all Header or the CompleteMessage
245 // Makes the assumption that Envelope < Header < CompleteMessage
247
248 if (!bEnabled || !applyOnAccount(id)) {
249 return static_cast<SearchRule::RequiredPart>(requiredPart);
250 }
251
252 if (pattern()) {
253 requiredPart = qMax(requiredPart, static_cast<int>(pattern()->requiredPart())); // no pattern means always matches?
254 }
255
256 int requiredPartByActions = SearchRule::Envelope;
257
258 QList<FilterAction *> actionList = *actions();
259 if (!actionList.isEmpty()) {
260 requiredPartByActions = (*std::max_element(actionList.constBegin(), actionList.constEnd(), [](auto lhs, auto rhs) {
261 return lhs->requiredPart() < rhs->requiredPart();
262 }))->requiredPart();
263 }
264 requiredPart = qMax(requiredPart, requiredPartByActions);
265
266 return static_cast<SearchRule::RequiredPart>(requiredPart);
267}
268
269void MailFilter::agentRemoved(const QString &identifier)
270{
271 mAccounts.removeAll(identifier);
272}
273
275{
277 while (it.hasNext()) {
278 it.next()->folderRemoved(aFolder, aNewFolder);
279 }
280}
281
282void MailFilter::clearApplyOnAccount()
283{
284 mAccounts.clear();
285}
286
287void MailFilter::setApplyOnAccount(const QString &id, bool aApply)
288{
289 if (aApply && !mAccounts.contains(id)) {
290 mAccounts.append(id);
291 } else if (!aApply && mAccounts.contains(id)) {
292 mAccounts.removeAll(id);
293 }
294}
295
297{
298 if (applicability() == All) {
299 return true;
300 }
301 if (applicability() == ButImap) {
303 if (instance.isValid()) {
304 return !PimCommon::Util::isImapResource(instance.type().identifier());
305 } else {
306 return false;
307 }
308 }
309 if (applicability() == Checked) {
310 return mAccounts.contains(id);
311 }
312
313 return false;
314}
315
316void MailFilter::setStopProcessingHere(bool aStop)
317{
318 bStopProcessingHere = aStop;
319}
320
321bool MailFilter::stopProcessingHere() const
322{
323 return bStopProcessingHere;
324}
325
327{
328 bConfigureShortcut = aShort;
329 bConfigureToolbar = (bConfigureToolbar && bConfigureShortcut);
330}
331
333{
334 return bConfigureShortcut;
335}
336
338{
339 bConfigureToolbar = (aTool && bConfigureShortcut);
340}
341
343{
344 return bConfigureToolbar;
345}
346
347void MailFilter::setToolbarName(const QString &toolbarName)
348{
349 mToolbarName = toolbarName;
350}
351
353{
354 mShortcut = shortcut;
355}
356
358{
359 return mShortcut;
360}
361
363{
364 mIcon = icon;
365}
366
368{
369 return mIcon;
370}
371
372void MailFilter::setAutoNaming(bool useAutomaticNames)
373{
374 bAutoNaming = useAutomaticNames;
375}
376
378{
379 return bAutoNaming;
380}
381
382//-----------------------------------------------------------------------------
383bool MailFilter::readConfig(const KConfigGroup &config, bool interactive)
384{
385 bool needUpdate = false;
386 // MKSearchPattern::readConfig ensures
387 // that the pattern is purified.
388 mPattern.readConfig(config);
389 mIdentifier = config.readEntry("identifier", KRandom::randomString(16));
390
391 const QStringList sets = config.readEntry("apply-on", QStringList());
392 if (sets.isEmpty() && !config.hasKey("apply-on")) {
393 bApplyBeforeOutbound = false;
394 bApplyOnOutbound = false;
395 bApplyOnInbound = true;
396 bApplyOnExplicit = true;
397 bApplyOnAllFolders = false;
398 mApplicability = ButImap;
399 } else {
400 bApplyBeforeOutbound = bool(sets.contains(QLatin1StringView("before-send-mail")));
401 bApplyOnInbound = bool(sets.contains(QLatin1StringView("check-mail")));
402 bApplyOnOutbound = bool(sets.contains(QLatin1StringView("send-mail")));
403 bApplyOnExplicit = bool(sets.contains(QLatin1StringView("manual-filtering")));
404 bApplyOnAllFolders = bool(sets.contains(QLatin1StringView("all-folders")));
405 mApplicability = static_cast<AccountType>(config.readEntry("Applicability", static_cast<int>(ButImap)));
406 }
407
408 bStopProcessingHere = config.readEntry("StopProcessingHere", true);
409 bConfigureShortcut = config.readEntry("ConfigureShortcut", false);
410 QString shortcut(config.readEntry("Shortcut", QString()));
411 if (!shortcut.isEmpty()) {
413 setShortcut(sc);
414 }
415 bConfigureToolbar = config.readEntry("ConfigureToolbar", false);
416 bConfigureToolbar = bConfigureToolbar && bConfigureShortcut;
417 mToolbarName = config.readEntry("ToolbarName", name());
418 mIcon = config.readEntry("Icon", "system-run");
419 bAutoNaming = config.readEntry("AutomaticName", false);
420 bEnabled = config.readEntry("Enabled", true);
421
422 mActions.clear();
423
424 int numActions = config.readEntry("actions", 0);
425 if (numActions > filterActionsMaximumSize()) {
426 numActions = filterActionsMaximumSize();
427 KMessageBox::information(nullptr, i18n("<qt>Too many filter actions in filter rule <b>%1</b>.</qt>", mPattern.name()));
428 }
429
430 for (int i = 0; i < numActions; ++i) {
431 const QString actName = QStringLiteral("action-name-%1").arg(i);
432 const QString argsName = QStringLiteral("action-args-%1").arg(i);
433 // get the action description...
434 const QString resultActName = config.readEntry(actName, QString());
436 if (desc) {
437 //...create an instance...
438 FilterAction *fa = desc->create();
439 if (fa) {
440 //...load it with it's parameter...
441 if (interactive) {
442 const bool ret = fa->argsFromStringInteractive(config.readEntry(argsName, QString()), name());
443 if (ret) {
444 needUpdate = true;
445 }
446 } else {
447 fa->argsFromString(config.readEntry(argsName, QString()));
448 }
449 //...check if it's empty and...
450 if (!fa->isEmpty()) {
451 //...append it if it's not and...
452 mActions.append(fa);
453 } else {
454 //...delete is else.
455 delete fa;
456 }
457 }
458 } else {
460 nullptr /* app-global modal dialog box */,
461 i18n("<qt>Unknown filter action <b>%1</b><br />in filter rule <b>%2</b>.<br />Ignoring it.</qt>", resultActName, mPattern.name()));
462 }
463 }
464
465 mAccounts = config.readEntry("accounts-set", QStringList());
466 if (!mAccounts.isEmpty() && interactive) {
467 if (!MailCommon::FilterActionMissingAccountDialog::allAccountExist(mAccounts)) {
468 QPointer<MailCommon::FilterActionMissingAccountDialog> dlg = new MailCommon::FilterActionMissingAccountDialog(mAccounts, name());
469 if (dlg->exec()) {
470 mAccounts = dlg->selectedAccount();
471 needUpdate = true;
472 }
473 delete dlg;
474 }
475 }
476 return needUpdate;
477}
478
479void MailFilter::generateSieveScript(QStringList &requiresModules, QString &code)
480{
481 mPattern.generateSieveScript(requiresModules, code);
482
484 QList<FilterAction *>::const_iterator end(mActions.constEnd());
485
486 const QString indentationStr{QStringLiteral(" ")};
487 code += QLatin1StringView(")\n{\n");
488 bool firstAction = true;
489 for (it = mActions.constBegin(); it != end; ++it) {
490 // Add endline here.
491 if (firstAction) {
492 firstAction = false;
493 } else {
494 code += QLatin1Char('\n');
495 }
496 code += indentationStr + (*it)->sieveCode();
497 const QStringList lstRequires = (*it)->sieveRequires();
498 for (const QString &str : lstRequires) {
499 if (!requiresModules.contains(str)) {
500 requiresModules.append(str);
501 }
502 }
503 }
504 if (bStopProcessingHere) {
505 code += QLatin1Char('\n') + indentationStr + QStringLiteral("stop;");
506 }
507 code += QLatin1StringView("\n}\n");
508}
509
510void MailFilter::writeConfig(KConfigGroup &config, bool exportFilter) const
511{
512 mPattern.writeConfig(config);
513 config.writeEntry("identifier", mIdentifier);
514
515 QStringList sets;
516 if (bApplyOnInbound) {
517 sets.append(QStringLiteral("check-mail"));
518 }
519 if (bApplyBeforeOutbound) {
520 sets.append(QStringLiteral("before-send-mail"));
521 }
522 if (bApplyOnOutbound) {
523 sets.append(QStringLiteral("send-mail"));
524 }
525 if (bApplyOnExplicit) {
526 sets.append(QStringLiteral("manual-filtering"));
527 }
528 if (bApplyOnAllFolders) {
529 sets.append(QStringLiteral("all-folders"));
530 }
531 config.writeEntry("apply-on", sets);
532
533 config.writeEntry("StopProcessingHere", bStopProcessingHere);
534 config.writeEntry("ConfigureShortcut", bConfigureShortcut);
535 if (!mShortcut.isEmpty()) {
536 config.writeEntry("Shortcut", mShortcut.toString());
537 }
538 config.writeEntry("ConfigureToolbar", bConfigureToolbar);
539 config.writeEntry("ToolbarName", mToolbarName);
540 if (!mIcon.isEmpty()) {
541 config.writeEntry("Icon", mIcon);
542 }
543 config.writeEntry("AutomaticName", bAutoNaming);
544 config.writeEntry("Applicability", static_cast<int>(mApplicability));
545 config.writeEntry("Enabled", bEnabled);
546 int i;
547
549 QList<FilterAction *>::const_iterator end(mActions.constEnd());
550
551 for (i = 0, it = mActions.constBegin(); it != end; ++it, ++i) {
552 config.writeEntry(QStringLiteral("action-name-%1").arg(i), (*it)->name());
553 config.writeEntry(QStringLiteral("action-args-%1").arg(i), exportFilter ? (*it)->argsAsStringReal() : (*it)->argsAsString());
554 }
555 config.writeEntry("actions", i);
556 if (!mAccounts.isEmpty()) {
557 config.writeEntry("accounts-set", mAccounts);
558 }
559}
560
561QString MailFilter::purify(bool removeAction)
562{
563 QString informationAboutNotValidAction = mPattern.purify(removeAction);
564
565 if (mActions.isEmpty()) {
566 if (!informationAboutNotValidAction.isEmpty()) {
567 informationAboutNotValidAction += QLatin1Char('\n');
568 }
569 informationAboutNotValidAction += i18n("Any action defined.");
570 } else {
572 it.toBack();
573 while (it.hasPrevious()) {
574 FilterAction *action = it.previous();
575 if (action->isEmpty()) {
576 if (!informationAboutNotValidAction.isEmpty()) {
577 informationAboutNotValidAction += QLatin1Char('\n');
578 }
579 informationAboutNotValidAction += action->informationAboutNotValidAction();
580 if (removeAction) {
581 mActions.removeAll(action);
582 }
583 }
584 }
585 }
586
587 if (!Akonadi::AgentManager::self()->instances().isEmpty()) { // safety test to ensure that Akonadi system is ready
588 // Remove invalid accounts from mAccounts - just to be tidy
589 QStringList::Iterator it2 = mAccounts.begin();
590 while (it2 != mAccounts.end()) {
591 if (!Akonadi::AgentManager::self()->instance(*it2).isValid()) {
592 it2 = mAccounts.erase(it2);
593 } else {
594 ++it2;
595 }
596 }
597 }
598 return informationAboutNotValidAction;
599}
600
602{
603 return (mPattern.isEmpty() && mActions.isEmpty()) || ((applicability() == Checked) && (bApplyOnInbound && mAccounts.isEmpty()));
604}
605
607{
608 if (mToolbarName.isEmpty()) {
609 return name();
610 } else {
611 return mToolbarName;
612 }
613}
614
616{
617 QString result;
618
619 result += QLatin1StringView("Filter name: ") + name() + QLatin1StringView(" (") + mIdentifier + QLatin1StringView(")\n");
620 result += mPattern.asString() + QLatin1Char('\n');
621
622 result += QStringLiteral("Filter is %1\n").arg(bEnabled ? QStringLiteral("enabled") : QStringLiteral("disabled"));
623
624 QList<FilterAction *>::const_iterator it(mActions.constBegin());
625 QList<FilterAction *>::const_iterator end(mActions.constEnd());
626 for (; it != end; ++it) {
627 result += QStringLiteral(" action: ");
628 result += (*it)->label();
629 result += QLatin1Char(' ');
630 result += (*it)->argsAsString();
631 result += QLatin1Char('\n');
632 }
633 result += QStringLiteral("This filter belongs to the following sets:");
634 if (bApplyOnInbound) {
635 result += QStringLiteral(" Inbound");
636 }
637 if (bApplyBeforeOutbound) {
638 result += QStringLiteral(" before-Outbound");
639 }
640 if (bApplyOnOutbound) {
641 result += QStringLiteral(" Outbound");
642 }
643 if (bApplyOnExplicit) {
644 result += QStringLiteral(" Explicit");
645 }
646 if (bApplyOnAllFolders) {
647 result += QStringLiteral(" All Folders");
648 }
649 result += QLatin1Char('\n');
650 if (bApplyOnInbound && mApplicability == All) {
651 result += QStringLiteral("This filter applies to all accounts.\n");
652 } else if (bApplyOnInbound && mApplicability == ButImap) {
653 result += QStringLiteral("This filter applies to all but IMAP accounts.\n");
654 } else if (bApplyOnInbound) {
655 result += QStringLiteral("This filter applies to the following accounts:");
656 if (mAccounts.isEmpty()) {
657 result += QStringLiteral(" None");
658 } else {
659 for (QStringList::ConstIterator it2 = mAccounts.begin(), it2End = mAccounts.end(); it2 != it2End; ++it2) {
660 if (Akonadi::AgentManager::self()->instance(*it2).isValid()) {
661 result += QLatin1Char(' ') + Akonadi::AgentManager::self()->instance(*it2).name();
662 }
663 }
664 }
665 result += QLatin1Char('\n');
666 }
667 if (bStopProcessingHere) {
668 result += QStringLiteral("If it matches, processing stops at this filter.\n");
669 }
670
671 return result;
672}
673
674QDataStream &MailCommon::operator<<(QDataStream &stream, const MailCommon::MailFilter &filter)
675{
676 stream << filter.mIdentifier;
677 stream << filter.mPattern.serialize();
678
679 stream << filter.mActions.count();
680 QListIterator<FilterAction *> it(filter.mActions);
681 while (it.hasNext()) {
682 const FilterAction *action = it.next();
683 stream << action->name();
684 stream << action->argsAsString();
685 }
686
687 stream << filter.mAccounts;
688 stream << filter.mIcon;
689 stream << filter.mToolbarName;
690 stream << filter.mShortcut;
691 stream << filter.bApplyOnInbound;
692 stream << filter.bApplyBeforeOutbound;
693 stream << filter.bApplyOnOutbound;
694 stream << filter.bApplyOnExplicit;
695 stream << filter.bApplyOnAllFolders;
696 stream << filter.bStopProcessingHere;
697 stream << filter.bConfigureShortcut;
698 stream << filter.bConfigureToolbar;
699 stream << filter.bAutoNaming;
700 stream << filter.mApplicability;
701 stream << filter.bEnabled;
702
703 return stream;
704}
705
706QDataStream &MailCommon::operator>>(QDataStream &stream, MailCommon::MailFilter &filter)
707{
708 QByteArray pattern;
709 int numberOfActions;
711 bool bApplyOnInbound;
712 bool bApplyBeforeOutbound;
713 bool bApplyOnOutbound;
714 bool bApplyOnExplicit;
715 bool bApplyOnAllFolders;
716 bool bStopProcessingHere;
717 bool bConfigureShortcut;
718 bool bConfigureToolbar;
719 bool bAutoNaming;
720 int applicability;
721 bool bEnabled;
722
723 stream >> filter.mIdentifier;
724 stream >> pattern;
725
726 stream >> numberOfActions;
727 qDeleteAll(filter.mActions);
728 filter.mActions.clear();
729
730 for (int i = 0; i < numberOfActions; ++i) {
731 QString actionName;
732 QString actionArguments;
733
734 stream >> actionName;
735 stream >> actionArguments;
736
737 FilterActionDesc *description = FilterManager::filterActionDict()->value(actionName);
738 if (description) {
739 FilterAction *filterAction = description->create();
740 if (filterAction) {
741 filterAction->argsFromString(actionArguments);
742 filter.mActions.append(filterAction);
743 }
744 }
745 }
746
747 stream >> filter.mAccounts;
748 stream >> filter.mIcon;
749 stream >> filter.mToolbarName;
750 stream >> shortcut;
751 stream >> bApplyOnInbound;
752 stream >> bApplyBeforeOutbound;
753 stream >> bApplyOnOutbound;
754 stream >> bApplyOnExplicit;
755 stream >> bApplyOnAllFolders;
756 stream >> bStopProcessingHere;
757 stream >> bConfigureShortcut;
758 stream >> bConfigureToolbar;
759 stream >> bAutoNaming;
760 stream >> applicability;
761 stream >> bEnabled;
762
763 filter.mPattern.deserialize(pattern);
764 filter.mShortcut = shortcut;
765 filter.bApplyOnInbound = bApplyOnInbound;
766 filter.bApplyBeforeOutbound = bApplyBeforeOutbound;
767 filter.bApplyOnOutbound = bApplyOnOutbound;
768 filter.bApplyOnExplicit = bApplyOnExplicit;
769 filter.bApplyOnAllFolders = bApplyOnAllFolders;
770 filter.bStopProcessingHere = bStopProcessingHere;
771 filter.bConfigureShortcut = bConfigureShortcut;
772 filter.bConfigureToolbar = bConfigureToolbar;
773 filter.bAutoNaming = bAutoNaming;
774 filter.bEnabled = bEnabled;
775 filter.mApplicability = static_cast<MailCommon::MailFilter::AccountType>(applicability);
776
777 return stream;
778}
779
781{
782 return bEnabled;
783}
784
785void MailFilter::setEnabled(bool enabled)
786{
787 bEnabled = enabled;
788}
AgentType type() const
QString name() const
static AgentManager * self()
AgentInstance instance(const QString &identifier) const
QString identifier() const
bool hasKey(const char *key) const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
Abstract base class for mail filter actions.
virtual void argsFromString(const QString &argsStr)=0
Read extra arguments from given string.
QString name() const
Returns identifier name, ie.
virtual QString argsAsString() const =0
Return extra arguments as string.
ReturnCode
Describes the possible return codes of filter processing:
@ ErrorNeedComplete
Could not process because a complete message is needed.
@ ErrorButGoOn
A non-critical error occurred.
@ GoOn
Go on with applying filter actions.
virtual bool isEmpty() const
Determines whether this action is valid.
virtual bool argsFromStringInteractive(const QString &argsStr, const QString &filterName)
Read extra arguments from given string.
KMail Filter Log Collector.
Definition filterlog.h:33
void add(const QString &entry, ContentType type)
Adds the given log entry under the given content type to the log.
@ AppliedAction
Log all applied actions.
Definition filterlog.h:55
static FilterLog * instance()
Returns the single global instance of the filter log.
Definition filterlog.cpp:71
static FilterActionDict * filterActionDict()
Returns the global filter action dictionary.
A helper class for the filtering process.
Definition itemcontext.h:27
The MailFilter class.
Definition mailfilter.h:29
bool applyOnOutbound() const
bool applyOnAccount(const QString &id) const
QString toolbarName() const
void setIcon(const QString &icon)
Set the icon to be used if plugged into the filter menu or toolbar.
SearchPattern * pattern()
Provides a reference to the internal pattern.
void setApplyBeforeOutbound(bool aApply)
Set whether this filter should be applied on outbound messages before sending (aApply == TRUE) or not...
bool isEnabled() const
Return if filter is enabled or not.
void folderRemoved(const Akonadi::Collection &aFolder, const Akonadi::Collection &aNewFolder)
Called from the filter manager when a folder is moved.
SearchRule::RequiredPart requiredPart(const QString &id) const
Returns the required part from the item that is needed for the filter to operate.
void setApplyOnInbound(bool aApply)
Set whether this filter should be applied on inbound messages (aApply == true) or not.
ReturnCode
Result codes returned by process.
Definition mailfilter.h:45
AccountType applicability() const
void setConfigureShortcut(bool aShort)
Set whether this filter should be plugged into the filter menu.
bool isAutoNaming() const
AccountType
Account type codes used by setApplicability.
Definition mailfilter.h:60
bool configureShortcut() const
void setApplyOnExplicit(bool aApply)
Set whether this filter should be applied on explicit (CTRL-J) filtering (aApply == true) or not.
bool isEmpty() const
Check for empty pattern and action list.
void setToolbarName(const QString &toolbarName)
This sets the toolbar name for this filter.
const QString asString() const
Returns the filter in a human-readable form.
void setAutoNaming(bool useAutomaticNames)
Set the mode for using automatic naming for the filter.
void setApplicability(AccountType aApply=All)
Set whether this filter should be applied on inbound messages for all accounts (aApply == All) or inb...
QString purify(bool removeAction=true)
Remove empty rules (and actions one day).
bool applyOnInbound() const
bool configureToolbar() const
void setApplyOnOutbound(bool aApply)
Set whether this filter should be applied on outbound messages (aApply == true) or not.
const QKeySequence & shortcut() const
QString identifier() const
Returns the unique identifier of this filter.
QString name() const
Equivalent to pattern()->name().
void setApplyOnAllFoldersInbound(bool aApply)
Sets whether the filter should be applied on inbound emails in all folders, not just Inbox.
QString icon() const
bool readConfig(const KConfigGroup &config, bool interactive=false)
Initialize from given config group.
bool applyOnExplicit() const
QList< FilterAction * > * actions()
Provides a reference to the internal action list.
ReturnCode execActions(ItemContext &context, bool &stopIt, bool applyOnOutbound) const
Execute the filter action(s) on the given message.
void setConfigureToolbar(bool aTool)
Set whether this filter should be plugged into the toolbar.
MailFilter()
Constructor that initializes basic settings.
bool applyOnAllFoldersInbound() const
Returns whether the filter should be applied on inbound emails in all folders, not just Inbox.
void setApplyOnAccount(const QString &id, bool aApply=true)
Set whether this filter should be applied on inbound messages for the account with id (id).
void setShortcut(const QKeySequence &shortcut)
Set the shortcut to be used if plugged into the filter menu or toolbar.
void writeConfig(KConfigGroup &config, bool exportFilter) const
Write contents to given config group.
bool applyBeforeOutbound() const
This class is an abstraction of a search over messages.
void writeConfig(KConfigGroup &config) const
Writes itself into config.
QString asString() const
Returns the pattern as string.
void readConfig(const KConfigGroup &config)
Reads a search pattern from a KConfigGroup.
QString name() const
Returns the name of the search pattern.
QString purify(bool removeAction=true)
Removes all empty rules from the list.
RequiredPart
Possible required parts.
Definition searchrule.h:68
Q_SCRIPTABLE QStringList logText()
QString i18n(const char *text, const TYPE &arg...)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
KCOREADDONS_EXPORT QString randomString(int length)
const QList< QKeySequence > & shortcut(StandardShortcut id)
The filter dialog.
bool isEmpty() const const
QString toString(SequenceFormat format) const const
void append(QList< T > &&value)
iterator begin()
void clear()
const_iterator constBegin() const const
const_iterator constEnd() const const
iterator end()
iterator erase(const_iterator begin, const_iterator end)
bool isEmpty() const const
qsizetype removeAll(const AT &t)
bool hasNext() const const
bool hasPrevious() const const
const T & next()
const T & previous()
T value(const Key &key) const const
QString arg(Args &&... args) const const
bool isEmpty() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
Auxiliary struct for FilterActionDict.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:09:01 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.