Commit d1a3ad6f authored by Daniel Vrátil's avatar Daniel Vrátil 🤖

MailFilterAgent: implement support for 'All folders' filters

When a filter has the 'Apply to inbound emails in all folders' option enabled,
the MFA will monitor all Collections and will match the filter against all
incoming emails in all folders. This option combines with the 'Only apply to
account' option, so one can restrict the filter to only apply against all
folders from only a specific account.

Differential Revision: https://phabricator.kde.org/D7135
parent 51ceae1e
......@@ -63,7 +63,7 @@ option(KDEPIM_ENTERPRISE_BUILD "Enable features specific to the enterprise branc
find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED DBus Network Test Widgets WebEngine WebEngineWidgets Xml)
set(LIBGRAVATAR_VERSION_LIB "5.6.40")
set(MAILCOMMON_LIB_VERSION_LIB "5.6.40")
set(MAILCOMMON_LIB_VERSION_LIB "5.6.41")
set(KDEPIM_APPS_LIB_VERSION_LIB "5.6.40")
set(MESSAGELIB_LIB_VERSION_LIB "5.6.41")
set(LIBKLEO_LIB_VERSION_LIB "5.6.40")
......
......@@ -84,6 +84,7 @@ public:
SearchRule::RequiredPart mRequiredPartsBasedOnAll;
QPixmap pixmapNotification;
bool mInboundFiltersExist;
bool mAllFoldersFiltersExist;
int mTotalProgressCount;
int mCurrentProgressCount;
};
......@@ -345,8 +346,17 @@ void FilterManager::readConfig()
}
}
// check if at least one filter is to be applied on inbound mail
d->mInboundFiltersExist = std::find_if(d->mFilters.constBegin(), d->mFilters.constEnd(),
std::mem_fn(&MailCommon::MailFilter::applyOnInbound)) != d->mFilters.constEnd();
for (auto i = d->mFilters.cbegin(), e = d->mFilters.cend();
i != e && (!d->mInboundFiltersExist || !d->mAllFoldersFiltersExist);
++i) {
if ((*i)->applyOnInbound()) {
d->mInboundFiltersExist = true;
}
if ((*i)->applyOnAllFoldersInbound()) {
d->mAllFoldersFiltersExist = true;
}
}
Q_EMIT filterListUpdated();
}
......@@ -512,9 +522,10 @@ bool FilterManager::process(const QList< MailFilter * > &mailFilters, const Akon
const bool outboundOk = ((set & Outbound) && (*it)->applyOnOutbound());
const bool beforeOutboundOk = ((set & BeforeOutbound) && (*it)->applyBeforeOutbound());
const bool explicitOk = ((set & Explicit) && (*it)->applyOnExplicit());
const bool allFoldersOk = ((set & AllFolders) && (*it)->applyOnAllFoldersInbound());
const bool accountOk = (!account || (account && (*it)->applyOnAccount(accountId)));
if ((inboundOk && accountOk) || outboundOk || beforeOutboundOk || explicitOk) {
if ((inboundOk && accountOk) || (allFoldersOk && accountOk) || outboundOk || beforeOutboundOk || explicitOk) {
// filter is applicable
if (d->isMatching(context.item(), *it)) {
......@@ -633,4 +644,9 @@ void FilterManager::applyFilters(const Akonadi::Item::List &selectedMessages, Fi
SLOT(itemsFetchJobForFilterDone(KJob *)));
}
bool FilterManager::hasAllFoldersFilter() const
{
return d->mAllFoldersFiltersExist;
}
#include "moc_filtermanager.cpp"
......@@ -44,7 +44,8 @@ public:
Outbound = 0x2,
Explicit = 0x4,
BeforeOutbound = 0x8,
All = Inbound | BeforeOutbound | Outbound | Explicit
AllFolders = 0x16,
All = Inbound | BeforeOutbound | Outbound | Explicit | AllFolders
};
enum FilterRequires {
......@@ -124,6 +125,8 @@ public:
void mailCollectionRemoved(const Akonadi::Collection &collection);
void agentRemoved(const QString &identifier);
bool hasAllFoldersFilter() const;
#ifndef NDEBUG
/**
* Outputs all filter rules to console. Used for debugging.
......
......@@ -54,9 +54,13 @@
#include <kdelibs4configmigrator.h>
static bool isFilterableCollection(const Akonadi::Collection &collection)
bool MailFilterAgent::isFilterableCollection(const Akonadi::Collection &collection) const
{
return MailCommon::Kernel::folderIsInbox(collection);
if (!collection.contentMimeTypes().contains(KMime::Message::mimeType())) {
return false;
}
return m_filterManager->hasAllFoldersFilter() || MailCommon::Kernel::folderIsInbox(collection);
//TODO: check got filter attribute here
}
......@@ -148,9 +152,12 @@ void MailFilterAgent::initializeCollections()
{
m_filterManager->readConfig();
Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob(Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive, this);
job->fetchScope().setContentMimeTypes(QStringList() << KMime::Message::mimeType());
connect(job, &Akonadi::CollectionFetchJob::result, this, &MailFilterAgent::initialCollectionFetchingDone);
Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob(Akonadi::Collection::root(),
Akonadi::CollectionFetchJob::Recursive,
this);
job->fetchScope().setContentMimeTypes({ KMime::Message::mimeType() });
connect(job, &Akonadi::CollectionFetchJob::result,
this, &MailFilterAgent::initialCollectionFetchingDone);
}
void MailFilterAgent::initialCollectionFetchingDone(KJob *job)
......@@ -160,23 +167,20 @@ void MailFilterAgent::initialCollectionFetchingDone(KJob *job)
return; //TODO: proper error handling
}
Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob *>(job);
const auto fetchJob = qobject_cast<Akonadi::CollectionFetchJob *>(job);
const QMap<QString, Akonadi::Collection::Id> pop3ResourceMap = MailCommon::Kernel::pop3ResourceTargetCollection();
const auto pop3ResourceMap = MailCommon::Kernel::pop3ResourceTargetCollection();
const Akonadi::Collection::List lstCols = fetchJob->collections();
const auto lstCols = fetchJob->collections();
for (const Akonadi::Collection &collection : lstCols) {
if (isFilterableCollection(collection)) {
changeRecorder()->setCollectionMonitored(collection, true);
} else {
QMap<QString, Akonadi::Collection::Id>::const_iterator i = pop3ResourceMap.constBegin();
const QMap<QString, Akonadi::Collection::Id>::const_iterator end = pop3ResourceMap.constEnd();
while (i != end) {
if (collection.id() == i.value()) {
for (auto pop3ColId : pop3ResourceMap) {
if (collection.id() == pop3ColId) {
changeRecorder()->setCollectionMonitored(collection, true);
break;
}
++i;
}
}
}
......
......@@ -80,6 +80,8 @@ public Q_SLOTS:
void configure(WId windowId) override;
private:
bool isFilterableCollection(const Akonadi::Collection &collection) const;
FilterManager *m_filterManager;
FilterLogDialog *m_filterLogDialog;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment