diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-14 13:46:33 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-14 13:46:33 +0200 |
| commit | 9fdac493c9a6e35f36dc45ff0e13583ddf88605e (patch) | |
| tree | ff561fba18bd543306b3166c8eb3591cb1d220e3 /src/mainwindow.h | |
| parent | d714483b6027425923340d1bcfa0263b8e7ac0bc (diff) | |
| download | qtmaildir-9fdac493c9a6e35f36dc45ff0e13583ddf88605e.tar.gz qtmaildir-9fdac493c9a6e35f36dc45ff0e13583ddf88605e.zip | |
feat: a Not spam action
Backlog item 201. A message in the Spam view had no way back out: spam is
one-way and Restore is hidden outside the trash. not_spam moves each message
to the folder its moved-from: origin names, falling back to the account's
inbox (reported) for provider-caught mail with no origin.
The action is labelled "Not junk" on the free Alt+J: every letter of "Not
spam" is taken in the Message menu, and Alt+P (Re&ply) and Alt+S (Mark &spam,
frozen) are unavailable.
restoreResolvedMessages() and the undelete_thread branch are parameterised
with the cleared tag and undo description rather than copied, so Delete and
Not spam cannot drift.
Diffstat (limited to 'src/mainwindow.h')
| -rw-r--r-- | src/mainwindow.h | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h index 478de2d..c3395c9 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -1130,6 +1130,17 @@ private: /// Delete on exactly the mail a trash view is full of. bool everySelectedRowIsInATrashFolder() const; + /// Whether every selected row's file already sits in its account's spam + /// folder. Empty selection answers false. The spam twin of + /// everySelectedRowIsInATrashFolder(), and asked of the PATH for the same + /// reason: provider-caught mail in the spam folder carries no `spam` tag. + bool everySelectedRowIsInASpamFolder() const; + + /// The one walk both predicates above share: \p folder names the Account + /// member (`&Account::trash` or `&Account::spam`) whose folder is asked + /// about. + bool everySelectedRowIsInAFolder(QString Account::*folder) const; + /// Opens the tag dialog on the current selection and applies its result. /// /// The only route to an arbitrary tag: every other tag action writes a @@ -1276,6 +1287,22 @@ private: /// this asks the worker and finishes in onThreadMessagesResolved(). void spamThreads(const QStringList &threadIds); + /// Moves each selected row's message back OUT of the spam folder, to the + /// folder its `moved-from:` tag names. Mark spam's inverse and Restore's + /// twin, offered only on a selection that is in a spam folder. + void notSpamSelected(); + + /// The half of notSpamSelected() that does the work, given the tags and + /// paths the WORKER reported. Forwards to restoreResolvedMessages() with + /// `spam` as the cleared tag, so the two restore directions cannot drift. + void notSpamMessages(const QStringList &messageIds, + const QStringList &paths, + const QStringList &tags); + + /// Moves every message of the named THREADS out of their accounts' spam + /// folders. Asynchronous like spamThreads(), and for the same reason. + void notSpamThreads(const QStringList &threadIds); + /// Runs the thread-scoped delete once the worker has resolved the /// threads to messages. void onThreadMessagesResolved(const QStringList &messageIds, @@ -1360,9 +1387,28 @@ private: /// Moves each resolved message home, using the tags and paths the WORKER /// reported rather than anything the model holds. + /// + /// One walk serves all four restore routes: Delete out of the trash + /// (message and thread scoped) and Not spam out of the spam folder + /// (message and thread scoped). \p clearedTag is the folder's marker tag + /// (`deleted` or `spam`) stripped by the move; \p description names the + /// action in the status line and on the undo entry. + /// + /// \p moveUnoriginToInbox picks what a message with no `moved-from:` + /// origin gets: the inbox, reported (the message-scoped routes and Not + /// spam, where the mail is demonstrably in the folder and must come out), + /// or a tag-only removal with no file move (the thread-scoped TRASH route, + /// which Delete's toggle also reaches on stranded mail sitting outside the + /// trash). \p skipUnmarked drops messages that do not carry \p clearedTag, + /// which only the thread-scoped trash route needs. void restoreResolvedMessages(const QStringList &messageIds, const QStringList &paths, - const QStringList &tags); + const QStringList &tags, + const QString &clearedTag, + const QString &description, + bool moveUnoriginToInbox, + bool skipUnmarked, + const QStringList &wholeThreadIds = {}); /// The messages a resolveMessages() request was made for. QStringList m_pendingRestoreIds; |
