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: 92.3% 12 / 0 / 13
Functions: 92.3% 12 / 0 / 13
Branches: -% 0 / 0 / 0

presentation/QuickSettingsNavigation.h
Line Branch Exec Source
1 #pragma once
2 #include <QHash>
3 #include <QObject>
4 #include <QStringList>
5 #include <QVariantMap>
6 #include <functional>
7
8 class WorkspaceState;
9
10 // Sprint 100 S100.1.2/S100.1.3 (D-1, D-3, D-11): where the settings area is
11 // and how one leaves it. Targets are ids, never indices (rule 9):
12 // "" the page visited last (Accounts the first time)
13 // "<page>" a page of SettingsCatalog
14 // "<page>/<group|setting>" a page, scrolled to that place and highlighted
15 // "accounts/new" the guided setup (param "services=dav" for DAV only)
16 // "accounts/<accountId>[/mail|rules|calendars|password|remove]"
17 // "accounts/<catalog setting>" the same for the active account
18 // Unknown targets open the page visited last and log a warning
19 // (mailjd.settings). The dirty registry is the one guard of every settings
20 // editor: leaving the page or the area, opening another editor and closing
21 // the window ask once ("Save · Discard · Keep editing") — through the
22 // shell (request(), guard()); open() is the unguarded step behind them.
23 class QuickSettingsNavigation final : public QObject {
24 Q_OBJECT
25 Q_PROPERTY(bool isOpen READ isOpen NOTIFY changed)
26 // A catalog page id, or "account" for the page of one account.
27 Q_PROPERTY(QString page READ page NOTIFY changed)
28 Q_PROPERTY(QString accountId READ accountId NOTIFY changed)
29 // What the account page opens: "", "mail", "rules", "calendars",
30 // "password", "remove"; on "accounts": "new".
31 Q_PROPERTY(QString section READ section NOTIFY changed)
32 // The place to reveal and highlight ("privacy/remote-images") or a field
33 // name of the opened editor ("password").
34 Q_PROPERTY(QString anchor READ anchor NOTIFY changed)
35 Q_PROPERTY(QVariantMap params READ params NOTIFY changed)
36 // Increments on every open(), so opening the same place again re-reveals it.
37 Q_PROPERTY(int revision READ revision NOTIFY changed)
38 Q_PROPERTY(QString backArea READ backArea NOTIFY changed)
39 Q_PROPERTY(QString lastPage READ lastPage NOTIFY changed)
40 Q_PROPERTY(QStringList attention READ attention NOTIFY attentionChanged)
41 Q_PROPERTY(bool dirty READ dirty NOTIFY dirtyChanged)
42 Q_PROPERTY(QString dirtyEditor READ dirtyEditor NOTIFY dirtyChanged)
43 // The guard question is open; `pendingAction` waits for the answer.
44 Q_PROPERTY(bool guardOpen READ guardOpen NOTIFY guardChanged)
45 Q_PROPERTY(QString pendingAction READ pendingAction NOTIFY guardChanged)
46 public:
47 struct Target {
48 QString page, accountId, section, anchor;
49 QVariantMap params;
50 bool known = true;
51 };
52 explicit QuickSettingsNavigation(WorkspaceState *workspace, QObject *parent = nullptr);
53 // The account "accounts/password" and friends act on.
54 766 void setActiveAccountResolver(std::function<QString()> resolver) { m_activeAccount = std::move(resolver); }
55 // Pure parser of the target grammar above.
56 static Target parse(const QString &target, const QString &activeAccount);
57
58 716 bool isOpen() const { return m_open; }
59 33019 QString page() const { return m_target.page; }
60 802 QString accountId() const { return m_target.accountId; }
61 364 QString section() const { return m_target.section; }
62 327 QString anchor() const { return m_target.anchor; }
63 74 QVariantMap params() const { return m_target.params; }
64 2 int revision() const { return m_revision; }
65 1356 QString backArea() const { return m_backArea; }
66 ✗ QString lastPage() const { return m_lastPage; }
67 9142 QStringList attention() const { return m_attention; }
68 bool dirty() const;
69 QString dirtyEditor() const;
70 69 bool guardOpen() const { return m_guardOpen; }
71 2 QString pendingAction() const { return m_pendingAction; }
72
73 // Opens the area on a target; switches the workspace area to "settings"
74 // and remembers the area to return to. Returns false for an unknown
75 // target (the area still opens on the last page).
76 Q_INVOKABLE bool open(const QString &target = {}, const QString &anchor = {});
77 // From views outside the area (empty states, banners) and from clicks
78 // inside it: asks the shell to open the target, so the shell's rules
79 // (composer, the dirty guard) apply first. open() itself never asks
80 // (S106-330); it is for the shell and for programmatic moves after a save.
81 Q_INVOKABLE void request(const QString &target, const QString &anchor = {});
82 // Returns to the area the settings were opened from. The caller asks the
83 // guard first (guard("close")).
84 Q_INVOKABLE void close();
85 // Editors report their state; `label` names the editor in the question.
86 Q_INVOKABLE void setEditorDirty(const QString &editorId, const QString &label, bool dirty);
87 Q_INVOKABLE void removeEditor(const QString &editorId);
88 // True when nothing is dirty: the caller may go on. Otherwise the question
89 // opens and `action` waits ("close", "open:<target>", "area:<area>", "quit",
90 // "editor:<id>"); answerGuard("save"|"discard"|"keep") resolves it.
91 Q_INVOKABLE bool guard(const QString &action);
92 Q_INVOKABLE void answerGuard(const QString &choice);
93 // An editor could not save after "Save" in the guard: the waiting action
94 // is dropped and the editor stays open with its error.
95 Q_INVOKABLE void saveFailed();
96 void setAttention(const QStringList &places);
97
98 signals:
99 void changed();
100 void attentionChanged();
101 void dirtyChanged();
102 void guardChanged();
103 // To every registered editor: save, or drop the draft.
104 void saveRequested();
105 void discardRequested();
106 // The guard is resolved; the shell performs the waiting action.
107 void proceed(const QString &action);
108 void openRequested(const QString &target, const QString &anchor);
109
110 private:
111 void finishGuard(bool go);
112 WorkspaceState *m_workspace;
113 std::function<QString()> m_activeAccount;
114 Target m_target;
115 bool m_open = false;
116 int m_revision = 0;
117 QString m_backArea = QStringLiteral("mail");
118 QString m_lastPage;
119 QStringList m_attention;
120 struct Editor { QString label; bool dirty = false; };
121 QHash<QString, Editor> m_editors;
122 QStringList m_editorOrder;
123 bool m_guardOpen = false;
124 bool m_saving = false;
125 QString m_pendingAction;
126 };
127