diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-31 12:24:32 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-31 12:24:32 +0100 |
| commit | ef42103bb1639006c5558eae5f857cd8f9ad2418 (patch) | |
| tree | 33aada792086d58d6a97690f52fdfd4e84f6f33e /src/notmuchworker.h | |
| parent | aa5fc733c768f8779af897c0cdcaf836b2afcefb (diff) | |
| download | qtmaildir-ef42103bb1639006c5558eae5f857cd8f9ad2418.tar.gz qtmaildir-ef42103bb1639006c5558eae5f857cd8f9ad2418.zip | |
feat: a worker entry point that applies a rule to existing mail
applyRule() replaces applyTagsToQuery(). It resolves the messages the
whole rule would move once, then writes one tag at a time over that
fixed list, and answers with ruleApplied(token, changes): one TagChange
per operation carrying the ids it actually moved. Always answered, even
when nothing moved, and never through tagsApplied(), so the window can
build the undo entry from the answer instead of the shared confirmation
queue that user gestures also use.
Resolving once matters when the query names a tag the rule removes:
re-resolving after the first write matched nothing and wrote half the
rule. Writing per tag keeps each effective set exact, so the undo never
strips a tag a message had before.
applyTags() keeps its behaviour; its body is now writeTags(), which
returns the changed ids without emitting.
Item 212.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/notmuchworker.h')
| -rw-r--r-- | src/notmuchworker.h | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/src/notmuchworker.h b/src/notmuchworker.h index fa223e6..a175d7a 100644 --- a/src/notmuchworker.h +++ b/src/notmuchworker.h @@ -232,14 +232,24 @@ public slots: const QStringList &remove, const QString &description); - /// Applies `+add -remove` to every message the change would move within - /// `query` (item 212, a rule applied to existing mail). The query is - /// narrowed with SearchTerm::changes() so already-correct messages are - /// never written, then the ids go through applyTags(), which reports the - /// effective set for undo. Emits nothing when nothing would change. - void applyTagsToQuery(const QString &query, const QStringList &add, - const QStringList &remove, - const QString &description); + /// Applies a tagging rule to existing mail (item 212). Resolves the + /// messages the WHOLE rule would move once, with SearchTerm::changes(), + /// then writes one tag at a time over that fixed list: `+a` for each add, + /// `-r` for each remove. + /// + /// One write per tag because the effective set is per MESSAGE: a single + /// `+promo -inbox` write reports a message that already had promo (it lost + /// inbox), and the undo built from it would strip promo. One resolution + /// because a query may name a tag the rule removes, and re-resolving after + /// the first write would match nothing for the rest, writing half the + /// rule where the hook writes all of it. + /// + /// Answers with ruleApplied() ALWAYS, even when nothing moved, and never + /// with tagsApplied(): the window builds the undo from the answer rather + /// than from the shared confirmation queue. + void applyRule(const QString &query, const QStringList &add, + const QStringList &remove, const QString &description, + quint64 token); /// Resolves whole threads to the message ids and file paths they contain. /// @@ -386,6 +396,13 @@ signals: void threadDigestLoaded(const ThreadDigest &digest, quint64 generation); void tagsApplied(const TagChange &change); + /// applyRule()'s answer: one TagChange per single-tag operation, in the + /// order applyRule() documents, each carrying the ids that operation + /// actually moved (possibly none). `token` is echoed from the request. + /// Emitted even after a write error, carrying what was written before it, + /// so the window can still offer undo for that part. + void ruleApplied(quint64 token, const QVector<TagChange> &changes); + /// One file entered or left the index outside a query (item 192). /// /// Emitted by indexDraftFile() and removeIndexedFile(), the two entry @@ -483,6 +500,11 @@ private: bool openReadOnly(); void close(); + /// applyTags() without the signal: writes `change` and fills `changedIds` + /// with the messages whose tags really moved. False, with errorOccurred() + /// emitted, when the database could not be opened for writing. + bool writeTags(const TagChange &change, QStringList *changedIds); + QByteArray configPathArg() const; QString m_configPath; |
