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

ui/MailFilterProxyModel.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QSet>
4 #include <QSortFilterProxyModel>
5
6 // MailFilterProxyModel filters the mail list based on programmatic state.
7 // Supports: unread-only, starred-only, text search (subject/from).
8 // Sits between MailListModel and the QTreeView.
9 //
10 // Sprint 15: QuickFilterBar dependency removed. Filters are now set directly
11 // via setFilterText(), setShowUnreadOnly(), etc. from CommandBar commands.
12 class MailFilterProxyModel : public QSortFilterProxyModel {
13 Q_OBJECT
14
15 public:
16 explicit MailFilterProxyModel(QObject *parent = nullptr);
17
18 // T-146: Direct filter setters (replace QuickFilterBar)
19 void setFilterText(const QString &text);
20 void setShowUnreadOnly(bool on);
21 void setShowStarredOnly(bool on);
22 void setShowWithAttachments(bool on);
23 // Publish a multi-field filter intent with one proxy invalidation.
24 void setFilters(const QString &text, bool unreadOnly, bool starredOnly,
25 bool withAttachments);
26
27 1401 bool showUnreadOnly() const { return m_showUnread; }
28 1405 bool showStarredOnly() const { return m_showStarred; }
29 1413 bool showWithAttachments() const { return m_showAttachments; }
30 1389 QString filterText() const { return m_filterText; }
31 // Mails the unread view showed in `folderId` (they stay listed once read).
32 9 QSet<qint64> shownUnread(qint64 folderId) const {
33
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 7 times.
9 return folderId == m_shownUnreadFolder ? m_shownUnread : QSet<qint64>{};
34 }
35 // P90 gate "one model commit per filter intent": when the source replaces
36 // its rows with a page already filtered by the new criteria, the driver
37 // returns true after starting that reload; the proxy then only adopts the
38 // criteria and the source's reset re-filters in the same commit. Without a
39 // driver (or when it returns false) the proxy filters the loaded rows now.
40 795 void setSourceFilterDriver(std::function<bool()> driver) { m_sourceFilterDriver = std::move(driver); }
41
42 signals:
43 // Selection is owned by MailId in MainWindow. These bracket filter changes
44 // because QSortFilterProxyModel otherwise invalidates QModelIndexes without
45 // exposing the semantic transition to the view owner.
46 void mailFilterAboutToChange();
47 void mailFilterChanged();
48
49 protected:
50 bool lessThan(const QModelIndex &sourceLeft,
51 const QModelIndex &sourceRight) const override;
52 bool filterAcceptsRow(int sourceRow,
53 const QModelIndex &sourceParent) const override;
54
55 private:
56 void invalidateMailFilter();
57 1053 void forgetShownUnread() { m_shownUnread.clear(); m_shownUnreadFolder = -1; }
58
59 // Mails shown while the unread filter is active stay listed after they are
60 // read (opening a mail marks it read) until the filter or folder changes.
61 mutable QSet<qint64> m_shownUnread;
62 mutable qint64 m_shownUnreadFolder = -1;
63 QString m_filterText;
64 bool m_showUnread = false;
65 bool m_showStarred = false;
66 bool m_showAttachments = false;
67 std::function<bool()> m_sourceFilterDriver;
68 };
69