From 9bec59c98a9f00e6e7f2c0181659a7639bc04e72 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 28 Aug 2026 11:26:41 +0200 Subject: feat: let a row say whether it is a conversation One predicate for the question every scope, label and membership decision in item 177 keys on. It repeats hasChildren()'s rule deliberately: an expander and a conversation are the same fact, including that a loaded thread trusts its children over a count that included duplicates. --- src/threadlistmodel.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/threadlistmodel.cpp') diff --git a/src/threadlistmodel.cpp b/src/threadlistmodel.cpp index f085b79..1bda728 100644 --- a/src/threadlistmodel.cpp +++ b/src/threadlistmodel.cpp @@ -1014,6 +1014,29 @@ bool ThreadListModel::isMessageRow(const QModelIndex &index) const return index.isValid() && index.parent().isValid(); } +bool ThreadListModel::isConversationRow(const QModelIndex &index) const +{ + if (!index.isValid() || isMessageRow(index)) + return false; + if (index.row() < 0 || index.row() >= m_threads.size()) + return false; + + // A flat view has no conversations by construction: every row is one + // message and there is nothing to expand. + if (m_flatMode) + return false; + + const ThreadNode &node = m_threads.at(index.row()); + + // Identical to hasChildren()'s rule, and deliberately so: an expander and a + // conversation are the same fact. Once loaded the children are the truth, + // which is how a thread whose totalCount counted DUPLICATES stops claiming + // to be a conversation it cannot open. + if (node.loaded) + return !node.children.isEmpty(); + return node.summary.totalCount > 1; +} + MessageNode ThreadListModel::messageAt(const QModelIndex &index) const { if (!isMessageRow(index)) -- cgit v1.2.3