diff options
Diffstat (limited to 'src/threadlistmodel.cpp')
| -rw-r--r-- | src/threadlistmodel.cpp | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/src/threadlistmodel.cpp b/src/threadlistmodel.cpp index c129be1..2f2882e 100644 --- a/src/threadlistmodel.cpp +++ b/src/threadlistmodel.cpp @@ -18,8 +18,24 @@ #include "threadlistmodel.h" +#include <QBrush> #include <QFont> +QColor ThreadListModel::deletedColour() +{ + // Desaturated crimson: legible under white text on a dark theme, and calm + // enough that deleting fifty threads does not repaint the list as a + // warning banner. + return QColor(0x8b, 0x2c, 0x2c); +} + +QColor ThreadListModel::spamColour() +{ + // Distinct hue rather than a lighter red, so spam and deleted are told + // apart by colour and not by shade. + return QColor(0xa8, 0x5c, 0x18); +} + ThreadListModel::ThreadListModel(QObject *parent) : QAbstractTableModel(parent) { @@ -49,6 +65,26 @@ QVariant ThreadListModel::data(const QModelIndex &index, int role) const if (role == ThreadIdRole) return thread.threadId; + if (role == TagsRole) + return thread.tags; + + if (role == AccountLabelRole || role == AccountColourRole) { + // At most one account tag per thread in practice, but a thread whose + // messages landed in two mailboxes carries both; the first is shown. + for (const QString &tag : thread.tags) { + if (!TagColors::isAccountTag(tag)) + continue; + if (role == AccountLabelRole) { + // The configured label when there is one, otherwise the key. + return m_tagColors ? m_tagColors->labelForAccountTag(tag) + : TagColors::accountKeyForTag(tag); + } + return m_tagColors ? m_tagColors->colourFor(tag) + : TagColors().colourFor(tag); + } + return {}; + } + if (role == Qt::DisplayRole) { switch (index.column()) { case DateColumn: @@ -60,17 +96,39 @@ QVariant ThreadListModel::data(const QModelIndex &index, int role) const ? QStringLiteral("%1 (%2)").arg(thread.subject) .arg(thread.totalCount) : thread.subject; - case TagsColumn: - return thread.tags.join(QLatin1Char(' ')); default: return {}; } } - if (role == Qt::FontRole && thread.isUnread()) { + // A thread tagged deleted or spam is on its way out, and the user needs to + // see that the moment they act. Every one of these roles applies to the + // whole row: a cue on a single column disappears as soon as that column + // scrolls out of view, which is exactly how the tag change used to go + // unnoticed. + if (thread.isDoomed()) { + if (role == Qt::BackgroundRole) + return QBrush(thread.isDeleted() ? deletedColour() : spamColour()); + if (role == Qt::ForegroundRole) + return QBrush(QColor(Qt::white)); + } + + if (role == Qt::FontRole) { QFont font; - font.setBold(true); - return font; + bool styled = false; + if (thread.isUnread()) { + font.setBold(true); + styled = true; + } + // Struck through as well as filled, so the state survives a + // screenshot, a colourblind reader, and a theme that overrides the + // background. + if (thread.isDoomed()) { + font.setStrikeOut(true); + styled = true; + } + if (styled) + return font; } return {}; @@ -86,7 +144,6 @@ QVariant ThreadListModel::headerData(int section, Qt::Orientation orientation, case DateColumn: return QStringLiteral("Date"); case AuthorsColumn: return QStringLiteral("From"); case SubjectColumn: return QStringLiteral("Subject"); - case TagsColumn: return QStringLiteral("Tags"); default: return {}; } } |
