aboutsummaryrefslogtreecommitdiffstats
path: root/src/threadlistmodel.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-03 15:42:40 +0200
committerDanilo M. <danix@danix.xyz>2026-08-03 15:42:40 +0200
commiteb35acda4207392c10b4b1192b3b057bcad99a47 (patch)
treec962e91fc502ec57d92df386e773033fe42fd17b /src/threadlistmodel.cpp
parentafd20c9527fa77ba60901707c7bc73b2af926a67 (diff)
parentf62ced3c2c85675e746bff7ef8aca5c75c9737e0 (diff)
downloadqtmaildir-eb35acda4207392c10b4b1192b3b057bcad99a47.tar.gz
qtmaildir-eb35acda4207392c10b4b1192b3b057bcad99a47.zip
Merge branch 'feature/qaction-menus'
Menus, a toolbar and a generated shortcut reference, built on converting the action registry from a hash of callbacks to QActions. Along the way: three default key bindings that had never fired, a shortcut dialog taller than the screen, thread list columns that could not be resized, no visible feedback that a tag action had landed, and a tags column so wide it was unreadable. Backlog items 3, 8, 9, 13 and 14 done; 11 partly.
Diffstat (limited to 'src/threadlistmodel.cpp')
-rw-r--r--src/threadlistmodel.cpp69
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 {};
}
}