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: 95.8% 229 / 0 / 239
Functions: 100.0% 29 / 0 / 29
Branches: 79.9% 270 / 0 / 338

presentation/QuickContactMapTiles.cpp
Line Branch Exec Source
1 // The tile layers of QuickContactMap (Sprint 103 S103.4.10, F103-23…F103-25):
2 // - the outline (image://maptile) at the nearest integer zoom plus the level
3 // above it, so a level change shows tiles that are already drawn;
4 // - the online tiles (opt-in, D-11) from the disk cache; a tile not cached
5 // yet is stood in for by the part of its nearest cached ancestor (up to 4
6 // levels up, zooming in) or by its cached children (zooming out), so
7 // nothing flashes while it loads;
8 // - both as models with stable rows (MapMarkerModel), so a pan or zoom moves
9 // the same images instead of reloading them;
10 // - the missing tiles are requested centre first, once the view rested for
11 // WantDelayMs;
12 // - the public styles of resources/contacts/map-styles.json (with the
13 // provider's API key where one is needed) or a custom server, and the
14 // size of the tile cache.
15
16 #include "QuickContactMap.h"
17
18 #include "MapMarkerModel.h"
19 #include "MapTileSource.h"
20 #include "MapTileStyles.h"
21
22 #include <QLocale>
23 #include <QLoggingCategory>
24 #include <QRegularExpression>
25 #include <QSettings>
26 #include <QTimer>
27 #include <QUrl>
28 #include <algorithm>
29 #include <cmath>
30 #include <functional>
31
32 Q_DECLARE_LOGGING_CATEGORY(lcMapTiles)
33
34 namespace {
35
36 const QString kCustom = QStringLiteral("custom");
37
38
1/1
✓ Branch 5 → 6 taken 1967 times.
3934 QString keySetting(const QString &provider) { return QStringLiteral("contacts/mapTileKeys/") + provider; }
39
40 // Each tile of `level` that covers the canvas: unwrapped x (rows of a world
41 // shown twice differ), wrapped x, y, its canvas origin and size.
42 326 void forVisibleTiles(const MapProjection::Viewport &viewport, int level,
43 const std::function<void(int, int, int, QPointF, double)> &visit) {
44 326 const int count = 1 << level;
45 326 const double size = MapProjection::TileSize * std::pow(2.0, viewport.zoom - level);
46
1/1
✓ Branch 2 → 3 taken 326 times.
326 const QRectF visible = viewport.visibleWorld();
47 326 const int firstY = qMax(0, int(std::floor(visible.top() * count)));
48 326 const int lastY = qMin(count - 1, int(std::floor(visible.bottom() * count)));
49
2/2
✓ Branch 17 → 8 taken 964 times.
✓ Branch 17 → 18 taken 326 times.
1290 for (int y = firstY; y <= lastY; ++y)
50
2/2
✓ Branch 15 → 10 taken 4265 times.
✓ Branch 15 → 16 taken 964 times.
5229 for (int x = int(std::floor(visible.left() * count)); x <= int(std::floor(visible.right() * count)); ++x)
51
2/2
✓ Branch 11 → 12 taken 4265 times.
✓ Branch 12 → 13 taken 4265 times.
4265 visit(x, ((x % count) + count) % count, y, viewport.toScreen(QPointF(double(x) / count, double(y) / count)), size);
52 326 }
53
54
3/3
✓ Branch 6 → 7 taken 8271 times.
✓ Branch 8 → 9 taken 8271 times.
✓ Branch 10 → 11 taken 8271 times.
41355 QString tileName(int level, int x, int y) { return QStringLiteral("%1/%2/%3").arg(level).arg(x).arg(y); }
55
56 3843 QVariantMap tileRow(const QString &id, const QString &source, QPointF origin, double size, int z,
57 const QVariantList &clip = {}, bool fade = false) {
58 11529 return {{QStringLiteral("id"), id}, {QStringLiteral("source"), source},
59 11529 {QStringLiteral("x"), origin.x()}, {QStringLiteral("y"), origin.y()},
60 11529 {QStringLiteral("size"), size}, {QStringLiteral("z"), z},
61
2/4
✓ Branch 38 → 39 taken 30744 times.
✓ Branch 38 → 40 taken 3843 times.
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 61 not taken.
46116 {QStringLiteral("clip"), clip}, {QStringLiteral("fade"), fade}};
62 34587 }
63
64 } // namespace
65
66 24 QObject *QuickContactMap::tileModel() const { return m_tileModel; }
67 27 QObject *QuickContactMap::onlineTileModel() const { return m_onlineTileModel; }
68
69 135 void QuickContactMap::updateTiles() {
70
1/1
✓ Branch 2 → 3 taken 135 times.
135 m_tiles.clear();
71 135 QVariantList rows;
72
1/2
✓ Branch 4 → 5 taken 135 times.
✗ Branch 4 → 14 not taken.
135 if (!m_viewport.size.isEmpty()) {
73 135 const int level = qBound(0, int(std::lround(m_viewport.zoom)), int(MapProjection::MaxZoom));
74
2/2
✓ Branch 12 → 7 taken 270 times.
✓ Branch 12 → 13 taken 135 times.
405 for (int shown = level; shown >= qMax(0, level - 1); --shown)
75
2/2
✓ Branch 7 → 8 taken 270 times.
✓ Branch 8 → 9 taken 270 times.
270 forVisibleTiles(m_viewport, shown, [&](int x, int wrapped, int y, QPointF origin, double size) {
76
1/1
✓ Branch 2 → 3 taken 3304 times.
3304 const QString source = tileName(shown, wrapped, y);
77
6/6
✓ Branch 4 → 5 taken 2462 times.
✓ Branch 4 → 6 taken 842 times.
✓ Branch 7 → 8 taken 3304 times.
✓ Branch 11 → 12 taken 3304 times.
✓ Branch 12 → 13 taken 3304 times.
✓ Branch 14 → 15 taken 3304 times.
6608 rows.append(tileRow(QStringLiteral("o:") + tileName(shown, x, y), source, origin, size, shown == level ? 1 : 0));
78
2/2
✓ Branch 22 → 23 taken 2462 times.
✓ Branch 22 → 58 taken 842 times.
3304 if (shown == level)
79
1/1
✓ Branch 43 → 44 taken 2462 times.
7386 m_tiles.append(QVariantMap{{QStringLiteral("source"), source},
80 4924 {QStringLiteral("x"), origin.x()},
81 4924 {QStringLiteral("y"), origin.y()},
82
2/4
✓ Branch 47 → 48 taken 9848 times.
✓ Branch 47 → 49 taken 2462 times.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 88 not taken.
17234 {QStringLiteral("size"), size}});
83
1/5
✓ Branch 41 → 42 taken 2462 times.
✗ Branch 115 → 116 not taken.
✗ Branch 115 → 119 not taken.
✗ Branch 117 → 118 not taken.
✗ Branch 117 → 119 not taken.
15614 });
84 }
85
1/1
✓ Branch 14 → 15 taken 135 times.
135 m_tileModel->setMarkers(rows);
86
1/1
✓ Branch 15 → 16 taken 135 times.
135 updateOnlineTiles();
87 135 }
88
89 174 void QuickContactMap::updateOnlineTiles() {
90
1/1
✓ Branch 2 → 3 taken 174 times.
174 m_onlineTileList.clear();
91
5/6
✓ Branch 3 → 4 taken 56 times.
✓ Branch 3 → 6 taken 118 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 56 times.
✓ Branch 8 → 9 taken 118 times.
✓ Branch 8 → 15 taken 56 times.
174 if (!m_onlineTiles || m_viewport.size.isEmpty()) {
92
1/1
✓ Branch 10 → 11 taken 118 times.
118 m_onlineTileModel->setMarkers({});
93 118 m_standIns.clear();
94 118 m_tileFade.clear();
95 118 return;
96 }
97
1/1
✓ Branch 15 → 16 taken 56 times.
56 const int maxLevel = onlineMaxZoom();
98 56 const int level = qBound(0, int(std::lround(m_viewport.zoom)), maxLevel);
99 56 const QPointF centre(m_viewport.size.width() / 2, m_viewport.size.height() / 2);
100 56 QVariantList rows;
101 56 QList<QPair<double, QString>> missing;
102 56 QSet<QString> standIns;
103 56 QHash<QString, bool> fades;
104
2/2
✓ Branch 21 → 22 taken 56 times.
✓ Branch 22 → 23 taken 56 times.
56 forVisibleTiles(m_viewport, level, [&](int x, int wrapped, int y, QPointF origin, double size) {
105
1/1
✓ Branch 2 → 3 taken 961 times.
961 const QString shown = tileName(level, x, y);
106
1/1
✓ Branch 3 → 4 taken 961 times.
961 const QString file = m_tileSource->cachedFile(level, wrapped, y);
107
2/2
✓ Branch 5 → 6 taken 259 times.
✓ Branch 5 → 67 taken 702 times.
961 if (!file.isEmpty()) {
108
2/2
✓ Branch 6 → 7 taken 259 times.
✓ Branch 8 → 9 taken 259 times.
259 const QString source = QUrl::fromLocalFile(file).toString();
109
1/1
✓ Branch 30 → 31 taken 259 times.
777 m_onlineTileList.append(QVariantMap{{QStringLiteral("source"), source},
110 518 {QStringLiteral("x"), origin.x()},
111 518 {QStringLiteral("y"), origin.y()},
112
2/4
✓ Branch 34 → 35 taken 1036 times.
✓ Branch 34 → 36 taken 259 times.
✗ Branch 179 → 180 not taken.
✗ Branch 179 → 181 not taken.
1813 {QStringLiteral("size"), size}});
113 // Over a stand-in it appears at once; over the outline it fades in (kept while shown).
114
1/1
✓ Branch 47 → 48 taken 259 times.
259 const QString id = QStringLiteral("t:") + shown;
115
2/2
✓ Branch 51 → 52 taken 170 times.
✓ Branch 51 → 54 taken 89 times.
259 const bool fade = m_tileFade.contains(id) ? m_tileFade.value(id) : !m_standIns.contains(shown);
116
1/1
✓ Branch 56 → 57 taken 259 times.
259 fades.insert(id, fade);
117
2/2
✓ Branch 58 → 59 taken 259 times.
✓ Branch 60 → 61 taken 259 times.
259 rows.append(tileRow(id, source, origin, size, 2, {}, fade));
118 259 return;
119 259 }
120 702 const QPointF middle = origin + QPointF(size / 2, size / 2) - centre;
121
2/2
✓ Branch 72 → 73 taken 702 times.
✓ Branch 74 → 75 taken 702 times.
702 missing.append({std::hypot(middle.x(), middle.y()), tileName(level, wrapped, y)});
122
4/4
✓ Branch 115 → 116 taken 2027 times.
✓ Branch 115 → 117 taken 68 times.
✓ Branch 116 → 78 taken 1673 times.
✓ Branch 116 → 117 taken 354 times.
2095 for (int up = 1; up <= 4 && level - up >= 0; ++up) {
123 1673 const int ax = wrapped >> up, ay = y >> up;
124
1/1
✓ Branch 78 → 79 taken 1673 times.
1673 const QString ancestor = m_tileSource->cachedFile(level - up, ax, ay);
125
2/2
✓ Branch 80 → 81 taken 1393 times.
✓ Branch 80 → 82 taken 280 times.
1673 if (ancestor.isEmpty())
126 1393 continue;
127 280 const double part = double(MapProjection::TileSize) / (1 << up);
128
2/4
✓ Branch 88 → 89 taken 1120 times.
✓ Branch 88 → 90 taken 280 times.
✗ Branch 244 → 245 not taken.
✗ Branch 244 → 246 not taken.
1400 const QVariantList clip{(wrapped - (ax << up)) * part, (y - (ay << up)) * part, part, part};
129
5/5
✓ Branch 90 → 91 taken 280 times.
✓ Branch 92 → 93 taken 280 times.
✓ Branch 96 → 97 taken 280 times.
✓ Branch 97 → 98 taken 280 times.
✓ Branch 99 → 100 taken 280 times.
560 rows.append(tileRow(QStringLiteral("a:") + shown, QUrl::fromLocalFile(ancestor).toString(), origin, size, 0, clip));
130
1/1
✓ Branch 107 → 108 taken 280 times.
280 standIns.insert(shown);
131 280 break;
132 1953 }
133
2/2
✓ Branch 117 → 118 taken 16 times.
✓ Branch 117 → 119 taken 686 times.
702 if (level + 1 > maxLevel)
134 16 return;
135
2/2
✓ Branch 158 → 120 taken 1372 times.
✓ Branch 158 → 159 taken 686 times.
2058 for (int dy = 0; dy < 2; ++dy)
136
2/2
✓ Branch 156 → 121 taken 2744 times.
✓ Branch 156 → 157 taken 1372 times.
4116 for (int dx = 0; dx < 2; ++dx) {
137
1/1
✓ Branch 121 → 122 taken 2744 times.
2744 const QString child = m_tileSource->cachedFile(level + 1, wrapped * 2 + dx, y * 2 + dy);
138
1/2
✓ Branch 123 → 124 taken 2744 times.
✗ Branch 123 → 125 not taken.
2744 if (child.isEmpty())
139 2744 continue;
140 ✗ rows.append(tileRow(QStringLiteral("c:") + tileName(level + 1, x * 2 + dx, y * 2 + dy),
141 ✗ QUrl::fromLocalFile(child).toString(), origin + QPointF(dx * size / 2, dy * size / 2),
142 size / 2, 1));
143 ✗ standIns.insert(shown);
144 2744 }
145
6/14
✓ Branch 28 → 29 taken 259 times.
✓ Branch 86 → 87 taken 280 times.
✓ Branch 161 → 162 taken 686 times.
✓ Branch 161 → 163 taken 275 times.
✓ Branch 165 → 166 taken 686 times.
✓ Branch 165 → 168 taken 275 times.
✗ Branch 208 → 209 not taken.
✗ Branch 208 → 212 not taken.
✗ Branch 210 → 211 not taken.
✗ Branch 210 → 212 not taken.
✗ Branch 247 → 248 not taken.
✗ Branch 247 → 251 not taken.
✗ Branch 249 → 250 not taken.
✗ Branch 249 → 251 not taken.
2811 });
146 56 m_standIns = standIns;
147 56 m_tileFade = fades;
148
1/1
✓ Branch 26 → 27 taken 56 times.
56 m_onlineTileModel->setMarkers(rows);
149
3/3
✓ Branch 27 → 28 taken 56 times.
✓ Branch 28 → 29 taken 56 times.
✓ Branch 29 → 30 taken 56 times.
56 std::stable_sort(missing.begin(), missing.end(),
150 2305 [](const QPair<double, QString> &a, const QPair<double, QString> &b) { return a.first < b.first; });
151 56 QStringList wanted;
152
2/2
✓ Branch 37 → 33 taken 702 times.
✓ Branch 37 → 38 taken 56 times.
758 for (const auto &tile : std::as_const(missing))
153
1/1
✓ Branch 34 → 35 taken 702 times.
702 wanted.append(tile.second);
154
3/3
✓ Branch 38 → 39 taken 56 times.
✓ Branch 39 → 40 taken 53 times.
✓ Branch 39 → 42 taken 3 times.
56 if (wanted != m_wantedTiles) {
155 53 m_wantedTiles = wanted;
156
1/1
✓ Branch 41 → 42 taken 53 times.
53 m_wantTimer->start();
157 }
158 56 }
159
160 7 void QuickContactMap::requestTiles() {
161
1/2
✓ Branch 2 → 3 taken 7 times.
✗ Branch 2 → 4 not taken.
7 if (m_onlineTiles)
162 7 m_tileSource->want(m_wantedTiles);
163 7 }
164
165 79 int QuickContactMap::onlineMaxZoom() const {
166
2/2
✓ Branch 3 → 4 taken 65 times.
✓ Branch 3 → 5 taken 14 times.
79 return m_tileStyle == kCustom ? int(MapProjection::MaxOnlineZoom) : MapTileStyles::byId(m_tileStyle).maxZoom;
167 }
168
169 842 void QuickContactMap::applyTileStyle() {
170
4/6
✓ Branch 3 → 4 taken 835 times.
✓ Branch 3 → 7 taken 7 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 835 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 12 taken 842 times.
842 if (m_tileStyle != kCustom && !MapTileStyles::known(m_tileStyle))
171 ✗ m_tileStyle = MapTileStyles::all().first().id;
172
2/2
✓ Branch 13 → 14 taken 7 times.
✓ Branch 13 → 28 taken 835 times.
842 if (m_tileStyle == kCustom) {
173
4/4
✓ Branch 14 → 15 taken 7 times.
✓ Branch 19 → 20 taken 7 times.
✓ Branch 20 → 21 taken 7 times.
✓ Branch 21 → 22 taken 7 times.
14 m_tileSource->setTemplate(QSettings().value(QStringLiteral("contacts/mapTileServer")).toString());
174 7 m_tileSource->setMaxParallel(MapTileSource::MaxParallel);
175 } else {
176
1/1
✓ Branch 28 → 29 taken 835 times.
835 const MapTileStyles::Style &style = MapTileStyles::byId(m_tileStyle);
177 // The key is part of the address and so of the cache folder: tiles of a
178 // wrong key (watermarks) are not shown once the right one is entered.
179
3/3
✓ Branch 31 → 32 taken 835 times.
✓ Branch 32 → 33 taken 835 times.
✓ Branch 33 → 34 taken 835 times.
835 const QString key = QString::fromLatin1(QUrl::toPercentEncoding(tileKey(style.provider)));
180
2/2
✓ Branch 40 → 41 taken 835 times.
✓ Branch 41 → 42 taken 835 times.
835 m_tileSource->setTemplate(QString(style.templateUrl).replace(QLatin1String("{key}"), key));
181
1/1
✓ Branch 43 → 44 taken 835 times.
835 m_tileSource->setMaxParallel(style.parallel);
182 835 }
183
4/4
✓ Branch 46 → 47 taken 5 times.
✓ Branch 46 → 50 taken 837 times.
✓ Branch 48 → 49 taken 3 times.
✓ Branch 48 → 50 taken 2 times.
842 m_tileSource->setEnabled(m_onlineTiles && !tileKeyMissing());
184 842 m_standIns.clear();
185 842 m_wantedTiles.clear();
186 842 }
187
188 // After a change of the tile settings: the deepest zoom follows, the layers
189 // are made again.
190 41 void QuickContactMap::tileSettingsApplied() {
191 41 MapProjection::Viewport next = m_viewport;
192
3/3
✓ Branch 2 → 3 taken 11 times.
✓ Branch 2 → 5 taken 30 times.
✓ Branch 3 → 4 taken 11 times.
41 next.maxZoom = m_onlineTiles ? onlineMaxZoom() : MapProjection::MaxZoom;
193 41 next.zoom = qMin(next.zoom, next.maxZoom);
194 41 m_viewport = next;
195
1/1
✓ Branch 7 → 8 taken 41 times.
41 updateTiles();
196
1/1
✓ Branch 8 → 9 taken 41 times.
41 updateMarkers();
197
1/1
✓ Branch 9 → 10 taken 41 times.
41 emit tileSettingsChanged();
198
1/1
✓ Branch 10 → 11 taken 41 times.
41 emit viewportChanged();
199 41 }
200
201 11 void QuickContactMap::setOnlineTiles(bool on) {
202
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 11 times.
11 if (on == m_onlineTiles)
203 ✗ return;
204 11 m_onlineTiles = on;
205
2/2
✓ Branch 4 → 5 taken 11 times.
✓ Branch 10 → 11 taken 11 times.
22 QSettings().setValue(QStringLiteral("contacts/mapTiles"), on);
206
4/4
✓ Branch 15 → 16 taken 6 times.
✓ Branch 15 → 19 taken 5 times.
✓ Branch 17 → 18 taken 5 times.
✓ Branch 17 → 19 taken 1 time.
11 m_tileSource->setEnabled(on && !tileKeyMissing());
207 11 m_wantedTiles.clear();
208
4/4
✓ Branch 22 → 23 taken 5 times.
✓ Branch 22 → 25 taken 6 times.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 25 taken 4 times.
11 if (!on && m_tilesUnavailable) {
209 1 m_tilesUnavailable = false;
210 1 emit tilesUnavailableChanged();
211 }
212 11 tileSettingsApplied();
213 }
214
215 513 QVariantList QuickContactMap::tileStyles() const {
216 513 QVariantList out;
217
3/3
✓ Branch 2 → 3 taken 513 times.
✓ Branch 34 → 5 taken 14877 times.
✓ Branch 34 → 35 taken 513 times.
15390 for (const MapTileStyles::Style &style : MapTileStyles::all())
218
1/1
✓ Branch 20 → 21 taken 14877 times.
44631 out.append(QVariantMap{{QStringLiteral("id"), style.id},
219 29754 {QStringLiteral("provider"), style.provider},
220
2/4
✓ Branch 24 → 25 taken 44631 times.
✓ Branch 24 → 26 taken 14877 times.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 44 not taken.
89262 {QStringLiteral("name"), style.name}});
221 513 return out;
222 59508 }
223
224 220 QVariantList QuickContactMap::tileProviders() const {
225 220 QVariantList out;
226
3/3
✓ Branch 2 → 3 taken 220 times.
✓ Branch 50 → 5 taken 1100 times.
✓ Branch 50 → 51 taken 220 times.
1320 for (const MapTileStyles::Provider &provider : MapTileStyles::providers())
227
1/1
✓ Branch 31 → 32 taken 1100 times.
3300 out.append(QVariantMap{{QStringLiteral("id"), provider.id},
228 2200 {QStringLiteral("name"), provider.name},
229 2200 {QStringLiteral("keyUrl"), provider.keyUrl},
230 2200 {QStringLiteral("needsKey"), provider.needsKey()},
231
3/5
✓ Branch 26 → 27 taken 1100 times.
✓ Branch 35 → 36 taken 5500 times.
✓ Branch 35 → 37 taken 1100 times.
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 60 not taken.
8800 {QStringLiteral("hasKey"), !tileKey(provider.id).isEmpty()}});
232 220 return out;
233 6600 }
234
235 583 QString QuickContactMap::tileProvider() const {
236
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 583 times.
583 return m_tileStyle == kCustom ? kCustom : MapTileStyles::byId(m_tileStyle).provider;
237 }
238
239 17 bool QuickContactMap::tileKeyMissing() const {
240
2/2
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 5 taken 12 times.
17 if (m_tileStyle == kCustom)
241 5 return false;
242
1/1
✓ Branch 5 → 6 taken 12 times.
12 const QString provider = MapTileStyles::byId(m_tileStyle).provider;
243
8/10
✓ Branch 7 → 8 taken 12 times.
✓ Branch 9 → 10 taken 10 times.
✓ Branch 9 → 14 taken 2 times.
✓ Branch 10 → 11 taken 10 times.
✓ Branch 12 → 13 taken 6 times.
✓ Branch 12 → 14 taken 4 times.
✓ Branch 16 → 17 taken 10 times.
✓ Branch 16 → 18 taken 2 times.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
12 return MapTileStyles::providerById(provider).needsKey() && tileKey(provider).isEmpty();
244 12 }
245
246 1965 QString QuickContactMap::tileKey(const QString &provider) const {
247
4/4
✓ Branch 2 → 3 taken 1965 times.
✓ Branch 3 → 4 taken 1965 times.
✓ Branch 5 → 6 taken 1965 times.
✓ Branch 6 → 7 taken 1965 times.
1965 return QSettings().value(keySetting(provider)).toString();
248 }
249
250 2 void QuickContactMap::setTileKey(const QString &provider, const QString &key) {
251
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 3 → 4 taken 2 times.
2 const QString text = key.trimmed().left(512);
252
6/13
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 12 not taken.
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 12 not taken.
✓ Branch 9 → 10 taken 2 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 2 times.
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 16 not taken.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 2 times.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 70 not taken.
2 if (provider.isEmpty() || provider == kCustom || text == tileKey(provider))
253 ✗ return;
254
2/2
✓ Branch 19 → 20 taken 1 time.
✓ Branch 19 → 27 taken 1 time.
2 if (text.isEmpty())
255
3/3
✓ Branch 20 → 21 taken 1 time.
✓ Branch 21 → 22 taken 1 time.
✓ Branch 23 → 24 taken 1 time.
1 QSettings().remove(keySetting(provider));
256 else
257
3/3
✓ Branch 27 → 28 taken 1 time.
✓ Branch 29 → 30 taken 1 time.
✓ Branch 31 → 32 taken 1 time.
1 QSettings().setValue(keySetting(provider), text);
258
9/9
✓ Branch 36 → 37 taken 2 times.
✓ Branch 40 → 41 taken 2 times.
✓ Branch 41 → 42 taken 2 times.
✓ Branch 43 → 44 taken 1 time.
✓ Branch 43 → 45 taken 1 time.
✓ Branch 46 → 47 taken 2 times.
✓ Branch 47 → 48 taken 2 times.
✓ Branch 51 → 38 taken 2 times.
✓ Branch 51 → 52 taken 2 times.
4 qCInfo(lcMapTiles) << "Map tile key" << (text.isEmpty() ? "removed for" : "stored for") << provider;
259
2/3
✓ Branch 52 → 53 taken 2 times.
✓ Branch 55 → 56 taken 2 times.
✗ Branch 55 → 57 not taken.
2 if (provider == tileProvider())
260
1/1
✓ Branch 56 → 57 taken 2 times.
2 applyTileStyle();
261
1/1
✓ Branch 57 → 58 taken 2 times.
2 tileSettingsApplied();
262 2 }
263
264 29 void QuickContactMap::setTileStyle(const QString &id) {
265
7/8
✓ Branch 3 → 4 taken 29 times.
✗ Branch 3 → 8 not taken.
✓ Branch 5 → 6 taken 24 times.
✓ Branch 5 → 9 taken 5 times.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 23 times.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 28 times.
29 if (id == m_tileStyle || (id != kCustom && !MapTileStyles::known(id)))
266 1 return;
267 28 m_tileStyle = id;
268
2/2
✓ Branch 13 → 14 taken 28 times.
✓ Branch 19 → 20 taken 28 times.
56 QSettings().setValue(QStringLiteral("contacts/mapTileStyle"), id);
269 28 applyTileStyle();
270
6/6
✓ Branch 25 → 26 taken 28 times.
✓ Branch 29 → 30 taken 28 times.
✓ Branch 30 → 31 taken 28 times.
✓ Branch 31 → 32 taken 28 times.
✓ Branch 35 → 27 taken 28 times.
✓ Branch 35 → 36 taken 28 times.
56 qCInfo(lcMapTiles) << "Map tile style:" << id;
271 28 tileSettingsApplied();
272 }
273
274 // The address in use; a public style's with its {key} placeholder, never the key.
275 33 QString QuickContactMap::tileServer() const {
276
2/2
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 30 times.
33 return m_tileStyle == kCustom ? m_tileSource->templateUrl() : MapTileStyles::byId(m_tileStyle).templateUrl;
277 }
278
279 // A server address is the custom style; "" returns to the default style.
280 8 void QuickContactMap::setTileServer(const QString &templateUrl) {
281
1/1
✓ Branch 2 → 3 taken 8 times.
8 const QString text = templateUrl.trimmed();
282
8/11
✓ Branch 4 → 5 taken 5 times.
✓ Branch 4 → 8 taken 3 times.
✓ Branch 5 → 6 taken 5 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5 times.
✓ Branch 10 → 11 taken 5 times.
✓ Branch 10 → 12 taken 3 times.
✓ Branch 12 → 13 taken 3 times.
✓ Branch 12 → 28 taken 5 times.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 59 not taken.
8 if (text.isEmpty() || text == MapTileSource::defaultTemplate()) {
283
2/2
✓ Branch 13 → 14 taken 3 times.
✓ Branch 18 → 19 taken 3 times.
6 QSettings().remove(QStringLiteral("contacts/mapTileServer"));
284
1/2
✓ Branch 23 → 24 taken 3 times.
✗ Branch 23 → 27 not taken.
3 if (m_tileStyle == kCustom)
285
2/2
✓ Branch 24 → 25 taken 3 times.
✓ Branch 26 → 27 taken 3 times.
3 setTileStyle(MapTileStyles::all().first().id);
286 3 return;
287 }
288
2/3
✓ Branch 28 → 29 taken 5 times.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 5 times.
5 if (!MapTileSource::validate(text).isEmpty())
289 ✗ return;
290
2/2
✓ Branch 33 → 34 taken 5 times.
✓ Branch 39 → 40 taken 5 times.
10 QSettings().setValue(QStringLiteral("contacts/mapTileServer"), text);
291
1/2
✓ Branch 45 → 46 taken 5 times.
✗ Branch 45 → 48 not taken.
5 if (m_tileStyle != kCustom) {
292
1/1
✓ Branch 46 → 47 taken 5 times.
5 setTileStyle(kCustom);
293 5 return;
294 }
295 ✗ applyTileStyle();
296 ✗ tileSettingsApplied();
297 8 }
298
299 1 QString QuickContactMap::checkTileServer(const QString &templateUrl) const {
300
2/4
✓ Branch 2 → 3 taken 1 time.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
✗ Branch 6 → 7 not taken.
1 return templateUrl.trimmed().isEmpty() ? QString() : MapTileSource::validate(templateUrl);
301 }
302
303 // The provider's credit on the map: the style's own, for a custom server
304 // the OpenStreetMap credit for its servers, else the server's host.
305 25 QString QuickContactMap::attribution() const {
306
2/2
✓ Branch 2 → 3 taken 23 times.
✓ Branch 2 → 7 taken 2 times.
25 if (!m_onlineTiles) // S103.1.9: positions from the online lookup are OpenStreetMap data
307
4/4
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 22 times.
✓ Branch 4 → 6 taken 1 time.
✓ Branch 5 → 6 taken 22 times.
23 return m_onlineLookup ? tr("Natural Earth · GeoNames · © OpenStreetMap contributors") : tr("Natural Earth · GeoNames");
308
2/2
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 11 taken 1 time.
2 if (m_tileStyle != kCustom)
309
1/1
✓ Branch 9 → 10 taken 1 time.
1 return MapTileStyles::byId(m_tileStyle).attribution;
310
2/2
✓ Branch 19 → 20 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
3 const QString host = QUrl(QString(m_tileSource->templateUrl()).replace(QRegularExpression(QStringLiteral("\\{[xyz]\\}")),
311
2/2
✓ Branch 21 → 22 taken 1 time.
✓ Branch 23 → 24 taken 1 time.
4 QStringLiteral("0"))).host();
312
2/3
✓ Branch 32 → 33 taken 1 time.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 36 taken 1 time.
1 if (host.endsWith(QLatin1String("openstreetmap.org")))
313 ✗ return tr("© OpenStreetMap contributors");
314
2/2
✓ Branch 36 → 37 taken 1 time.
✓ Branch 38 → 39 taken 1 time.
2 return tr("Tiles: %1").arg(host);
315 1 }
316
317 25 void QuickContactMap::refreshTileCacheSize() {
318 25 const qint64 bytes = m_tileSource->cacheBytes();
319 //: Settings › Privacy › Contact map: the size of the map tile cache ("12.3 MB on disk").
320
4/4
✓ Branch 3 → 4 taken 24 times.
✓ Branch 3 → 5 taken 1 time.
✓ Branch 4 → 11 taken 24 times.
✓ Branch 10 → 11 taken 1 time.
52 m_tileCacheSize = bytes == 0 ? tr("The cache is empty.")
321
9/15
✓ Branch 5 → 6 taken 1 time.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 24 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 17 taken 24 times.
✓ Branch 17 → 18 taken 1 time.
✓ Branch 17 → 19 taken 24 times.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 33 not taken.
52 : tr("%1 on disk").arg(QLocale().formattedDataSize(bytes, 1, QLocale::DataSizeTraditionalFormat));
322 25 emit tileCacheChanged();
323 25 }
324
325 7 void QuickContactMap::clearTileCache() {
326 7 m_tileSource->clearCache();
327 7 m_standIns.clear();
328 7 m_wantedTiles.clear();
329 7 updateOnlineTiles();
330 7 refreshTileCacheSize();
331 7 emit viewportChanged();
332 7 }
333