diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/threadlistmodel.cpp | 37 | ||||
| -rw-r--r-- | src/threadlistmodel.h | 20 |
2 files changed, 57 insertions, 0 deletions
diff --git a/src/threadlistmodel.cpp b/src/threadlistmodel.cpp index 9a74041..0956e6b 100644 --- a/src/threadlistmodel.cpp +++ b/src/threadlistmodel.cpp @@ -268,6 +268,37 @@ QVariant ThreadListModel::data(const QModelIndex &index, int role) const return QStringList(); case PillColoursRole: return QVariantList(); + case MessageOwnTagsRole: { + // Set difference against the parent THREAD, not against a global + // list: "own" means "not already said by the card above this one". + // The parent row indexes m_threads directly, which is the same + // mapping messageAt() uses to reach this node. + const int threadRow = index.parent().row(); + const QStringList threadTags = + (threadRow >= 0 && threadRow < m_threads.size()) + ? m_threads.at(threadRow).summary.tags + : QStringList(); + QStringList own; + for (const QString &tag : node.tags) { + if (!threadTags.contains(tag)) + own.append(tag); + } + // Sorted, so a reply does not reshuffle its own chips between + // repaints, matching what PillTagsRole already guarantees. + own.sort(); + return own; + } + case MessageOwnColoursRole: { + const QStringList own = + data(index, MessageOwnTagsRole).toStringList(); + QVariantList colours; + colours.reserve(own.size()); + for (const QString &tag : own) { + colours.append(m_tagColors ? m_tagColors->colourFor(tag) + : TagColors().colourFor(tag)); + } + return colours; + } case AccountLabelRole: return QString(); case Qt::DisplayRole: @@ -344,6 +375,12 @@ QVariant ThreadListModel::data(const QModelIndex &index, int role) const if (role == TagsRole) return thread.tags; + if (role == MessageOwnTagsRole) + return QStringList(); + + if (role == MessageOwnColoursRole) + return QVariantList(); + if (role == PillTagsRole || role == PillColoursRole) { // Everything the row already says another way is dropped: the account // is the chip in the subject cell, flagged is the star column, diff --git a/src/threadlistmodel.h b/src/threadlistmodel.h index b80488b..b13165c 100644 --- a/src/threadlistmodel.h +++ b/src/threadlistmodel.h @@ -103,6 +103,26 @@ public: /// delegate cannot call hasChildren without the model, and the same /// answer has to reach the cell that reserves room for the glyph. HasRepliesRole, + + /// The tags this MESSAGE carries that its thread does not. + /// + /// A reply card shows these and nothing else. Showing a reply's full + /// tag set instead was measured against the user's own database and + /// rejected: of 48691 messages, 7 carry `unread` and 75 carry + /// `flagged`, and both are already drawn another way (the sender's + /// weight, and the mark on line 2). Every other tag is applied to a + /// whole thread and is identical on all its messages, so full sets + /// would repeat the thread's own chips down the entire expansion, + /// which is the striping the old row-wide strip existed to avoid. + /// + /// Empty on a thread row, which has no thread to differ from. + MessageOwnTagsRole, + + /// The colours for MessageOwnTagsRole, in the same order. Supplied by + /// the model for the same reason as PillColoursRole: it owns the + /// TagColors instance, and a delegate reading config itself would be a + /// second source of truth. + MessageOwnColoursRole, }; /// Row fill for a thread tagged `deleted`, and for one tagged `spam`. |
