aboutsummaryrefslogtreecommitdiffstats
path: root/src/mainwindow.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-25 19:19:21 +0200
committerDanilo M. <danix@danix.xyz>2026-08-25 19:19:21 +0200
commitdd6e7a051c22e5145c1b23da0614179aef2e1379 (patch)
tree5fd840216d5ae06715e7ca4116c6cea603a7a232 /src/mainwindow.h
parentdfb36213c03e678178ec1abb2327266d23015bc0 (diff)
downloadqtmaildir-dd6e7a051c22e5145c1b23da0614179aef2e1379.tar.gz
qtmaildir-dd6e7a051c22e5145c1b23da0614179aef2e1379.zip
fix: offer Delete and Restore only where they mean something
Item 168, found by the user while hand-testing 118: Delete could be triggered on a message already in the trash. Not dangerous, which is how it survived. moveMessages() finds the file already in the destination and takes its early-return branch, so the message is reported as moved, an unsynced change is counted, and nothing happened. Restore had the mirror of the same problem, added unconditionally to both menus and so offered on mail that was never deleted. Each is now hidden where it has no meaning, which is the rule item 112 established for the unread entry. The question is about the PATH, never the deleted tag: a message trashed by another client carries no such tag, which is why the trash view is path-based, and asking the tag would hide Delete on exactly the mail a trash view is full of. Delete also removes unread now, at the user's request on the same tangent. It travels inside the same sendMove() call rather than as a second write, so one undo returns the folder and the tag together. This rewrites the Maildir filename, because maildir.synchronize_flags is true, and so reaches the server: the same mechanism the post-new hook refuses to touch, and the difference is that the hook acts unattended on arriving mail while this is an explicit gesture on a message in front of the user. A mutation survived the first round and found a real hole: comparing the prefix without its trailing separator passed every test, because no fixture had a folder whose name starts with the trash folder's. Under it Delete silently vanished from mail in acct/trash-old, which is not the trash. The fixture carries that row now and all three properties are mutation-checked. The suite is 37 of 38, the failure being item 136 on an unrelated path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFuRPtzFrSxCQjFk6tq7gD
Diffstat (limited to 'src/mainwindow.h')
-rw-r--r--src/mainwindow.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 42708d9..a5a8c31 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -909,6 +909,20 @@ private:
/// single state. Called whenever the selection changes.
void refreshUnreadAction();
+ /// Hides Delete on mail already in the trash, and Restore on mail that
+ /// was never there (item 168). Each is offered only where it means
+ /// something, the same rule refreshUnreadAction() applies to the label.
+ void refreshTrashActions();
+
+ /// Whether every selected row's file already sits in its account's trash
+ /// folder. Empty selection answers false.
+ ///
+ /// The question is about the PATH, never the `deleted` TAG: a message
+ /// trashed by another client carries no such tag at all, which is why the
+ /// trash view is path-based (item 103), and asking the tag would offer
+ /// Delete on exactly the mail a trash view is full of.
+ bool everySelectedRowIsInATrashFolder() const;
+
void editTagsOnSelection();
/// Set once the user has answered the exit prompt, or once a sync started