presentation/QuickContactMap.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "QuickContactMap.h" | ||
| 2 | |||
| 3 | #include "data/ContactIndex.h" | ||
| 4 | #include "data/ContactPlaceIndexer.h" | ||
| 5 | #include "data/ContactQueries.h" | ||
| 6 | #include "data/ContactStore.h" | ||
| 7 | #include "data/GeoData.h" | ||
| 8 | #include "data/PlaceGazetteer.h" | ||
| 9 | #include "presentation/MapMarkerModel.h" | ||
| 10 | #include "presentation/MapTileSource.h" | ||
| 11 | |||
| 12 | #include <QElapsedTimer> | ||
| 13 | #include <QHash> | ||
| 14 | #include <QLocale> | ||
| 15 | #include <QMap> | ||
| 16 | #include <QLoggingCategory> | ||
| 17 | #include <QPointer> | ||
| 18 | #include <QRegularExpression> | ||
| 19 | #include <QSet> | ||
| 20 | #include <QSettings> | ||
| 21 | #include <QSqlQuery> | ||
| 22 | #include <QStandardPaths> | ||
| 23 | #include <QTimer> | ||
| 24 | #include <QUrl> | ||
| 25 | #include <algorithm> | ||
| 26 | #include <cmath> | ||
| 27 | |||
| 28 | Q_DECLARE_LOGGING_CATEGORY(lcMapTiles) | ||
| 29 | |||
| 30 | 812 | QuickContactMap::QuickContactMap(QString databasePath, QObject *parent) | |
| 31 | 812 | : QObject(parent), m_databasePath(std::move(databasePath)), | |
| 32 |
1/3✓ Branch 42 → 43 taken 812 times.
✗ Branch 196 → 197 not taken.
✗ Branch 196 → 199 not taken.
|
1624 | m_tileSource(new MapTileSource(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + |
| 33 |
3/4✓ Branch 43 → 44 taken 812 times.
✓ Branch 44 → 45 taken 812 times.
✗ Branch 51 → 52 not taken.
✓ Branch 51 → 54 taken 812 times.
|
2436 | QStringLiteral("/maptiles")), |
| 34 |
6/12✓ Branch 5 → 6 taken 812 times.
✓ Branch 27 → 28 taken 812 times.
✓ Branch 29 → 30 taken 4060 times.
✓ Branch 29 → 31 taken 812 times.
✓ Branch 38 → 39 taken 812 times.
✓ Branch 45 → 46 taken 812 times.
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 159 not taken.
✗ Branch 175 → 176 not taken.
✗ Branch 175 → 179 not taken.
✗ Branch 177 → 178 not taken.
✗ Branch 177 → 179 not taken.
|
11368 | this)) { |
| 35 |
1/1✓ Branch 63 → 64 taken 812 times.
|
812 | m_pool.setMaxThreadCount(1); |
| 36 | 812 | m_viewport.zoom = 1.5; | |
| 37 |
4/7✓ Branch 64 → 65 taken 812 times.
✓ Branch 65 → 66 taken 812 times.
✓ Branch 66 → 67 taken 812 times.
✗ Branch 68 → 69 not taken.
✓ Branch 68 → 70 taken 812 times.
✗ Branch 203 → 204 not taken.
✗ Branch 203 → 205 not taken.
|
812 | m_markerModel = new MapMarkerModel("cluster", this); |
| 38 |
4/7✓ Branch 70 → 71 taken 812 times.
✓ Branch 71 → 72 taken 812 times.
✓ Branch 72 → 73 taken 812 times.
✗ Branch 74 → 75 not taken.
✓ Branch 74 → 76 taken 812 times.
✗ Branch 209 → 210 not taken.
✗ Branch 209 → 211 not taken.
|
812 | m_tileModel = new MapMarkerModel("tile", this); |
| 39 |
4/7✓ Branch 76 → 77 taken 812 times.
✓ Branch 77 → 78 taken 812 times.
✓ Branch 78 → 79 taken 812 times.
✗ Branch 80 → 81 not taken.
✓ Branch 80 → 82 taken 812 times.
✗ Branch 215 → 216 not taken.
✗ Branch 215 → 217 not taken.
|
812 | m_onlineTileModel = new MapMarkerModel("tile", this); |
| 40 |
3/6✓ Branch 82 → 83 taken 812 times.
✓ Branch 83 → 84 taken 812 times.
✗ Branch 84 → 85 not taken.
✓ Branch 84 → 86 taken 812 times.
✗ Branch 218 → 219 not taken.
✗ Branch 218 → 220 not taken.
|
812 | m_wantTimer = new QTimer(this); |
| 41 |
1/1✓ Branch 86 → 87 taken 812 times.
|
812 | m_wantTimer->setSingleShot(true); |
| 42 |
1/1✓ Branch 87 → 88 taken 812 times.
|
812 | m_wantTimer->setInterval(WantDelayMs); |
| 43 |
1/1✓ Branch 88 → 89 taken 812 times.
|
812 | connect(m_wantTimer, &QTimer::timeout, this, &QuickContactMap::requestTiles); |
| 44 |
1/1✓ Branch 90 → 91 taken 812 times.
|
812 | const QSettings settings; |
| 45 | // F103-24: a server set before the styles existed is the custom style. | ||
| 46 |
2/2✓ Branch 95 → 96 taken 812 times.
✓ Branch 96 → 97 taken 812 times.
|
812 | const QString custom = settings.value(QStringLiteral("contacts/mapTileServer")).toString(); |
| 47 |
3/5✓ Branch 101 → 102 taken 810 times.
✓ Branch 101 → 105 taken 2 times.
✓ Branch 113 → 114 taken 812 times.
✗ Branch 250 → 251 not taken.
✗ Branch 250 → 252 not taken.
|
4058 | m_tileStyle = settings.value(QStringLiteral("contacts/mapTileStyle"), custom.isEmpty() ? QStringLiteral("osm") |
| 48 |
4/6✓ Branch 122 → 123 taken 2 times.
✓ Branch 122 → 124 taken 810 times.
✓ Branch 124 → 125 taken 810 times.
✓ Branch 124 → 126 taken 2 times.
✗ Branch 246 → 247 not taken.
✗ Branch 246 → 248 not taken.
|
812 | : QStringLiteral("custom")) |
| 49 |
1/1✓ Branch 114 → 115 taken 812 times.
|
812 | .toString(); |
| 50 |
1/1✓ Branch 126 → 127 taken 812 times.
|
812 | applyTileStyle(); |
| 51 |
2/2✓ Branch 132 → 133 taken 812 times.
✓ Branch 133 → 134 taken 812 times.
|
1624 | m_onlineTiles = settings.value(QStringLiteral("contacts/mapTiles"), false).toBool(); |
| 52 |
5/6✓ Branch 138 → 139 taken 1 time.
✓ Branch 138 → 142 taken 811 times.
✓ Branch 139 → 140 taken 1 time.
✓ Branch 140 → 141 taken 1 time.
✗ Branch 140 → 142 not taken.
✓ Branch 143 → 144 taken 812 times.
|
812 | m_tileSource->setEnabled(m_onlineTiles && !tileKeyMissing()); |
| 53 |
3/3✓ Branch 144 → 145 taken 1 time.
✓ Branch 144 → 147 taken 811 times.
✓ Branch 145 → 146 taken 1 time.
|
812 | m_viewport.maxZoom = m_onlineTiles ? onlineMaxZoom() : MapProjection::MaxZoom; |
| 54 | // Arriving tiles are shown in one pass per event loop turn (two requests run at a time). | ||
| 55 |
1/1✓ Branch 148 → 149 taken 812 times.
|
812 | connect(m_tileSource, &MapTileSource::tileReady, this, [this] { |
| 56 |
2/2✓ Branch 2 → 3 taken 31 times.
✓ Branch 2 → 4 taken 33 times.
|
64 | if (m_tileRefreshQueued) |
| 57 | 31 | return; | |
| 58 | 33 | m_tileRefreshQueued = true; | |
| 59 |
1/1✓ Branch 4 → 5 taken 33 times.
|
33 | QTimer::singleShot(0, this, [this] { |
| 60 | 32 | m_tileRefreshQueued = false; | |
| 61 | 32 | updateOnlineTiles(); | |
| 62 | 32 | emit viewportChanged(); | |
| 63 | 32 | }); | |
| 64 | }); | ||
| 65 |
1/1✓ Branch 150 → 151 taken 812 times.
|
812 | connect(m_tileSource, &MapTileSource::unavailableChanged, this, [this](bool unavailable) { |
| 66 | 1 | m_tilesUnavailable = unavailable; | |
| 67 | 1 | emit tilesUnavailableChanged(); | |
| 68 | 1 | }); | |
| 69 |
1/1✓ Branch 152 → 153 taken 812 times.
|
812 | initLookup(); |
| 70 | 812 | } | |
| 71 | |||
| 72 | 812 | QuickContactMap::~QuickContactMap() { m_pool.waitForDone(); } | |
| 73 | |||
| 74 | 22 | QObject *QuickContactMap::markerModel() const { return m_markerModel; } | |
| 75 | |||
| 76 | // The first fit waits for the worker: fitted to the few places known | ||
| 77 | // before it (pinned ones), the map would stay zoomed in on them. | ||
| 78 | 49 | void QuickContactMap::activate() { | |
| 79 | 49 | m_active = true; | |
| 80 | 49 | placeOnWorker(); | |
| 81 | 49 | readPlaces(); | |
| 82 | 49 | } | |
| 83 | |||
| 84 | 42 | void QuickContactMap::deactivate() { | |
| 85 |
2/2✓ Branch 2 → 3 taken 19 times.
✓ Branch 2 → 4 taken 23 times.
|
42 | if (!m_active) |
| 86 | 19 | return; | |
| 87 | 23 | m_active = false; | |
| 88 | 23 | stopBackgroundLookups(); | |
| 89 |
5/5✓ Branch 5 → 6 taken 23 times.
✓ Branch 9 → 10 taken 23 times.
✓ Branch 10 → 11 taken 23 times.
✓ Branch 14 → 7 taken 23 times.
✓ Branch 14 → 15 taken 23 times.
|
46 | qCInfo(lcMapTiles) << "Map inactive: background address lookups stopped"; |
| 90 | } | ||
| 91 | |||
| 92 | 45 | void QuickContactMap::reload() { | |
| 93 |
2/2✓ Branch 2 → 3 taken 41 times.
✓ Branch 2 → 4 taken 4 times.
|
45 | if (!m_active) |
| 94 | 41 | return; | |
| 95 | 4 | placeOnWorker(); | |
| 96 | 4 | readPlaces(); | |
| 97 | } | ||
| 98 | |||
| 99 | // Pending rows are placed in slices of 200 on the worker; the GUI reads the | ||
| 100 | // places again when a slice placed something and once at the end. | ||
| 101 | 53 | void QuickContactMap::placeOnWorker() { | |
| 102 |
10/13✓ Branch 2 → 3 taken 42 times.
✓ Branch 2 → 8 taken 11 times.
✓ Branch 4 → 5 taken 42 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 42 times.
✓ Branch 7 → 8 taken 20 times.
✓ Branch 7 → 9 taken 22 times.
✓ Branch 10 → 11 taken 42 times.
✓ Branch 10 → 12 taken 11 times.
✓ Branch 12 → 13 taken 31 times.
✓ Branch 12 → 14 taken 22 times.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 33 not taken.
|
53 | if (m_placing || m_databasePath.isEmpty() || !GeoData::builtIn()) |
| 103 | 31 | return; | |
| 104 | 22 | m_placing = true; | |
| 105 |
1/1✓ Branch 14 → 15 taken 22 times.
|
22 | emit placingChanged(); |
| 106 | 22 | const QString path = m_databasePath; | |
| 107 |
3/3✓ Branch 16 → 17 taken 22 times.
✓ Branch 17 → 18 taken 22 times.
✓ Branch 18 → 19 taken 22 times.
|
22 | const QString country = QLocale::territoryToCode(QLocale::system().territory()); |
| 108 |
1/1✓ Branch 20 → 21 taken 22 times.
|
22 | QPointer<QuickContactMap> self(this); |
| 109 |
1/5✓ Branch 24 → 25 taken 22 times.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 42 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
|
22 | m_pool.start([self, path, country] { |
| 110 | 22 | QElapsedTimer timer; | |
| 111 | 22 | timer.start(); | |
| 112 | 22 | int placed = 0; | |
| 113 |
1/1✓ Branch 3 → 4 taken 22 times.
|
22 | ContactStore store; |
| 114 |
2/3✓ Branch 4 → 5 taken 22 times.
✓ Branch 5 → 6 taken 22 times.
✗ Branch 5 → 19 not taken.
|
22 | if (store.open(path)) { |
| 115 |
1/1✓ Branch 6 → 7 taken 22 times.
|
22 | QSqlDatabase db = store.database(); |
| 116 |
1/2✓ Branch 16 → 8 taken 22 times.
✗ Branch 16 → 17 not taken.
|
22 | for (int slice = 0; slice < 500; ++slice) { |
| 117 |
2/2✓ Branch 8 → 9 taken 22 times.
✓ Branch 10 → 11 taken 22 times.
|
22 | const ContactPlaceIndexer::Result result = ContactPlaceIndexer::run(db, *GeoData::builtIn(), country, 200); |
| 118 | 22 | placed += result.placed; | |
| 119 |
1/4✗ Branch 12 → 13 not taken.
✓ Branch 12 → 15 taken 22 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
|
22 | if (result.remaining == 0 || result.processed == 0) |
| 120 | break; | ||
| 121 | } | ||
| 122 | 22 | } | |
| 123 |
9/9✓ Branch 19 → 20 taken 22 times.
✓ Branch 23 → 24 taken 22 times.
✓ Branch 24 → 25 taken 22 times.
✓ Branch 25 → 26 taken 22 times.
✓ Branch 26 → 27 taken 22 times.
✓ Branch 28 → 29 taken 22 times.
✓ Branch 29 → 30 taken 22 times.
✓ Branch 33 → 21 taken 22 times.
✓ Branch 33 → 34 taken 22 times.
|
44 | qCInfo(lcMapTiles) << "Places placed on the worker:" << placed << "in" << timer.elapsed() << "ms"; |
| 124 |
1/1✓ Branch 36 → 37 taken 22 times.
|
22 | QMetaObject::invokeMethod( |
| 125 | 22 | self.data(), | |
| 126 |
0/2✗ Branch 54 → 55 not taken.
✗ Branch 54 → 56 not taken.
|
44 | [self, placed] { |
| 127 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 19 times.
|
19 | if (!self) |
| 128 | ✗ | return; | |
| 129 | 19 | self->m_placing = false; | |
| 130 | 19 | emit self->placingChanged(); | |
| 131 |
6/6✓ Branch 8 → 9 taken 8 times.
✓ Branch 8 → 11 taken 11 times.
✓ Branch 10 → 11 taken 5 times.
✓ Branch 10 → 12 taken 3 times.
✓ Branch 13 → 14 taken 16 times.
✓ Branch 13 → 16 taken 3 times.
|
19 | if (placed > 0 || !self->m_fitted) |
| 132 | 16 | self->readPlaces(); | |
| 133 | 19 | self->queueLookups(); // S103.1.9: only with the setting on | |
| 134 | }, | ||
| 135 | Qt::QueuedConnection); | ||
| 136 | 22 | }); | |
| 137 | 22 | } | |
| 138 | |||
| 139 | 73 | void QuickContactMap::readPlaces() { | |
| 140 | 73 | QElapsedTimer timer; | |
| 141 | 73 | timer.start(); | |
| 142 |
1/1✓ Branch 3 → 4 taken 73 times.
|
73 | m_places.clear(); |
| 143 | // S106-278: the clusters index into m_places, so they go with it; the | ||
| 144 | // next updateMarkers re-forms them even when the new set has the same size. | ||
| 145 |
1/1✓ Branch 4 → 5 taken 73 times.
|
73 | m_clusterInput.clear(); |
| 146 |
1/1✓ Branch 5 → 6 taken 73 times.
|
73 | m_clusters.clear(); |
| 147 | 73 | m_clusterKeys.clear(); | |
| 148 | 73 | m_clusterZoom = -1; | |
| 149 | 73 | QHash<QString, int> personOf; | |
| 150 | 73 | QSet<QString> placed; | |
| 151 | 73 | QSet<QString> withPlaceText; | |
| 152 |
1/1✓ Branch 9 → 10 taken 73 times.
|
73 | ContactStore store; |
| 153 |
4/7✓ Branch 11 → 12 taken 73 times.
✗ Branch 11 → 15 not taken.
✓ Branch 12 → 13 taken 73 times.
✓ Branch 13 → 14 taken 73 times.
✗ Branch 13 → 15 not taken.
✓ Branch 16 → 17 taken 73 times.
✗ Branch 16 → 148 not taken.
|
73 | if (!m_databasePath.isEmpty() && store.open(m_databasePath)) { |
| 154 |
2/2✓ Branch 17 → 18 taken 73 times.
✓ Branch 18 → 19 taken 73 times.
|
73 | QSqlQuery q(store.database()); |
| 155 |
1/1✓ Branch 20 → 21 taken 73 times.
|
73 | q.setForwardOnly(true); |
| 156 |
2/3✓ Branch 24 → 25 taken 73 times.
✓ Branch 27 → 28 taken 73 times.
✗ Branch 27 → 146 not taken.
|
73 | if (q.exec(QStringLiteral("SELECT c.book_id, c.uid, c.display_name, c.has_photo, p.kind, p.lat, p.lon," |
| 157 | " CASE WHEN p.locality <> '' THEN p.locality WHEN p.place_name <> '' THEN p.place_name" | ||
| 158 | " ELSE p.text END, p.country, p.source, p.precision" | ||
| 159 | " FROM card_places p JOIN cards c ON c.id = p.card_id" | ||
| 160 | " JOIN address_books b ON b.id = c.book_id WHERE b.show_in_all = 1 AND c.kind <> 'group'"))) { | ||
| 161 |
3/3✓ Branch 144 → 145 taken 3566 times.
✓ Branch 145 → 29 taken 3493 times.
✓ Branch 145 → 146 taken 73 times.
|
3566 | while (q.next()) { |
| 162 |
5/5✓ Branch 29 → 30 taken 3493 times.
✓ Branch 30 → 31 taken 3493 times.
✓ Branch 31 → 32 taken 3493 times.
✓ Branch 32 → 33 taken 3493 times.
✓ Branch 33 → 34 taken 3493 times.
|
3493 | const QString key = ContactQueries::cardKey(q.value(0).toLongLong(), q.value(1).toString()); |
| 163 |
2/2✓ Branch 37 → 38 taken 3493 times.
✓ Branch 38 → 39 taken 3493 times.
|
3493 | const QString kind = q.value(4).toString(); |
| 164 |
2/2✓ Branch 41 → 42 taken 6 times.
✓ Branch 41 → 43 taken 3487 times.
|
3493 | if (!m_kinds.contains(kind)) |
| 165 | 6 | continue; | |
| 166 |
1/1✓ Branch 43 → 44 taken 3487 times.
|
3487 | withPlaceText.insert(key); |
| 167 |
12/18✓ Branch 44 → 45 taken 3487 times.
✓ Branch 45 → 46 taken 3487 times.
✓ Branch 46 → 47 taken 1881 times.
✓ Branch 46 → 50 taken 1606 times.
✓ Branch 47 → 48 taken 1881 times.
✓ Branch 48 → 49 taken 1881 times.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 1881 times.
✓ Branch 52 → 53 taken 1881 times.
✓ Branch 52 → 54 taken 1606 times.
✓ Branch 54 → 55 taken 3487 times.
✗ Branch 54 → 56 not taken.
✓ Branch 56 → 57 taken 1606 times.
✓ Branch 56 → 58 taken 1881 times.
✗ Branch 211 → 212 not taken.
✗ Branch 211 → 213 not taken.
✗ Branch 215 → 216 not taken.
✗ Branch 215 → 217 not taken.
|
3487 | if (q.value(5).isNull() || q.value(6).isNull()) |
| 168 | 1606 | continue; | |
| 169 | 1881 | Place place; | |
| 170 | 1881 | place.key = key; | |
| 171 |
2/2✓ Branch 59 → 60 taken 1881 times.
✓ Branch 60 → 61 taken 1881 times.
|
1881 | place.name = q.value(2).toString(); |
| 172 |
1/1✓ Branch 64 → 65 taken 1881 times.
|
1881 | ContactCard named; |
| 173 | 1881 | named.formattedName = place.name; | |
| 174 |
1/1✓ Branch 66 → 67 taken 1881 times.
|
1881 | place.initials = ContactIndex::initials(named); |
| 175 |
3/3✓ Branch 69 → 70 taken 1881 times.
✓ Branch 70 → 71 taken 1881 times.
✓ Branch 71 → 72 taken 1881 times.
|
1881 | place.avatarColor = ContactIndex::avatarColorIndex(q.value(1).toString()); |
| 176 |
2/2✓ Branch 74 → 75 taken 1881 times.
✓ Branch 75 → 76 taken 1881 times.
|
1881 | place.hasPhoto = q.value(3).toBool(); |
| 177 | 1881 | place.kind = kind; | |
| 178 |
2/2✓ Branch 78 → 79 taken 1881 times.
✓ Branch 79 → 80 taken 1881 times.
|
1881 | place.label = q.value(7).toString(); |
| 179 |
2/2✓ Branch 83 → 84 taken 1881 times.
✓ Branch 84 → 85 taken 1881 times.
|
1881 | place.country = q.value(8).toString(); |
| 180 |
2/2✓ Branch 88 → 89 taken 1881 times.
✓ Branch 89 → 90 taken 1881 times.
|
1881 | const QString source = q.value(9).toString(); |
| 181 | // S103.1.9: a street-level answer of the online lookup is no estimate. | ||
| 182 |
9/14✓ Branch 93 → 94 taken 4 times.
✓ Branch 93 → 100 taken 1877 times.
✓ Branch 95 → 96 taken 4 times.
✓ Branch 96 → 97 taken 4 times.
✓ Branch 98 → 99 taken 4 times.
✗ Branch 98 → 100 not taken.
✓ Branch 101 → 102 taken 4 times.
✓ Branch 101 → 103 taken 1877 times.
✓ Branch 103 → 104 taken 4 times.
✓ Branch 103 → 105 taken 1877 times.
✗ Branch 244 → 245 not taken.
✗ Branch 244 → 246 not taken.
✗ Branch 248 → 249 not taken.
✗ Branch 248 → 250 not taken.
|
1881 | const bool exactOnline = source == QLatin1String("online") && q.value(10).toString() == QLatin1String("exact"); |
| 183 |
5/6✓ Branch 107 → 108 taken 1861 times.
✓ Branch 107 → 113 taken 20 times.
✓ Branch 110 → 111 taken 1861 times.
✗ Branch 110 → 113 not taken.
✓ Branch 111 → 112 taken 1857 times.
✓ Branch 111 → 113 taken 4 times.
|
1881 | place.approximate = source != QLatin1String("pinned") && source != QLatin1String("card") && !exactOnline; |
| 184 | 1881 | place.person = int(personOf.size()); | |
| 185 |
2/2✓ Branch 118 → 119 taken 96 times.
✓ Branch 118 → 121 taken 1785 times.
|
1881 | if (const auto known = personOf.constFind(key); known != personOf.cend()) |
| 186 | 96 | place.person = *known; | |
| 187 | else | ||
| 188 |
1/1✓ Branch 121 → 122 taken 1785 times.
|
1785 | personOf.insert(key, place.person); |
| 189 |
5/5✓ Branch 122 → 123 taken 1881 times.
✓ Branch 123 → 124 taken 1881 times.
✓ Branch 124 → 125 taken 1881 times.
✓ Branch 125 → 126 taken 1881 times.
✓ Branch 126 → 127 taken 1881 times.
|
1881 | place.world = MapProjection::project(q.value(5).toDouble(), q.value(6).toDouble()); |
| 190 |
1/1✓ Branch 129 → 130 taken 1881 times.
|
1881 | m_places.append(place); |
| 191 |
1/1✓ Branch 130 → 131 taken 1881 times.
|
1881 | placed.insert(key); |
| 192 | 5105 | } | |
| 193 | } | ||
| 194 | 73 | } | |
| 195 | 73 | m_personCount = int(personOf.size()); | |
| 196 |
1/1✓ Branch 149 → 150 taken 73 times.
|
73 | m_seenAt.assign(size_t(m_personCount), -1); |
| 197 | 73 | m_placedPeople = int(placed.size()); | |
| 198 |
1/1✓ Branch 151 → 152 taken 73 times.
|
73 | m_unplacedPeople = int((withPlaceText - placed).size()); |
| 199 |
9/9✓ Branch 154 → 155 taken 73 times.
✓ Branch 158 → 159 taken 73 times.
✓ Branch 159 → 160 taken 73 times.
✓ Branch 161 → 162 taken 73 times.
✓ Branch 162 → 163 taken 73 times.
✓ Branch 163 → 164 taken 73 times.
✓ Branch 164 → 165 taken 73 times.
✓ Branch 171 → 156 taken 73 times.
✓ Branch 171 → 172 taken 73 times.
|
146 | qCInfo(lcMapTiles) << "Map places read:" << m_places.size() << "places of" << m_placedPeople << "people in" |
| 200 |
2/2✓ Branch 166 → 167 taken 73 times.
✓ Branch 167 → 168 taken 73 times.
|
73 | << timer.elapsed() << "ms"; |
| 201 |
1/1✓ Branch 172 → 173 taken 73 times.
|
73 | emit placesChanged(); |
| 202 |
9/10✓ Branch 173 → 174 taken 61 times.
✓ Branch 173 → 180 taken 12 times.
✓ Branch 174 → 175 taken 36 times.
✓ Branch 174 → 180 taken 25 times.
✓ Branch 176 → 177 taken 13 times.
✓ Branch 176 → 180 taken 23 times.
✓ Branch 178 → 179 taken 13 times.
✗ Branch 178 → 180 not taken.
✓ Branch 181 → 182 taken 13 times.
✓ Branch 181 → 183 taken 60 times.
|
73 | if (!m_fitted && !m_placing && !m_places.isEmpty() && !m_viewport.size.isEmpty()) { |
| 203 | 13 | m_fitted = true; | |
| 204 |
1/1✓ Branch 182 → 184 taken 13 times.
|
13 | fitAll(); |
| 205 | } else { | ||
| 206 |
1/1✓ Branch 183 → 184 taken 60 times.
|
60 | updateMarkers(); |
| 207 | } | ||
| 208 | 73 | } | |
| 209 | |||
| 210 | 158 | QString QuickContactMap::viewMode() const { | |
| 211 |
3/3✓ Branch 2 → 3 taken 158 times.
✓ Branch 7 → 8 taken 158 times.
✓ Branch 8 → 9 taken 158 times.
|
316 | const QString mode = QSettings().value(QStringLiteral("contacts/viewMode")).toString(); |
| 212 |
6/6✓ Branch 15 → 16 taken 120 times.
✓ Branch 15 → 19 taken 38 times.
✓ Branch 18 → 19 taken 30 times.
✓ Branch 18 → 20 taken 90 times.
✓ Branch 24 → 25 taken 90 times.
✓ Branch 24 → 26 taken 68 times.
|
564 | return mode == QLatin1String("map") || mode == QLatin1String("graph") ? mode : QStringLiteral("list"); |
| 213 | 158 | } | |
| 214 | |||
| 215 | 36 | void QuickContactMap::setViewMode(const QString &mode) { | |
| 216 |
5/7✓ Branch 2 → 3 taken 36 times.
✓ Branch 4 → 5 taken 22 times.
✓ Branch 4 → 14 taken 14 times.
✓ Branch 18 → 19 taken 15 times.
✓ Branch 18 → 20 taken 21 times.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
|
94 | if (mode == viewMode() || |
| 217 |
7/8✓ Branch 7 → 8 taken 18 times.
✓ Branch 7 → 15 taken 4 times.
✓ Branch 10 → 11 taken 9 times.
✓ Branch 10 → 15 taken 9 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 8 times.
✓ Branch 16 → 17 taken 36 times.
✗ Branch 16 → 18 not taken.
|
58 | (mode != QLatin1String("list") && mode != QLatin1String("map") && mode != QLatin1String("graph"))) |
| 218 | 15 | return; | |
| 219 |
2/2✓ Branch 20 → 21 taken 21 times.
✓ Branch 26 → 27 taken 21 times.
|
42 | QSettings().setValue(QStringLiteral("contacts/viewMode"), mode); |
| 220 |
6/6✓ Branch 31 → 32 taken 21 times.
✓ Branch 35 → 36 taken 21 times.
✓ Branch 36 → 37 taken 21 times.
✓ Branch 37 → 38 taken 21 times.
✓ Branch 41 → 33 taken 21 times.
✓ Branch 41 → 42 taken 21 times.
|
42 | qCInfo(lcMapTiles) << "Contact view:" << mode; |
| 221 | 21 | emit viewModeChanged(); | |
| 222 | } | ||
| 223 | |||
| 224 | 2 | void QuickContactMap::setPlacesList(bool on) { | |
| 225 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
|
2 | if (on == m_placesList) |
| 226 | ✗ | return; | |
| 227 | 2 | m_placesList = on; | |
| 228 | 2 | emit viewModeChanged(); | |
| 229 | } | ||
| 230 | |||
| 231 | 2 | QVariantList QuickContactMap::placesTree() const { | |
| 232 | struct City { | ||
| 233 | QList<const Place *> people; | ||
| 234 | }; | ||
| 235 | 2 | QMap<QString, QMap<QString, City>> countries; | |
| 236 |
2/2✓ Branch 20 → 4 taken 165 times.
✓ Branch 20 → 21 taken 2 times.
|
167 | for (const Place &place : m_places) { |
| 237 |
3/3✓ Branch 6 → 7 taken 119 times.
✓ Branch 6 → 8 taken 46 times.
✓ Branch 7 → 9 taken 119 times.
|
165 | const QString country = place.country.isEmpty() ? tr("Other places") : place.country; |
| 238 |
4/6✓ Branch 9 → 10 taken 165 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 165 times.
✗ Branch 12 → 14 not taken.
✓ Branch 14 → 15 taken 165 times.
✓ Branch 15 → 16 taken 165 times.
|
165 | countries[country][place.label.isEmpty() ? tr("Unnamed place") : place.label].people.append(&place); |
| 239 | 165 | } | |
| 240 | 2 | QVariantList out; | |
| 241 |
4/4✓ Branch 21 → 22 taken 2 times.
✓ Branch 129 → 130 taken 26 times.
✓ Branch 131 → 23 taken 24 times.
✓ Branch 131 → 132 taken 2 times.
|
26 | for (auto country = countries.cbegin(); country != countries.cend(); ++country) { |
| 242 | 24 | QVariantList cities; | |
| 243 | 24 | int total = 0; | |
| 244 |
4/4✓ Branch 24 → 25 taken 24 times.
✓ Branch 94 → 95 taken 94 times.
✓ Branch 96 → 26 taken 70 times.
✓ Branch 96 → 97 taken 24 times.
|
94 | for (auto city = country->cbegin(); city != country->cend(); ++city) { |
| 245 | 70 | QVariantList people; | |
| 246 |
2/2✓ Branch 58 → 29 taken 165 times.
✓ Branch 58 → 59 taken 70 times.
|
235 | for (const Place *place : city->people) |
| 247 |
1/1✓ Branch 44 → 45 taken 165 times.
|
495 | people.append(QVariantMap{{QStringLiteral("key"), place->key}, |
| 248 | 330 | {QStringLiteral("name"), place->name}, | |
| 249 |
2/4✓ Branch 48 → 49 taken 495 times.
✓ Branch 48 → 50 taken 165 times.
✗ Branch 150 → 151 not taken.
✗ Branch 150 → 152 not taken.
|
990 | {QStringLiteral("kind"), place->kind}}); |
| 250 |
3/3✓ Branch 59 → 60 taken 70 times.
✓ Branch 60 → 61 taken 70 times.
✓ Branch 61 → 62 taken 70 times.
|
70 | std::sort(people.begin(), people.end(), [](const QVariant &a, const QVariant &b) { |
| 251 |
4/4✓ Branch 2 → 3 taken 317 times.
✓ Branch 7 → 8 taken 317 times.
✓ Branch 8 → 9 taken 317 times.
✓ Branch 16 → 17 taken 317 times.
|
1268 | return a.toMap().value(QStringLiteral("name")).toString().localeAwareCompare( |
| 252 |
3/3✓ Branch 9 → 10 taken 317 times.
✓ Branch 14 → 15 taken 317 times.
✓ Branch 15 → 16 taken 317 times.
|
1268 | b.toMap().value(QStringLiteral("name")).toString()) < 0; |
| 253 | }); | ||
| 254 | 70 | total += int(people.size()); | |
| 255 |
1/1✓ Branch 79 → 80 taken 70 times.
|
210 | cities.append(QVariantMap{{QStringLiteral("city"), city.key()}, |
| 256 | 140 | {QStringLiteral("count"), int(people.size())}, | |
| 257 |
2/4✓ Branch 83 → 84 taken 210 times.
✓ Branch 83 → 85 taken 70 times.
✗ Branch 185 → 186 not taken.
✗ Branch 185 → 187 not taken.
|
350 | {QStringLiteral("people"), people}}); |
| 258 | 70 | } | |
| 259 | 157 | const auto byCount = [](const QVariant &a, const QVariant &b) { | |
| 260 |
3/3✓ Branch 2 → 3 taken 157 times.
✓ Branch 7 → 8 taken 157 times.
✓ Branch 8 → 9 taken 157 times.
|
314 | const int ca = a.toMap().value(QStringLiteral("count")).toInt(); |
| 261 |
3/3✓ Branch 14 → 15 taken 157 times.
✓ Branch 19 → 20 taken 157 times.
✓ Branch 20 → 21 taken 157 times.
|
314 | const int cb = b.toMap().value(QStringLiteral("count")).toInt(); |
| 262 |
4/4✓ Branch 26 → 27 taken 80 times.
✓ Branch 26 → 29 taken 77 times.
✓ Branch 27 → 28 taken 41 times.
✓ Branch 27 → 29 taken 39 times.
|
157 | return ca != cb ? ca > cb : false; |
| 263 | }; | ||
| 264 |
3/3✓ Branch 97 → 98 taken 24 times.
✓ Branch 98 → 99 taken 24 times.
✓ Branch 99 → 100 taken 24 times.
|
24 | std::stable_sort(cities.begin(), cities.end(), byCount); |
| 265 |
1/1✓ Branch 115 → 116 taken 24 times.
|
72 | out.append(QVariantMap{{QStringLiteral("country"), country.key()}, |
| 266 | 48 | {QStringLiteral("count"), total}, | |
| 267 |
2/4✓ Branch 119 → 120 taken 72 times.
✓ Branch 119 → 121 taken 24 times.
✗ Branch 225 → 226 not taken.
✗ Branch 225 → 227 not taken.
|
120 | {QStringLiteral("cities"), cities}}); |
| 268 | 24 | } | |
| 269 |
3/3✓ Branch 132 → 133 taken 2 times.
✓ Branch 133 → 134 taken 2 times.
✓ Branch 134 → 135 taken 2 times.
|
2 | std::stable_sort(out.begin(), out.end(), [](const QVariant &a, const QVariant &b) { |
| 270 |
6/6✓ Branch 2 → 3 taken 71 times.
✓ Branch 7 → 8 taken 71 times.
✓ Branch 8 → 9 taken 71 times.
✓ Branch 9 → 10 taken 71 times.
✓ Branch 14 → 15 taken 71 times.
✓ Branch 15 → 16 taken 71 times.
|
213 | return a.toMap().value(QStringLiteral("count")).toInt() > b.toMap().value(QStringLiteral("count")).toInt(); |
| 271 | }); | ||
| 272 | 2 | return out; | |
| 273 | 1038 | } | |
| 274 | |||
| 275 | 2 | void QuickContactMap::setKinds(const QStringList &kinds) { | |
| 276 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2 times.
|
2 | if (kinds == m_kinds) |
| 277 | ✗ | return; | |
| 278 | 2 | m_kinds = kinds; | |
| 279 | 2 | readPlaces(); | |
| 280 | } | ||
| 281 | |||
| 282 | 84 | void QuickContactMap::setSize(double width, double height) { | |
| 283 |
4/4✓ Branch 2 → 3 taken 65 times.
✓ Branch 2 → 4 taken 19 times.
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 63 times.
|
84 | if (width <= 0 || height <= 0) |
| 284 | 21 | return; | |
| 285 | 63 | MapProjection::Viewport next = m_viewport; | |
| 286 | 63 | next.size = QSizeF(width, height); | |
| 287 |
1/1✓ Branch 6 → 7 taken 63 times.
|
63 | next.zoom = qMax(next.zoom, MapProjection::minZoomFor(next.size)); |
| 288 |
1/1✓ Branch 8 → 9 taken 63 times.
|
63 | setViewport(next); |
| 289 |
6/8✓ Branch 9 → 10 taken 50 times.
✓ Branch 9 → 14 taken 13 times.
✓ Branch 10 → 11 taken 44 times.
✓ Branch 10 → 14 taken 6 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 44 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 63 times.
|
63 | if (!m_fitted && !m_placing && !m_places.isEmpty()) { |
| 290 | ✗ | m_fitted = true; | |
| 291 | ✗ | fitAll(); | |
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 |
2/2✓ Branch 3 → 4 taken 5 times.
✓ Branch 4 → 5 taken 5 times.
|
5 | void QuickContactMap::panBy(double dx, double dy) { setViewport(m_viewport.panned(QPointF(dx, dy))); } |
| 296 | |||
| 297 |
2/2✓ Branch 3 → 4 taken 21 times.
✓ Branch 4 → 5 taken 21 times.
|
21 | void QuickContactMap::zoomAt(double steps, double x, double y) { setViewport(m_viewport.zoomed(steps, QPointF(x, y))); } |
| 298 | |||
| 299 | 14 | void QuickContactMap::fitAll() { | |
| 300 | 14 | QList<QPointF> points; | |
| 301 |
2/2✓ Branch 9 → 5 taken 888 times.
✓ Branch 9 → 10 taken 14 times.
|
902 | for (const Place &place : std::as_const(m_places)) |
| 302 |
1/1✓ Branch 6 → 7 taken 888 times.
|
888 | points.append(place.world); |
| 303 |
1/1✓ Branch 10 → 11 taken 14 times.
|
14 | MapProjection::Viewport next = MapProjection::fit(points, m_viewport.size); |
| 304 |
1/1✓ Branch 11 → 12 taken 14 times.
|
14 | next.zoom = qMax(next.zoom, MapProjection::minZoomFor(next.size)); |
| 305 |
1/1✓ Branch 13 → 14 taken 14 times.
|
14 | setViewport(next); |
| 306 | 14 | } | |
| 307 | |||
| 308 | // §6.5: pan (never zoom) to the person's first place when none is in view. | ||
| 309 | 5 | void QuickContactMap::showKey(const QString &key) { | |
| 310 | 5 | QList<QPointF> points; | |
| 311 |
2/2✓ Branch 11 → 5 taken 330 times.
✓ Branch 11 → 12 taken 5 times.
|
335 | for (const Place &place : std::as_const(m_places)) |
| 312 |
2/2✓ Branch 7 → 8 taken 4 times.
✓ Branch 7 → 9 taken 326 times.
|
330 | if (place.key == key) |
| 313 |
1/1✓ Branch 8 → 9 taken 4 times.
|
4 | points.append(place.world); |
| 314 |
5/6✓ Branch 13 → 14 taken 4 times.
✓ Branch 13 → 16 taken 1 time.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 4 times.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 20 taken 4 times.
|
5 | if (points.isEmpty() || m_viewport.size.isEmpty()) |
| 315 | 1 | return; | |
| 316 | 4 | const QRectF canvas(QPointF(0, 0), m_viewport.size); | |
| 317 |
4/4✓ Branch 22 → 23 taken 4 times.
✓ Branch 23 → 24 taken 4 times.
✓ Branch 32 → 25 taken 4 times.
✓ Branch 32 → 33 taken 1 time.
|
5 | for (const QPointF &point : points) |
| 318 |
3/3✓ Branch 26 → 27 taken 4 times.
✓ Branch 28 → 29 taken 3 times.
✓ Branch 28 → 30 taken 1 time.
|
4 | if (canvas.contains(m_viewport.toScreen(point))) |
| 319 | 3 | return; | |
| 320 | 1 | MapProjection::Viewport next = m_viewport; | |
| 321 |
1/1✓ Branch 33 → 34 taken 1 time.
|
1 | next.center = points.first(); |
| 322 |
1/1✓ Branch 34 → 35 taken 1 time.
|
1 | setViewport(next); |
| 323 | 5 | } | |
| 324 | |||
| 325 | 7 | QVariantMap QuickContactMap::toLatLon(double x, double y) const { | |
| 326 |
2/2✓ Branch 3 → 4 taken 7 times.
✓ Branch 4 → 5 taken 7 times.
|
7 | const QPointF lonLat = MapProjection::unproject(m_viewport.toWorld(QPointF(x, y))); |
| 327 |
2/4✓ Branch 17 → 18 taken 14 times.
✓ Branch 17 → 19 taken 7 times.
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
|
35 | return {{QStringLiteral("latitude"), lonLat.y()}, {QStringLiteral("longitude"), lonLat.x()}}; |
| 328 | 21 | } | |
| 329 | |||
| 330 | 8 | void QuickContactMap::centerOn(double latitude, double longitude, double zoom) { | |
| 331 | 8 | MapProjection::Viewport next = m_viewport; | |
| 332 |
1/1✓ Branch 2 → 3 taken 8 times.
|
8 | next.center = MapProjection::project(latitude, longitude); |
| 333 |
1/2✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 7 not taken.
|
8 | if (zoom > 0) |
| 334 |
1/1✓ Branch 4 → 5 taken 8 times.
|
8 | next.zoom = qBound(MapProjection::minZoomFor(next.size), zoom, next.maxZoom); |
| 335 |
1/1✓ Branch 7 → 8 taken 8 times.
|
8 | setViewport(next); |
| 336 | 8 | } | |
| 337 | |||
| 338 | 2 | QVariantMap QuickContactMap::toScreen(double latitude, double longitude) const { | |
| 339 |
2/2✓ Branch 2 → 3 taken 2 times.
✓ Branch 3 → 4 taken 2 times.
|
2 | const QPointF point = m_viewport.toScreen(MapProjection::project(latitude, longitude)); |
| 340 |
2/4✓ Branch 16 → 17 taken 4 times.
✓ Branch 16 → 18 taken 2 times.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
|
10 | return {{QStringLiteral("x"), point.x()}, {QStringLiteral("y"), point.y()}}; |
| 341 | 6 | } | |
| 342 | |||
| 343 | 2 | bool QuickContactMap::showPlace(const QString &text) { | |
| 344 |
1/1✓ Branch 2 → 3 taken 2 times.
|
2 | const std::shared_ptr<const GeoData> data = GeoData::builtIn(); |
| 345 |
5/11✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 2 times.
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 12 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 2 times.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 52 not taken.
|
2 | if (!data || text.trimmed().isEmpty()) |
| 346 | ✗ | return false; | |
| 347 |
2/2✓ Branch 15 → 16 taken 2 times.
✓ Branch 17 → 18 taken 2 times.
|
2 | const PlaceGazetteer::Place place = PlaceGazetteer::locateText(*data, text.trimmed()); |
| 348 |
1/2✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 2 times.
|
2 | if (!place.isValid()) |
| 349 | ✗ | return false; | |
| 350 |
2/4✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 2 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 2 times.
|
2 | const double zoom = place.precision == QLatin1String("country") ? 4 : place.precision == QLatin1String("region") ? 6 : 9; |
| 351 |
1/1✓ Branch 33 → 34 taken 2 times.
|
2 | centerOn(place.position.latitude, place.position.longitude, zoom); |
| 352 |
6/6✓ Branch 34 → 35 taken 2 times.
✓ Branch 38 → 39 taken 2 times.
✓ Branch 39 → 40 taken 2 times.
✓ Branch 40 → 41 taken 2 times.
✓ Branch 44 → 36 taken 2 times.
✓ Branch 44 → 45 taken 2 times.
|
4 | qCInfo(lcMapTiles) << "Map shows a place of precision" << place.precision; |
| 353 | 2 | return true; | |
| 354 | 2 | } | |
| 355 | |||
| 356 | 20 | QVariantMap QuickContactMap::nearby(const QString &text) const { | |
| 357 |
1/1✓ Branch 2 → 3 taken 20 times.
|
20 | const std::shared_ptr<const GeoData> data = GeoData::builtIn(); |
| 358 |
9/13✓ Branch 4 → 5 taken 10 times.
✓ Branch 4 → 10 taken 10 times.
✓ Branch 5 → 6 taken 10 times.
✓ Branch 7 → 8 taken 10 times.
✗ Branch 7 → 10 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 10 times.
✓ Branch 12 → 13 taken 10 times.
✓ Branch 12 → 14 taken 10 times.
✓ Branch 14 → 15 taken 10 times.
✓ Branch 14 → 16 taken 10 times.
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 116 not taken.
|
20 | if (!data || text.trimmed().isEmpty() || m_databasePath.isEmpty()) |
| 359 | 10 | return {}; | |
| 360 |
2/2✓ Branch 17 → 18 taken 10 times.
✓ Branch 19 → 20 taken 10 times.
|
10 | const PlaceGazetteer::Place place = PlaceGazetteer::locateText(*data, text.trimmed()); |
| 361 |
6/6✓ Branch 23 → 24 taken 9 times.
✓ Branch 23 → 27 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
✓ Branch 26 → 28 taken 8 times.
✓ Branch 29 → 30 taken 2 times.
✓ Branch 29 → 31 taken 8 times.
|
10 | if (!place.isValid() || place.precision == QLatin1String("country")) |
| 362 | 2 | return {}; | |
| 363 |
1/1✓ Branch 31 → 32 taken 8 times.
|
8 | ContactStore store; |
| 364 |
2/3✓ Branch 32 → 33 taken 8 times.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 8 times.
|
8 | if (!store.open(m_databasePath)) |
| 365 | ✗ | return {}; | |
| 366 | // About 50 km: the box of the contact search's near: (ContactPeopleFilter). | ||
| 367 | 8 | const double lat = place.position.latitude, lon = place.position.longitude; | |
| 368 | 8 | const double dLon = 0.45 / qMax(0.1, std::cos(lat * M_PI / 180.0)); | |
| 369 |
2/2✓ Branch 36 → 37 taken 8 times.
✓ Branch 37 → 38 taken 8 times.
|
8 | QSqlQuery q(store.database()); |
| 370 |
1/1✓ Branch 42 → 43 taken 8 times.
|
8 | q.prepare(QStringLiteral("SELECT DISTINCT c.book_id, c.uid FROM card_places p JOIN cards c ON c.id = p.card_id" |
| 371 | " JOIN address_books b ON b.id = c.book_id WHERE b.show_in_all = 1 AND c.kind <> 'group'" | ||
| 372 | " AND p.precision <> 'country' AND p.lat BETWEEN ? AND ? AND p.lon BETWEEN ? AND ?")); | ||
| 373 |
1/1✓ Branch 47 → 48 taken 8 times.
|
8 | q.addBindValue(lat - 0.45); |
| 374 |
1/1✓ Branch 51 → 52 taken 8 times.
|
8 | q.addBindValue(lat + 0.45); |
| 375 |
1/1✓ Branch 55 → 56 taken 8 times.
|
8 | q.addBindValue(lon - dLon); |
| 376 |
1/1✓ Branch 59 → 60 taken 8 times.
|
8 | q.addBindValue(lon + dLon); |
| 377 |
3/3✓ Branch 61 → 62 taken 8 times.
✓ Branch 66 → 67 taken 8 times.
✓ Branch 67 → 68 taken 8 times.
|
16 | const QString me = QSettings().value(QStringLiteral("contacts/meCard")).toString(); |
| 378 | 8 | int count = 0; | |
| 379 |
2/3✓ Branch 72 → 73 taken 8 times.
✓ Branch 73 → 74 taken 8 times.
✗ Branch 73 → 91 not taken.
|
8 | if (q.exec()) |
| 380 |
3/3✓ Branch 89 → 90 taken 33 times.
✓ Branch 90 → 75 taken 25 times.
✓ Branch 90 → 91 taken 8 times.
|
33 | while (q.next()) |
| 381 |
6/7✓ Branch 75 → 76 taken 25 times.
✓ Branch 76 → 77 taken 25 times.
✓ Branch 77 → 78 taken 25 times.
✓ Branch 78 → 79 taken 25 times.
✓ Branch 79 → 80 taken 25 times.
✓ Branch 81 → 82 taken 25 times.
✗ Branch 81 → 83 not taken.
|
25 | count += ContactQueries::cardKey(q.value(0).toLongLong(), q.value(1).toString()) != me ? 1 : 0; |
| 382 |
2/4✓ Branch 101 → 102 taken 16 times.
✓ Branch 101 → 103 taken 8 times.
✗ Branch 173 → 174 not taken.
✗ Branch 173 → 175 not taken.
|
40 | return {{QStringLiteral("place"), place.placeName}, {QStringLiteral("count"), count}}; |
| 383 | 44 | } | |
| 384 | |||
| 385 | 112 | void QuickContactMap::setViewport(const MapProjection::Viewport &requested) { | |
| 386 | 112 | MapProjection::Viewport viewport = requested; // fit() knows nothing of the online tiles | |
| 387 |
3/3✓ Branch 2 → 3 taken 11 times.
✓ Branch 2 → 5 taken 101 times.
✓ Branch 3 → 4 taken 11 times.
|
112 | viewport.maxZoom = m_onlineTiles ? onlineMaxZoom() : MapProjection::MaxZoom; |
| 388 |
5/6✓ Branch 7 → 8 taken 18 times.
✓ Branch 7 → 11 taken 94 times.
✓ Branch 9 → 10 taken 18 times.
✗ Branch 9 → 11 not taken.
✓ Branch 12 → 13 taken 18 times.
✓ Branch 12 → 14 taken 94 times.
|
112 | if (viewport == m_viewport && !m_tiles.isEmpty()) |
| 389 | 18 | return; | |
| 390 | 94 | m_viewport = viewport; | |
| 391 |
1/1✓ Branch 14 → 15 taken 94 times.
|
94 | updateTiles(); |
| 392 |
1/1✓ Branch 15 → 16 taken 94 times.
|
94 | updateMarkers(); |
| 393 |
1/1✓ Branch 16 → 17 taken 94 times.
|
94 | emit viewportChanged(); |
| 394 | } | ||
| 395 | |||
| 396 | 31 | void QuickContactMap::rebuildClusterInput() { | |
| 397 | 31 | m_clusterInput.clear(); | |
| 398 | 31 | m_clusterInput.reserve(m_places.size()); | |
| 399 |
2/2✓ Branch 12 → 6 taken 1881 times.
✓ Branch 12 → 13 taken 31 times.
|
1912 | for (int i = 0; i < m_places.size(); ++i) |
| 400 | 1881 | m_clusterInput.append({QString::number(i), m_places.at(i).world}); | |
| 401 | 31 | m_clusterZoom = -1; | |
| 402 | 1912 | } | |
| 403 | |||
| 404 | // The people of a cluster, computed when it first becomes visible at a zoom. | ||
| 405 | 296 | const QStringList &QuickContactMap::clusterKeys(int cluster) { | |
| 406 |
1/1✓ Branch 2 → 3 taken 296 times.
|
296 | auto found = m_clusterKeys.find(cluster); |
| 407 |
2/2✓ Branch 5 → 6 taken 103 times.
✓ Branch 5 → 7 taken 193 times.
|
296 | if (found != m_clusterKeys.end()) |
| 408 | 103 | return *found; | |
| 409 | 193 | QStringList keys; | |
| 410 |
2/2✓ Branch 19 → 10 taken 1587 times.
✓ Branch 19 → 20 taken 193 times.
|
1780 | for (const QString &member : m_clusters.at(cluster).members) { |
| 411 |
1/1✓ Branch 11 → 12 taken 1587 times.
|
1587 | const Place &place = m_places.at(member.toInt()); |
| 412 |
2/2✓ Branch 14 → 15 taken 1538 times.
✓ Branch 14 → 17 taken 49 times.
|
1587 | if (m_seenAt[size_t(place.person)] != cluster) { |
| 413 | 1538 | m_seenAt[size_t(place.person)] = cluster; | |
| 414 |
1/1✓ Branch 16 → 17 taken 1538 times.
|
1538 | keys.append(place.key); |
| 415 | } | ||
| 416 | } | ||
| 417 |
1/1✓ Branch 20 → 21 taken 193 times.
|
193 | return *m_clusterKeys.insert(cluster, keys); |
| 418 | 193 | } | |
| 419 | |||
| 420 | 195 | void QuickContactMap::updateMarkers() { | |
| 421 | 195 | QElapsedTimer timer; | |
| 422 | 195 | timer.start(); | |
| 423 |
2/2✓ Branch 5 → 6 taken 31 times.
✓ Branch 5 → 7 taken 164 times.
|
195 | if (m_clusterInput.size() != m_places.size()) |
| 424 |
1/1✓ Branch 6 → 7 taken 31 times.
|
31 | rebuildClusterInput(); |
| 425 | // F103-14: clusters are made per whole zoom level; between levels the | ||
| 426 | // same clusters only move (each fractional step re-formed them, so the | ||
| 427 | // bubbles jumped while zooming). 88 px cells at the level are 62–124 px | ||
| 428 | // on screen, still apart for markers up to 44 px. | ||
| 429 | 195 | const double level = std::round(m_viewport.zoom); | |
| 430 |
2/2✓ Branch 7 → 8 taken 112 times.
✓ Branch 7 → 16 taken 83 times.
|
195 | if (level != m_clusterZoom) { |
| 431 |
1/1✓ Branch 8 → 9 taken 112 times.
|
112 | m_clusters = MapClusterer::cluster(m_clusterInput, level, 88.0); |
| 432 | 112 | m_clusterZoom = level; | |
| 433 | 112 | m_clusterKeys.clear(); | |
| 434 |
1/1✓ Branch 14 → 15 taken 112 times.
|
112 | std::fill(m_seenAt.begin(), m_seenAt.end(), -1); |
| 435 | } | ||
| 436 | 195 | QVariantList markers; | |
| 437 |
1/1✓ Branch 16 → 17 taken 195 times.
|
195 | const double worldPixels = m_viewport.worldPixels(); |
| 438 |
2/2✓ Branch 174 → 18 taken 664 times.
✓ Branch 174 → 175 taken 195 times.
|
859 | for (int c = 0; c < m_clusters.size(); ++c) { |
| 439 | 664 | const MapClusterer::Cluster &cluster = m_clusters.at(c); | |
| 440 |
1/1✓ Branch 19 → 20 taken 664 times.
|
664 | QPointF point = m_viewport.toScreen(cluster.world); |
| 441 | // The world repeats east–west: take the copy inside the canvas. | ||
| 442 |
5/6✓ Branch 24 → 25 taken 37 times.
✓ Branch 24 → 27 taken 664 times.
✓ Branch 25 → 26 taken 37 times.
✗ Branch 25 → 27 not taken.
✓ Branch 28 → 21 taken 37 times.
✓ Branch 28 → 29 taken 664 times.
|
701 | while (point.x() < -32 && worldPixels > 0) |
| 443 | 37 | point.rx() += worldPixels; | |
| 444 |
5/6✓ Branch 34 → 35 taken 344 times.
✓ Branch 34 → 37 taken 664 times.
✓ Branch 35 → 36 taken 344 times.
✗ Branch 35 → 37 not taken.
✓ Branch 38 → 30 taken 344 times.
✓ Branch 38 → 39 taken 664 times.
|
1008 | while (point.x() > m_viewport.size.width() + 32 && worldPixels > 0) |
| 445 | 344 | point.rx() -= worldPixels; | |
| 446 |
7/8✓ Branch 40 → 41 taken 320 times.
✓ Branch 40 → 49 taken 344 times.
✓ Branch 42 → 43 taken 306 times.
✓ Branch 42 → 49 taken 14 times.
✓ Branch 45 → 46 taken 306 times.
✗ Branch 45 → 49 not taken.
✓ Branch 51 → 52 taken 368 times.
✓ Branch 51 → 53 taken 296 times.
|
970 | if (point.x() < -32 || point.y() < -32 || point.x() > m_viewport.size.width() + 32 || |
| 447 |
2/2✓ Branch 48 → 49 taken 10 times.
✓ Branch 48 → 50 taken 296 times.
|
306 | point.y() > m_viewport.size.height() + 32) |
| 448 | 368 | continue; | |
| 449 |
1/2✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 296 times.
|
296 | if (cluster.members.isEmpty()) |
| 450 | ✗ | continue; | |
| 451 |
1/1✓ Branch 56 → 57 taken 296 times.
|
296 | const QStringList &keys = clusterKeys(c); |
| 452 |
1/1✓ Branch 58 → 59 taken 296 times.
|
296 | const Place *first = &m_places.at(cluster.members.first().toInt()); |
| 453 | 592 | QVariantMap marker{{QStringLiteral("id"), cluster.id}, | |
| 454 | 592 | {QStringLiteral("x"), point.x()}, | |
| 455 | 592 | {QStringLiteral("y"), point.y()}, | |
| 456 | 592 | {QStringLiteral("count"), int(keys.size())}, | |
| 457 | 592 | {QStringLiteral("keys"), keys}, | |
| 458 | 592 | {QStringLiteral("sameSpot"), cluster.sameSpot}, | |
| 459 |
2/4✓ Branch 93 → 94 taken 2072 times.
✓ Branch 93 → 95 taken 296 times.
✗ Branch 202 → 203 not taken.
✗ Branch 202 → 204 not taken.
|
2664 | {QStringLiteral("place"), first->label}}; |
| 460 |
2/2✓ Branch 110 → 111 taken 148 times.
✓ Branch 110 → 166 taken 148 times.
|
296 | if (keys.size() == 1) |
| 461 |
3/5✓ Branch 144 → 145 taken 148 times.
✓ Branch 147 → 148 taken 1184 times.
✓ Branch 147 → 149 taken 148 times.
✗ Branch 259 → 260 not taken.
✗ Branch 259 → 261 not taken.
|
1628 | marker.insert({{QStringLiteral("key"), first->key}, |
| 462 | 296 | {QStringLiteral("name"), first->name}, | |
| 463 | 296 | {QStringLiteral("initials"), first->initials}, | |
| 464 | 296 | {QStringLiteral("avatarColor"), first->avatarColor}, | |
| 465 | 296 | {QStringLiteral("hasPhoto"), first->hasPhoto}, | |
| 466 | 296 | {QStringLiteral("kind"), first->kind}, | |
| 467 | 296 | {QStringLiteral("country"), first->country}, | |
| 468 | 296 | {QStringLiteral("approximate"), first->approximate}}); | |
| 469 |
1/1✓ Branch 167 → 168 taken 296 times.
|
296 | markers.append(marker); |
| 470 | 296 | } | |
| 471 | 195 | m_markers = markers; | |
| 472 |
1/1✓ Branch 176 → 177 taken 195 times.
|
195 | m_markerModel->setMarkers(markers); |
| 473 |
9/9✓ Branch 177 → 178 taken 195 times.
✓ Branch 181 → 182 taken 195 times.
✓ Branch 182 → 183 taken 195 times.
✓ Branch 184 → 185 taken 195 times.
✓ Branch 185 → 186 taken 195 times.
✓ Branch 187 → 188 taken 195 times.
✓ Branch 188 → 189 taken 195 times.
✓ Branch 195 → 179 taken 195 times.
✓ Branch 195 → 196 taken 195 times.
|
390 | qCDebug(lcMapTiles) << "Markers:" << markers.size() << "from" << m_places.size() << "places in" |
| 474 |
2/2✓ Branch 190 → 191 taken 195 times.
✓ Branch 191 → 192 taken 195 times.
|
195 | << timer.nsecsElapsed() / 1000 << "µs"; |
| 475 |
1/1✓ Branch 196 → 197 taken 195 times.
|
195 | emit markersChanged(); |
| 476 | 3895 | } | |
| 477 |