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: 97.5% 231 / 0 / 237
Functions: 100.0% 18 / 0 / 18
Branches: 88.3% 273 / 0 / 309

presentation/CalendarLayout.cpp
Line Branch Exec Source
1 #include "CalendarLayout.h"
2
3 #include <QLocale>
4 #include <QTimeZone>
5 #include <algorithm>
6 #include <queue>
7
8 namespace CalendarLayout {
9
10 // Locale short time without seconds (24 h or 12 h with AM/PM, S93.3.7).
11 55848 QString timeText(const QDateTime &value) {
12
2/2
✓ Branch 2 → 3 taken 55848 times.
✓ Branch 3 → 4 taken 55848 times.
55848 QString format = QLocale().timeFormat(QLocale::ShortFormat);
13
2/2
✓ Branch 8 → 9 taken 55848 times.
✓ Branch 12 → 13 taken 55848 times.
111696 format.remove(QStringLiteral(":ss")).remove(QStringLiteral(".ss"));
14
3/3
✓ Branch 17 → 18 taken 55848 times.
✓ Branch 18 → 19 taken 55848 times.
✓ Branch 19 → 20 taken 55848 times.
111696 return QLocale().toString(value.time(), format);
15 55848 }
16
17 namespace {
18
19 11641 int minuteOf(const QDateTime &value) {
20
4/4
✓ Branch 2 → 3 taken 11641 times.
✓ Branch 3 → 4 taken 11641 times.
✓ Branch 4 → 5 taken 11641 times.
✓ Branch 5 → 6 taken 11641 times.
11641 return value.time().hour() * 60 + value.time().minute();
21 }
22
23 84 bool spanOrder(const CalendarOccurrence &a, const CalendarOccurrence &b) {
24
2/2
✓ Branch 3 → 4 taken 82 times.
✓ Branch 3 → 6 taken 2 times.
84 if (a.firstDay != b.firstDay) return a.firstDay < b.firstDay;
25
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 10 taken 2 times.
2 if (a.lastDay != b.lastDay) return a.lastDay > b.lastDay;
26
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 2 times.
2 if (a.allDay != b.allDay) return a.allDay;
27
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 2 times.
2 if (a.start != b.start) return a.start < b.start;
28
4/4
✓ Branch 16 → 17 taken 2 times.
✓ Branch 17 → 18 taken 2 times.
✓ Branch 18 → 19 taken 2 times.
✓ Branch 19 → 20 taken 2 times.
2 return a.accountId + a.calendarPath + a.uid < b.accountId + b.calendarPath + b.uid;
29 }
30
31 } // namespace
32
33 3361 QDate weekStart(const QDate &date, int firstDayOfWeek) {
34
1/1
✓ Branch 2 → 3 taken 3361 times.
3361 const int first = qBound(1, firstDayOfWeek, 7);
35 3361 return date.addDays(-((date.dayOfWeek() - first + 7) % 7));
36 }
37
38 27532 CalendarOccurrence fromEvent(const CalendarEvent &event,
39 const QHash<QString, CalendarInfoLookup> &calendars) {
40
1/1
✓ Branch 2 → 3 taken 27532 times.
27532 CalendarOccurrence occurrence;
41 27532 occurrence.uid = event.uid;
42 27532 occurrence.accountId = event.accountId;
43 27532 occurrence.calendarPath = event.calendarPath;
44
1/1
✓ Branch 6 → 7 taken 27532 times.
27532 const auto info = calendars.value(calendarSelectionKey(event.accountId, event.calendarPath));
45
2/2
✓ Branch 10 → 11 taken 11446 times.
✓ Branch 10 → 12 taken 16086 times.
27532 occurrence.calendarName = info.displayName.isEmpty() ? event.calendarPath : info.displayName;
46 27532 occurrence.readOnly = info.readOnly;
47 27532 occurrence.color = event.color;
48 27532 occurrence.summary = event.summary;
49 27532 occurrence.location = event.location;
50 27532 occurrence.description = event.description;
51
2/2
✓ Branch 18 → 19 taken 27532 times.
✓ Branch 19 → 20 taken 27532 times.
27532 occurrence.startIso = event.dtStart.toUTC().toString(Qt::ISODate);
52 occurrence.recurrenceIso =
53
7/9
✓ Branch 23 → 24 taken 27532 times.
✓ Branch 24 → 25 taken 9 times.
✓ Branch 24 → 27 taken 27523 times.
✓ Branch 25 → 26 taken 9 times.
✓ Branch 26 → 28 taken 9 times.
✓ Branch 30 → 31 taken 9 times.
✓ Branch 30 → 32 taken 27523 times.
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 100 not taken.
27532 event.recurrenceId.isValid() ? event.recurrenceId.toUTC().toString(Qt::ISODate) : QString();
54 27532 occurrence.syncState = event.syncState;
55 27532 occurrence.partial = event.partialRecurrence; occurrence.limited = event.occurrencesLimited;
56
6/7
✓ Branch 34 → 35 taken 3549 times.
✓ Branch 34 → 39 taken 23983 times.
✓ Branch 36 → 37 taken 3549 times.
✗ Branch 36 → 39 not taken.
✓ Branch 37 → 38 taken 3549 times.
✓ Branch 38 → 39 taken 9 times.
✓ Branch 38 → 40 taken 3540 times.
27532 occurrence.recurring = !event.rrule.isEmpty() || !event.rdates.isEmpty() || event.recurrenceId.isValid();
57 27532 occurrence.allDay = event.allDay;
58
2/2
✓ Branch 41 → 42 taken 340 times.
✓ Branch 41 → 64 taken 27192 times.
27532 if (event.allDay) {
59 // DATE values are calendar days: show them on the same local dates.
60
2/2
✓ Branch 42 → 43 taken 340 times.
✓ Branch 43 → 44 taken 340 times.
340 const QDate first = event.dtStart.toUTC().date();
61
6/10
✓ Branch 45 → 46 taken 340 times.
✓ Branch 46 → 47 taken 340 times.
✗ Branch 46 → 50 not taken.
✓ Branch 47 → 48 taken 340 times.
✓ Branch 48 → 49 taken 340 times.
✓ Branch 49 → 51 taken 340 times.
✓ Branch 51 → 52 taken 340 times.
✗ Branch 51 → 53 not taken.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 109 not taken.
340 QDate last = event.dtEnd.isValid() ? event.dtEnd.toUTC().date().addDays(-1) : first;
62 340 last = qMax(first, last);
63
2/2
✓ Branch 54 → 55 taken 340 times.
✓ Branch 55 → 56 taken 340 times.
340 occurrence.start = QDateTime(first, QTime(0, 0));
64
3/3
✓ Branch 58 → 59 taken 340 times.
✓ Branch 59 → 60 taken 340 times.
✓ Branch 60 → 61 taken 340 times.
340 occurrence.end = QDateTime(last.addDays(1), QTime(0, 0));
65 340 occurrence.firstDay = first;
66 340 occurrence.lastDay = last;
67 } else {
68
1/1
✓ Branch 64 → 65 taken 27192 times.
27192 occurrence.start = event.dtStart.toLocalTime();
69
3/4
✓ Branch 67 → 68 taken 27192 times.
✓ Branch 68 → 69 taken 27192 times.
✗ Branch 68 → 70 not taken.
✓ Branch 69 → 71 taken 27192 times.
27192 occurrence.end = event.dtEnd.isValid() ? event.dtEnd.toLocalTime() : occurrence.start;
70
1/1
✓ Branch 73 → 74 taken 27192 times.
27192 occurrence.firstDay = occurrence.start.date();
71
1/1
✓ Branch 74 → 75 taken 27192 times.
27192 QDate last = occurrence.end.date();
72 // DTEND is exclusive, including an end at midnight.
73
8/9
✓ Branch 75 → 76 taken 27192 times.
✓ Branch 77 → 78 taken 27192 times.
✗ Branch 77 → 83 not taken.
✓ Branch 78 → 79 taken 27192 times.
✓ Branch 79 → 80 taken 27192 times.
✓ Branch 81 → 82 taken 16 times.
✓ Branch 81 → 83 taken 27176 times.
✓ Branch 84 → 85 taken 16 times.
✓ Branch 84 → 86 taken 27176 times.
27192 if (occurrence.end > occurrence.start && occurrence.end.time() == QTime(0, 0))
74
1/1
✓ Branch 85 → 86 taken 16 times.
16 last = last.addDays(-1);
75 27192 occurrence.lastDay = qMax(occurrence.firstDay, last);
76 }
77 27532 occurrence.multiDay = occurrence.lastDay > occurrence.firstDay;
78 27532 return occurrence;
79 27532 }
80
81 1096 QVector<QList<CalendarOccurrence>> bucketByDay(const QList<CalendarOccurrence> &occurrences,
82 const QDate &start, int days) {
83
1/1
✓ Branch 3 → 4 taken 1096 times.
1096 QVector<QList<CalendarOccurrence>> buckets(qMax(0, days));
84
1/1
✓ Branch 4 → 5 taken 1096 times.
1096 const QDate end = start.addDays(days - 1);
85
2/2
✓ Branch 43 → 7 taken 5951 times.
✓ Branch 43 → 44 taken 1096 times.
7047 for (const CalendarOccurrence &occurrence : occurrences) {
86 5951 const QDate from = qMax(occurrence.firstDay, start);
87 5951 const QDate to = qMin(occurrence.lastDay, end);
88
3/3
✓ Branch 37 → 38 taken 6047 times.
✓ Branch 40 → 11 taken 6047 times.
✓ Branch 40 → 41 taken 5951 times.
11998 for (QDate day = from; day <= to; day = day.addDays(1)) {
89 6047 CalendarOccurrence placed = occurrence;
90
5/5
✓ Branch 12 → 13 taken 5824 times.
✓ Branch 12 → 18 taken 223 times.
✓ Branch 15 → 16 taken 5823 times.
✓ Branch 15 → 18 taken 1 time.
✓ Branch 16 → 17 taken 5823 times.
6047 placed.startMinute = occurrence.allDay || day > occurrence.firstDay ? 0 : minuteOf(occurrence.start);
91
5/5
✓ Branch 19 → 20 taken 5824 times.
✓ Branch 19 → 31 taken 223 times.
✓ Branch 20 → 21 taken 5824 times.
✓ Branch 23 → 24 taken 5818 times.
✓ Branch 23 → 31 taken 6 times.
11865 const int endMinute = occurrence.allDay || day < occurrence.end.date() ? 1440
92
3/4
✓ Branch 24 → 25 taken 5818 times.
✓ Branch 26 → 27 taken 5818 times.
✗ Branch 26 → 29 not taken.
✓ Branch 27 → 28 taken 5818 times.
5818 : occurrence.end > occurrence.start ? minuteOf(occurrence.end)
93 ✗ : placed.startMinute + 60;
94
1/1
✓ Branch 32 → 33 taken 6047 times.
6047 placed.endMinute = qBound(placed.startMinute + 1, endMinute, 1440);
95
3/3
✓ Branch 33 → 34 taken 6047 times.
✓ Branch 34 → 35 taken 6047 times.
✓ Branch 35 → 36 taken 6047 times.
6047 buckets[int(start.daysTo(day))].append(placed);
96 6047 }
97 }
98 1096 return buckets;
99 ✗ }
100
101 42496 void assignLanes(QList<CalendarOccurrence> &dayEvents) {
102
3/4
✓ Branch 2 → 3 taken 75644 times.
✓ Branch 2 → 4 taken 908 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 75644 times.
76552 const auto inBand = [](const CalendarOccurrence &event) { return event.allDay || event.multiDay; };
103
3/3
✓ Branch 2 → 3 taken 42496 times.
✓ Branch 3 → 4 taken 42496 times.
✓ Branch 4 → 5 taken 42496 times.
42496 std::sort(dayEvents.begin(), dayEvents.end(), [&inBand](const auto &a, const auto &b) {
104
2/2
✓ Branch 4 → 5 taken 458 times.
✓ Branch 4 → 6 taken 31545 times.
32003 if (inBand(a) != inBand(b)) return inBand(a);
105
2/2
✓ Branch 6 → 7 taken 31537 times.
✓ Branch 6 → 8 taken 8 times.
31545 if (a.startMinute != b.startMinute) return a.startMinute < b.startMinute;
106
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 8 times.
8 if (a.endMinute != b.endMinute) return a.endMinute > b.endMinute;
107
4/4
✓ Branch 10 → 11 taken 8 times.
✓ Branch 11 → 12 taken 8 times.
✓ Branch 12 → 13 taken 8 times.
✓ Branch 13 → 14 taken 8 times.
8 return a.accountId + a.calendarPath + a.uid < b.accountId + b.calendarPath + b.uid;
108 });
109 42496 int groupStart = 0, groupEnd = 0, laneCount = 0;
110 using ActiveLane = std::pair<int, int>; // end minute, lane
111 42496 std::priority_queue<ActiveLane, std::vector<ActiveLane>, std::greater<ActiveLane>> active;
112 42496 std::priority_queue<int, std::vector<int>, std::greater<int>> freeLanes;
113 48209 const auto finishGroup = [&](int endIndex) {
114
2/2
✓ Branch 10 → 3 taken 6044 times.
✓ Branch 10 → 11 taken 48209 times.
54253 for (int i = groupStart; i < endIndex; ++i)
115
3/3
✓ Branch 5 → 6 taken 5821 times.
✓ Branch 5 → 9 taken 223 times.
✓ Branch 7 → 8 taken 5821 times.
6044 if (!inBand(dayEvents[i])) dayEvents[i].laneCount = qMax(1, laneCount);
116 48209 };
117
2/2
✓ Branch 46 → 8 taken 6044 times.
✓ Branch 46 → 47 taken 42496 times.
48540 for (int i = 0; i < dayEvents.size(); ++i) {
118
1/1
✓ Branch 8 → 9 taken 6044 times.
6044 auto &event = dayEvents[i];
119
2/2
✓ Branch 10 → 11 taken 223 times.
✓ Branch 10 → 12 taken 5821 times.
6044 if (inBand(event)) continue;
120
2/2
✓ Branch 12 → 13 taken 5713 times.
✓ Branch 12 → 21 taken 108 times.
5821 if (event.startMinute >= groupEnd) {
121
1/1
✓ Branch 13 → 14 taken 5713 times.
5713 finishGroup(i);
122 5713 groupStart = i;
123 5713 groupEnd = event.endMinute;
124 5713 laneCount = 0;
125 5713 active = {};
126 5713 freeLanes = {};
127 }
128
6/6
✓ Branch 26 → 27 taken 110 times.
✓ Branch 26 → 30 taken 5713 times.
✓ Branch 28 → 29 taken 2 times.
✓ Branch 28 → 30 taken 108 times.
✓ Branch 31 → 22 taken 2 times.
✓ Branch 31 → 32 taken 5821 times.
5823 while (!active.empty() && active.top().first <= event.startMinute) {
129
1/1
✓ Branch 23 → 24 taken 2 times.
2 freeLanes.push(active.top().second);
130
1/1
✓ Branch 24 → 25 taken 2 times.
2 active.pop();
131 }
132
2/2
✓ Branch 33 → 34 taken 5819 times.
✓ Branch 33 → 35 taken 2 times.
5821 const int lane = freeLanes.empty() ? laneCount++ : freeLanes.top();
133
3/3
✓ Branch 38 → 39 taken 2 times.
✓ Branch 38 → 40 taken 5819 times.
✓ Branch 39 → 40 taken 2 times.
5821 if (!freeLanes.empty()) freeLanes.pop();
134
1/1
✓ Branch 40 → 41 taken 5821 times.
5821 active.emplace(event.endMinute, lane);
135 5821 event.lane = lane;
136 5821 groupEnd = qMax(groupEnd, event.endMinute);
137 }
138
1/1
✓ Branch 48 → 49 taken 42496 times.
42496 finishGroup(int(dayEvents.size()));
139 42496 }
140
141 5726 QList<CalendarSpan> spanRow(const QList<CalendarOccurrence> &occurrences, const QDate &rowStart,
142 int days) {
143
1/1
✓ Branch 2 → 3 taken 5726 times.
5726 const QDate rowEnd = rowStart.addDays(days - 1);
144 5726 QList<CalendarOccurrence> candidates;
145
2/2
✓ Branch 20 → 5 taken 15877 times.
✓ Branch 20 → 21 taken 5726 times.
21603 for (const CalendarOccurrence &occurrence : occurrences)
146
9/10
✓ Branch 6 → 7 taken 15615 times.
✓ Branch 6 → 8 taken 262 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 15 taken 15615 times.
✓ Branch 10 → 11 taken 211 times.
✓ Branch 10 → 15 taken 51 times.
✓ Branch 13 → 14 taken 124 times.
✓ Branch 13 → 15 taken 87 times.
✓ Branch 16 → 17 taken 124 times.
✓ Branch 16 → 18 taken 15753 times.
16088 if ((occurrence.allDay || occurrence.multiDay) && occurrence.lastDay >= rowStart &&
147 211 occurrence.firstDay <= rowEnd)
148
1/1
✓ Branch 17 → 18 taken 124 times.
124 candidates.append(occurrence);
149
3/3
✓ Branch 21 → 22 taken 5726 times.
✓ Branch 22 → 23 taken 5726 times.
✓ Branch 23 → 24 taken 5726 times.
5726 std::sort(candidates.begin(), candidates.end(), spanOrder);
150 5726 QList<CalendarSpan> spans;
151 5726 QList<QVector<bool>> levels; // occupied columns per level
152
4/4
✓ Branch 24 → 25 taken 5726 times.
✓ Branch 25 → 26 taken 5726 times.
✓ Branch 66 → 27 taken 124 times.
✓ Branch 66 → 67 taken 5726 times.
5850 for (const CalendarOccurrence &occurrence : candidates) {
153
1/1
✓ Branch 28 → 29 taken 124 times.
124 CalendarSpan span;
154 124 span.occurrence = occurrence;
155 124 const QDate from = qMax(occurrence.firstDay, rowStart);
156 124 const QDate to = qMin(occurrence.lastDay, rowEnd);
157
1/1
✓ Branch 32 → 33 taken 124 times.
124 span.column = int(rowStart.daysTo(from));
158
1/1
✓ Branch 33 → 34 taken 124 times.
124 span.length = int(from.daysTo(to)) + 1;
159 124 span.continuesBefore = occurrence.firstDay < rowStart;
160 124 span.continuesAfter = occurrence.lastDay > rowEnd;
161 124 int level = 0;
162 2 for (;; ++level) {
163
2/2
✓ Branch 40 → 41 taken 84 times.
✓ Branch 40 → 45 taken 42 times.
126 if (level == levels.size())
164
2/2
✓ Branch 41 → 42 taken 84 times.
✓ Branch 42 → 43 taken 84 times.
84 levels.append(QVector<bool>(days, false));
165 126 bool free = true;
166
2/2
✓ Branch 53 → 46 taken 194 times.
✓ Branch 53 → 54 taken 126 times.
320 for (int column = span.column; column < span.column + span.length; ++column)
167
6/6
✓ Branch 46 → 47 taken 193 times.
✓ Branch 46 → 51 taken 1 time.
✓ Branch 47 → 48 taken 193 times.
✓ Branch 48 → 49 taken 193 times.
✓ Branch 49 → 50 taken 191 times.
✓ Branch 49 → 51 taken 2 times.
194 free = free && !levels[level][column];
168
2/2
✓ Branch 54 → 55 taken 124 times.
✓ Branch 54 → 56 taken 2 times.
126 if (free) break;
169 2 }
170
2/2
✓ Branch 61 → 58 taken 191 times.
✓ Branch 61 → 62 taken 124 times.
315 for (int column = span.column; column < span.column + span.length; ++column)
171
2/2
✓ Branch 58 → 59 taken 191 times.
✓ Branch 59 → 60 taken 191 times.
191 levels[level][column] = true;
172 124 span.level = level;
173
1/1
✓ Branch 62 → 63 taken 124 times.
124 spans.append(span);
174 124 }
175 5726 return spans;
176 5726 }
177
178 1150 QHash<QDate, CalendarDaySummary> yearSummary(const QList<CalendarOccurrence> &occurrences, int year) {
179 1150 QHash<QDate, CalendarDaySummary> summaries;
180
2/2
✓ Branch 2 → 3 taken 1150 times.
✓ Branch 3 → 4 taken 1150 times.
1150 const QDate first(year, 1, 1), last(year, 12, 31);
181
2/2
✓ Branch 45 → 6 taken 24351 times.
✓ Branch 45 → 46 taken 1150 times.
25501 for (const CalendarOccurrence &occurrence : occurrences) {
182
2/2
✓ Branch 42 → 9 taken 17652 times.
✓ Branch 42 → 43 taken 24351 times.
42003 for (QDate day = qMax(occurrence.firstDay, first); day <= qMin(occurrence.lastDay, last);
183 17652 day = day.addDays(1)) {
184
1/1
✓ Branch 9 → 10 taken 17652 times.
17652 auto &summary = summaries[day];
185 17652 ++summary.count;
186
5/6
✓ Branch 11 → 12 taken 17652 times.
✗ Branch 11 → 15 not taken.
✓ Branch 13 → 14 taken 3240 times.
✓ Branch 13 → 15 taken 14412 times.
✓ Branch 16 → 17 taken 3240 times.
✓ Branch 16 → 18 taken 14412 times.
17652 if (summary.colors.size() < 3 && !summary.colors.contains(occurrence.color))
187
1/1
✓ Branch 17 → 18 taken 3240 times.
3240 summary.colors.append(occurrence.color);
188
2/2
✓ Branch 19 → 20 taken 3708 times.
✓ Branch 19 → 21 taken 13944 times.
17652 if (summary.titles.size() < 3)
189
1/1
✓ Branch 20 → 21 taken 3708 times.
3708 summary.titles.append(occurrence.summary);
190
4/5
✓ Branch 21 → 22 taken 17122 times.
✓ Branch 21 → 26 taken 530 times.
✓ Branch 22 → 23 taken 17122 times.
✓ Branch 24 → 25 taken 17122 times.
✗ Branch 24 → 26 not taken.
17652 const bool timed = !occurrence.allDay && day == occurrence.start.date();
191
2/2
✓ Branch 27 → 28 taken 17122 times.
✓ Branch 27 → 29 taken 530 times.
35304 summary.entries.append({timed ? timeText(occurrence.start) : QString(), occurrence.summary,
192 17652 occurrence.color,
193
1/1
✓ Branch 34 → 35 taken 530 times.
530 timed ? occurrence.start : QDateTime(day, QTime(0, 0))});
194 }
195 }
196 // All-day lines first, then by start time; five lines are enough for a
197 // tooltip ("+N more" covers the rest).
198
3/3
✓ Branch 46 → 47 taken 1150 times.
✓ Branch 57 → 48 taken 2547 times.
✓ Branch 57 → 58 taken 1150 times.
3697 for (auto &summary : summaries) {
199
3/3
✓ Branch 49 → 50 taken 2547 times.
✓ Branch 50 → 51 taken 2547 times.
✓ Branch 51 → 52 taken 2547 times.
2547 std::stable_sort(summary.entries.begin(), summary.entries.end(),
200 69613 [](const CalendarDayEntry &a, const CalendarDayEntry &b) { return a.start < b.start; });
201
3/3
✓ Branch 53 → 54 taken 62 times.
✓ Branch 53 → 55 taken 2485 times.
✓ Branch 54 → 55 taken 62 times.
2547 if (summary.entries.size() > 5) summary.entries.resize(5);
202 }
203 1150 return summaries;
204 35834 }
205
206 19319 QVariantMap toVariant(const CalendarOccurrence &occurrence) {
207
3/4
✓ Branch 2 → 3 taken 18953 times.
✓ Branch 2 → 4 taken 366 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 18953 times.
19319 const bool band = occurrence.allDay || occurrence.multiDay;
208
3/3
✓ Branch 6 → 7 taken 366 times.
✓ Branch 6 → 8 taken 18953 times.
✓ Branch 8 → 9 taken 18953 times.
19319 const QString start = band ? QString() : timeText(occurrence.start);
209
5/6
✓ Branch 9 → 10 taken 18953 times.
✓ Branch 9 → 13 taken 366 times.
✓ Branch 10 → 11 taken 18953 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 18953 times.
✓ Branch 14 → 15 taken 18953 times.
19319 const QString end = band || occurrence.end <= occurrence.start ? QString() : timeText(occurrence.end);
210
3/4
✓ Branch 15 → 16 taken 19319 times.
✓ Branch 17 → 18 taken 19319 times.
✗ Branch 17 → 20 not taken.
✓ Branch 18 → 19 taken 19319 times.
19319 const int duration = occurrence.end > occurrence.start ? int(occurrence.start.secsTo(occurrence.end) / 60) : 0;
211 38638 return {{QStringLiteral("summary"), occurrence.summary},
212 38638 {QStringLiteral("color"), occurrence.color},
213 38638 {QStringLiteral("timeText"), start},
214 38638 {QStringLiteral("endTimeText"), end},
215
10/16
✓ Branch 41 → 42 taken 366 times.
✓ Branch 41 → 43 taken 18953 times.
✓ Branch 46 → 47 taken 18953 times.
✓ Branch 47 → 48 taken 18953 times.
✓ Branch 247 → 248 taken 18953 times.
✓ Branch 247 → 249 taken 366 times.
✓ Branch 249 → 250 taken 18953 times.
✓ Branch 249 → 251 taken 366 times.
✓ Branch 251 → 252 taken 18953 times.
✓ Branch 251 → 253 taken 366 times.
✗ Branch 472 → 473 not taken.
✗ Branch 472 → 474 not taken.
✗ Branch 476 → 477 not taken.
✗ Branch 476 → 478 not taken.
✗ Branch 480 → 481 not taken.
✗ Branch 480 → 482 not taken.
57591 {QStringLiteral("timeRangeText"), end.isEmpty() ? start : start + QStringLiteral(" – ") + end},
216 38638 {QStringLiteral("durationMinutes"), duration},
217 // "allDay" places the occurrence in the all-day band (multi-day
218 // timed events too); "dateOnly" is the event's own DATE flag.
219 38638 {QStringLiteral("allDay"), band},
220 38638 {QStringLiteral("dateOnly"), occurrence.allDay},
221 38638 {QStringLiteral("multiDay"), occurrence.multiDay},
222 38638 {QStringLiteral("uid"), occurrence.uid},
223 38638 {QStringLiteral("accountId"), occurrence.accountId},
224 38638 {QStringLiteral("calendarPath"), occurrence.calendarPath},
225 38638 {QStringLiteral("calendarName"), occurrence.calendarName},
226 38638 {QStringLiteral("readOnly"), occurrence.readOnly},
227 38638 {QStringLiteral("pending"), occurrence.syncState == QLatin1String("pending")},
228 38638 {QStringLiteral("conflict"), occurrence.syncState == QLatin1String("conflict")},
229 57957 {QStringLiteral("partial"), occurrence.partial}, {QStringLiteral("limited"), occurrence.limited},
230 38638 {QStringLiteral("recurring"), occurrence.recurring},
231 57957 {QStringLiteral("task"), occurrence.task}, {QStringLiteral("overdue"), occurrence.overdue},
232 38638 {QStringLiteral("location"), occurrence.location},
233 38638 {QStringLiteral("description"), occurrence.description},
234
3/3
✓ Branch 128 → 129 taken 19319 times.
✓ Branch 129 → 130 taken 19319 times.
✓ Branch 130 → 131 taken 19319 times.
38638 {QStringLiteral("dateText"), QLocale().toString(occurrence.start.date(), QLocale::ShortFormat)},
235 // Formatted here, not per delegate in QML (CAL-PERIOD-REBUILD: JS date
236 // formatting dominated the rebind of a month's chips).
237
2/2
✓ Branch 135 → 136 taken 19319 times.
✓ Branch 136 → 137 taken 19319 times.
38638 {QStringLiteral("longDateText"), QLocale().toString(occurrence.firstDay, QLocale::LongFormat)},
238
1/1
✓ Branch 141 → 142 taken 19319 times.
38638 {QStringLiteral("firstDayIso"), occurrence.firstDay.toString(Qt::ISODate)},
239
1/1
✓ Branch 146 → 147 taken 19319 times.
38638 {QStringLiteral("lastDayIso"), occurrence.lastDay.toString(Qt::ISODate)},
240 38638 {QStringLiteral("startIso"), occurrence.startIso},
241 38638 {QStringLiteral("recurrenceIso"), occurrence.recurrenceIso},
242 38638 {QStringLiteral("startMinute"), occurrence.startMinute},
243 38638 {QStringLiteral("endMinute"), occurrence.endMinute},
244 38638 {QStringLiteral("lane"), occurrence.lane},
245 38638 {QStringLiteral("laneCount"), occurrence.laneCount},
246
3/5
✓ Branch 175 → 176 taken 19319 times.
✓ Branch 179 → 180 taken 656846 times.
✓ Branch 179 → 181 taken 19319 times.
✗ Branch 268 → 269 not taken.
✗ Branch 268 → 270 not taken.
714803 {QStringLiteral("people"), peopleList(occurrence.people)}};
247 695484 }
248
249 121 QVariantMap toVariant(const CalendarSpan &span) {
250 121 QVariantMap map = toVariant(span.occurrence);
251
1/1
✓ Branch 7 → 8 taken 121 times.
242 map.insert(QStringLiteral("column"), span.column);
252
1/1
✓ Branch 15 → 16 taken 121 times.
242 map.insert(QStringLiteral("length"), span.length);
253
1/1
✓ Branch 23 → 24 taken 121 times.
242 map.insert(QStringLiteral("level"), span.level);
254
1/1
✓ Branch 31 → 32 taken 121 times.
242 map.insert(QStringLiteral("continuesBefore"), span.continuesBefore);
255
1/1
✓ Branch 39 → 40 taken 121 times.
242 map.insert(QStringLiteral("continuesAfter"), span.continuesAfter);
256 121 return map;
257 ✗ }
258
259 // F93-03 / S93.3.5: day maps of the navigator and the year view.
260
261 55776 static QVariantList entryMaps(const QList<CalendarDayEntry> &entries) {
262 55776 QVariantList list;
263
2/2
✓ Branch 18 → 4 taken 4093 times.
✓ Branch 18 → 19 taken 55776 times.
59869 for (const auto &entry : entries)
264
3/5
✓ Branch 10 → 11 taken 4093 times.
✓ Branch 14 → 15 taken 12279 times.
✓ Branch 14 → 16 taken 4093 times.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
16372 list.append(QVariantMap{{"time", entry.time}, {"title", entry.title}, {"color", entry.color}});
265 55776 return list;
266 4093 }
267
268 // 42 day maps of the grid starting at `first` (year view, navigator).
269 1328 QVariantList monthDayMaps(const QDate &first, int month,
270 const QHash<QDate, CalendarDaySummary> &summaries) {
271 1328 QVariantList days;
272
2/2
✓ Branch 40 → 3 taken 55776 times.
✓ Branch 40 → 41 taken 1328 times.
57104 for (int offset = 0; offset < 42; ++offset) {
273
1/1
✓ Branch 3 → 4 taken 55776 times.
55776 const QDate date = first.addDays(offset);
274 55776 const auto summary = summaries.value(date);
275
1/1
✓ Branch 28 → 29 taken 55776 times.
55776 days.append(QVariantMap{{"dateIso", date.toString(Qt::ISODate)},
276 ✗ {"dayNumber", date.day()}, {"inMonth", date.month() == month},
277 55776 {"isToday", date == QDate::currentDate()}, {"eventCount", summary.count},
278
1/1
✓ Branch 16 → 17 taken 55776 times.
111552 {"longDate", QLocale().toString(date, QLocale::LongFormat)},
279 ✗ {"isWeekend", date.dayOfWeek() >= 6}, {"weekNumber", date.weekNumber()},
280
2/4
✓ Branch 32 → 33 taken 613536 times.
✓ Branch 32 → 34 taken 55776 times.
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 50 not taken.
669312 {"colors", summary.colors}, {"titles", summary.titles}, {"entries", entryMaps(summary.entries)}});
281 55776 }
282 1328 return days;
283 167328 }
284
285 // Per-date counts of `occurrences` inside [from, to].
286 1124 QHash<QDate, CalendarDaySummary> rangeSummary(const QList<CalendarOccurrence> &occurrences,
287 const QDate &from, const QDate &to) {
288 1124 QHash<QDate, CalendarDaySummary> summaries;
289
4/4
✓ Branch 2 → 3 taken 1124 times.
✓ Branch 26 → 27 taken 2255 times.
✓ Branch 27 → 4 taken 1131 times.
✓ Branch 27 → 28 taken 1124 times.
2255 for (int year = from.year(); year <= to.year(); ++year) {
290
1/1
✓ Branch 4 → 5 taken 1131 times.
1131 const auto part = CalendarLayout::yearSummary(occurrences, year);
291
2/2
✓ Branch 23 → 6 taken 2181 times.
✓ Branch 23 → 24 taken 1131 times.
3312 for (auto it = part.constBegin(); it != part.constEnd(); ++it)
292
3/6
✓ Branch 9 → 10 taken 2181 times.
✗ Branch 9 → 15 not taken.
✓ Branch 13 → 14 taken 2181 times.
✗ Branch 13 → 15 not taken.
✓ Branch 16 → 17 taken 2181 times.
✗ Branch 16 → 20 not taken.
2181 if (it.key() >= from && it.key() <= to)
293
1/1
✓ Branch 19 → 20 taken 2181 times.
2181 summaries.insert(it.key(), it.value());
294 1131 }
295 1124 return summaries;
296 ✗ }
297
298
299 } // namespace CalendarLayout
300