diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-10 08:28:22 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-10 08:28:22 +0200 |
| commit | 2d062241732f7396e8cb12295962d3f3e5c1a2b0 (patch) | |
| tree | 6dfb0655d5b32d4457bd5bf508a844da7b57736a /src/threadlistmodel.cpp | |
| parent | 1335d3c7f891a22f61307d2d186483f56e8e558c (diff) | |
| download | qtmaildir-2d062241732f7396e8cb12295962d3f3e5c1a2b0.tar.gz qtmaildir-2d062241732f7396e8cb12295962d3f3e5c1a2b0.zip | |
feat(model): expose the tags a reply has and its thread does not
A reply card shows only these. The alternative, a reply's full tag set, was
rejected on measurement rather than taste: in the user's database 7 of 48691
messages carry unread and 75 carry flagged, both already drawn another way, and
every other tag is applied per thread and identical on all its messages. Full
sets would repeat the thread's chips down the whole expansion, which is the
striping the row-wide strip was built to avoid.
Diffstat (limited to 'src/threadlistmodel.cpp')
| -rw-r--r-- | src/threadlistmodel.cpp | 37 |
1 files changed, 37 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, |
