diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-13 20:03:17 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-13 20:03:17 +0200 |
| commit | 18ff1f33f64428ab96ca0b5ea22e681be564c886 (patch) | |
| tree | 4c283551bba03a1436cc1f1ac3b3b4c2dcdfc95b /src/config.cpp | |
| parent | 2623b762a90b04c57491a5d58ab72c8807c65c80 (diff) | |
| download | qtmaildir-18ff1f33f64428ab96ca0b5ea22e681be564c886.tar.gz qtmaildir-18ff1f33f64428ab96ca0b5ea22e681be564c886.zip | |
feat(config): a threaded, path-based spam filter
Diffstat (limited to 'src/config.cpp')
| -rw-r--r-- | src/config.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/config.cpp b/src/config.cpp index 0fa3c85..390848a 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -64,7 +64,8 @@ const QStringList kQueryGenerators = { QStringLiteral("unread"), QStringLiteral("flagged"), QStringLiteral("sent"), QStringLiteral("drafts"), - QStringLiteral("trash") }; + QStringLiteral("trash"), + QStringLiteral("spam") }; /// The tag a generator matches, for the three filters that are a plain tag /// query. Empty for "sent", "drafts" and "trash", which compose from each @@ -1018,6 +1019,8 @@ QString Config::resolvedQuery(const SavedQuery &query) const return allSentQuery(); if (query.generated == QStringLiteral("trash")) return allTrashQuery(); + if (query.generated == QStringLiteral("spam")) + return allSpamQuery(); // An unknown generator was reported on load. Empty rather than the // bare stored query, which for a generated entry is empty anyway and // would otherwise run as "match everything". @@ -1106,6 +1109,10 @@ SavedQuery Config::builtinFilter(const QString &generator) // NOT flat, unlike Sent. A deleted message still belongs to its // conversation, and folding it back is what Sent had to avoid rather // than something every folder filter wants. + } else if (generator == QStringLiteral("spam")) { + filter.name = tr("Spam"); + // NOT flat, like trash: a spam message still belongs to its + // conversation. } return filter; @@ -1138,6 +1145,10 @@ QString Config::resolvedQuery(const SavedQuery &query, const QString all = allTrashQuery(); return all.isEmpty() ? matchNothingQuery() : all; } + if (query.generated == QStringLiteral("spam")) { + const QString all = allSpamQuery(); + return all.isEmpty() ? matchNothingQuery() : all; + } return QStringLiteral("tag:%1").arg(generatorTag(query.generated)); } @@ -1173,6 +1184,14 @@ QString Config::resolvedQuery(const SavedQuery &query, return trash.isEmpty() ? matchNothingQuery() : trash; } + if (query.generated == QStringLiteral("spam")) { + // The account's OWN spam query, for the reason spelled out above the + // sent case: wrapping the all-accounts query in this account's path + // works by accident of path: being hierarchical. + const QString spam = scope.spamQuery(); + return spam.isEmpty() ? matchNothingQuery() : spam; + } + // A tag filter carries no path of its own, so scoping is exactly what // scopedQuery() does. Its parentheses are load-bearing: `path:... and a or // b` binds as `(path:... and a) or b`. |
