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: 100.0% 6 / 0 / 6
Functions: 100.0% 6 / 0 / 6
Branches: -% 0 / 0 / 0

presentation/MailSearchSessions.h
Line Branch Exec Source
1 #pragma once
2
3 #include "MailSearchSession.h"
4 #include "SearchTimelineModel.h"
5 #include <QObject>
6 #include <QStringList>
7 #include <functional>
8 #include <map>
9 #include <memory>
10
11 class MailController;
12 class WorkspaceState;
13
14 // Sprint 101 S101.1.2/S101.3.x (D-2, D-3, D-12, D-29): the search sessions
15 // of the search tabs. One session per search tab, created when the tab is
16 // first shown (restored tabs re-run lazily, D-16) and destroyed with the
17 // tab. It keeps at most MaximumLiveSessions sessions with rows in memory,
18 // gives the one search connection to the active tab, keeps the rows in
19 // step with mail actions and moves the selection to the first result or
20 // the successor when the selected result leaves the list.
21 //
22 // Owner: QuickMailBackend. GUI thread only. QML reads `active`.
23 class MailSearchSessions final : public QObject {
24 Q_OBJECT
25 Q_PROPERTY(MailSearchSession *active READ active NOTIFY activeChanged)
26 Q_PROPERTY(bool activeDormant READ activeDormant NOTIFY activeChanged)
27 Q_PROPERTY(QString activeAccount READ activeAccount NOTIFY activeChanged)
28 // D-26: the timeline band of every search tab ("View ▾ → Timeline").
29 Q_PROPERTY(bool timelineShown READ timelineShown WRITE setTimelineShown NOTIFY timelineShownChanged)
30 Q_PROPERTY(SearchTimelineModel *timeline READ timeline CONSTANT)
31 // D-32: the sidebar of a search tab shows the facets; true brings the
32 // full folder tree back (with its usual folder clicks).
33 Q_PROPERTY(bool allFolders READ allFolders WRITE setAllFolders NOTIFY allFoldersChanged)
34 // S101.5.9 (D-22): the result list grouped by the timeline's unit.
35 Q_PROPERTY(bool grouped READ grouped WRITE setGrouped NOTIFY groupedChanged)
36 // D-30: the one-time "click a bar to zoom in" hint was shown.
37 Q_PROPERTY(bool timelineHintSeen READ timelineHintSeen WRITE setTimelineHintSeen NOTIFY timelineHintSeenChanged)
38
39 public:
40 struct Deps {
41 WorkspaceState *workspace = nullptr;
42 MailController *controller = nullptr;
43 // The session dependencies for an account (cache, reader, admission, …).
44 std::function<MailSearchSession::Deps(const QString &accountId)> sessionDeps;
45 std::function<QString()> currentAccount;
46 std::function<bool(const MailId &)> acceptIdentity;
47 };
48 static constexpr int MaximumLiveSessions = 3;
49
50 MailSearchSessions(Deps deps, QObject *parent = nullptr);
51 ~MailSearchSessions() override;
52
53 MailSearchSession *active() const;
54 bool activeDormant() const;
55 QString activeAccount() const;
56 MailSearchSession *session(const QString &tabId) const;
57 // S101.1.10: `text` escaped for StyledText with the active search's
58 // free-text words (folded like the index) wrapped in open/close.
59 Q_INVOKABLE QString markMatches(const QString &text, const QString &open, const QString &close) const;
60 2 int sessionCount() const { return int(m_sessions.size()); }
61 int liveCount() const;
62 4129 bool timelineShown() const { return m_timelineShown; }
63 110 SearchTimelineModel *timeline() { return &m_timeline; }
64 94 bool timelineHintSeen() const { return m_timelineHintSeen; }
65 112 bool allFolders() const { return m_allFolders; }
66 102 bool grouped() const { return m_grouped; }
67 void setGrouped(bool on);
68 void setAllFolders(bool on);
69 void setTimelineHintSeen(bool seen);
70 void setTimelineShown(bool shown);
71
72 // D-1/D-2: a search in the search tab of the current account — the most
73 // recently used one unless `newTab`; an empty query opens an empty tab.
74 // False at the tab limit or without an account.
75 bool open(const QString &query, bool newTab);
76 void refreshAfterIndexReady();
77
78 signals:
79 void activeChanged();
80 void timelineShownChanged();
81 void timelineHintSeenChanged();
82 void allFoldersChanged();
83 void groupedChanged();
84 // The active search tab moved its selection (the view scrolls to it).
85 void selectionRevealRequested(int row);
86
87 private:
88 MailSearchSession *ensure(const QString &tabId);
89 void syncActive();
90 void touch(const QString &tabId);
91 void selectRow(MailSearchSession *session, int row);
92 void onRowsReplaced(MailSearchSession *session, const MailId &selected);
93 void onMovesPending(qint64 folderId, const QList<qint64> &uids);
94 MailSearchSession *serverOwner() const;
95 void wireController();
96 void updatePeriods();
97 void updateMatchWords(MailSearchSession *session);
98
99 Deps m_deps;
100 std::map<QString, std::unique_ptr<MailSearchSession>> m_sessions;
101 QStringList m_recent; // most recently active first (D-3)
102 // Folded free-text words per tab, shared with the tab's match provider.
103 std::map<QString, std::shared_ptr<QStringList>> m_matchWords;
104 QString m_activeTabId;
105 bool m_timelineShown = true;
106 bool m_timelineHintSeen = false;
107 bool m_allFolders = false;
108 bool m_grouped = false;
109 SearchTimelineModel m_timeline;
110 };
111