File indexing completed on 2025-01-05 03:58:36
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-12-01 0007 * Description : world map widget library - Appearance management 0008 * 0009 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2009-2011 by Michael G. Hansen <mike at mghansen dot de> 0011 * SPDX-FileCopyrightText: 2014 by Justus Schwartz <justus at gmx dot li> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "mapwidget_p.h" 0018 0019 namespace Digikam 0020 { 0021 0022 void MapWidget::stopThumbnailTimer() 0023 { 0024 d->currentBackend->updateMarkers(); 0025 d->thumbnailTimerCount++; 0026 0027 if (d->thumbnailTimerCount == 10) 0028 { 0029 d->thumbnailTimer->stop(); 0030 d->thumbnailsHaveBeenLoaded = true; 0031 } 0032 } 0033 0034 void MapWidget::slotZoomIn() 0035 { 0036 if (!currentBackendReady()) 0037 { 0038 return; 0039 } 0040 0041 d->currentBackend->zoomIn(); 0042 } 0043 0044 void MapWidget::slotZoomOut() 0045 { 0046 if (!currentBackendReady()) 0047 { 0048 return; 0049 } 0050 0051 d->currentBackend->zoomOut(); 0052 } 0053 0054 void MapWidget::getColorInfos(const int clusterIndex, 0055 QColor* fillColor, 0056 QColor* strokeColor, 0057 Qt::PenStyle* strokeStyle, 0058 QString* labelText, 0059 QColor* labelColor, 0060 const GeoGroupState* const overrideSelection, 0061 const int* const overrideCount) const 0062 { 0063 /// @todo Call the new getColorInfos function! 0064 0065 const GeoIfaceCluster& cluster = s->clusterList.at(clusterIndex); 0066 0067 /// @todo Check that this number is already valid! 0068 0069 const int nMarkers = overrideCount ? *overrideCount : cluster.markerCount; 0070 0071 getColorInfos(overrideSelection ? *overrideSelection : cluster.groupState, 0072 nMarkers, 0073 fillColor, strokeColor, strokeStyle, labelText, labelColor); 0074 } 0075 0076 void MapWidget::getColorInfos(const GeoGroupState groupState, 0077 const int nMarkers, 0078 QColor* fillColor, QColor* strokeColor, 0079 Qt::PenStyle* strokeStyle, QString* labelText, 0080 QColor* labelColor) const 0081 { 0082 if (nMarkers < 1000) 0083 { 0084 *labelText = QString::number(nMarkers); 0085 } 0086 else if ((nMarkers >= 1000) && (nMarkers <= 1950)) // cppcheck-suppress knownConditionTrueFalse 0087 { 0088 *labelText = QString::fromLatin1("%L1k").arg(qreal(nMarkers)/1000.0, 0, 'f', 1); 0089 } 0090 else if ((nMarkers >= 1951) && (nMarkers < 19500)) // cppcheck-suppress knownConditionTrueFalse 0091 { 0092 *labelText = QString::fromLatin1("%L1k").arg(qreal(nMarkers)/1000.0, 0, 'f', 0); 0093 } 0094 else 0095 { 0096 // convert to "1E5" notation for numbers >=20k: 0097 0098 qreal exponent = floor(log((qreal)nMarkers)/log((qreal)10)); 0099 qreal nMarkersFirstDigit = round(qreal(nMarkers)/pow(10, exponent)); 0100 0101 if (nMarkersFirstDigit >= 10) 0102 { 0103 nMarkersFirstDigit=round(nMarkersFirstDigit/10.0); 0104 exponent++; 0105 } 0106 0107 *labelText = QString::fromLatin1("%1E%2").arg(int(nMarkersFirstDigit)).arg(int(exponent)); 0108 } 0109 0110 *labelColor = QColor(Qt::black); 0111 *strokeStyle = Qt::NoPen; 0112 0113 /// @todo On my system, digikam uses QColor(67, 172, 232) as the selection color. Or should we just use blue? 0114 0115 switch (groupState & SelectedMask) 0116 { 0117 case SelectedNone: 0118 { 0119 *strokeStyle = Qt::SolidLine; 0120 *strokeColor = QColor(Qt::black); 0121 break; 0122 } 0123 0124 case SelectedSome: 0125 { 0126 *strokeStyle = Qt::DotLine; 0127 *strokeColor = QColor(Qt::blue); // 67, 172, 232); 0128 break; 0129 } 0130 0131 case SelectedAll: 0132 { 0133 *strokeStyle = Qt::SolidLine; 0134 *strokeColor = QColor(Qt::blue); // 67, 172, 232); 0135 break; 0136 } 0137 } 0138 0139 /** 0140 * @todo These are the fill colors for the circles, for cases in which only some or all of the images 0141 * are positively filtered. Filtering is implemented in GeoIface, but the code here has not been adapted yet. 0142 */ 0143 QColor fillAll, fillSome, fillNone; 0144 0145 if (nMarkers >= 100) 0146 { 0147 fillAll = QColor(255, 0, 0); 0148 fillSome = QColor(255, 188, 125); 0149 fillNone = QColor(255, 185, 185); 0150 } 0151 else if (nMarkers >= 50) 0152 { 0153 fillAll = QColor(255, 127, 0); 0154 fillSome = QColor(255, 190, 125); 0155 fillNone = QColor(255, 220, 185); 0156 } 0157 else if (nMarkers >= 10) 0158 { 0159 fillAll = QColor(255, 255, 0); 0160 fillSome = QColor(255, 255, 105); 0161 fillNone = QColor(255, 255, 185); 0162 } 0163 else if (nMarkers >= 2) 0164 { 0165 fillAll = QColor(0, 255, 0); 0166 fillSome = QColor(125, 255, 125); 0167 fillNone = QColor(185, 255, 255); 0168 } 0169 else 0170 { 0171 fillAll = QColor(0, 255, 255); 0172 fillSome = QColor(125, 255, 255); 0173 fillNone = QColor(185, 255, 255); 0174 } 0175 0176 *fillColor = fillAll; 0177 /* 0178 switch (groupState) 0179 { 0180 case PartialAll: 0181 { 0182 *fillColor = fillAll; 0183 break; 0184 } 0185 0186 case PartialSome: 0187 { 0188 *fillColor = fillSome; 0189 break; 0190 } 0191 0192 case PartialNone: 0193 { 0194 if (haveAnySolo) 0195 { 0196 *fillColor = fillNone; 0197 } 0198 else 0199 { 0200 *fillColor = fillAll; 0201 } 0202 0203 break; 0204 } 0205 } 0206 */ 0207 } 0208 0209 QString MapWidget::convertZoomToBackendZoom(const QString& someZoom, 0210 const QString& targetBackend) const 0211 { 0212 const QStringList zoomParts = someZoom.split(QLatin1Char(':')); 0213 GEOIFACE_ASSERT(zoomParts.count() == 2); 0214 const QString sourceBackend = zoomParts.first(); 0215 0216 if (sourceBackend == targetBackend) 0217 { 0218 return someZoom; 0219 } 0220 0221 const int sourceZoom = zoomParts.last().toInt(); 0222 int targetZoom = -1; 0223 0224 #ifdef HAVE_GEOLOCATION 0225 0226 // all of these values were found experimentally! 0227 0228 if (targetBackend == QLatin1String("marble" )) 0229 { 0230 if (sourceZoom == 0) { targetZoom = 900; } 0231 else if (sourceZoom == 1) { targetZoom = 970; } 0232 else if (sourceZoom == 2) { targetZoom = 1108; } 0233 else if (sourceZoom == 3) { targetZoom = 1250; } 0234 else if (sourceZoom == 4) { targetZoom = 1384; } 0235 else if (sourceZoom == 5) { targetZoom = 1520; } 0236 else if (sourceZoom == 6) { targetZoom = 1665; } 0237 else if (sourceZoom == 7) { targetZoom = 1800; } 0238 else if (sourceZoom == 8) { targetZoom = 1940; } 0239 else if (sourceZoom == 9) { targetZoom = 2070; } 0240 else if (sourceZoom ==10) { targetZoom = 2220; } 0241 else if (sourceZoom ==11) { targetZoom = 2357; } 0242 else if (sourceZoom ==12) { targetZoom = 2510; } 0243 else if (sourceZoom ==13) { targetZoom = 2635; } 0244 else if (sourceZoom ==14) { targetZoom = 2775; } 0245 else if (sourceZoom ==15) { targetZoom = 2900; } 0246 else if (sourceZoom ==16) { targetZoom = 3051; } 0247 else if (sourceZoom ==17) { targetZoom = 3180; } 0248 else if (sourceZoom ==18) { targetZoom = 3295; } 0249 else if (sourceZoom ==19) { targetZoom = 3450; } 0250 else { targetZoom = 3500; } /// @todo Find values for level 20 and up 0251 } 0252 0253 #endif 0254 0255 if (targetBackend == QLatin1String("googlemaps" )) 0256 { 0257 if (sourceZoom <= 900) { targetZoom = 0; } 0258 else if (sourceZoom <= 970) { targetZoom = 1; } 0259 else if (sourceZoom <=1108) { targetZoom = 2; } 0260 else if (sourceZoom <=1250) { targetZoom = 3; } 0261 else if (sourceZoom <=1384) { targetZoom = 4; } 0262 else if (sourceZoom <=1520) { targetZoom = 5; } 0263 else if (sourceZoom <=1665) { targetZoom = 6; } 0264 else if (sourceZoom <=1800) { targetZoom = 7; } 0265 else if (sourceZoom <=1940) { targetZoom = 8; } 0266 else if (sourceZoom <=2070) { targetZoom = 9; } 0267 else if (sourceZoom <=2220) { targetZoom = 10; } 0268 else if (sourceZoom <=2357) { targetZoom = 11; } 0269 else if (sourceZoom <=2510) { targetZoom = 12; } 0270 else if (sourceZoom <=2635) { targetZoom = 13; } 0271 else if (sourceZoom <=2775) { targetZoom = 14; } 0272 else if (sourceZoom <=2900) { targetZoom = 15; } 0273 else if (sourceZoom <=3051) { targetZoom = 16; } 0274 else if (sourceZoom <=3180) { targetZoom = 17; } 0275 else if (sourceZoom <=3295) { targetZoom = 18; } 0276 else if (sourceZoom <=3450) { targetZoom = 19; } 0277 else { targetZoom = 20; } /// @todo Find values for level 20 and up 0278 } 0279 0280 GEOIFACE_ASSERT(targetZoom >= 0); 0281 0282 return QString::fromLatin1("%1:%2").arg(targetBackend).arg(targetZoom); 0283 } 0284 0285 0286 void MapWidget::setShowThumbnails(const bool state) 0287 { 0288 s->showThumbnails = state; 0289 0290 rebuildConfigurationMenu(); 0291 slotUpdateActionsEnabled(); 0292 slotRequestLazyReclustering(); 0293 } 0294 0295 void MapWidget::slotShowThumbnailsChanged() 0296 { 0297 setShowThumbnails(d->actionShowThumbnails->isChecked()); 0298 } 0299 0300 void MapWidget::setSortKey(const int sortKey) 0301 { 0302 s->sortKey = sortKey; 0303 0304 // this is probably faster than writing a function that changes all the clusters icons... 0305 /// @todo We just need to update the display, no need to recluster? 0306 0307 slotRequestLazyReclustering(); 0308 } 0309 0310 void MapWidget::setThumnailSize(const int newThumbnailSize) 0311 { 0312 s->thumbnailSize = qMax(GeoIfaceMinThumbnailSize, newThumbnailSize); 0313 0314 // make sure the grouping radius is larger than the thumbnail size 0315 0316 if (2 * s->thumbnailGroupingRadius < newThumbnailSize) 0317 { 0318 /// @todo more straightforward way for this? 0319 0320 s->thumbnailGroupingRadius = newThumbnailSize / 2 + newThumbnailSize % 2; 0321 } 0322 0323 if (s->showThumbnails) 0324 { 0325 slotRequestLazyReclustering(); 0326 } 0327 0328 slotUpdateActionsEnabled(); 0329 } 0330 0331 void MapWidget::setThumbnailGroupingRadius(const int newGroupingRadius) 0332 { 0333 s->thumbnailGroupingRadius = qMax(GeoIfaceMinThumbnailGroupingRadius, newGroupingRadius); 0334 0335 // make sure the thumbnails are smaller than the grouping radius 0336 0337 if (2*s->thumbnailGroupingRadius < s->thumbnailSize) 0338 { 0339 s->thumbnailSize = 2 * newGroupingRadius; 0340 } 0341 0342 if (s->showThumbnails) 0343 { 0344 slotRequestLazyReclustering(); 0345 } 0346 0347 slotUpdateActionsEnabled(); 0348 } 0349 0350 void MapWidget::setMarkerGroupingRadius(const int newGroupingRadius) 0351 { 0352 s->markerGroupingRadius = qMax(GeoIfaceMinMarkerGroupingRadius, newGroupingRadius); 0353 0354 if (!s->showThumbnails) 0355 { 0356 slotRequestLazyReclustering(); 0357 } 0358 0359 slotUpdateActionsEnabled(); 0360 } 0361 0362 void MapWidget::slotDecreaseThumbnailSize() 0363 { 0364 if (!s->showThumbnails) 0365 { 0366 return; 0367 } 0368 0369 if (s->thumbnailSize > GeoIfaceMinThumbnailSize) 0370 { 0371 const int newThumbnailSize = qMax(GeoIfaceMinThumbnailSize, s->thumbnailSize-5); 0372 0373 // make sure the grouping radius is also decreased 0374 // this will automatically decrease the thumbnail size as well 0375 0376 setThumbnailGroupingRadius(newThumbnailSize / 2); 0377 } 0378 } 0379 0380 void MapWidget::slotIncreaseThumbnailSize() 0381 { 0382 if (!s->showThumbnails) 0383 { 0384 return; 0385 } 0386 0387 setThumnailSize(s->thumbnailSize+5); 0388 } 0389 0390 int MapWidget::getThumbnailSize() const 0391 { 0392 return s->thumbnailSize; 0393 } 0394 0395 int MapWidget::getUndecoratedThumbnailSize() const 0396 { 0397 return s->thumbnailSize-2; 0398 } 0399 0400 } // namespace Digikam