aboutsummaryrefslogtreecommitdiffstats
path: root/src/threadlistmodel.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-28 12:33:52 +0200
committerDanilo M. <danix@danix.xyz>2026-08-28 12:33:52 +0200
commit978c9b51935f8597ce307166bfba29368bd4fc23 (patch)
treed07ee82615113e31f788c731ffdfffa626e7ec21 /src/threadlistmodel.cpp
parentcc551a4ed348e663601f2fb8e06b59c07a09ead4 (diff)
downloadqtmaildir-978c9b51935f8597ce307166bfba29368bd4fc23.tar.gz
qtmaildir-978c9b51935f8597ce307166bfba29368bd4fc23.zip
feat: scope an action to the row it was invoked on
The five *_thread actions and their submenu are gone: the row's identity is what decides the scope, so a second set of actions was a second answer to a settled question. mark_thread_unread went with them, being the sixth entry in the same submenu. tagSelected() loses its TagScope parameter, and everySelectedRowHasTag() its own, so the direction and the write ask the same question of the same object. ThreadListModel::scopeFor() and messageScopeFor() are deleted; scopeForSelection() is the one resolver. Labels name the scope. Archive, Delete, Restore, Spam, Important and the unread toggle all say "thread" on a conversation row, and Delete, Restore and Archive are ABSENT on a reply: a single reply cannot be removed from a conversation. Compose follows the same rule. Forward, Save, Reply-all and Reply without quoting disappear on a conversation row, which shows no message to act on, and Reply becomes "Reply to this thread": reply-all, quoting nothing, threaded off the conversation's NEWEST message so the answer lands at its end rather than forking the discussion at its opening post. That id is not in the model, since an unexpanded conversation holds no nodes for its replies, so it comes from resolveThreadMessages(); resolveQuery() states its newest-first sort rather than inheriting notmuch's default. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012iDeN6C7y97nHYPvP6ST4L
Diffstat (limited to 'src/threadlistmodel.cpp')
-rw-r--r--src/threadlistmodel.cpp67
1 files changed, 0 insertions, 67 deletions
diff --git a/src/threadlistmodel.cpp b/src/threadlistmodel.cpp
index ddddf0b..fd4899b 100644
--- a/src/threadlistmodel.cpp
+++ b/src/threadlistmodel.cpp
@@ -1050,73 +1050,6 @@ MessageNode ThreadListModel::messageById(const QString &messageId) const
return {};
}
-ActionScope ThreadListModel::messageScopeFor(
- const QModelIndexList &selection) const
-{
- ActionScope scope;
-
- for (const QModelIndex &index : selection) {
- QString messageId;
- if (isMessageRow(index)) {
- messageId = messageAt(index).messageId;
- } else {
- if (index.row() < 0 || index.row() >= m_threads.size())
- continue;
- // The message the CARD displays, which the query already named.
- // Not the loaded children: a thread the user never expanded still
- // shows its first message, and this must work without one.
- messageId = m_threads.at(index.row()).summary.firstMessageId;
- }
-
- // Skipped rather than widened. Falling back to the thread here would
- // silently act on messages the row does not display, which is the
- // behaviour item 108 removed.
- if (messageId.isEmpty() || scope.messageIds.contains(messageId))
- continue;
-
- scope.messageIds.append(messageId);
- scope.messageCount += 1;
- }
-
- return scope;
-}
-
-ActionScope ThreadListModel::scopeFor(const QModelIndexList &selection) const
-{
- ActionScope scope;
-
- for (const QModelIndex &index : selection) {
- if (isMessageRow(index)) {
- const MessageNode node = messageAt(index);
- if (node.messageId.isEmpty()
- || scope.messageIds.contains(node.messageId))
- continue;
- scope.messageIds.append(node.messageId);
- scope.messageCount += 1;
- continue;
- }
-
- if (index.row() < 0 || index.row() >= m_threads.size())
- continue;
-
- const ThreadSummary &summary = m_threads.at(index.row()).summary;
- if (scope.threadIds.contains(summary.threadId))
- continue;
-
- scope.threadIds.append(summary.threadId);
-
- // totalCount, not the loaded children: a thread that was never expanded
- // still has all of its messages, and counting only what happens to be
- // on screen would understate what the action does. Floored at 1, since
- // a summary with no count still stands for at least the message that
- // produced it.
- scope.messageCount += qMax(1, summary.totalCount);
- scope.wholeThread = true;
- }
-
- return scope;
-}
-
ActionScope ThreadListModel::scopeForSelection(
const QModelIndexList &selection) const
{