MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 50.0% 3 / 0 / 6
Functions: 50.0% 3 / 0 / 6
Branches: -% 0 / 0 / 0

ui/ThemeManager.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QColor>
4 #include <QObject>
5 #include <QString>
6 #include <QStringList>
7 #include <QMap>
8
9 class QApplication;
10
11 /**
12 * @brief The ThemeManager class centralizes UI styling for MailJD.
13 *
14 * It supports Light and Dark modes by loading QSS templates and injecting
15 * theme-specific variables. This ensures a consistent design language
16 * across all components while maintaining high performance.
17 *
18 * 67.B2: A user-facing Mode (Light / Dark / System) sits above the
19 * concrete Theme. System follows the OS color scheme via QStyleHints
20 * (Qt >= 6.5) and reacts to runtime scheme changes. The mode is
21 * persisted as QSettings "appearance/theme" = light|dark|system.
22 */
23 class ThemeManager : public QObject {
24 Q_OBJECT
25 #ifdef MAILJD_UNIT_TEST
26 friend class TestThemeManager;
27 #endif
28 public:
29 enum Theme {
30 Light,
31 Dark
32 };
33
34 // User-facing theme mode (67.B2). System resolves to Light/Dark from
35 // the OS color scheme.
36 enum Mode {
37 ModeLight,
38 ModeDark,
39 ModeSystem
40 };
41 1 Q_ENUM(Theme)
42 ✗ Q_ENUM(Mode)
43
44 static ThemeManager& instance();
45
46 // Apply a specific theme to the application
47 void applyTheme(Theme theme);
48
49 // Current active theme
50 5 Theme currentTheme() const { return m_currentTheme; }
51
52 // Helper to get a color value for the current theme. Falls back to
53 // the Light palette when no theme has been applied yet (e.g. unit
54 // tests), so consumers never need their own literal fallbacks.
55 QString color(const QString &key) const;
56
57 // ── 67.B3: shared programmatic palettes ───────────────
58 // All color decisions live here (docs/DESIGN.md) — src/ outside this
59 // class must not contain hex literals (ctest gate no_inline_colors).
60
61 // Confidence → color mapping for folder-suggestion UI
62 // (MailListModel, MailThreadModel, SuggestionOverlay, status label).
63 static QColor confidenceColor(double confidence);
64
65 // Default calendar colors (theme-independent data palette).
66 static QStringList calendarPalette();
67 // Colour of the read-only birthday layer (avatar4 of DESIGN.md §10,
68 // readable as an event colour in both themes).
69 static QString birthdayLayerColor();
70
71 // Muted confidence palette for the status-bar suggestion label
72 // (T-198 semantics: > 0.8 blue, > 0.6 warm grey, else light grey).
73 static QColor mutedConfidenceColor(double confidence);
74
75 // Label/keyword chip palette (LabelDelegate): red, orange, green,
76 // blue, purple, gold, gray.
77 static QList<QColor> labelPalette();
78
79 // 67.B4: deterministic avatar color for a sender address — same
80 // input always yields the same hue (HSL, readable with white text).
81 static QColor avatarColor(const QString &key);
82
83 // 67.B6: shortcut-help overlay canvas (dark scrim/card in BOTH
84 // themes — the overlay is intentionally theme-invariant).
85 static QColor overlayScrimColor();
86 static QColor overlayCardColor();
87
88 // ── 67.B2: mode handling ──────────────────────────────
89
90 // Set the mode, apply the resolved theme, persist the choice
91 // (QSettings appearance/theme) and start/stop the OS scheme watch.
92 void setMode(Mode mode);
93
94 3 Mode mode() const { return m_mode; }
95
96 // Resolve a mode to a concrete theme. System uses
97 // QStyleHints::colorScheme() (Qt >= 6.5; falls back to Light).
98 Theme resolveTheme(Mode mode) const;
99
100 // Read QSettings appearance/theme (default: system) and apply it.
101 // Called once at startup from main().
102 void initFromSettings();
103
104 static Mode modeFromString(const QString &value);
105 static QString modeToString(Mode mode);
106
107 signals:
108 // Emitted after every applyTheme(). Consumers with code-painted
109 // colors (folder icons, delegates, calendar) re-pull color() here.
110 void themeChanged(ThemeManager::Theme theme);
111
112 private:
113 explicit ThemeManager(QObject *parent = nullptr);
114 QString loadAndProcessQss(const QString &path, const QMap<QString, QString> &vars);
115 void applyModeInternal(Mode mode, bool persist);
116 static QMap<QString, QString> lightPalette();
117 static QMap<QString, QString> darkPalette();
118
119 Theme m_currentTheme = Light;
120 Mode m_mode = ModeLight;
121 bool m_systemWatchActive = false;
122 QMap<QString, QString> m_currentVars;
123 };
124