File indexing completed on 2024-11-10 04:50:09
0001 /* 0002 * kmail: KDE mail client 0003 * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <taferner@kde.org> 0004 * SPDX-FileCopyrightText: 2012 Andras Mantia <amantia@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 * 0008 */ 0009 0010 // my header 0011 #include "mailfilter.h" 0012 0013 // other kmail headers 0014 #include "dialog/filteractionmissingaccountdialog.h" 0015 #include "filteractions/filteraction.h" 0016 #include "filteractions/filteractiondict.h" 0017 #include "filterlog.h" 0018 #include "filtermanager.h" 0019 using MailCommon::FilterLog; 0020 0021 #include <PimCommon/PimUtil> 0022 0023 // KDEPIMLIBS headers 0024 #include <Akonadi/AgentManager> 0025 0026 // other KDE headers 0027 #include <KConfig> 0028 #include <KConfigGroup> 0029 #include <KLocalizedString> 0030 #include <KMessageBox> 0031 #include <KRandom> 0032 #include <QPointer> 0033 0034 #include <algorithm> 0035 0036 using namespace MailCommon; 0037 0038 MailFilter::MailFilter() 0039 { 0040 generateRandomIdentifier(); 0041 bApplyOnInbound = true; 0042 bApplyBeforeOutbound = false; 0043 bApplyOnOutbound = false; 0044 bApplyOnExplicit = true; 0045 bApplyOnAllFolders = false; 0046 bStopProcessingHere = true; 0047 bConfigureShortcut = false; 0048 bConfigureToolbar = false; 0049 bAutoNaming = true; 0050 mApplicability = All; 0051 bEnabled = true; 0052 } 0053 0054 MailFilter::MailFilter(const KConfigGroup &aConfig, bool interactive, bool &needUpdate) 0055 { 0056 needUpdate = readConfig(aConfig, interactive); 0057 } 0058 0059 MailFilter::MailFilter(const MailFilter &aFilter) 0060 { 0061 mIdentifier = aFilter.mIdentifier; 0062 mPattern = aFilter.mPattern; 0063 0064 bApplyOnInbound = aFilter.applyOnInbound(); 0065 bApplyBeforeOutbound = aFilter.applyBeforeOutbound(); 0066 bApplyOnOutbound = aFilter.applyOnOutbound(); 0067 bApplyOnExplicit = aFilter.applyOnExplicit(); 0068 bApplyOnAllFolders = aFilter.applyOnAllFoldersInbound(); 0069 bStopProcessingHere = aFilter.stopProcessingHere(); 0070 bConfigureShortcut = aFilter.configureShortcut(); 0071 bConfigureToolbar = aFilter.configureToolbar(); 0072 mToolbarName = aFilter.toolbarName(); 0073 mApplicability = aFilter.applicability(); 0074 bAutoNaming = aFilter.isAutoNaming(); 0075 bEnabled = aFilter.isEnabled(); 0076 mIcon = aFilter.icon(); 0077 mShortcut = aFilter.shortcut(); 0078 0079 QListIterator<FilterAction *> it(aFilter.mActions); 0080 while (it.hasNext()) { 0081 FilterAction *action = it.next(); 0082 FilterActionDesc *desc = FilterManager::filterActionDict()->value(action->name()); 0083 if (desc) { 0084 FilterAction *f = desc->create(); 0085 if (f) { 0086 f->argsFromString(action->argsAsString()); 0087 mActions.append(f); 0088 } 0089 } 0090 } 0091 0092 mAccounts.clear(); 0093 QStringList::ConstIterator it2; 0094 QStringList::ConstIterator end2 = aFilter.mAccounts.constEnd(); 0095 for (it2 = aFilter.mAccounts.constBegin(); it2 != end2; ++it2) { 0096 mAccounts.append(*it2); 0097 } 0098 } 0099 0100 MailFilter::~MailFilter() 0101 { 0102 qDeleteAll(mActions); 0103 } 0104 0105 int MailFilter::filterActionsMaximumSize() 0106 { 0107 return 8; 0108 } 0109 0110 void MailFilter::generateRandomIdentifier() 0111 { 0112 mIdentifier = KRandom::randomString(16); 0113 } 0114 0115 QString MailFilter::identifier() const 0116 { 0117 return mIdentifier; 0118 } 0119 0120 QString MailFilter::name() const 0121 { 0122 return mPattern.name(); 0123 } 0124 0125 MailFilter::ReturnCode MailFilter::execActions(ItemContext &context, bool &stopIt, bool applyOnOutbound) const 0126 { 0127 QList<FilterAction *>::const_iterator it(mActions.constBegin()); 0128 QList<FilterAction *>::const_iterator end(mActions.constEnd()); 0129 for (; it != end; ++it) { 0130 if (FilterLog::instance()->isLogging()) { 0131 const QString logText(i18n("<b>Applying filter action:</b> %1", (*it)->displayString())); 0132 FilterLog::instance()->add(logText, FilterLog::AppliedAction); 0133 } 0134 0135 const FilterAction::ReturnCode result = (*it)->process(context, applyOnOutbound); 0136 0137 switch (result) { 0138 case FilterAction::CriticalError: 0139 if (FilterLog::instance()->isLogging()) { 0140 const QString logText = QStringLiteral("<font color=#FF0000>%1</font>").arg(i18n("A critical error occurred. Processing stops here.")); 0141 FilterLog::instance()->add(logText, FilterLog::AppliedAction); 0142 } 0143 // in case it's a critical error: return immediately! 0144 return CriticalError; 0145 case FilterAction::ErrorButGoOn: 0146 if (FilterLog::instance()->isLogging()) { 0147 const QString logText = QStringLiteral("<font color=#FF0000>%1</font>").arg(i18n("A problem was found while applying this action.")); 0148 FilterLog::instance()->add(logText, FilterLog::AppliedAction); 0149 } 0150 case FilterAction::GoOn: 0151 case FilterAction::ErrorNeedComplete: 0152 break; 0153 } 0154 } 0155 0156 stopIt = stopProcessingHere(); 0157 0158 return GoOn; 0159 } 0160 0161 QList<FilterAction *> *MailFilter::actions() 0162 { 0163 return &mActions; 0164 } 0165 0166 const QList<FilterAction *> *MailFilter::actions() const 0167 { 0168 return &mActions; 0169 } 0170 0171 SearchPattern *MailFilter::pattern() 0172 { 0173 return &mPattern; 0174 } 0175 0176 const SearchPattern *MailFilter::pattern() const 0177 { 0178 return &mPattern; 0179 } 0180 0181 void MailFilter::setApplyOnOutbound(bool aApply) 0182 { 0183 bApplyOnOutbound = aApply; 0184 } 0185 0186 void MailFilter::setApplyBeforeOutbound(bool aApply) 0187 { 0188 bApplyBeforeOutbound = aApply; 0189 } 0190 0191 bool MailFilter::applyOnOutbound() const 0192 { 0193 return bApplyOnOutbound; 0194 } 0195 0196 bool MailFilter::applyBeforeOutbound() const 0197 { 0198 return bApplyBeforeOutbound; 0199 } 0200 0201 void MailFilter::setApplyOnInbound(bool aApply) 0202 { 0203 bApplyOnInbound = aApply; 0204 } 0205 0206 bool MailFilter::applyOnInbound() const 0207 { 0208 return bApplyOnInbound; 0209 } 0210 0211 void MailFilter::setApplyOnExplicit(bool aApply) 0212 { 0213 bApplyOnExplicit = aApply; 0214 } 0215 0216 bool MailFilter::applyOnExplicit() const 0217 { 0218 return bApplyOnExplicit; 0219 } 0220 0221 void MailFilter::setApplyOnAllFoldersInbound(bool aApply) 0222 { 0223 bApplyOnAllFolders = aApply; 0224 } 0225 0226 bool MailFilter::applyOnAllFoldersInbound() const 0227 { 0228 return bApplyOnAllFolders; 0229 } 0230 0231 void MailFilter::setApplicability(AccountType aApply) 0232 { 0233 mApplicability = aApply; 0234 } 0235 0236 MailFilter::AccountType MailFilter::applicability() const 0237 { 0238 return mApplicability; 0239 } 0240 0241 SearchRule::RequiredPart MailFilter::requiredPart(const QString &id) const 0242 { 0243 // find the required message part needed for the filter 0244 // this can be either only the Envelope, all Header or the CompleteMessage 0245 // Makes the assumption that Envelope < Header < CompleteMessage 0246 int requiredPart = SearchRule::Envelope; 0247 0248 if (!bEnabled || !applyOnAccount(id)) { 0249 return static_cast<SearchRule::RequiredPart>(requiredPart); 0250 } 0251 0252 if (pattern()) { 0253 requiredPart = qMax(requiredPart, static_cast<int>(pattern()->requiredPart())); // no pattern means always matches? 0254 } 0255 0256 int requiredPartByActions = SearchRule::Envelope; 0257 0258 QList<FilterAction *> actionList = *actions(); 0259 if (!actionList.isEmpty()) { 0260 requiredPartByActions = (*std::max_element(actionList.constBegin(), actionList.constEnd(), [](auto lhs, auto rhs) { 0261 return lhs->requiredPart() < rhs->requiredPart(); 0262 }))->requiredPart(); 0263 } 0264 requiredPart = qMax(requiredPart, requiredPartByActions); 0265 0266 return static_cast<SearchRule::RequiredPart>(requiredPart); 0267 } 0268 0269 void MailFilter::agentRemoved(const QString &identifier) 0270 { 0271 mAccounts.removeAll(identifier); 0272 } 0273 0274 void MailFilter::folderRemoved(const Akonadi::Collection &aFolder, const Akonadi::Collection &aNewFolder) 0275 { 0276 QListIterator<FilterAction *> it(mActions); 0277 while (it.hasNext()) { 0278 it.next()->folderRemoved(aFolder, aNewFolder); 0279 } 0280 } 0281 0282 void MailFilter::clearApplyOnAccount() 0283 { 0284 mAccounts.clear(); 0285 } 0286 0287 void MailFilter::setApplyOnAccount(const QString &id, bool aApply) 0288 { 0289 if (aApply && !mAccounts.contains(id)) { 0290 mAccounts.append(id); 0291 } else if (!aApply && mAccounts.contains(id)) { 0292 mAccounts.removeAll(id); 0293 } 0294 } 0295 0296 bool MailFilter::applyOnAccount(const QString &id) const 0297 { 0298 if (applicability() == All) { 0299 return true; 0300 } 0301 if (applicability() == ButImap) { 0302 Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(id); 0303 if (instance.isValid()) { 0304 return !PimCommon::Util::isImapResource(instance.type().identifier()); 0305 } else { 0306 return false; 0307 } 0308 } 0309 if (applicability() == Checked) { 0310 return mAccounts.contains(id); 0311 } 0312 0313 return false; 0314 } 0315 0316 void MailFilter::setStopProcessingHere(bool aStop) 0317 { 0318 bStopProcessingHere = aStop; 0319 } 0320 0321 bool MailFilter::stopProcessingHere() const 0322 { 0323 return bStopProcessingHere; 0324 } 0325 0326 void MailFilter::setConfigureShortcut(bool aShort) 0327 { 0328 bConfigureShortcut = aShort; 0329 bConfigureToolbar = (bConfigureToolbar && bConfigureShortcut); 0330 } 0331 0332 bool MailFilter::configureShortcut() const 0333 { 0334 return bConfigureShortcut; 0335 } 0336 0337 void MailFilter::setConfigureToolbar(bool aTool) 0338 { 0339 bConfigureToolbar = (aTool && bConfigureShortcut); 0340 } 0341 0342 bool MailFilter::configureToolbar() const 0343 { 0344 return bConfigureToolbar; 0345 } 0346 0347 void MailFilter::setToolbarName(const QString &toolbarName) 0348 { 0349 mToolbarName = toolbarName; 0350 } 0351 0352 void MailFilter::setShortcut(const QKeySequence &shortcut) 0353 { 0354 mShortcut = shortcut; 0355 } 0356 0357 const QKeySequence &MailFilter::shortcut() const 0358 { 0359 return mShortcut; 0360 } 0361 0362 void MailFilter::setIcon(const QString &icon) 0363 { 0364 mIcon = icon; 0365 } 0366 0367 QString MailFilter::icon() const 0368 { 0369 return mIcon; 0370 } 0371 0372 void MailFilter::setAutoNaming(bool useAutomaticNames) 0373 { 0374 bAutoNaming = useAutomaticNames; 0375 } 0376 0377 bool MailFilter::isAutoNaming() const 0378 { 0379 return bAutoNaming; 0380 } 0381 0382 //----------------------------------------------------------------------------- 0383 bool MailFilter::readConfig(const KConfigGroup &config, bool interactive) 0384 { 0385 bool needUpdate = false; 0386 // MKSearchPattern::readConfig ensures 0387 // that the pattern is purified. 0388 mPattern.readConfig(config); 0389 mIdentifier = config.readEntry("identifier", KRandom::randomString(16)); 0390 0391 const QStringList sets = config.readEntry("apply-on", QStringList()); 0392 if (sets.isEmpty() && !config.hasKey("apply-on")) { 0393 bApplyBeforeOutbound = false; 0394 bApplyOnOutbound = false; 0395 bApplyOnInbound = true; 0396 bApplyOnExplicit = true; 0397 bApplyOnAllFolders = false; 0398 mApplicability = ButImap; 0399 } else { 0400 bApplyBeforeOutbound = bool(sets.contains(QLatin1StringView("before-send-mail"))); 0401 bApplyOnInbound = bool(sets.contains(QLatin1StringView("check-mail"))); 0402 bApplyOnOutbound = bool(sets.contains(QLatin1StringView("send-mail"))); 0403 bApplyOnExplicit = bool(sets.contains(QLatin1StringView("manual-filtering"))); 0404 bApplyOnAllFolders = bool(sets.contains(QLatin1StringView("all-folders"))); 0405 mApplicability = static_cast<AccountType>(config.readEntry("Applicability", static_cast<int>(ButImap))); 0406 } 0407 0408 bStopProcessingHere = config.readEntry("StopProcessingHere", true); 0409 bConfigureShortcut = config.readEntry("ConfigureShortcut", false); 0410 QString shortcut(config.readEntry("Shortcut", QString())); 0411 if (!shortcut.isEmpty()) { 0412 QKeySequence sc(shortcut); 0413 setShortcut(sc); 0414 } 0415 bConfigureToolbar = config.readEntry("ConfigureToolbar", false); 0416 bConfigureToolbar = bConfigureToolbar && bConfigureShortcut; 0417 mToolbarName = config.readEntry("ToolbarName", name()); 0418 mIcon = config.readEntry("Icon", "system-run"); 0419 bAutoNaming = config.readEntry("AutomaticName", false); 0420 bEnabled = config.readEntry("Enabled", true); 0421 0422 mActions.clear(); 0423 0424 int numActions = config.readEntry("actions", 0); 0425 if (numActions > filterActionsMaximumSize()) { 0426 numActions = filterActionsMaximumSize(); 0427 KMessageBox::information(nullptr, i18n("<qt>Too many filter actions in filter rule <b>%1</b>.</qt>", mPattern.name())); 0428 } 0429 0430 for (int i = 0; i < numActions; ++i) { 0431 const QString actName = QStringLiteral("action-name-%1").arg(i); 0432 const QString argsName = QStringLiteral("action-args-%1").arg(i); 0433 // get the action description... 0434 const QString resultActName = config.readEntry(actName, QString()); 0435 FilterActionDesc *desc = FilterManager::filterActionDict()->value(resultActName); 0436 if (desc) { 0437 //...create an instance... 0438 FilterAction *fa = desc->create(); 0439 if (fa) { 0440 //...load it with it's parameter... 0441 if (interactive) { 0442 const bool ret = fa->argsFromStringInteractive(config.readEntry(argsName, QString()), name()); 0443 if (ret) { 0444 needUpdate = true; 0445 } 0446 } else { 0447 fa->argsFromString(config.readEntry(argsName, QString())); 0448 } 0449 //...check if it's empty and... 0450 if (!fa->isEmpty()) { 0451 //...append it if it's not and... 0452 mActions.append(fa); 0453 } else { 0454 //...delete is else. 0455 delete fa; 0456 } 0457 } 0458 } else { 0459 KMessageBox::information( 0460 nullptr /* app-global modal dialog box */, 0461 i18n("<qt>Unknown filter action <b>%1</b><br />in filter rule <b>%2</b>.<br />Ignoring it.</qt>", resultActName, mPattern.name())); 0462 } 0463 } 0464 0465 mAccounts = config.readEntry("accounts-set", QStringList()); 0466 if (!mAccounts.isEmpty() && interactive) { 0467 if (!MailCommon::FilterActionMissingAccountDialog::allAccountExist(mAccounts)) { 0468 QPointer<MailCommon::FilterActionMissingAccountDialog> dlg = new MailCommon::FilterActionMissingAccountDialog(mAccounts, name()); 0469 if (dlg->exec()) { 0470 mAccounts = dlg->selectedAccount(); 0471 needUpdate = true; 0472 } 0473 delete dlg; 0474 } 0475 } 0476 return needUpdate; 0477 } 0478 0479 void MailFilter::generateSieveScript(QStringList &requiresModules, QString &code) 0480 { 0481 mPattern.generateSieveScript(requiresModules, code); 0482 0483 QList<FilterAction *>::const_iterator it; 0484 QList<FilterAction *>::const_iterator end(mActions.constEnd()); 0485 0486 const QString indentationStr{QStringLiteral(" ")}; 0487 code += QLatin1StringView(")\n{\n"); 0488 bool firstAction = true; 0489 for (it = mActions.constBegin(); it != end; ++it) { 0490 // Add endline here. 0491 if (firstAction) { 0492 firstAction = false; 0493 } else { 0494 code += QLatin1Char('\n'); 0495 } 0496 code += indentationStr + (*it)->sieveCode(); 0497 const QStringList lstRequires = (*it)->sieveRequires(); 0498 for (const QString &str : lstRequires) { 0499 if (!requiresModules.contains(str)) { 0500 requiresModules.append(str); 0501 } 0502 } 0503 } 0504 if (bStopProcessingHere) { 0505 code += QLatin1Char('\n') + indentationStr + QStringLiteral("stop;"); 0506 } 0507 code += QLatin1StringView("\n}\n"); 0508 } 0509 0510 void MailFilter::writeConfig(KConfigGroup &config, bool exportFilter) const 0511 { 0512 mPattern.writeConfig(config); 0513 config.writeEntry("identifier", mIdentifier); 0514 0515 QStringList sets; 0516 if (bApplyOnInbound) { 0517 sets.append(QStringLiteral("check-mail")); 0518 } 0519 if (bApplyBeforeOutbound) { 0520 sets.append(QStringLiteral("before-send-mail")); 0521 } 0522 if (bApplyOnOutbound) { 0523 sets.append(QStringLiteral("send-mail")); 0524 } 0525 if (bApplyOnExplicit) { 0526 sets.append(QStringLiteral("manual-filtering")); 0527 } 0528 if (bApplyOnAllFolders) { 0529 sets.append(QStringLiteral("all-folders")); 0530 } 0531 config.writeEntry("apply-on", sets); 0532 0533 config.writeEntry("StopProcessingHere", bStopProcessingHere); 0534 config.writeEntry("ConfigureShortcut", bConfigureShortcut); 0535 if (!mShortcut.isEmpty()) { 0536 config.writeEntry("Shortcut", mShortcut.toString()); 0537 } 0538 config.writeEntry("ConfigureToolbar", bConfigureToolbar); 0539 config.writeEntry("ToolbarName", mToolbarName); 0540 if (!mIcon.isEmpty()) { 0541 config.writeEntry("Icon", mIcon); 0542 } 0543 config.writeEntry("AutomaticName", bAutoNaming); 0544 config.writeEntry("Applicability", static_cast<int>(mApplicability)); 0545 config.writeEntry("Enabled", bEnabled); 0546 int i; 0547 0548 QList<FilterAction *>::const_iterator it; 0549 QList<FilterAction *>::const_iterator end(mActions.constEnd()); 0550 0551 for (i = 0, it = mActions.constBegin(); it != end; ++it, ++i) { 0552 config.writeEntry(QStringLiteral("action-name-%1").arg(i), (*it)->name()); 0553 config.writeEntry(QStringLiteral("action-args-%1").arg(i), exportFilter ? (*it)->argsAsStringReal() : (*it)->argsAsString()); 0554 } 0555 config.writeEntry("actions", i); 0556 if (!mAccounts.isEmpty()) { 0557 config.writeEntry("accounts-set", mAccounts); 0558 } 0559 } 0560 0561 QString MailFilter::purify(bool removeAction) 0562 { 0563 QString informationAboutNotValidAction = mPattern.purify(removeAction); 0564 0565 if (mActions.isEmpty()) { 0566 if (!informationAboutNotValidAction.isEmpty()) { 0567 informationAboutNotValidAction += QLatin1Char('\n'); 0568 } 0569 informationAboutNotValidAction += i18n("Any action defined."); 0570 } else { 0571 QListIterator<FilterAction *> it(mActions); 0572 it.toBack(); 0573 while (it.hasPrevious()) { 0574 FilterAction *action = it.previous(); 0575 if (action->isEmpty()) { 0576 if (!informationAboutNotValidAction.isEmpty()) { 0577 informationAboutNotValidAction += QLatin1Char('\n'); 0578 } 0579 informationAboutNotValidAction += action->informationAboutNotValidAction(); 0580 if (removeAction) { 0581 mActions.removeAll(action); 0582 } 0583 } 0584 } 0585 } 0586 0587 if (!Akonadi::AgentManager::self()->instances().isEmpty()) { // safety test to ensure that Akonadi system is ready 0588 // Remove invalid accounts from mAccounts - just to be tidy 0589 QStringList::Iterator it2 = mAccounts.begin(); 0590 while (it2 != mAccounts.end()) { 0591 if (!Akonadi::AgentManager::self()->instance(*it2).isValid()) { 0592 it2 = mAccounts.erase(it2); 0593 } else { 0594 ++it2; 0595 } 0596 } 0597 } 0598 return informationAboutNotValidAction; 0599 } 0600 0601 bool MailFilter::isEmpty() const 0602 { 0603 return (mPattern.isEmpty() && mActions.isEmpty()) || ((applicability() == Checked) && (bApplyOnInbound && mAccounts.isEmpty())); 0604 } 0605 0606 QString MailFilter::toolbarName() const 0607 { 0608 if (mToolbarName.isEmpty()) { 0609 return name(); 0610 } else { 0611 return mToolbarName; 0612 } 0613 } 0614 0615 const QString MailFilter::asString() const 0616 { 0617 QString result; 0618 0619 result += QLatin1StringView("Filter name: ") + name() + QLatin1StringView(" (") + mIdentifier + QLatin1StringView(")\n"); 0620 result += mPattern.asString() + QLatin1Char('\n'); 0621 0622 result += QStringLiteral("Filter is %1\n").arg(bEnabled ? QStringLiteral("enabled") : QStringLiteral("disabled")); 0623 0624 QList<FilterAction *>::const_iterator it(mActions.constBegin()); 0625 QList<FilterAction *>::const_iterator end(mActions.constEnd()); 0626 for (; it != end; ++it) { 0627 result += QStringLiteral(" action: "); 0628 result += (*it)->label(); 0629 result += QLatin1Char(' '); 0630 result += (*it)->argsAsString(); 0631 result += QLatin1Char('\n'); 0632 } 0633 result += QStringLiteral("This filter belongs to the following sets:"); 0634 if (bApplyOnInbound) { 0635 result += QStringLiteral(" Inbound"); 0636 } 0637 if (bApplyBeforeOutbound) { 0638 result += QStringLiteral(" before-Outbound"); 0639 } 0640 if (bApplyOnOutbound) { 0641 result += QStringLiteral(" Outbound"); 0642 } 0643 if (bApplyOnExplicit) { 0644 result += QStringLiteral(" Explicit"); 0645 } 0646 if (bApplyOnAllFolders) { 0647 result += QStringLiteral(" All Folders"); 0648 } 0649 result += QLatin1Char('\n'); 0650 if (bApplyOnInbound && mApplicability == All) { 0651 result += QStringLiteral("This filter applies to all accounts.\n"); 0652 } else if (bApplyOnInbound && mApplicability == ButImap) { 0653 result += QStringLiteral("This filter applies to all but IMAP accounts.\n"); 0654 } else if (bApplyOnInbound) { 0655 result += QStringLiteral("This filter applies to the following accounts:"); 0656 if (mAccounts.isEmpty()) { 0657 result += QStringLiteral(" None"); 0658 } else { 0659 for (QStringList::ConstIterator it2 = mAccounts.begin(), it2End = mAccounts.end(); it2 != it2End; ++it2) { 0660 if (Akonadi::AgentManager::self()->instance(*it2).isValid()) { 0661 result += QLatin1Char(' ') + Akonadi::AgentManager::self()->instance(*it2).name(); 0662 } 0663 } 0664 } 0665 result += QLatin1Char('\n'); 0666 } 0667 if (bStopProcessingHere) { 0668 result += QStringLiteral("If it matches, processing stops at this filter.\n"); 0669 } 0670 0671 return result; 0672 } 0673 0674 QDataStream &MailCommon::operator<<(QDataStream &stream, const MailCommon::MailFilter &filter) 0675 { 0676 stream << filter.mIdentifier; 0677 stream << filter.mPattern.serialize(); 0678 0679 stream << filter.mActions.count(); 0680 QListIterator<FilterAction *> it(filter.mActions); 0681 while (it.hasNext()) { 0682 const FilterAction *action = it.next(); 0683 stream << action->name(); 0684 stream << action->argsAsString(); 0685 } 0686 0687 stream << filter.mAccounts; 0688 stream << filter.mIcon; 0689 stream << filter.mToolbarName; 0690 stream << filter.mShortcut; 0691 stream << filter.bApplyOnInbound; 0692 stream << filter.bApplyBeforeOutbound; 0693 stream << filter.bApplyOnOutbound; 0694 stream << filter.bApplyOnExplicit; 0695 stream << filter.bApplyOnAllFolders; 0696 stream << filter.bStopProcessingHere; 0697 stream << filter.bConfigureShortcut; 0698 stream << filter.bConfigureToolbar; 0699 stream << filter.bAutoNaming; 0700 stream << filter.mApplicability; 0701 stream << filter.bEnabled; 0702 0703 return stream; 0704 } 0705 0706 QDataStream &MailCommon::operator>>(QDataStream &stream, MailCommon::MailFilter &filter) 0707 { 0708 QByteArray pattern; 0709 int numberOfActions; 0710 QKeySequence shortcut; 0711 bool bApplyOnInbound; 0712 bool bApplyBeforeOutbound; 0713 bool bApplyOnOutbound; 0714 bool bApplyOnExplicit; 0715 bool bApplyOnAllFolders; 0716 bool bStopProcessingHere; 0717 bool bConfigureShortcut; 0718 bool bConfigureToolbar; 0719 bool bAutoNaming; 0720 int applicability; 0721 bool bEnabled; 0722 0723 stream >> filter.mIdentifier; 0724 stream >> pattern; 0725 0726 stream >> numberOfActions; 0727 qDeleteAll(filter.mActions); 0728 filter.mActions.clear(); 0729 0730 for (int i = 0; i < numberOfActions; ++i) { 0731 QString actionName; 0732 QString actionArguments; 0733 0734 stream >> actionName; 0735 stream >> actionArguments; 0736 0737 FilterActionDesc *description = FilterManager::filterActionDict()->value(actionName); 0738 if (description) { 0739 FilterAction *filterAction = description->create(); 0740 if (filterAction) { 0741 filterAction->argsFromString(actionArguments); 0742 filter.mActions.append(filterAction); 0743 } 0744 } 0745 } 0746 0747 stream >> filter.mAccounts; 0748 stream >> filter.mIcon; 0749 stream >> filter.mToolbarName; 0750 stream >> shortcut; 0751 stream >> bApplyOnInbound; 0752 stream >> bApplyBeforeOutbound; 0753 stream >> bApplyOnOutbound; 0754 stream >> bApplyOnExplicit; 0755 stream >> bApplyOnAllFolders; 0756 stream >> bStopProcessingHere; 0757 stream >> bConfigureShortcut; 0758 stream >> bConfigureToolbar; 0759 stream >> bAutoNaming; 0760 stream >> applicability; 0761 stream >> bEnabled; 0762 0763 filter.mPattern.deserialize(pattern); 0764 filter.mShortcut = shortcut; 0765 filter.bApplyOnInbound = bApplyOnInbound; 0766 filter.bApplyBeforeOutbound = bApplyBeforeOutbound; 0767 filter.bApplyOnOutbound = bApplyOnOutbound; 0768 filter.bApplyOnExplicit = bApplyOnExplicit; 0769 filter.bApplyOnAllFolders = bApplyOnAllFolders; 0770 filter.bStopProcessingHere = bStopProcessingHere; 0771 filter.bConfigureShortcut = bConfigureShortcut; 0772 filter.bConfigureToolbar = bConfigureToolbar; 0773 filter.bAutoNaming = bAutoNaming; 0774 filter.bEnabled = bEnabled; 0775 filter.mApplicability = static_cast<MailCommon::MailFilter::AccountType>(applicability); 0776 0777 return stream; 0778 } 0779 0780 bool MailFilter::isEnabled() const 0781 { 0782 return bEnabled; 0783 } 0784 0785 void MailFilter::setEnabled(bool enabled) 0786 { 0787 bEnabled = enabled; 0788 }