diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-11 10:56:40 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-11 10:56:40 +0200 |
| commit | 00c029a819eca601e9ac58e5c236d667505ac566 (patch) | |
| tree | 52513f0f57129b95e1533863f82be00f5eff404b /src/config.cpp | |
| parent | a8844303aeb9295a6f94408cd809e521483a8b9a (diff) | |
| download | qtmaildir-00c029a819eca601e9ac58e5c236d667505ac566.tar.gz qtmaildir-00c029a819eca601e9ac58e5c236d667505ac566.zip | |
feat(config): let the date format on a card be configured
Adds [general] date_format, a QDateTime pattern for the date a thread card
shows. Absent or empty means the system locale's short format, which is what
every other application on the desktop uses and stays the default.
The format reaches the LAYOUT, not only the painter. CardLayout::compute()
reserves the date's width from widestDateSample(), so a pattern that arrived
only at the drawText call would be elided into a rect sized for the old
format, which is the clipping the bold-font fault already produced once. It
rides on CardLayout::Input and defaults to an empty string, leaving every
existing call site unchanged. Confirmed by mutation: making the width ignore
the format fails the test.
widestDateSample() memoised its result in a static, which would have sized
every format after the first from whichever arrived first. It is a plain call
now, costing one QLocale lookup per row, the same as formatting the date.
Validation rejects only a pattern whose output is CONSTANT, found by
formatting two different instants and comparing. QDateTime::toString() treats
nearly every letter as a field, so "banana" formats as "bpmnpmnpm" and
"hello" as "22ello": nonsense, but they vary with the instant, and a check
claiming to find "no date field" cannot reject them. What harms the user is
the pattern that prints the same text on every card, and that is what is
refused, with the value named in the message.
The model supplies the pattern through DateFormatRole for the same reason it
supplies the tag colours: it is the one object here holding config, and a
delegate reading config itself would be a second source of truth.
Backlog item 62.
Diffstat (limited to 'src/config.cpp')
| -rw-r--r-- | src/config.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/config.cpp b/src/config.cpp index 4f5831c..9e223f8 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -23,7 +23,9 @@ // so this reports the same numbers rather than keeping a second copy. #include "messageview.h" +#include <QDateTime> #include <QFileInfo> +#include <QLocale> #include <QSettings> #include <QStandardPaths> @@ -146,6 +148,29 @@ void Config::load(const QString &path) } } + // Absent or empty means the system locale's short format, which is what + // every other application on the desktop shows. Only a non-empty pattern is + // validated, and a rejected one falls back to that same default. + const QString dateFormat = + settings.value(QStringLiteral("date_format")).toString().trimmed(); + if (!dateFormat.isEmpty()) { + // QDateTime::toString() with a pattern carrying no date or time field + // returns the pattern verbatim rather than failing, so "banana" would + // print "banana" on every card. Formatting two DIFFERENT instants and + // comparing is what catches that: a pattern with any real field gives + // two different strings, one with none gives the same string twice. + const QDateTime a(QDate(2028, 12, 28), QTime(22, 58)); + const QDateTime b(QDate(2019, 1, 3), QTime(4, 5)); + const QLocale locale = QLocale::system(); + if (locale.toString(a, dateFormat) == locale.toString(b, dateFormat)) { + addProblem(QStringLiteral("Date format '%1' contains no date or " + "time field; using the system format.") + .arg(dateFormat)); + } else { + m_dateFormat = dateFormat; + } + } + // Absent is silent, the default being 2000. Present but unparseable warns, // for the same reason message_zoom does: the user asked for something and // is not getting it. |
