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: 77.9% 74 / 0 / 95
Functions: 66.7% 6 / 0 / 9
Branches: 72.2% 91 / 0 / 126

ui/MailFilterProxyModel.cpp
Line Branch Exec Source
1 #include "MailFilterProxyModel.h"
2
3 #include "MailListModel.h"
4 #include "data/Models.h"
5
6 975 MailFilterProxyModel::MailFilterProxyModel(QObject *parent)
7 975 : QSortFilterProxyModel(parent) {
8 // T-79.B2/M19: keep a thread visible when only a descendant matches the
9 // filter (e.g. unread reply under a read root). Flat models have no
10 // children, so their filtering is unaffected.
11
1/1
✓ Branch 6 → 7 taken 975 times.
975 setRecursiveFilteringEnabled(true);
12 975 connect(this, &QAbstractProxyModel::sourceModelChanged, this,
13
1/1
✓ Branch 7 → 8 taken 975 times.
975 &MailFilterProxyModel::forgetShownUnread);
14 975 }
15
16 102202 bool MailFilterProxyModel::lessThan(const QModelIndex &sourceLeft,
17 const QModelIndex &sourceRight) const {
18 102202 const auto *mailModel = qobject_cast<const MailListModel *>(sourceModel());
19
2/3
✓ Branch 5 → 6 taken 102202 times.
✓ Branch 7 → 8 taken 102202 times.
✗ Branch 7 → 15 not taken.
102202 if (mailModel && !sourceLeft.parent().isValid() &&
20
5/9
✓ Branch 4 → 5 taken 102202 times.
✗ Branch 4 → 15 not taken.
✓ Branch 8 → 9 taken 102202 times.
✓ Branch 10 → 11 taken 102202 times.
✗ Branch 10 → 15 not taken.
✓ Branch 13 → 14 taken 102202 times.
✗ Branch 13 → 15 not taken.
✓ Branch 16 → 17 taken 102202 times.
✗ Branch 16 → 33 not taken.
306606 !sourceRight.parent().isValid() &&
21 102202 sourceLeft.column() == sourceRight.column()) {
22 102202 const MailHeader *left = mailModel->headerAt(sourceLeft.row());
23 102202 const MailHeader *right = mailModel->headerAt(sourceRight.row());
24
2/4
✓ Branch 21 → 22 taken 102202 times.
✗ Branch 21 → 33 not taken.
✓ Branch 22 → 23 taken 102202 times.
✗ Branch 22 → 33 not taken.
102202 if (left && right) {
25
1/4
✓ Branch 24 → 25 taken 102202 times.
✗ Branch 24 → 27 not taken.
✗ Branch 24 → 28 not taken.
✗ Branch 24 → 31 not taken.
102202 switch (sourceLeft.column()) {
26 102202 case MailListModel::Date:
27 102202 return left->date < right->date;
28 ✗ case MailListModel::Size:
29 ✗ return left->size < right->size;
30 ✗ case MailListModel::Star:
31 ✗ return left->isFlagged() < right->isFlagged();
32 ✗ default:
33 ✗ break;
34 }
35 }
36 }
37 ✗ return QSortFilterProxyModel::lessThan(sourceLeft, sourceRight);
38 }
39
40 78 void MailFilterProxyModel::invalidateMailFilter() {
41 78 forgetShownUnread();
42
5/6
✓ Branch 4 → 5 taken 58 times.
✓ Branch 4 → 8 taken 20 times.
✓ Branch 6 → 7 taken 58 times.
✗ Branch 6 → 8 not taken.
✓ Branch 9 → 10 taken 58 times.
✓ Branch 9 → 12 taken 20 times.
78 if (m_sourceFilterDriver && m_sourceFilterDriver()) {
43 58 emit mailFilterChanged();
44 58 return;
45 }
46 20 emit mailFilterAboutToChange();
47 #if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
48 beginFilterChange();
49 endFilterChange(QSortFilterProxyModel::Direction::Rows);
50 #else
51 20 invalidateFilter();
52 #endif
53 20 emit mailFilterChanged();
54 }
55
56 ✗ void MailFilterProxyModel::setFilterText(const QString &text) {
57 ✗ if (m_filterText == text) return;
58 ✗ m_filterText = text;
59 ✗ invalidateMailFilter();
60 }
61
62 5 void MailFilterProxyModel::setShowUnreadOnly(bool on) {
63
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 5 times.
5 if (m_showUnread == on) return;
64 5 m_showUnread = on;
65 5 invalidateMailFilter();
66 }
67
68 ✗ void MailFilterProxyModel::setShowStarredOnly(bool on) {
69 ✗ if (m_showStarred == on) return;
70 ✗ m_showStarred = on;
71 ✗ invalidateMailFilter();
72 }
73
74 ✗ void MailFilterProxyModel::setShowWithAttachments(bool on) {
75 ✗ if (m_showAttachments == on) return;
76 ✗ m_showAttachments = on;
77 ✗ invalidateMailFilter();
78 }
79
80 1669 void MailFilterProxyModel::setFilters(const QString &text, bool unreadOnly,
81 bool starredOnly, bool withAttachments) {
82
2/2
✓ Branch 4 → 5 taken 1615 times.
✓ Branch 4 → 8 taken 10 times.
3294 if (m_filterText == text && m_showUnread == unreadOnly &&
83
8/8
✓ Branch 3 → 4 taken 1625 times.
✓ Branch 3 → 8 taken 44 times.
✓ Branch 5 → 6 taken 1603 times.
✓ Branch 5 → 8 taken 12 times.
✓ Branch 6 → 7 taken 1596 times.
✓ Branch 6 → 8 taken 7 times.
✓ Branch 9 → 10 taken 1596 times.
✓ Branch 9 → 11 taken 73 times.
3294 m_showStarred == starredOnly && m_showAttachments == withAttachments)
84 1596 return;
85 73 m_filterText = text;
86 73 m_showUnread = unreadOnly;
87 73 m_showStarred = starredOnly;
88 73 m_showAttachments = withAttachments;
89 73 invalidateMailFilter();
90 }
91
92 73657 bool MailFilterProxyModel::filterAcceptsRow(
93 int sourceRow, const QModelIndex &sourceParent) const {
94 // MailListModel is flat. Its retained MailHeader already holds the values
95 // needed by the common chip filters; avoid creating indexes and QVariants
96 // for every row of each filter pass.
97
2/2
✓ Branch 2 → 3 taken 73657 times.
✓ Branch 3 → 4 taken 73657 times.
73657 const auto *mailModel = qobject_cast<const MailListModel *>(sourceModel());
98
1/2
✓ Branch 6 → 7 taken 73654 times.
✗ Branch 6 → 9 not taken.
73654 const MailHeader *header = mailModel && !sourceParent.isValid()
99
3/3
✓ Branch 4 → 5 taken 73654 times.
✓ Branch 4 → 9 taken 3 times.
✓ Branch 7 → 8 taken 73654 times.
147311 ? mailModel->headerAt(sourceRow)
100 73657 : nullptr;
101 73657 QModelIndex idx;
102
2/2
✓ Branch 10 → 11 taken 3 times.
✓ Branch 10 → 13 taken 73654 times.
73657 if (!header)
103
2/2
✓ Branch 11 → 12 taken 3 times.
✓ Branch 12 → 13 taken 3 times.
3 idx = sourceModel()->index(sourceRow, 0, sourceParent);
104
105 // Unread filter: check Seen flag
106
2/2
✓ Branch 13 → 14 taken 49 times.
✓ Branch 13 → 37 taken 73608 times.
73657 if (m_showUnread) {
107
2/2
✓ Branch 14 → 15 taken 46 times.
✓ Branch 14 → 16 taken 3 times.
49 quint32 flags = header ? header->flags
108
4/6
✓ Branch 16 → 17 taken 3 times.
✓ Branch 17 → 18 taken 3 times.
✓ Branch 19 → 20 taken 3 times.
✓ Branch 19 → 21 taken 46 times.
✗ Branch 90 → 91 not taken.
✗ Branch 90 → 92 not taken.
49 : idx.data(MailListModel::FlagsRole).toUInt();
109 49 const bool seen = flags & MailFlag::Seen;
110 // Read mails stay while this unread view lasts if it already showed
111 // them; the view is scoped to one folder, so another folder starts over.
112
4/4
✓ Branch 21 → 22 taken 46 times.
✓ Branch 21 → 25 taken 3 times.
✓ Branch 22 → 23 taken 6 times.
✓ Branch 22 → 25 taken 40 times.
49 if (header && header->folderId != m_shownUnreadFolder) {
113 6 m_shownUnread.clear();
114 6 m_shownUnreadFolder = header->folderId;
115 }
116
8/8
✓ Branch 25 → 26 taken 29 times.
✓ Branch 25 → 30 taken 20 times.
✓ Branch 26 → 27 taken 28 times.
✓ Branch 26 → 29 taken 1 time.
✓ Branch 28 → 29 taken 26 times.
✓ Branch 28 → 30 taken 2 times.
✓ Branch 31 → 32 taken 27 times.
✓ Branch 31 → 33 taken 22 times.
49 if (seen && (!header || !m_shownUnread.contains(header->uid)))
117 27 return false; // mail is read → hide
118
5/5
✓ Branch 33 → 34 taken 20 times.
✓ Branch 33 → 37 taken 2 times.
✓ Branch 34 → 35 taken 18 times.
✓ Branch 34 → 37 taken 2 times.
✓ Branch 35 → 36 taken 18 times.
22 if (!seen && header) m_shownUnread.insert(header->uid);
119 }
120
121 // Starred filter: check Flagged flag
122
2/2
✓ Branch 37 → 38 taken 1 time.
✓ Branch 37 → 47 taken 73629 times.
73630 if (m_showStarred) {
123
1/2
✓ Branch 38 → 39 taken 1 time.
✗ Branch 38 → 40 not taken.
1 quint32 flags = header ? header->flags
124
1/6
✗ Branch 40 → 41 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 45 taken 1 time.
✗ Branch 95 → 96 not taken.
✗ Branch 95 → 97 not taken.
1 : idx.data(MailListModel::FlagsRole).toUInt();
125
1/2
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 1 time.
1 if (!(flags & MailFlag::Flagged))
126 ✗ return false; // mail is not starred → hide
127 }
128
129 // Attachments filter
130
2/2
✓ Branch 47 → 48 taken 1 time.
✓ Branch 47 → 57 taken 73629 times.
73630 if (m_showAttachments) {
131
1/2
✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 50 not taken.
1 bool hasAtt = header ? header->hasAttachments
132
1/6
✗ Branch 50 → 51 not taken.
✗ Branch 51 → 52 not taken.
✗ Branch 53 → 54 not taken.
✓ Branch 53 → 55 taken 1 time.
✗ Branch 99 → 100 not taken.
✗ Branch 99 → 101 not taken.
1 : idx.data(MailListModel::HasAttachmentsRole).toBool();
133
1/2
✗ Branch 55 → 56 not taken.
✓ Branch 55 → 57 taken 1 time.
1 if (!hasAtt)
134 ✗ return false;
135 }
136
137 // Text filter: match against Subject and From columns
138
2/2
✓ Branch 58 → 59 taken 327 times.
✓ Branch 58 → 87 taken 73303 times.
73630 if (!m_filterText.isEmpty()) {
139 auto subjectIdx =
140
2/2
✓ Branch 59 → 60 taken 327 times.
✓ Branch 60 → 61 taken 327 times.
327 sourceModel()->index(sourceRow, MailListModel::Subject, sourceParent);
141 auto fromIdx =
142
2/2
✓ Branch 61 → 62 taken 327 times.
✓ Branch 62 → 63 taken 327 times.
327 sourceModel()->index(sourceRow, MailListModel::From, sourceParent);
143
144
2/2
✓ Branch 63 → 64 taken 327 times.
✓ Branch 64 → 65 taken 327 times.
327 QString subject = subjectIdx.data(Qt::DisplayRole).toString();
145
2/2
✓ Branch 66 → 67 taken 327 times.
✓ Branch 67 → 68 taken 327 times.
327 QString from = fromIdx.data(Qt::DisplayRole).toString();
146
147
5/5
✓ Branch 69 → 70 taken 327 times.
✓ Branch 70 → 71 taken 257 times.
✓ Branch 70 → 74 taken 70 times.
✓ Branch 75 → 76 taken 237 times.
✓ Branch 75 → 77 taken 90 times.
584 if (!subject.contains(m_filterText, Qt::CaseInsensitive) &&
148
3/3
✓ Branch 71 → 72 taken 257 times.
✓ Branch 72 → 73 taken 237 times.
✓ Branch 72 → 74 taken 20 times.
257 !from.contains(m_filterText, Qt::CaseInsensitive)) {
149 237 return false;
150 }
151 564 }
152
153 73393 return true;
154 }
155