1 #include <QApplication>
9 #include <QPrintDialog>
11 #include <QPaintEngine>
12 #include <QPaintDevice>
17 #include <QActionGroup>
24 #include <QPixmapCache>
29 #include <QGeoPositionInfoSource>
30 #include "common/config.h"
31 #include "common/programpaths.h"
32 #include "common/downloader.h"
33 #include "data/data.h"
35 #include "data/demloader.h"
36 #include "map/maplist.h"
37 #include "map/emptymap.h"
42 #include "elevationgraph.h"
43 #include "speedgraph.h"
44 #include "heartrategraph.h"
45 #include "temperaturegraph.h"
46 #include "cadencegraph.h"
47 #include "powergraph.h"
48 #include "gearratiograph.h"
50 #include "trackinfo.h"
51 #include "filebrowser.h"
53 #include "graphitem.h"
56 #include "mapaction.h"
57 #include "poiaction.h"
58 #include "navigationwidget.h"
62 #define TOOLBAR_ICON_SIZE 22
67 QStringList disabledPOIs
;
70 _dem
= new DEMLoader(ProgramPaths::demDir(true), this);
71 connect(_dem
, &DEMLoader::finished
, this, &GUI::demLoaded
);
82 #endif // Q_OS_ANDROID
85 _splitter
= new QSplitter();
86 _splitter
->setOrientation(Qt::Vertical
);
87 _splitter
->setChildrenCollapsible(false);
88 _splitter
->addWidget(_mapView
);
89 _splitter
->addWidget(_graphTabWidget
);
90 _splitter
->setContentsMargins(0, 0, 0, 0);
91 _splitter
->setStretchFactor(0, 255);
92 _splitter
->setStretchFactor(1, 1);
94 setCentralWidget(_splitter
);
96 setWindowIcon(QIcon(APP_ICON
));
97 setWindowTitle(APP_NAME
);
98 setUnifiedTitleAndToolBarOnMac(true);
111 readSettings(activeMap
, disabledPOIs
);
113 loadInitialMaps(activeMap
);
114 loadInitialPOIs(disabledPOIs
);
117 updateStatusBarInfo();
120 void GUI::createBrowser()
122 _browser
= new FileBrowser(this);
123 _browser
->setFilter(Data::filter());
124 connect(_browser
, &FileBrowser::listChanged
, this,
125 &GUI::updateNavigationActions
);
128 TreeNode
<MapAction
*> GUI::createMapActionsNode(const TreeNode
<Map
*> &node
)
130 TreeNode
<MapAction
*> tree(node
.name());
132 for (int i
= 0; i
< node
.childs().size(); i
++)
133 tree
.addChild(createMapActionsNode(node
.childs().at(i
)));
135 for (int i
= 0; i
< node
.items().size(); i
++) {
136 Map
*map
= node
.items().at(i
);
137 if (map
->isValid()) {
138 MapAction
*a
= new MapAction(map
, _mapsActionGroup
);
139 connect(a
, &MapAction::loaded
, this, &GUI::mapInitialized
);
148 void GUI::mapInitialized()
150 MapAction
*action
= static_cast<MapAction
*>(QObject::sender());
151 Map
*map
= action
->data().value
<Map
*>();
153 if (map
->isValid()) {
154 if (!_mapsActionGroup
->checkedAction())
156 _showMapAction
->setEnabled(true);
157 _clearMapCacheAction
->setEnabled(true);
159 qWarning("%s: %s", qPrintable(map
->path()), qPrintable(map
->errorString()));
160 action
->deleteLater();
164 TreeNode
<POIAction
*> GUI::createPOIActionsNode(const TreeNode
<QString
> &node
)
166 TreeNode
<POIAction
*> tree(node
.name());
168 for (int i
= 0; i
< node
.childs().size(); i
++)
169 tree
.addChild(createPOIActionsNode(node
.childs().at(i
)));
170 for (int i
= 0; i
< node
.items().size(); i
++)
171 tree
.addItem(new POIAction(node
.items().at(i
), _poisActionGroup
));
176 void GUI::createActions()
181 _fileActionGroup
= new QActionGroup(this);
182 _fileActionGroup
->setExclusive(false);
183 _fileActionGroup
->setEnabled(false);
185 _navigationActionGroup
= new QActionGroup(this);
186 _navigationActionGroup
->setEnabled(false);
189 #if !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID)
190 _exitAction
= new QAction(QIcon(QUIT_ICON
), tr("Quit"), this);
191 _exitAction
->setShortcut(QUIT_SHORTCUT
);
192 _exitAction
->setMenuRole(QAction::QuitRole
);
193 connect(_exitAction
, &QAction::triggered
, this, &GUI::close
);
194 addAction(_exitAction
);
195 #endif // Q_OS_MAC + Q_OS_ANDROID
198 _pathsAction
= new QAction(tr("Paths"), this);
199 _pathsAction
->setMenuRole(QAction::NoRole
);
200 connect(_pathsAction
, &QAction::triggered
, this, &GUI::paths
);
202 _keysAction
= new QAction(tr("Keyboard controls"), this);
203 _keysAction
->setMenuRole(QAction::NoRole
);
204 connect(_keysAction
, &QAction::triggered
, this, &GUI::keys
);
205 #endif // Q_OS_ANDROID
206 _aboutAction
= new QAction(QIcon(APP_ICON
), tr("About GPXSee"), this);
207 _aboutAction
->setMenuRole(QAction::AboutRole
);
208 connect(_aboutAction
, &QAction::triggered
, this, &GUI::about
);
211 _openFileAction
= new QAction(QIcon(OPEN_FILE_ICON
), tr("Open..."), this);
212 _openFileAction
->setMenuRole(QAction::NoRole
);
213 _openFileAction
->setShortcut(OPEN_SHORTCUT
);
214 connect(_openFileAction
, &QAction::triggered
, this,
215 QOverload
<>::of(&GUI::openFile
));
216 addAction(_openFileAction
);
218 _openDirAction
= new QAction(QIcon(OPEN_FILE_ICON
), tr("Open directory..."),
220 _openDirAction
->setMenuRole(QAction::NoRole
);
221 connect(_openDirAction
, &QAction::triggered
, this, &GUI::openDir
);
222 #endif // Q_OS_ANDROID
223 _printFileAction
= new QAction(QIcon(PRINT_FILE_ICON
), tr("Print..."),
225 _printFileAction
->setMenuRole(QAction::NoRole
);
226 _printFileAction
->setActionGroup(_fileActionGroup
);
227 connect(_printFileAction
, &QAction::triggered
, this, &GUI::printFile
);
228 addAction(_printFileAction
);
229 _exportPDFFileAction
= new QAction(QIcon(EXPORT_FILE_ICON
),
230 tr("Export to PDF..."), this);
231 _exportPDFFileAction
->setMenuRole(QAction::NoRole
);
232 _exportPDFFileAction
->setShortcut(PDF_EXPORT_SHORTCUT
);
233 _exportPDFFileAction
->setActionGroup(_fileActionGroup
);
234 connect(_exportPDFFileAction
, &QAction::triggered
, this, &GUI::exportPDFFile
);
235 addAction(_exportPDFFileAction
);
236 _exportPNGFileAction
= new QAction(QIcon(EXPORT_FILE_ICON
),
237 tr("Export to PNG..."), this);
238 _exportPNGFileAction
->setMenuRole(QAction::NoRole
);
239 _exportPNGFileAction
->setShortcut(PNG_EXPORT_SHORTCUT
);
240 _exportPNGFileAction
->setActionGroup(_fileActionGroup
);
241 connect(_exportPNGFileAction
, &QAction::triggered
, this, &GUI::exportPNGFile
);
242 addAction(_exportPNGFileAction
);
243 _closeFileAction
= new QAction(QIcon(CLOSE_FILE_ICON
), tr("Close"), this);
244 _closeFileAction
->setMenuRole(QAction::NoRole
);
245 _closeFileAction
->setShortcut(CLOSE_SHORTCUT
);
246 _closeFileAction
->setActionGroup(_fileActionGroup
);
247 connect(_closeFileAction
, &QAction::triggered
, this, &GUI::closeAll
);
248 addAction(_closeFileAction
);
249 _reloadFileAction
= new QAction(QIcon(RELOAD_FILE_ICON
), tr("Reload"),
251 _reloadFileAction
->setMenuRole(QAction::NoRole
);
252 _reloadFileAction
->setShortcut(RELOAD_SHORTCUT
);
253 _reloadFileAction
->setActionGroup(_fileActionGroup
);
254 connect(_reloadFileAction
, &QAction::triggered
, this, &GUI::reloadFiles
);
255 addAction(_reloadFileAction
);
256 _statisticsAction
= new QAction(tr("Statistics..."), this);
257 _statisticsAction
->setMenuRole(QAction::NoRole
);
258 _statisticsAction
->setShortcut(STATISTICS_SHORTCUT
);
259 _statisticsAction
->setActionGroup(_fileActionGroup
);
260 connect(_statisticsAction
, &QAction::triggered
, this, &GUI::statistics
);
261 addAction(_statisticsAction
);
264 _poisActionGroup
= new QActionGroup(this);
265 _poisActionGroup
->setExclusive(false);
266 connect(_poisActionGroup
, &QActionGroup::triggered
, this,
267 &GUI::poiFileChecked
);
268 _openPOIAction
= new QAction(QIcon(OPEN_FILE_ICON
), tr("Load POI file..."),
270 _openPOIAction
->setMenuRole(QAction::NoRole
);
271 connect(_openPOIAction
, &QAction::triggered
, this,
272 QOverload
<>::of(&GUI::openPOIFile
));
273 _selectAllPOIAction
= new QAction(tr("Select all files"), this);
274 _selectAllPOIAction
->setMenuRole(QAction::NoRole
);
275 _selectAllPOIAction
->setEnabled(false);
276 connect(_selectAllPOIAction
, &QAction::triggered
, this,
277 &GUI::selectAllPOIs
);
278 _unselectAllPOIAction
= new QAction(tr("Unselect all files"), this);
279 _unselectAllPOIAction
->setMenuRole(QAction::NoRole
);
280 _unselectAllPOIAction
->setEnabled(false);
281 connect(_unselectAllPOIAction
, &QAction::triggered
, this,
282 &GUI::unselectAllPOIs
);
283 _overlapPOIAction
= new QAction(tr("Overlap POIs"), this);
284 _overlapPOIAction
->setMenuRole(QAction::NoRole
);
285 _overlapPOIAction
->setCheckable(true);
286 connect(_overlapPOIAction
, &QAction::triggered
, _mapView
,
287 &MapView::showOverlappedPOIs
);
288 _showPOIIconsAction
= new QAction(tr("Show POI icons"), this);
289 _showPOIIconsAction
->setMenuRole(QAction::NoRole
);
290 _showPOIIconsAction
->setCheckable(true);
291 connect(_showPOIIconsAction
, &QAction::triggered
, _mapView
,
292 &MapView::showPOIIcons
);
293 _showPOILabelsAction
= new QAction(tr("Show POI labels"), this);
294 _showPOILabelsAction
->setMenuRole(QAction::NoRole
);
295 _showPOILabelsAction
->setCheckable(true);
296 connect(_showPOILabelsAction
, &QAction::triggered
, _mapView
,
297 &MapView::showPOILabels
);
298 _showPOIAction
= new QAction(QIcon(SHOW_POI_ICON
), tr("Show POIs"), this);
299 _showPOIAction
->setMenuRole(QAction::NoRole
);
300 _showPOIAction
->setCheckable(true);
301 _showPOIAction
->setShortcut(SHOW_POI_SHORTCUT
);
302 connect(_showPOIAction
, &QAction::triggered
, _mapView
, &MapView::showPOI
);
303 addAction(_showPOIAction
);
306 _mapsActionGroup
= new QActionGroup(this);
307 _mapsActionGroup
->setExclusive(true);
308 connect(_mapsActionGroup
, &QActionGroup::triggered
, this, &GUI::mapChanged
);
309 _showMapAction
= new QAction(QIcon(SHOW_MAP_ICON
), tr("Show map"),
311 _showMapAction
->setEnabled(false);
312 _showMapAction
->setMenuRole(QAction::NoRole
);
313 _showMapAction
->setCheckable(true);
314 _showMapAction
->setShortcut(SHOW_MAP_SHORTCUT
);
315 connect(_showMapAction
, &QAction::triggered
, _mapView
,
317 addAction(_showMapAction
);
318 _loadMapAction
= new QAction(QIcon(OPEN_FILE_ICON
), tr("Load map..."),
320 _loadMapAction
->setMenuRole(QAction::NoRole
);
321 connect(_loadMapAction
, &QAction::triggered
, this,
322 QOverload
<>::of(&GUI::loadMap
));
323 _loadMapDirAction
= new QAction(QIcon(OPEN_FILE_ICON
),
324 tr("Load map directory..."), this);
325 _loadMapDirAction
->setMenuRole(QAction::NoRole
);
326 connect(_loadMapDirAction
, &QAction::triggered
, this, &GUI::loadMapDir
);
327 _clearMapCacheAction
= new QAction(tr("Clear tile cache"), this);
328 _clearMapCacheAction
->setEnabled(false);
329 _clearMapCacheAction
->setMenuRole(QAction::NoRole
);
330 connect(_clearMapCacheAction
, &QAction::triggered
, this,
331 &GUI::clearMapCache
);
332 _nextMapAction
= new QAction(tr("Next map"), this);
333 _nextMapAction
->setMenuRole(QAction::NoRole
);
334 _nextMapAction
->setShortcut(NEXT_MAP_SHORTCUT
);
335 connect(_nextMapAction
, &QAction::triggered
, this, &GUI::nextMap
);
336 addAction(_nextMapAction
);
337 _prevMapAction
= new QAction(tr("Next map"), this);
338 _prevMapAction
->setMenuRole(QAction::NoRole
);
339 _prevMapAction
->setShortcut(PREV_MAP_SHORTCUT
);
340 connect(_prevMapAction
, &QAction::triggered
, this, &GUI::prevMap
);
341 addAction(_prevMapAction
);
342 _showCoordinatesAction
= new QAction(tr("Show cursor coordinates"), this);
343 _showCoordinatesAction
->setMenuRole(QAction::NoRole
);
344 _showCoordinatesAction
->setCheckable(true);
345 connect(_showCoordinatesAction
, &QAction::triggered
, _mapView
,
346 &MapView::showCursorCoordinates
);
349 _showPositionAction
= new QAction(QIcon(SHOW_POS_ICON
),
350 tr("Show position"), this);
351 _showPositionAction
->setMenuRole(QAction::NoRole
);
352 _showPositionAction
->setCheckable(true);
353 _showPositionAction
->setEnabled(false);
354 connect(_showPositionAction
, &QAction::triggered
, _mapView
,
355 &MapView::showPosition
);
356 _followPositionAction
= new QAction(tr("Follow position"), this);
357 _followPositionAction
->setMenuRole(QAction::NoRole
);
358 _followPositionAction
->setCheckable(true);
359 connect(_followPositionAction
, &QAction::triggered
, _mapView
,
360 &MapView::followPosition
);
361 _showPositionCoordinatesAction
= new QAction(tr("Show coordinates"),
363 _showPositionCoordinatesAction
->setMenuRole(QAction::NoRole
);
364 _showPositionCoordinatesAction
->setCheckable(true);
365 connect(_showPositionCoordinatesAction
, &QAction::triggered
, _mapView
,
366 &MapView::showPositionCoordinates
);
367 _showMotionInfoAction
= new QAction(tr("Show motion info"), this);
368 _showMotionInfoAction
->setMenuRole(QAction::NoRole
);
369 _showMotionInfoAction
->setCheckable(true);
370 connect(_showMotionInfoAction
, &QAction::triggered
, _mapView
,
371 &MapView::showMotionInfo
);
374 _showTracksAction
= new QAction(tr("Show tracks"), this);
375 _showTracksAction
->setMenuRole(QAction::NoRole
);
376 _showTracksAction
->setCheckable(true);
377 _showTracksAction
->setShortcut(SHOW_TRACKS_SHORTCUT
);
378 connect(_showTracksAction
, &QAction::triggered
, this, &GUI::showTracks
);
379 _showRoutesAction
= new QAction(tr("Show routes"), this);
380 _showRoutesAction
->setMenuRole(QAction::NoRole
);
381 _showRoutesAction
->setCheckable(true);
382 connect(_showRoutesAction
, &QAction::triggered
, this, &GUI::showRoutes
);
383 _showWaypointsAction
= new QAction(tr("Show waypoints"), this);
384 _showWaypointsAction
->setMenuRole(QAction::NoRole
);
385 _showWaypointsAction
->setCheckable(true);
386 connect(_showWaypointsAction
, &QAction::triggered
, this,
387 &GUI::showWaypoints
);
388 _showAreasAction
= new QAction(tr("Show areas"), this);
389 _showAreasAction
->setMenuRole(QAction::NoRole
);
390 _showAreasAction
->setCheckable(true);
391 connect(_showAreasAction
, &QAction::triggered
, this, &GUI::showAreas
);
392 _showWaypointIconsAction
= new QAction(tr("Waypoint icons"), this);
393 _showWaypointIconsAction
->setMenuRole(QAction::NoRole
);
394 _showWaypointIconsAction
->setCheckable(true);
395 connect(_showWaypointIconsAction
, &QAction::triggered
, _mapView
,
396 &MapView::showWaypointIcons
);
397 _showWaypointLabelsAction
= new QAction(tr("Waypoint labels"), this);
398 _showWaypointLabelsAction
->setMenuRole(QAction::NoRole
);
399 _showWaypointLabelsAction
->setCheckable(true);
400 connect(_showWaypointLabelsAction
, &QAction::triggered
, _mapView
,
401 &MapView::showWaypointLabels
);
402 _showRouteWaypointsAction
= new QAction(tr("Route waypoints"), this);
403 _showRouteWaypointsAction
->setMenuRole(QAction::NoRole
);
404 _showRouteWaypointsAction
->setCheckable(true);
405 connect(_showRouteWaypointsAction
, &QAction::triggered
, _mapView
,
406 &MapView::showRouteWaypoints
);
407 _showTicksAction
= new QAction(tr("km/mi markers"), this);
408 _showTicksAction
->setMenuRole(QAction::NoRole
);
409 _showTicksAction
->setCheckable(true);
410 connect(_showTicksAction
, &QAction::triggered
, _mapView
,
411 &MapView::showTicks
);
412 QActionGroup
*markerInfoGroup
= new QActionGroup(this);
413 connect(markerInfoGroup
, &QActionGroup::triggered
, this,
414 &GUI::showPathMarkerInfo
);
415 _hideMarkersAction
= new QAction(tr("Do not show"), this);
416 _hideMarkersAction
->setMenuRole(QAction::NoRole
);
417 _hideMarkersAction
->setCheckable(true);
418 _hideMarkersAction
->setActionGroup(markerInfoGroup
);
419 _showMarkersAction
= new QAction(tr("Marker only"), this);
420 _showMarkersAction
->setMenuRole(QAction::NoRole
);
421 _showMarkersAction
->setCheckable(true);
422 _showMarkersAction
->setActionGroup(markerInfoGroup
);
423 _showMarkerDateAction
= new QAction(tr("Date/time"), this);
424 _showMarkerDateAction
->setMenuRole(QAction::NoRole
);
425 _showMarkerDateAction
->setCheckable(true);
426 _showMarkerDateAction
->setActionGroup(markerInfoGroup
);
427 _showMarkerCoordinatesAction
= new QAction(tr("Coordinates"), this);
428 _showMarkerCoordinatesAction
->setMenuRole(QAction::NoRole
);
429 _showMarkerCoordinatesAction
->setCheckable(true);
430 _showMarkerCoordinatesAction
->setActionGroup(markerInfoGroup
);
431 _useStylesAction
= new QAction(tr("Use styles"), this);
432 _useStylesAction
->setMenuRole(QAction::NoRole
);
433 _useStylesAction
->setCheckable(true);
434 connect(_useStylesAction
, &QAction::triggered
, _mapView
,
435 &MapView::useStyles
);
438 _downloadDEMAction
= new QAction(tr("Download DEM data"), this);
439 _downloadDEMAction
->setMenuRole(QAction::NoRole
);
440 _downloadDEMAction
->setEnabled(false);
441 _downloadDEMAction
->setShortcut(DOWNLOAD_DEM_SHORTCUT
);
442 connect(_downloadDEMAction
, &QAction::triggered
, this, &GUI::downloadDEM
);
443 _showDEMTilesAction
= new QAction(tr("Show local DEM tiles"), this);
444 _showDEMTilesAction
->setMenuRole(QAction::NoRole
);
445 connect(_showDEMTilesAction
, &QAction::triggered
, this, &GUI::showDEMTiles
);
448 _showGraphsAction
= new QAction(QIcon(SHOW_GRAPHS_ICON
), tr("Show graphs"),
450 _showGraphsAction
->setMenuRole(QAction::NoRole
);
451 _showGraphsAction
->setCheckable(true);
452 _showGraphsAction
->setShortcut(SHOW_GRAPHS_SHORTCUT
);
453 connect(_showGraphsAction
, &QAction::triggered
, this, &GUI::showGraphs
);
454 addAction(_showGraphsAction
);
455 ag
= new QActionGroup(this);
456 ag
->setExclusive(true);
457 _distanceGraphAction
= new QAction(tr("Distance"), this);
458 _distanceGraphAction
->setMenuRole(QAction::NoRole
);
459 _distanceGraphAction
->setCheckable(true);
460 _distanceGraphAction
->setActionGroup(ag
);
461 connect(_distanceGraphAction
, &QAction::triggered
, this,
462 &GUI::setDistanceGraph
);
463 addAction(_distanceGraphAction
);
464 _timeGraphAction
= new QAction(tr("Time"), this);
465 _timeGraphAction
->setMenuRole(QAction::NoRole
);
466 _timeGraphAction
->setCheckable(true);
467 _timeGraphAction
->setActionGroup(ag
);
468 connect(_timeGraphAction
, &QAction::triggered
, this, &GUI::setTimeGraph
);
469 addAction(_timeGraphAction
);
470 _showGraphGridAction
= new QAction(tr("Show grid"), this);
471 _showGraphGridAction
->setMenuRole(QAction::NoRole
);
472 _showGraphGridAction
->setCheckable(true);
473 connect(_showGraphGridAction
, &QAction::triggered
, this,
474 &GUI::showGraphGrids
);
475 _showGraphSliderInfoAction
= new QAction(tr("Show slider info"), this);
476 _showGraphSliderInfoAction
->setMenuRole(QAction::NoRole
);
477 _showGraphSliderInfoAction
->setCheckable(true);
478 connect(_showGraphSliderInfoAction
, &QAction::triggered
, this,
479 &GUI::showGraphSliderInfo
);
481 _showGraphTabsAction
= new QAction(tr("Show tabs"), this);
482 _showGraphTabsAction
->setMenuRole(QAction::NoRole
);
483 _showGraphTabsAction
->setCheckable(true);
484 connect(_showGraphTabsAction
, &QAction::triggered
, this,
485 &GUI::showGraphTabs
);
486 #endif // Q_OS_ANDROID
490 _showToolbarsAction
= new QAction(tr("Show toolbars"), this);
491 _showToolbarsAction
->setMenuRole(QAction::NoRole
);
492 _showToolbarsAction
->setCheckable(true);
493 connect(_showToolbarsAction
, &QAction::triggered
, this, &GUI::showToolbars
);
494 #endif // Q_OS_ANDROID
495 ag
= new QActionGroup(this);
496 ag
->setExclusive(true);
497 _totalTimeAction
= new QAction(tr("Total time"), this);
498 _totalTimeAction
->setMenuRole(QAction::NoRole
);
499 _totalTimeAction
->setCheckable(true);
500 _totalTimeAction
->setActionGroup(ag
);
501 connect(_totalTimeAction
, &QAction::triggered
, this, &GUI::setTotalTime
);
502 _movingTimeAction
= new QAction(tr("Moving time"), this);
503 _movingTimeAction
->setMenuRole(QAction::NoRole
);
504 _movingTimeAction
->setCheckable(true);
505 _movingTimeAction
->setActionGroup(ag
);
506 connect(_movingTimeAction
, &QAction::triggered
, this, &GUI::setMovingTime
);
507 ag
= new QActionGroup(this);
508 ag
->setExclusive(true);
509 _metricUnitsAction
= new QAction(tr("Metric"), this);
510 _metricUnitsAction
->setMenuRole(QAction::NoRole
);
511 _metricUnitsAction
->setCheckable(true);
512 _metricUnitsAction
->setActionGroup(ag
);
513 connect(_metricUnitsAction
, &QAction::triggered
, this, &GUI::setMetricUnits
);
514 _imperialUnitsAction
= new QAction(tr("Imperial"), this);
515 _imperialUnitsAction
->setMenuRole(QAction::NoRole
);
516 _imperialUnitsAction
->setCheckable(true);
517 _imperialUnitsAction
->setActionGroup(ag
);
518 connect(_imperialUnitsAction
, &QAction::triggered
, this,
519 &GUI::setImperialUnits
);
520 _nauticalUnitsAction
= new QAction(tr("Nautical"), this);
521 _nauticalUnitsAction
->setMenuRole(QAction::NoRole
);
522 _nauticalUnitsAction
->setCheckable(true);
523 _nauticalUnitsAction
->setActionGroup(ag
);
524 connect(_nauticalUnitsAction
, &QAction::triggered
, this,
525 &GUI::setNauticalUnits
);
526 ag
= new QActionGroup(this);
527 ag
->setExclusive(true);
528 _decimalDegreesAction
= new QAction(tr("Decimal degrees (DD)"), this);
529 _decimalDegreesAction
->setMenuRole(QAction::NoRole
);
530 _decimalDegreesAction
->setCheckable(true);
531 _decimalDegreesAction
->setActionGroup(ag
);
532 connect(_decimalDegreesAction
, &QAction::triggered
, this,
533 &GUI::setDecimalDegrees
);
534 _degreesMinutesAction
= new QAction(tr("Degrees and decimal minutes (DMM)"),
536 _degreesMinutesAction
->setMenuRole(QAction::NoRole
);
537 _degreesMinutesAction
->setCheckable(true);
538 _degreesMinutesAction
->setActionGroup(ag
);
539 connect(_degreesMinutesAction
, &QAction::triggered
, this,
540 &GUI::setDegreesMinutes
);
541 _dmsAction
= new QAction(tr("Degrees, minutes, seconds (DMS)"), this);
542 _dmsAction
->setMenuRole(QAction::NoRole
);
543 _dmsAction
->setCheckable(true);
544 _dmsAction
->setActionGroup(ag
);
545 connect(_dmsAction
, &QAction::triggered
, this, &GUI::setDMS
);
547 _fullscreenAction
= new QAction(QIcon(FULLSCREEN_ICON
),
548 tr("Fullscreen mode"), this);
549 _fullscreenAction
->setMenuRole(QAction::NoRole
);
550 _fullscreenAction
->setCheckable(true);
551 _fullscreenAction
->setShortcut(FULLSCREEN_SHORTCUT
);
552 connect(_fullscreenAction
, &QAction::triggered
, this, &GUI::showFullscreen
);
553 addAction(_fullscreenAction
);
554 #endif // Q_OS_ANDROID
555 _openOptionsAction
= new QAction(tr("Options..."), this);
556 _openOptionsAction
->setMenuRole(QAction::PreferencesRole
);
557 connect(_openOptionsAction
, &QAction::triggered
, this, &GUI::openOptions
);
559 // Navigation actions
561 _nextAction
= new QAction(QIcon(NEXT_FILE_ICON
), tr("Next"), this);
562 _nextAction
->setActionGroup(_navigationActionGroup
);
563 _nextAction
->setMenuRole(QAction::NoRole
);
564 connect(_nextAction
, &QAction::triggered
, this, &GUI::next
);
565 _prevAction
= new QAction(QIcon(PREV_FILE_ICON
), tr("Previous"), this);
566 _prevAction
->setMenuRole(QAction::NoRole
);
567 _prevAction
->setActionGroup(_navigationActionGroup
);
568 connect(_prevAction
, &QAction::triggered
, this, &GUI::prev
);
569 _lastAction
= new QAction(QIcon(LAST_FILE_ICON
), tr("Last"), this);
570 _lastAction
->setMenuRole(QAction::NoRole
);
571 _lastAction
->setActionGroup(_navigationActionGroup
);
572 connect(_lastAction
, &QAction::triggered
, this, &GUI::last
);
573 _firstAction
= new QAction(QIcon(FIRST_FILE_ICON
), tr("First"), this);
574 _firstAction
->setMenuRole(QAction::NoRole
);
575 _firstAction
->setActionGroup(_navigationActionGroup
);
576 connect(_firstAction
, &QAction::triggered
, this, &GUI::first
);
577 #endif // Q_OS_ANDROID
580 void GUI::createMapNodeMenu(const TreeNode
<MapAction
*> &node
, QMenu
*menu
,
583 for (int i
= 0; i
< node
.childs().size(); i
++) {
584 QMenu
*cm
= new QMenu(node
.childs().at(i
).name(), menu
);
585 menu
->insertMenu(action
, cm
);
586 createMapNodeMenu(node
.childs().at(i
), cm
);
589 for (int i
= 0; i
< node
.items().size(); i
++)
590 menu
->insertAction(action
, node
.items().at(i
));
593 void GUI::createPOINodeMenu(const TreeNode
<POIAction
*> &node
, QMenu
*menu
,
596 for (int i
= 0; i
< node
.childs().size(); i
++) {
597 QMenu
*cm
= new QMenu(node
.childs().at(i
).name(), menu
);
598 menu
->insertMenu(action
, cm
);
599 createPOINodeMenu(node
.childs().at(i
), cm
);
602 for (int i
= 0; i
< node
.items().size(); i
++)
603 menu
->insertAction(action
, node
.items().at(i
));
606 void GUI::createMenus()
608 QMenu
*fileMenu
= menuBar()->addMenu(tr("&File"));
609 fileMenu
->addAction(_openFileAction
);
611 fileMenu
->addAction(_openDirAction
);
612 #endif // Q_OS_ANDROID
613 fileMenu
->addSeparator();
615 fileMenu
->addAction(_printFileAction
);
616 #endif // Q_OS_ANDROID
617 fileMenu
->addAction(_exportPDFFileAction
);
618 fileMenu
->addAction(_exportPNGFileAction
);
619 fileMenu
->addSeparator();
620 fileMenu
->addAction(_statisticsAction
);
621 fileMenu
->addSeparator();
622 fileMenu
->addAction(_reloadFileAction
);
623 fileMenu
->addAction(_closeFileAction
);
624 #if !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID)
625 fileMenu
->addSeparator();
626 fileMenu
->addAction(_exitAction
);
627 #endif // Q_OS_MAC + Q_OS_ANDROID
629 _mapMenu
= menuBar()->addMenu(tr("&Map"));
630 _mapsEnd
= _mapMenu
->addSeparator();
631 _mapMenu
->addAction(_loadMapAction
);
632 _mapMenu
->addAction(_loadMapDirAction
);
633 _mapMenu
->addAction(_clearMapCacheAction
);
634 _mapMenu
->addSeparator();
635 _mapMenu
->addAction(_showCoordinatesAction
);
636 _mapMenu
->addSeparator();
637 _mapMenu
->addAction(_showMapAction
);
639 QMenu
*graphMenu
= menuBar()->addMenu(tr("&Graph"));
640 graphMenu
->addAction(_distanceGraphAction
);
641 graphMenu
->addAction(_timeGraphAction
);
642 graphMenu
->addSeparator();
643 graphMenu
->addAction(_showGraphGridAction
);
644 graphMenu
->addAction(_showGraphSliderInfoAction
);
646 graphMenu
->addAction(_showGraphTabsAction
);
647 #endif // Q_OS_ANDROID
648 graphMenu
->addSeparator();
649 graphMenu
->addAction(_showGraphsAction
);
651 QMenu
*dataMenu
= menuBar()->addMenu(tr("&Data"));
652 dataMenu
->addAction(_showWaypointIconsAction
);
653 dataMenu
->addAction(_showWaypointLabelsAction
);
654 dataMenu
->addAction(_showRouteWaypointsAction
);
655 dataMenu
->addAction(_showTicksAction
);
656 QMenu
*markerMenu
= dataMenu
->addMenu(tr("Position info"));
657 markerMenu
->addAction(_hideMarkersAction
);
658 markerMenu
->addAction(_showMarkersAction
);
659 markerMenu
->addAction(_showMarkerDateAction
);
660 markerMenu
->addAction(_showMarkerCoordinatesAction
);
661 dataMenu
->addSeparator();
662 dataMenu
->addAction(_useStylesAction
);
663 dataMenu
->addSeparator();
664 dataMenu
->addAction(_showTracksAction
);
665 dataMenu
->addAction(_showRoutesAction
);
666 dataMenu
->addAction(_showAreasAction
);
667 dataMenu
->addAction(_showWaypointsAction
);
669 _poiMenu
= menuBar()->addMenu(tr("&POI"));
670 _poisEnd
= _poiMenu
->addSeparator();
671 _poiMenu
->addAction(_openPOIAction
);
672 _poiMenu
->addAction(_selectAllPOIAction
);
673 _poiMenu
->addAction(_unselectAllPOIAction
);
674 _poiMenu
->addSeparator();
675 _poiMenu
->addAction(_showPOIIconsAction
);
676 _poiMenu
->addAction(_showPOILabelsAction
);
677 _poiMenu
->addAction(_overlapPOIAction
);
678 _poiMenu
->addSeparator();
679 _poiMenu
->addAction(_showPOIAction
);
681 QMenu
*demMenu
= menuBar()->addMenu(tr("DEM"));
682 demMenu
->addAction(_showDEMTilesAction
);
683 demMenu
->addAction(_downloadDEMAction
);
685 QMenu
*positionMenu
= menuBar()->addMenu(tr("Position"));
686 positionMenu
->addAction(_showPositionCoordinatesAction
);
687 positionMenu
->addAction(_showMotionInfoAction
);
688 positionMenu
->addAction(_followPositionAction
);
689 positionMenu
->addSeparator();
690 positionMenu
->addAction(_showPositionAction
);
692 QMenu
*settingsMenu
= menuBar()->addMenu(tr("&Settings"));
693 QMenu
*timeMenu
= settingsMenu
->addMenu(tr("Time"));
694 timeMenu
->addAction(_totalTimeAction
);
695 timeMenu
->addAction(_movingTimeAction
);
696 QMenu
*unitsMenu
= settingsMenu
->addMenu(tr("Units"));
697 unitsMenu
->addAction(_metricUnitsAction
);
698 unitsMenu
->addAction(_imperialUnitsAction
);
699 unitsMenu
->addAction(_nauticalUnitsAction
);
700 QMenu
*coordinatesMenu
= settingsMenu
->addMenu(tr("Coordinates format"));
701 coordinatesMenu
->addAction(_decimalDegreesAction
);
702 coordinatesMenu
->addAction(_degreesMinutesAction
);
703 coordinatesMenu
->addAction(_dmsAction
);
704 settingsMenu
->addSeparator();
706 settingsMenu
->addAction(_showToolbarsAction
);
707 settingsMenu
->addAction(_fullscreenAction
);
708 settingsMenu
->addSeparator();
709 #endif // Q_OS_ANDROID
710 settingsMenu
->addAction(_openOptionsAction
);
712 QMenu
*helpMenu
= menuBar()->addMenu(tr("&Help"));
713 helpMenu
->addAction(_pathsAction
);
715 helpMenu
->addAction(_keysAction
);
716 #endif // Q_OS_ANDROID
717 helpMenu
->addSeparator();
718 helpMenu
->addAction(_aboutAction
);
722 void GUI::createNavigation()
724 _navigation
= new NavigationWidget(_mapView
);
726 connect(_navigation
, &NavigationWidget::next
, this, &GUI::next
);
727 connect(_navigation
, &NavigationWidget::prev
, this, &GUI::prev
);
729 #else // Q_OS_ANDROID
730 void GUI::createToolBars()
732 int is
= style()->pixelMetric(QStyle::PM_ToolBarIconSize
);
733 QSize
iconSize(qMin(is
, TOOLBAR_ICON_SIZE
), qMin(is
, TOOLBAR_ICON_SIZE
));
736 setToolButtonStyle(Qt::ToolButtonTextUnderIcon
);
739 _fileToolBar
= addToolBar(tr("File"));
740 _fileToolBar
->setObjectName("File");
741 _fileToolBar
->setIconSize(iconSize
);
742 _fileToolBar
->addAction(_openFileAction
);
743 _fileToolBar
->addAction(_reloadFileAction
);
744 _fileToolBar
->addAction(_closeFileAction
);
746 _fileToolBar
->addAction(_printFileAction
);
749 _showToolBar
= addToolBar(tr("Show"));
750 _showToolBar
->setObjectName("Show");
751 _showToolBar
->setIconSize(iconSize
);
752 _showToolBar
->addAction(_showPOIAction
);
753 _showToolBar
->addAction(_showMapAction
);
754 _showToolBar
->addAction(_showGraphsAction
);
755 _showToolBar
->addAction(_showPositionAction
);
757 _navigationToolBar
= addToolBar(tr("Navigation"));
758 _navigationToolBar
->setObjectName("Navigation");
759 _navigationToolBar
->setIconSize(iconSize
);
760 _navigationToolBar
->addAction(_firstAction
);
761 _navigationToolBar
->addAction(_prevAction
);
762 _navigationToolBar
->addAction(_nextAction
);
763 _navigationToolBar
->addAction(_lastAction
);
765 #endif // Q_OS_ANDROID
767 void GUI::createMapView()
769 _map
= new EmptyMap(this);
770 _mapView
= new MapView(_map
, _poi
, this);
771 _mapView
->setSizePolicy(QSizePolicy(QSizePolicy::Ignored
,
772 QSizePolicy::Expanding
));
774 _mapView
->setMinimumHeight(100);
775 #else // Q_OS_ANDROID
776 _mapView
->setMinimumHeight(200);
777 #endif // Q_OS_ANDROID
779 _mapView
->setFrameShape(QFrame::NoFrame
);
783 void GUI::createGraphTabs()
785 _graphTabWidget
= new QTabWidget();
786 _graphTabWidget
->setSizePolicy(QSizePolicy(QSizePolicy::Ignored
,
787 QSizePolicy::Preferred
));
788 _graphTabWidget
->setMinimumHeight(200);
790 _graphTabWidget
->setDocumentMode(true);
793 connect(_graphTabWidget
, &QTabWidget::currentChanged
, this,
796 _tabs
.append(new ElevationGraph(_graphTabWidget
));
797 _tabs
.append(new SpeedGraph(_graphTabWidget
));
798 _tabs
.append(new HeartRateGraph(_graphTabWidget
));
799 _tabs
.append(new CadenceGraph(_graphTabWidget
));
800 _tabs
.append(new PowerGraph(_graphTabWidget
));
801 _tabs
.append(new TemperatureGraph(_graphTabWidget
));
802 _tabs
.append(new GearRatioGraph(_graphTabWidget
));
804 for (int i
= 0; i
< _tabs
.size(); i
++)
805 connect(_tabs
.at(i
), &GraphTab::sliderPositionChanged
, _mapView
,
806 &MapView::setMarkerPosition
);
809 void GUI::createStatusBar()
811 _fileNameLabel
= new QLabel();
812 _distanceLabel
= new QLabel();
813 _timeLabel
= new QLabel();
814 _distanceLabel
->setAlignment(Qt::AlignHCenter
);
815 _timeLabel
->setAlignment(Qt::AlignHCenter
);
817 statusBar()->addPermanentWidget(_fileNameLabel
, 8);
818 statusBar()->addPermanentWidget(_distanceLabel
, 1);
819 statusBar()->addPermanentWidget(_timeLabel
, 1);
820 statusBar()->setSizeGripEnabled(false);
825 QMessageBox
msgBox(this);
826 QUrl
homepage(APP_HOMEPAGE
);
828 msgBox
.setWindowTitle(tr("About GPXSee"));
830 msgBox
.setText("<h2>" + QString(APP_NAME
) + "</h2><p>" + tr("Version %1")
831 .arg(QString(APP_VERSION
) + " (" + QSysInfo::buildCpuArchitecture()
832 + ", Qt " + QT_VERSION_STR
+ ")") + "</p><p>"
833 + tr("GPXSee is distributed under the terms of the GNU General Public "
834 "License version 3. For more info about GPXSee visit the project "
835 "homepage at %1.").arg("<a href=\"" + homepage
.toString() + "\">"
836 + homepage
.toString(QUrl::RemoveScheme
).mid(2) + "</a>") + "</p>");
837 #else // Q_OS_ANDROID
838 msgBox
.setText("<h2>" + QString(APP_NAME
) + "</h2><p>" + tr("Version %1")
839 .arg(QString(APP_VERSION
) + " (" + QSysInfo::buildCpuArchitecture()
840 + ", Qt " + QT_VERSION_STR
+ ")") + "</p>");
841 msgBox
.setInformativeText("<table width=\"300\"><tr><td>"
842 + tr("GPXSee is distributed under the terms of the GNU General Public "
843 "License version 3. For more info about GPXSee visit the project "
844 "homepage at %1.").arg("<a href=\"" + homepage
.toString() + "\">"
845 + homepage
.toString(QUrl::RemoveScheme
).mid(2) + "</a>")
846 + "</td></tr></table>");
848 QIcon icon
= msgBox
.windowIcon();
849 QSize size
= icon
.actualSize(QSize(64, 64));
850 msgBox
.setIconPixmap(icon
.pixmap(size
));
851 #endif // Q_OS_ANDROID
859 QMessageBox
msgBox(this);
861 msgBox
.setWindowTitle(tr("Keyboard controls"));
862 msgBox
.setText("<h3>" + tr("Keyboard controls") + "</h3>");
863 msgBox
.setInformativeText(
864 "<style>td {padding-right: 1.5em;}</style><div><table><tr><td>"
865 + tr("Next file") + "</td><td><i>" + QKeySequence(NEXT_KEY
).toString()
866 + "</i></td></tr><tr><td>" + tr("Previous file")
867 + "</td><td><i>" + QKeySequence(PREV_KEY
).toString()
868 + "</i></td></tr><tr><td>" + tr("First file") + "</td><td><i>"
869 + QKeySequence(FIRST_KEY
).toString() + "</i></td></tr><tr><td>"
870 + tr("Last file") + "</td><td><i>" + QKeySequence(LAST_KEY
).toString()
871 + "</i></td></tr><tr><td>" + tr("Append file")
872 + "</td><td><i>" + QKeySequence(MODIFIER
).toString() + tr("Next/Previous")
873 + "</i></td></tr><tr><td></td><td></td></tr><tr><td>"
874 + tr("Toggle graph type") + "</td><td><i>"
875 + QKeySequence(TOGGLE_GRAPH_TYPE_KEY
).toString() + "</i></td></tr><tr><td>"
876 + tr("Toggle time type") + "</td><td><i>"
877 + QKeySequence(TOGGLE_TIME_TYPE_KEY
).toString() + "</i></td></tr><tr><td>"
878 + tr("Toggle position info") + "</td><td><i>"
879 + QKeySequence(TOGGLE_MARKER_INFO_KEY
).toString() + "</i></td></tr>"
880 + "<tr><td></td><td></td></tr><tr><td>" + tr("Next map")
881 + "</td><td><i>" + NEXT_MAP_SHORTCUT
.toString() + "</i></td></tr><tr><td>"
882 + tr("Previous map") + "</td><td><i>" + PREV_MAP_SHORTCUT
.toString()
883 + "</i></td></tr><tr><td></td><td></td></tr><tr><td>" + tr("Zoom in")
884 + "</td><td><i>" + QKeySequence(ZOOM_IN
).toString()
885 + "</i></td></tr><tr><td>" + tr("Zoom out") + "</td><td><i>"
886 + QKeySequence(ZOOM_OUT
).toString() + "</i></td></tr><tr><td>"
887 + tr("Digital zoom") + "</td><td><i>" + QKeySequence(MODIFIER
).toString()
888 + tr("Zoom") + "</i></td></tr><tr><td></td><td></td></tr><tr><td>"
889 + tr("Copy coordinates") + "</td><td><i>"
890 + QKeySequence(MODIFIER
).toString() + tr("Left Click")
891 + "</i></td></tr></table></div>");
895 #endif // Q_OS_ANDROID
899 QMessageBox
msgBox(this);
901 msgBox
.setWindowTitle(tr("Paths"));
904 + "<small><b>" + tr("Map directory:") + "</b><br>"
905 + QDir::cleanPath(ProgramPaths::mapDir(true)) + "<br><br><b>"
906 + tr("POI directory:") + "</b><br>"
907 + QDir::cleanPath(ProgramPaths::poiDir(true)) + "<br><br><b>"
908 + tr("CRS directory:") + "</b><br>"
909 + QDir::cleanPath(ProgramPaths::crsDir(true)) + "<br><br><b>"
910 + tr("DEM directory:") + "</b><br>"
911 + QDir::cleanPath(ProgramPaths::demDir(true)) + "<br><br><b>"
912 + tr("Styles directory:") + "</b><br>"
913 + QDir::cleanPath(ProgramPaths::styleDir(true)) + "<br><br><b>"
914 + tr("Symbols directory:") + "</b><br>"
915 + QDir::cleanPath(ProgramPaths::symbolsDir(true)) + "<br><br><b>"
916 + tr("Tile cache directory:") + "</b><br>"
917 + QDir::cleanPath(ProgramPaths::tilesDir()) + "</small>");
918 #else // Q_OS_ANDROID
919 msgBox
.setText("<h3>" + tr("Paths") + "</h3>");
920 msgBox
.setInformativeText(
921 "<style>td {white-space: pre; padding-right: 1em;}</style><table><tr><td>"
922 + tr("Map directory:") + "</td><td><code>"
923 + QDir::cleanPath(ProgramPaths::mapDir(true)) + "</code></td></tr><tr><td>"
924 + tr("POI directory:") + "</td><td><code>"
925 + QDir::cleanPath(ProgramPaths::poiDir(true)) + "</code></td></tr><tr><td>"
926 + tr("CRS directory:") + "</td><td><code>"
927 + QDir::cleanPath(ProgramPaths::crsDir(true)) + "</code></td></tr><tr><td>"
928 + tr("DEM directory:") + "</td><td><code>"
929 + QDir::cleanPath(ProgramPaths::demDir(true)) + "</code></td></tr><tr><td>"
930 + tr("Styles directory:") + "</td><td><code>"
931 + QDir::cleanPath(ProgramPaths::styleDir(true)) + "</code></td></tr><tr><td>"
932 + tr("Symbols directory:") + "</td><td><code>"
933 + QDir::cleanPath(ProgramPaths::symbolsDir(true)) + "</code></td></tr><tr><td>"
934 + tr("Tile cache directory:") + "</td><td><code>"
935 + QDir::cleanPath(ProgramPaths::tilesDir()) + "</code></td></tr></table>"
937 #endif // Q_OS_ANDROID
945 QStringList
files(QFileDialog::getOpenFileNames(this, tr("Open file"),
947 #else // Q_OS_ANDROID
948 QStringList
files(QFileDialog::getOpenFileNames(this, tr("Open file"),
949 _dataDir
, Data::formats()));
950 #endif // Q_OS_ANDROID
951 int showError
= (files
.size() > 1) ? 2 : 1;
953 for (int i
= 0; i
< files
.size(); i
++)
954 openFile(files
.at(i
), true, showError
);
955 if (!files
.isEmpty())
956 _dataDir
= QFileInfo(files
.last()).path();
962 QString
dir(QFileDialog::getExistingDirectory(this, tr("Open directory"),
966 if (!dir
.isEmpty()) {
967 _browser
->setCurrentDir(dir
);
968 openFile(_browser
->current(), true, showError
);
971 #endif // Q_OS_ANDROID
973 bool GUI::openFile(const QString
&fileName
, bool tryUnknown
, int &showError
)
975 if (_files
.contains(fileName
))
978 if (!loadFile(fileName
, tryUnknown
, showError
))
981 _files
.append(fileName
);
983 _browser
->setCurrent(fileName
);
984 #endif // Q_OS_ANDROID
985 _fileActionGroup
->setEnabled(true);
986 // Explicitly enable the reload action as it may be disabled by loadMapDir()
987 _reloadFileAction
->setEnabled(true);
988 _navigationActionGroup
->setEnabled(true);
990 updateNavigationActions();
991 updateStatusBarInfo();
997 bool GUI::loadFile(const QString
&fileName
, bool tryUnknown
, int &showError
)
999 Data
data(fileName
, tryUnknown
);
1001 if (data
.isValid()) {
1005 updateNavigationActions();
1006 updateStatusBarInfo();
1007 updateWindowTitle();
1009 updateDEMDownloadAction();
1010 if (_files
.isEmpty())
1011 _fileActionGroup
->setEnabled(false);
1014 QString error
= tr("Error loading data file:") + "\n"
1015 + Util::displayName(fileName
) + ": " + data
.errorString();
1016 if (data
.errorLine())
1017 error
.append("\n" + tr("Line: %1").arg(data
.errorLine()));
1019 if (showError
> 1) {
1020 QMessageBox
message(QMessageBox::Critical
, APP_NAME
, error
,
1021 QMessageBox::Ok
, this);
1022 QCheckBox
checkBox(tr("Don't show again"));
1023 message
.setCheckBox(&checkBox
);
1025 if (checkBox
.isChecked())
1028 QMessageBox::critical(this, APP_NAME
, error
);
1035 void GUI::loadData(const Data
&data
)
1037 QList
<QList
<GraphItem
*> > graphs
;
1038 QList
<PathItem
*> paths
;
1040 for (int i
= 0; i
< data
.tracks().count(); i
++) {
1041 const Track
&track
= data
.tracks().at(i
);
1042 _trackDistance
+= track
.distance();
1043 _time
+= track
.time();
1044 _movingTime
+= track
.movingTime();
1045 const QDateTime date
= track
.date().toTimeZone(_options
.timeZone
.zone());
1046 if (_dateRange
.first
.isNull() || _dateRange
.first
> date
)
1047 _dateRange
.first
= date
;
1048 if (_dateRange
.second
.isNull() || _dateRange
.second
< date
)
1049 _dateRange
.second
= date
;
1051 _trackCount
+= data
.tracks().count();
1053 for (int i
= 0; i
< data
.routes().count(); i
++)
1054 _routeDistance
+= data
.routes().at(i
).distance();
1055 _routeCount
+= data
.routes().count();
1057 _waypointCount
+= data
.waypoints().count();
1058 _areaCount
+= data
.areas().count();
1060 if (_pathName
.isNull()) {
1061 if (data
.tracks().count() == 1 && !data
.routes().count())
1062 _pathName
= data
.tracks().first().name();
1063 else if (data
.routes().count() == 1 && !data
.tracks().count())
1064 _pathName
= data
.routes().first().name();
1066 _pathName
= QString();
1068 for (int i
= 0; i
< _tabs
.count(); i
++)
1069 graphs
.append(_tabs
.at(i
)->loadData(data
));
1070 if (updateGraphTabs())
1071 _splitter
->refresh();
1072 paths
= _mapView
->loadData(data
);
1074 GraphTab
*gt
= static_cast<GraphTab
*>(_graphTabWidget
->currentWidget());
1076 for (int i
= 0; i
< paths
.count(); i
++) {
1077 PathItem
*pi
= paths
.at(i
);
1081 for (int j
= 0; j
< graphs
.count(); j
++)
1082 pi
->addGraph(graphs
.at(j
).at(i
));
1085 pi
->setGraph(_tabs
.indexOf(gt
));
1086 pi
->setMarkerPosition(gt
->sliderPosition());
1090 updateDEMDownloadAction();
1093 void GUI::openPOIFile()
1096 QStringList
files(QFileDialog::getOpenFileNames(this, tr("Open POI file"),
1098 #else // Q_OS_ANDROID
1099 QStringList
files(QFileDialog::getOpenFileNames(this, tr("Open POI file"),
1100 _poiDir
, Data::formats()));
1101 #endif // Q_OS_ANDROID
1103 for (int i
= 0; i
< files
.size(); i
++)
1104 openPOIFile(files
.at(i
));
1105 if (!files
.isEmpty())
1106 _poiDir
= QFileInfo(files
.last()).path();
1109 bool GUI::openPOIFile(const QString
&fileName
)
1111 if (_poi
->isLoaded(fileName
))
1114 if (_poi
->loadFile(fileName
)) {
1115 _mapView
->showPOI(true);
1116 _showPOIAction
->setChecked(true);
1117 QAction
*action
= new POIAction(fileName
, _poisActionGroup
);
1118 action
->setChecked(true);
1119 _poiMenu
->insertAction(_poisEnd
, action
);
1121 _selectAllPOIAction
->setEnabled(true);
1122 _unselectAllPOIAction
->setEnabled(true);
1126 QString error
= tr("Error loading POI file:") + "\n"
1127 + Util::displayName(fileName
) + ": " + _poi
->errorString();
1128 if (_poi
->errorLine())
1129 error
.append("\n" + tr("Line: %1").arg(_poi
->errorLine()));
1130 QMessageBox::critical(this, APP_NAME
, error
);
1136 void GUI::openOptions()
1138 Options
options(_options
);
1139 OptionsDialog
dialog(options
, _units
, this);
1141 if (dialog
.exec() != QDialog::Accepted
)
1144 updateOptions(options
);
1147 void GUI::printFile()
1149 QPrinter
printer(QPrinter::HighResolution
);
1150 QPrintDialog
dialog(&printer
, this);
1152 if (dialog
.exec() == QDialog::Accepted
)
1156 void GUI::exportPDFFile()
1158 PDFExportDialog
dialog(_pdfExport
, _units
, this);
1159 if (dialog
.exec() != QDialog::Accepted
)
1162 QPrinter
printer(QPrinter::HighResolution
);
1163 printer
.setOutputFormat(QPrinter::PdfFormat
);
1164 printer
.setCreator(QString(APP_NAME
) + QString(" ")
1165 + QString(APP_VERSION
));
1166 printer
.setResolution(_pdfExport
.resolution
);
1167 printer
.setPageLayout(QPageLayout(QPageSize(_pdfExport
.paperSize
),
1168 _pdfExport
.orientation
, _pdfExport
.margins
, QPageLayout::Millimeter
));
1169 printer
.setOutputFileName(_pdfExport
.fileName
);
1174 void GUI::exportPNGFile()
1176 PNGExportDialog
dialog(_pngExport
, this);
1177 if (dialog
.exec() != QDialog::Accepted
)
1180 QImage
img(_pngExport
.size
, QImage::Format_ARGB32_Premultiplied
);
1182 QRectF
rect(0, 0, img
.width(), img
.height());
1183 QRectF
contentRect(rect
.adjusted(_pngExport
.margins
.left(),
1184 _pngExport
.margins
.top(), -_pngExport
.margins
.right(),
1185 -_pngExport
.margins
.bottom()));
1187 if (_pngExport
.antialiasing
)
1188 p
.setRenderHint(QPainter::Antialiasing
);
1189 p
.fillRect(rect
, Qt::white
);
1190 plotMainPage(&p
, contentRect
, 1.0, true);
1191 img
.save(_pngExport
.fileName
, "png");
1193 if (!_tabs
.isEmpty() && _options
.separateGraphPage
) {
1194 QImage
img2(_pngExport
.size
.width(), (int)graphPlotHeight(rect
, 1)
1195 + _pngExport
.margins
.bottom(), QImage::Format_ARGB32_Premultiplied
);
1197 QRectF
rect2(0, 0, img2
.width(), img2
.height());
1199 if (_pngExport
.antialiasing
)
1200 p2
.setRenderHint(QPainter::Antialiasing
);
1201 p2
.fillRect(rect2
, Qt::white
);
1202 plotGraphsPage(&p2
, contentRect
, 1);
1204 QFileInfo
fi(_pngExport
.fileName
);
1205 img2
.save(fi
.absolutePath() + "/" + fi
.baseName() + "-graphs."
1206 + fi
.suffix(), "png");
1210 void GUI::statistics()
1212 QLocale
l(QLocale::system());
1213 QMessageBox
msgBox(this);
1217 if (_showTracksAction
->isChecked() && _trackCount
> 1)
1218 text
.append("<b>" + tr("Tracks") + ":</b> "
1219 + l
.toString(_trackCount
) + "<br>");
1220 if (_showRoutesAction
->isChecked() && _routeCount
> 1)
1221 text
.append("<b>" + tr("Routes") + ":</b> "
1222 + l
.toString(_routeCount
) + "<br>");
1223 if (_showWaypointsAction
->isChecked() && _waypointCount
> 1)
1224 text
.append("<b>" + tr("Waypoints") + ":</b> "
1225 + l
.toString(_waypointCount
) + "<br>");
1226 if (_showAreasAction
->isChecked() && _areaCount
> 1)
1227 text
.append("<b>" + tr("Areas") + ":</b> "
1228 + l
.toString(_areaCount
) + "<br>");
1230 if (_dateRange
.first
.isValid()) {
1231 QString format
= l
.dateFormat(QLocale::ShortFormat
);
1232 if (_dateRange
.first
== _dateRange
.second
)
1233 text
.append("<b>" + tr("Date") + ":</b> "
1234 + _dateRange
.first
.toString(format
) + "<br>");
1236 text
.append("<b>" + tr("Date") + ":</b> "
1237 + QString("%1 - %2").arg(_dateRange
.first
.toString(format
),
1238 _dateRange
.second
.toString(format
)) + "<br>");
1242 text
.append("<b>" + tr("Distance") + ":</b> "
1243 + Format::distance(distance(), units()) + "<br>");
1245 text
.append("<b>" + tr("Time") + ":</b> "
1246 + Format::timeSpan(time()) + "<br>");
1247 text
.append("<b>" + tr("Moving time") + ":</b> "
1248 + Format::timeSpan(movingTime()) + "<br>");
1250 text
.append("<br>");
1252 for (int i
= 0; i
< _tabs
.count(); i
++) {
1253 const GraphTab
*tab
= _tabs
.at(i
);
1257 text
.append("<i>" + tab
->label() + "</i><br>");
1258 for (int j
= 0; j
< tab
->info().size(); j
++) {
1259 const KV
<QString
, QString
> &kv
= tab
->info().at(j
);
1260 text
.append("<b>" + kv
.key() + ":</b> " + kv
.value());
1261 if (j
!= tab
->info().size() - 1)
1264 if (i
!= _tabs
.count() - 1)
1265 text
.append("<br><br>");
1268 msgBox
.setWindowTitle(tr("Statistics"));
1269 msgBox
.setText(text
);
1271 #else // Q_OS_ANDROID
1274 text
= "<style>td {white-space: pre; padding-right: 4em;}"
1275 "th {text-align: left; padding-top: 0.5em;}</style><table>";
1277 text
= "<style>td {white-space: pre; padding-right: 2em;}"
1278 "th {text-align: left; padding-top: 0.5em;}</style><table>";
1279 #endif // Q_OS_WIN32
1281 if (_showTracksAction
->isChecked() && _trackCount
> 1)
1282 text
.append("<tr><td>" + tr("Tracks") + ":</td><td>"
1283 + l
.toString(_trackCount
) + "</td></tr>");
1284 if (_showRoutesAction
->isChecked() && _routeCount
> 1)
1285 text
.append("<tr><td>" + tr("Routes") + ":</td><td>"
1286 + l
.toString(_routeCount
) + "</td></tr>");
1287 if (_showWaypointsAction
->isChecked() && _waypointCount
> 1)
1288 text
.append("<tr><td>" + tr("Waypoints") + ":</td><td>"
1289 + l
.toString(_waypointCount
) + "</td></tr>");
1290 if (_showAreasAction
->isChecked() && _areaCount
> 1)
1291 text
.append("<tr><td>" + tr("Areas") + ":</td><td>"
1292 + l
.toString(_areaCount
) + "</td></tr>");
1294 if (_dateRange
.first
.isValid()) {
1295 if (_dateRange
.first
== _dateRange
.second
) {
1296 QString format
= l
.dateFormat(QLocale::LongFormat
);
1297 text
.append("<tr><td>" + tr("Date") + ":</td><td>"
1298 + _dateRange
.first
.toString(format
) + "</td></tr>");
1300 QString format
= l
.dateFormat(QLocale::ShortFormat
);
1301 text
.append("<tr><td>" + tr("Date") + ":</td><td>"
1302 + QString("%1 - %2").arg(_dateRange
.first
.toString(format
),
1303 _dateRange
.second
.toString(format
)) + "</td></tr>");
1308 text
.append("<tr><td>" + tr("Distance") + ":</td><td>"
1309 + Format::distance(distance(), units()) + "</td></tr>");
1311 text
.append("<tr><td>" + tr("Time") + ":</td><td>"
1312 + Format::timeSpan(time()) + "</td></tr>");
1313 text
.append("<tr><td>" + tr("Moving time") + ":</td><td>"
1314 + Format::timeSpan(movingTime()) + "</td></tr>");
1317 for (int i
= 0; i
< _tabs
.count(); i
++) {
1318 const GraphTab
*tab
= _tabs
.at(i
);
1322 text
.append("<tr><th colspan=\"2\">" + tab
->label() + "</th></tr>");
1323 for (int j
= 0; j
< tab
->info().size(); j
++) {
1324 const KV
<QString
, QString
> &kv
= tab
->info().at(j
);
1325 text
.append("<tr><td>" + kv
.key() + ":</td><td>" + kv
.value()
1330 text
.append("</table>");
1332 msgBox
.setWindowTitle(tr("Statistics"));
1333 msgBox
.setText("<h3>" + tr("Statistics") + "</h3>");
1334 msgBox
.setInformativeText(text
);
1335 #endif // Q_OS_ANDROID
1340 void GUI::plotMainPage(QPainter
*painter
, const QRectF
&rect
, qreal ratio
,
1343 QLocale
l(QLocale::system());
1349 if (!_pathName
.isNull() && _options
.printName
)
1350 info
.insert(tr("Name"), _pathName
);
1352 if (_options
.printItemCount
) {
1353 if (_showTracksAction
->isChecked() && _trackCount
> 1)
1354 info
.insert(tr("Tracks"), l
.toString(_trackCount
));
1355 if (_showRoutesAction
->isChecked() && _routeCount
> 1)
1356 info
.insert(tr("Routes"), l
.toString(_routeCount
));
1357 if (_showWaypointsAction
->isChecked() && _waypointCount
> 1)
1358 info
.insert(tr("Waypoints"), l
.toString(_waypointCount
));
1359 if (_showAreasAction
->isChecked() && _areaCount
> 1)
1360 info
.insert(tr("Areas"), l
.toString(_areaCount
));
1363 if (_dateRange
.first
.isValid() && _options
.printDate
) {
1364 if (_dateRange
.first
== _dateRange
.second
) {
1365 QString format
= l
.dateFormat(QLocale::LongFormat
);
1366 info
.insert(tr("Date"), _dateRange
.first
.toString(format
));
1368 QString format
= l
.dateFormat(QLocale::ShortFormat
);
1369 info
.insert(tr("Date"), QString("%1 - %2")
1370 .arg(_dateRange
.first
.toString(format
),
1371 _dateRange
.second
.toString(format
)));
1375 if (distance() > 0 && _options
.printDistance
)
1376 info
.insert(tr("Distance"), Format::distance(distance(), units()));
1377 if (time() > 0 && _options
.printTime
)
1378 info
.insert(tr("Time"), Format::timeSpan(time()));
1379 if (movingTime() > 0 && _options
.printMovingTime
)
1380 info
.insert(tr("Moving time"), Format::timeSpan(movingTime()));
1382 if (info
.isEmpty()) {
1386 ih
= info
.contentSize().height() * ratio
;
1388 info
.plot(painter
, QRectF(rect
.x(), rect
.y(), rect
.width(), ih
), ratio
);
1390 if (_graphTabWidget
->isVisible() && !_options
.separateGraphPage
) {
1391 qreal r
= rect
.width() / rect
.height();
1392 gh
= (rect
.width() > rect
.height())
1393 ? 0.15 * r
* (rect
.height() - ih
- 2*mh
)
1394 : 0.15 * (rect
.height() - ih
- 2*mh
);
1398 GraphTab
*gt
= static_cast<GraphTab
*>(_graphTabWidget
->currentWidget());
1399 gt
->plot(painter
, QRectF(rect
.x(), rect
.y() + rect
.height() - gh
,
1400 rect
.width(), gh
), ratio
);
1406 MapView::PlotFlags flags
;
1407 if (_options
.hiresPrint
)
1408 flags
|= MapView::HiRes
;
1410 flags
|= MapView::Expand
;
1412 _mapView
->plot(painter
, QRectF(rect
.x(), rect
.y() + ih
+ mh
, rect
.width(),
1413 rect
.height() - (ih
+ sc
*mh
+ gh
)), ratio
, flags
);
1416 void GUI::plotGraphsPage(QPainter
*painter
, const QRectF
&rect
, qreal ratio
)
1419 for (int i
= 0; i
< _tabs
.size(); i
++)
1420 if (!_tabs
.at(i
)->isEmpty())
1423 qreal sp
= ratio
* 20;
1424 qreal gh
= qMin((rect
.height() - ((cnt
- 1) * sp
))/(qreal
)cnt
,
1425 0.20 * rect
.height());
1428 for (int i
= 0; i
< _tabs
.size(); i
++) {
1429 if (!_tabs
.at(i
)->isEmpty()) {
1430 _tabs
.at(i
)->plot(painter
, QRectF(rect
.x(), rect
.y() + y
,
1431 rect
.width(), gh
), ratio
);
1437 qreal
GUI::graphPlotHeight(const QRectF
&rect
, qreal ratio
)
1440 for (int i
= 0; i
< _tabs
.size(); i
++)
1441 if (!_tabs
.at(i
)->isEmpty())
1444 qreal sp
= ratio
* 20;
1445 qreal gh
= qMin((rect
.height() - ((cnt
- 1) * sp
))/(qreal
)cnt
,
1446 0.20 * rect
.height());
1448 return cnt
* gh
+ (cnt
- 1) * sp
;
1451 void GUI::plot(QPrinter
*printer
)
1453 QPainter
p(printer
);
1454 qreal fsr
= 1085.0 / (qMax(printer
->width(), printer
->height())
1455 / (qreal
)printer
->resolution());
1456 qreal ratio
= p
.paintEngine()->paintDevice()->logicalDpiX() / fsr
;
1457 QRectF
rect(0, 0, printer
->width(), printer
->height());
1459 plotMainPage(&p
, rect
, ratio
);
1461 if (!_tabs
.isEmpty() && _options
.separateGraphPage
) {
1463 plotGraphsPage(&p
, rect
, ratio
);
1467 void GUI::reloadFiles()
1477 _dateRange
= DateTimeRange(QDateTime(), QDateTime());
1478 _pathName
= QString();
1480 for (int i
= 0; i
< _tabs
.count(); i
++)
1481 _tabs
.at(i
)->clear();
1485 for (int i
= 0; i
< _files
.size(); i
++) {
1486 if (!loadFile(_files
.at(i
), true, showError
)) {
1492 updateStatusBarInfo();
1493 updateWindowTitle();
1494 if (_files
.isEmpty())
1495 _fileActionGroup
->setEnabled(false);
1496 #ifndef Q_OS_ANDROID
1498 _browser
->setCurrent(_files
.last());
1499 #endif // Q_OS_ANDROID
1500 updateDEMDownloadAction();
1503 void GUI::closeFiles()
1513 _dateRange
= DateTimeRange(QDateTime(), QDateTime());
1514 _pathName
= QString();
1516 for (int i
= 0; i
< _tabs
.count(); i
++)
1517 _tabs
.at(i
)->clear();
1525 void GUI::closeAll()
1529 _fileActionGroup
->setEnabled(false);
1530 updateStatusBarInfo();
1531 updateWindowTitle();
1533 updateDEMDownloadAction();
1536 _browser
->setCurrentDir(QString());
1537 #endif // Q_OS_ANDROID
1540 void GUI::showGraphs(bool show
)
1542 _graphTabWidget
->setHidden(!show
);
1546 void GUI::showGraphTabs(bool show
)
1548 _graphTabWidget
->tabBar()->setVisible(show
);
1550 #else // Q_OS_ANDROID
1551 void GUI::showToolbars(bool show
)
1554 Q_ASSERT(!_windowStates
.isEmpty());
1555 restoreState(_windowStates
.last());
1556 _windowStates
.removeLast();
1558 _windowStates
.append(saveState());
1559 removeToolBar(_fileToolBar
);
1560 removeToolBar(_showToolBar
);
1561 removeToolBar(_navigationToolBar
);
1565 void GUI::showFullscreen(bool show
)
1568 _windowGeometries
.append(saveGeometry());
1569 _frameStyle
= _mapView
->frameStyle();
1570 statusBar()->hide();
1572 showToolbars(false);
1573 _mapView
->setFrameStyle(QFrame::NoFrame
);
1574 _graphTabWidget
->tabBar()->hide();
1576 _graphTabWidget
->setDocumentMode(true);
1580 Q_ASSERT(!_windowGeometries
.isEmpty());
1581 _windowGeometries
.removeLast();
1582 statusBar()->show();
1585 _mapView
->setFrameStyle(_frameStyle
);
1586 _graphTabWidget
->tabBar()->show();
1588 _graphTabWidget
->setDocumentMode(false);
1593 #endif // Q_OS_ANDROID
1595 void GUI::showTracks(bool show
)
1597 _mapView
->showTracks(show
);
1599 for (int i
= 0; i
< _tabs
.size(); i
++)
1600 _tabs
.at(i
)->showTracks(show
);
1602 updateStatusBarInfo();
1604 updateDEMDownloadAction();
1607 void GUI::showRoutes(bool show
)
1609 _mapView
->showRoutes(show
);
1611 for (int i
= 0; i
< _tabs
.size(); i
++)
1612 _tabs
.at(i
)->showRoutes(show
);
1614 updateStatusBarInfo();
1616 updateDEMDownloadAction();
1619 void GUI::showWaypoints(bool show
)
1621 _mapView
->showWaypoints(show
);
1622 updateDEMDownloadAction();
1625 void GUI::showAreas(bool show
)
1627 _mapView
->showAreas(show
);
1628 updateDEMDownloadAction();
1631 void GUI::showGraphGrids(bool show
)
1633 for (int i
= 0; i
< _tabs
.size(); i
++)
1634 _tabs
.at(i
)->showGrid(show
);
1637 void GUI::showGraphSliderInfo(bool show
)
1639 for (int i
= 0; i
< _tabs
.size(); i
++)
1640 _tabs
.at(i
)->showSliderInfo(show
);
1643 void GUI::showPathMarkerInfo(QAction
*action
)
1645 if (action
== _showMarkersAction
) {
1646 _mapView
->showMarkers(true);
1647 _mapView
->showMarkerInfo(MarkerInfoItem::None
);
1648 } else if (action
== _showMarkerDateAction
) {
1649 _mapView
->showMarkers(true);
1650 _mapView
->showMarkerInfo(MarkerInfoItem::Date
);
1651 } else if (action
== _showMarkerCoordinatesAction
) {
1652 _mapView
->showMarkers(true);
1653 _mapView
->showMarkerInfo(MarkerInfoItem::Position
);
1655 _mapView
->showMarkers(false);
1656 _mapView
->showMarkerInfo(MarkerInfoItem::None
);
1663 QStringList
files(QFileDialog::getOpenFileNames(this, tr("Open map file"),
1665 #else // Q_OS_ANDROID
1666 QStringList
files(QFileDialog::getOpenFileNames(this, tr("Open map file"),
1667 _mapDir
, MapList::formats()));
1668 #endif // Q_OS_ANDROID
1669 MapAction
*a
, *lastReady
= 0;
1671 for (int i
= 0; i
< files
.size(); i
++) {
1672 if (loadMap(files
.at(i
), a
) && a
)
1675 if (!files
.isEmpty())
1676 _mapDir
= QFileInfo(files
.last()).path();
1678 lastReady
->trigger();
1681 static MapAction
*findMapAction(const QList
<QAction
*> &mapActions
,
1684 for (int i
= 0; i
< mapActions
.count(); i
++) {
1685 const Map
*m
= mapActions
.at(i
)->data().value
<Map
*>();
1686 if (map
->path() == m
->path())
1687 return static_cast<MapAction
*>(mapActions
.at(i
));
1693 bool GUI::loadMapNode(const TreeNode
<Map
*> &node
, MapAction
*&action
,
1694 bool silent
, const QList
<QAction
*> &existingActions
)
1700 for (int i
= 0; i
< node
.childs().size(); i
++)
1701 valid
= loadMapNode(node
.childs().at(i
), action
, silent
, existingActions
);
1703 for (int i
= 0; i
< node
.items().size(); i
++) {
1704 Map
*map
= node
.items().at(i
);
1707 if (!(a
= findMapAction(existingActions
, map
))) {
1708 if (!map
->isValid()) {
1710 QMessageBox::critical(this, APP_NAME
,
1711 tr("Error loading map:") + "\n"
1712 + Util::displayName(map
->path()) + ": "
1713 + map
->errorString());
1717 a
= new MapAction(map
, _mapsActionGroup
);
1718 _mapMenu
->insertAction(_mapsEnd
, a
);
1720 if (map
->isReady()) {
1722 _showMapAction
->setEnabled(true);
1723 _clearMapCacheAction
->setEnabled(true);
1725 connect(a
, &MapAction::loaded
, this, &GUI::mapLoaded
);
1729 map
= a
->data().value
<Map
*>();
1738 bool GUI::loadMap(const QString
&fileName
, MapAction
*&action
, bool silent
)
1740 TreeNode
<Map
*> maps(MapList::loadMaps(fileName
));
1741 QList
<QAction
*> existingActions(_mapsActionGroup
->actions());
1743 return loadMapNode(maps
, action
, silent
, existingActions
);
1746 void GUI::mapLoaded()
1748 MapAction
*action
= static_cast<MapAction
*>(QObject::sender());
1749 Map
*map
= action
->data().value
<Map
*>();
1751 if (map
->isValid()) {
1753 _showMapAction
->setEnabled(true);
1754 _clearMapCacheAction
->setEnabled(true);
1756 QString error
= tr("Error loading map:") + "\n"
1757 + Util::displayName(map
->path()) + ": " + map
->errorString();
1758 QMessageBox::critical(this, APP_NAME
, error
);
1759 action
->deleteLater();
1763 void GUI::mapLoadedDir()
1765 MapAction
*action
= static_cast<MapAction
*>(QObject::sender());
1766 Map
*map
= action
->data().value
<Map
*>();
1768 if (map
->isValid()) {
1769 _showMapAction
->setEnabled(true);
1770 _clearMapCacheAction
->setEnabled(true);
1771 QList
<MapAction
*> actions
;
1772 actions
.append(action
);
1773 _mapView
->loadMaps(actions
);
1775 QString error
= tr("Error loading map:") + "\n"
1776 + Util::displayName(map
->path()) + ": " + map
->errorString();
1777 QMessageBox::critical(this, APP_NAME
, error
);
1778 action
->deleteLater();
1782 void GUI::loadMapDirNode(const TreeNode
<Map
*> &node
, QList
<MapAction
*> &actions
,
1783 QMenu
*menu
, const QList
<QAction
*> &existingActions
)
1785 for (int i
= 0; i
< node
.childs().size(); i
++) {
1786 QMenu
*cm
= new QMenu(node
.childs().at(i
).name(), menu
);
1788 loadMapDirNode(node
.childs().at(i
), actions
, cm
, existingActions
);
1791 for (int i
= 0; i
< node
.items().size(); i
++) {
1792 Map
*map
= node
.items().at(i
);
1795 if (!(a
= findMapAction(existingActions
, map
))) {
1796 if (!map
->isValid()) {
1797 QMessageBox::critical(this, APP_NAME
, tr("Error loading map:")
1798 + "\n" + Util::displayName(map
->path()) + ": "
1799 + map
->errorString());
1802 a
= new MapAction(map
, _mapsActionGroup
);
1805 if (map
->isReady()) {
1806 _showMapAction
->setEnabled(true);
1807 _clearMapCacheAction
->setEnabled(true);
1810 connect(a
, &MapAction::loaded
, this, &GUI::mapLoadedDir
);
1815 map
= a
->data().value
<Map
*>();
1822 void GUI::loadMapDir()
1824 QString
dir(QFileDialog::getExistingDirectory(this,
1825 tr("Select map directory"), _mapDir
, QFileDialog::ShowDirsOnly
));
1830 TreeNode
<Map
*> maps(MapList::loadMaps(dir
));
1831 QList
<QAction
*> existingActions(_mapsActionGroup
->actions());
1832 QList
<MapAction
*> actions
;
1833 QMenu
*menu
= new QMenu(maps
.name());
1835 loadMapDirNode(maps
, actions
, menu
, existingActions
);
1837 _mapView
->loadMaps(actions
);
1839 if (menu
->isEmpty())
1842 _mapMenu
->insertMenu(_mapsEnd
, menu
);
1844 _mapDir
= fi
.absolutePath();
1845 _fileActionGroup
->setEnabled(true);
1846 _reloadFileAction
->setEnabled(false);
1849 void GUI::clearMapCache()
1851 if (QMessageBox::question(this, APP_NAME
,
1852 tr("Clear \"%1\" tile cache?").arg(_map
->name())) == QMessageBox::Yes
)
1853 _mapView
->clearMapCache();
1856 void GUI::downloadDEM()
1858 RectC
br(_mapView
->boundingRect());
1859 _demRects
.append(br
);
1861 if (!_dem
->loadTiles(br
) && _demRects
.size() == 1)
1865 void GUI::demLoaded()
1867 for (int i
= 0; i
< _demRects
.size(); i
++) {
1868 if (!_dem
->checkTiles(_demRects
.at(i
))) {
1869 QMessageBox::warning(this, APP_NAME
,
1870 tr("Could not download all required DEM files."));
1880 void GUI::showDEMTiles()
1882 QList
<Area
> tiles(DEM::tiles());
1884 if (tiles
.isEmpty()) {
1885 QMessageBox::information(this, APP_NAME
, tr("No local DEM tiles found."));
1887 _mapView
->loadDEMs(tiles
);
1889 _areaCount
+= tiles
.size();
1891 _fileActionGroup
->setEnabled(true);
1892 _reloadFileAction
->setEnabled(false);
1896 void GUI::updateStatusBarInfo()
1898 if (_files
.count() == 0)
1899 _fileNameLabel
->setText(tr("No files loaded"));
1900 else if (_files
.count() == 1)
1901 _fileNameLabel
->setText(Util::displayName(_files
.at(0)));
1903 _fileNameLabel
->setText(tr("%n files", "", _files
.count()));
1906 _distanceLabel
->setText(Format::distance(distance(), units()));
1908 _distanceLabel
->clear();
1911 if (_movingTimeAction
->isChecked()) {
1912 _timeLabel
->setText(Format::timeSpan(movingTime())
1914 _timeLabel
->setToolTip(Format::timeSpan(time()));
1916 _timeLabel
->setText(Format::timeSpan(time()));
1917 _timeLabel
->setToolTip(Format::timeSpan(movingTime())
1921 _timeLabel
->clear();
1922 _timeLabel
->setToolTip(QString());
1926 statusBar()->setVisible(!_files
.isEmpty());
1927 #endif // Q_OS_ANDROID
1930 void GUI::updateWindowTitle()
1932 if (_files
.count() == 1)
1933 setWindowTitle(QFileInfo(_files
.at(0)).fileName() + " - " + APP_NAME
);
1935 setWindowTitle(APP_NAME
);
1938 void GUI::mapChanged(QAction
*action
)
1940 _map
= action
->data().value
<Map
*>();
1941 _mapView
->setMap(_map
);
1946 QAction
*checked
= _mapsActionGroup
->checkedAction();
1950 QList
<QAction
*> maps(_mapsActionGroup
->actions());
1951 for (int i
= 1; i
< maps
.size(); i
++) {
1952 int next
= (maps
.indexOf(checked
) + i
) % maps
.count();
1953 if (maps
.at(next
)->isEnabled()) {
1954 maps
.at(next
)->trigger();
1962 QAction
*checked
= _mapsActionGroup
->checkedAction();
1966 QList
<QAction
*> maps(_mapsActionGroup
->actions());
1967 for (int i
= 1; i
< maps
.size(); i
++) {
1968 int prev
= (maps
.indexOf(checked
) + maps
.count() - i
) % maps
.count();
1969 if (maps
.at(prev
)->isEnabled()) {
1970 maps
.at(prev
)->trigger();
1976 void GUI::poiFileChecked(QAction
*action
)
1978 _poi
->enableFile(action
->data().value
<QString
>(), action
->isChecked());
1981 void GUI::selectAllPOIs()
1983 QList
<QAction
*> actions(_poisActionGroup
->actions());
1984 for (int i
= 0; i
< actions
.size(); i
++) {
1985 POIAction
*a
= static_cast<POIAction
*>(actions
.at(i
));
1986 if (_poi
->enableFile(a
->data().toString(), true))
1987 a
->setChecked(true);
1991 void GUI::unselectAllPOIs()
1993 QList
<QAction
*> actions(_poisActionGroup
->actions());
1994 for (int i
= 0; i
< actions
.size(); i
++) {
1995 POIAction
*a
= static_cast<POIAction
*>(actions
.at(i
));
1996 if (_poi
->enableFile(a
->data().toString(), false))
1997 a
->setChecked(false);
2001 void GUI::graphChanged(int index
)
2006 GraphTab
*gt
= static_cast<GraphTab
*>(_graphTabWidget
->widget(index
));
2008 _mapView
->setGraph(_tabs
.indexOf(gt
));
2011 gt
->setSliderPosition(_lastTab
->sliderPosition());
2015 void GUI::updateNavigationActions()
2018 _navigation
->enableNext(!_browser
->isLast()
2019 && !_browser
->current().isNull());
2020 _navigation
->enablePrev(!_browser
->isFirst()
2021 && !_browser
->current().isNull());
2022 #else // Q_OS_ANDROID
2023 _lastAction
->setEnabled(!_browser
->isLast());
2024 _nextAction
->setEnabled(!_browser
->isLast());
2025 _firstAction
->setEnabled(!_browser
->isFirst());
2026 _prevAction
->setEnabled(!_browser
->isFirst());
2027 #endif // Q_OS_ANDROID
2030 bool GUI::updateGraphTabs()
2034 bool hidden
= _graphTabWidget
->isHidden();
2036 for (int i
= 0; i
< _tabs
.size(); i
++) {
2038 if (tab
->isEmpty() && (index
= _graphTabWidget
->indexOf(tab
)) >= 0)
2039 _graphTabWidget
->removeTab(index
);
2042 for (int i
= 0; i
< _tabs
.size(); i
++) {
2044 if (!tab
->isEmpty() && _graphTabWidget
->indexOf(tab
) < 0)
2045 _graphTabWidget
->insertTab(i
, tab
, _tabs
.at(i
)->label());
2048 if (_graphTabWidget
->count() &&
2049 ((_showTracksAction
->isChecked() && _trackCount
)
2050 || (_showRoutesAction
->isChecked() && _routeCount
))) {
2051 if (_showGraphsAction
->isChecked())
2052 _graphTabWidget
->setHidden(false);
2053 _showGraphsAction
->setEnabled(true);
2055 _graphTabWidget
->setHidden(true);
2056 _showGraphsAction
->setEnabled(false);
2059 return (hidden
!= _graphTabWidget
->isHidden());
2062 void GUI::updateDEMDownloadAction()
2064 _downloadDEMAction
->setEnabled(!_dem
->url().isEmpty()
2065 && !_dem
->checkTiles(_mapView
->boundingRect()));
2068 void GUI::setTimeType(TimeType type
)
2070 for (int i
= 0; i
<_tabs
.count(); i
++)
2071 _tabs
.at(i
)->setTimeType(type
);
2073 updateStatusBarInfo();
2076 void GUI::setUnits(Units units
)
2080 _mapView
->setUnits(units
);
2081 for (int i
= 0; i
<_tabs
.count(); i
++)
2082 _tabs
.at(i
)->setUnits(units
);
2083 updateStatusBarInfo();
2086 void GUI::setCoordinatesFormat(CoordinatesFormat format
)
2088 _mapView
->setCoordinatesFormat(format
);
2091 void GUI::setGraphType(GraphType type
)
2093 for (int i
= 0; i
<_tabs
.count(); i
++)
2094 _tabs
.at(i
)->setGraphType(type
);
2100 QString file
= _browser
->next();
2105 openFile(file
, true, showError
);
2111 QString file
= _browser
->prev();
2116 openFile(file
, true, showError
);
2122 QString file
= _browser
->last();
2127 openFile(file
, true, showError
);
2133 QString file
= _browser
->first();
2138 openFile(file
, true, showError
);
2141 #ifndef Q_OS_ANDROID
2142 void GUI::keyPressEvent(QKeyEvent
*event
)
2147 switch (event
->key()) {
2149 file
= _browser
->prev();
2152 file
= _browser
->next();
2155 file
= _browser
->first();
2158 file
= _browser
->last();
2161 case TOGGLE_GRAPH_TYPE_KEY
:
2162 if (_timeGraphAction
->isChecked())
2163 _distanceGraphAction
->trigger();
2165 _timeGraphAction
->trigger();
2167 case TOGGLE_TIME_TYPE_KEY
:
2168 if (_movingTimeAction
->isChecked())
2169 _totalTimeAction
->trigger();
2171 _movingTimeAction
->trigger();
2173 case TOGGLE_MARKER_INFO_KEY
:
2174 if (_showMarkerDateAction
->isChecked())
2175 _showMarkerCoordinatesAction
->trigger();
2176 else if (_showMarkerCoordinatesAction
->isChecked())
2177 _showMarkerDateAction
->trigger();
2179 case Qt::Key_Escape
:
2180 if (_fullscreenAction
->isChecked()) {
2181 _fullscreenAction
->setChecked(false);
2182 showFullscreen(false);
2188 if (!file
.isNull()) {
2189 if (!(event
->modifiers() & MODIFIER
))
2191 openFile(file
, false, showError
);
2195 QMainWindow::keyPressEvent(event
);
2197 #endif // Q_OS_ANDROID
2199 void GUI::closeEvent(QCloseEvent
*event
)
2202 QMainWindow::closeEvent(event
);
2205 void GUI::dragEnterEvent(QDragEnterEvent
*event
)
2207 if (!event
->mimeData()->hasUrls())
2209 if (event
->proposedAction() != Qt::CopyAction
)
2212 QList
<QUrl
> urls
= event
->mimeData()->urls();
2213 for (int i
= 0; i
< urls
.size(); i
++)
2214 if (!urls
.at(i
).isLocalFile())
2217 event
->acceptProposedAction();
2220 void GUI::dropEvent(QDropEvent
*event
)
2222 MapAction
*lastReady
= 0;
2223 QList
<QUrl
> urls(event
->mimeData()->urls());
2225 int showError
= (urls
.size() > 1) ? 2 : 1;
2227 for (int i
= 0; i
< urls
.size(); i
++) {
2228 QString
file(urls
.at(i
).toLocalFile());
2230 if (!openFile(file
, false, silent
)) {
2232 if (!loadMap(file
, a
, true))
2233 openFile(file
, true, showError
);
2242 lastReady
->trigger();
2244 event
->acceptProposedAction();
2247 QGeoPositionInfoSource
*GUI::positionSource(const Options
&options
)
2249 QGeoPositionInfoSource
*source
;
2251 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
2252 source
= QGeoPositionInfoSource::createSource(options
.plugin
, this);
2254 source
= QGeoPositionInfoSource::createSource(options
.plugin
,
2255 options
.pluginParams
.value(options
.plugin
), this);
2258 source
->setPreferredPositioningMethods(
2259 QGeoPositionInfoSource::SatellitePositioningMethods
);
2264 void GUI::writeSettings()
2266 #define WRITE(name, value) \
2267 Settings::name.write(settings, value);
2269 QSettings
settings(qApp
->applicationName(), qApp
->applicationName());
2273 #ifndef Q_OS_ANDROID
2274 settings
.beginGroup(SETTINGS_WINDOW
);
2275 if (!_windowStates
.isEmpty() && !_windowGeometries
.isEmpty()) {
2276 WRITE(windowState
, _windowStates
.first());
2277 WRITE(windowGeometry
, _windowGeometries
.first());
2279 WRITE(windowState
, saveState());
2280 WRITE(windowGeometry
, saveGeometry());
2282 settings
.endGroup();
2283 #endif // Q_OS_ANDROID
2286 settings
.beginGroup(SETTINGS_SETTINGS
);
2287 WRITE(timeType
, _movingTimeAction
->isChecked() ? Moving
: Total
);
2288 WRITE(units
, _imperialUnitsAction
->isChecked()
2289 ? Imperial
: _nauticalUnitsAction
->isChecked()
2290 ? Nautical
: Metric
);
2291 WRITE(coordinatesFormat
, _dmsAction
->isChecked()
2292 ? DMS
: _degreesMinutesAction
->isChecked()
2293 ? DegreesMinutes
: DecimalDegrees
);
2294 #ifndef Q_OS_ANDROID
2295 WRITE(showToolbars
, _showToolbarsAction
->isChecked());
2296 #endif // Q_OS_ANDROID
2297 settings
.endGroup();
2300 settings
.beginGroup(SETTINGS_MAP
);
2301 WRITE(activeMap
, _map
->name());
2302 WRITE(showMap
, _showMapAction
->isChecked());
2303 WRITE(cursorCoordinates
, _showCoordinatesAction
->isChecked());
2304 settings
.endGroup();
2307 settings
.beginGroup(SETTINGS_GRAPH
);
2308 WRITE(showGraphs
, _showGraphsAction
->isChecked());
2309 WRITE(graphType
, _timeGraphAction
->isChecked() ? Time
: Distance
);
2310 WRITE(showGrid
, _showGraphGridAction
->isChecked());
2311 WRITE(sliderInfo
, _showGraphSliderInfoAction
->isChecked());
2313 WRITE(showGraphTabs
, _showGraphTabsAction
->isChecked());
2314 #endif // Q_OS_ANDROID
2315 settings
.endGroup();
2318 QList
<QAction
*> actions(_poisActionGroup
->actions());
2319 QStringList disabled
;
2320 for (int i
= 0; i
< actions
.size(); i
++)
2321 if (!actions
.at(i
)->isChecked())
2322 disabled
.append(actions
.at(i
)->data().toString());
2324 settings
.beginGroup(SETTINGS_POI
);
2325 WRITE(showPoi
, _showPOIAction
->isChecked());
2326 WRITE(poiOverlap
, _overlapPOIAction
->isChecked());
2327 WRITE(poiLabels
, _showPOILabelsAction
->isChecked());
2328 WRITE(poiIcons
, _showPOIIconsAction
->isChecked());
2329 WRITE(disabledPoiFiles
, disabled
);
2330 settings
.endGroup();
2333 MarkerInfoItem::Type mi
;
2334 if (_showMarkerDateAction
->isChecked())
2335 mi
= MarkerInfoItem::Date
;
2336 else if (_showMarkerCoordinatesAction
->isChecked())
2337 mi
= MarkerInfoItem::Position
;
2339 mi
= MarkerInfoItem::None
;
2341 settings
.beginGroup(SETTINGS_DATA
);
2342 WRITE(tracks
, _showTracksAction
->isChecked());
2343 WRITE(routes
, _showRoutesAction
->isChecked());
2344 WRITE(waypoints
, _showWaypointsAction
->isChecked());
2345 WRITE(areas
, _showAreasAction
->isChecked());
2346 WRITE(waypointIcons
, _showWaypointIconsAction
->isChecked());
2347 WRITE(waypointLabels
, _showWaypointLabelsAction
->isChecked());
2348 WRITE(routeWaypoints
, _showRouteWaypointsAction
->isChecked());
2349 WRITE(pathTicks
, _showTicksAction
->isChecked());
2350 WRITE(positionMarkers
, _showMarkersAction
->isChecked()
2351 || _showMarkerDateAction
->isChecked()
2352 || _showMarkerCoordinatesAction
->isChecked());
2353 WRITE(markerInfo
, mi
);
2354 WRITE(useStyles
, _useStylesAction
->isChecked());
2355 settings
.endGroup();
2358 settings
.beginGroup(SETTINGS_POSITION
);
2359 WRITE(showPosition
, _showPositionAction
->isChecked());
2360 WRITE(followPosition
, _followPositionAction
->isChecked());
2361 WRITE(positionCoordinates
, _showPositionCoordinatesAction
->isChecked());
2362 WRITE(motionInfo
, _showMotionInfoAction
->isChecked());
2363 settings
.endGroup();
2366 settings
.beginGroup(SETTINGS_PDF_EXPORT
);
2367 WRITE(pdfOrientation
, _pdfExport
.orientation
);
2368 WRITE(pdfResolution
, _pdfExport
.resolution
);
2369 WRITE(pdfSize
, _pdfExport
.paperSize
);
2370 WRITE(pdfMarginLeft
, _pdfExport
.margins
.left());
2371 WRITE(pdfMarginTop
, _pdfExport
.margins
.top());
2372 WRITE(pdfMarginRight
, _pdfExport
.margins
.right());
2373 WRITE(pdfMarginBottom
, _pdfExport
.margins
.bottom());
2374 WRITE(pdfFileName
, _pdfExport
.fileName
);
2375 settings
.endGroup();
2378 settings
.beginGroup(SETTINGS_PNG_EXPORT
);
2379 WRITE(pngWidth
, _pngExport
.size
.width());
2380 WRITE(pngHeight
, _pngExport
.size
.height());
2381 WRITE(pngMarginLeft
, _pngExport
.margins
.left());
2382 WRITE(pngMarginTop
, _pngExport
.margins
.top());
2383 WRITE(pngMarginRight
, _pngExport
.margins
.right());
2384 WRITE(pngMarginBottom
, _pngExport
.margins
.bottom());
2385 WRITE(pngAntialiasing
, _pngExport
.antialiasing
);
2386 WRITE(pngFileName
, _pngExport
.fileName
);
2387 settings
.endGroup();
2390 settings
.beginGroup(SETTINGS_OPTIONS
);
2391 WRITE(paletteColor
, _options
.palette
.color());
2392 WRITE(paletteShift
, _options
.palette
.shift());
2393 WRITE(mapOpacity
, _options
.mapOpacity
);
2394 WRITE(backgroundColor
, _options
.backgroundColor
);
2395 WRITE(crosshairColor
, _options
.crosshairColor
);
2396 WRITE(infoColor
, _options
.infoColor
);
2397 WRITE(infoBackground
, _options
.infoBackground
);
2398 WRITE(trackWidth
, _options
.trackWidth
);
2399 WRITE(routeWidth
, _options
.routeWidth
);
2400 WRITE(areaWidth
, _options
.areaWidth
);
2401 WRITE(trackStyle
, (int)_options
.trackStyle
);
2402 WRITE(routeStyle
, (int)_options
.routeStyle
);
2403 WRITE(areaStyle
, (int)_options
.areaStyle
);
2404 WRITE(areaOpacity
, _options
.areaOpacity
);
2405 WRITE(waypointSize
, _options
.waypointSize
);
2406 WRITE(waypointColor
, _options
.waypointColor
);
2407 WRITE(poiSize
, _options
.poiSize
);
2408 WRITE(poiColor
, _options
.poiColor
);
2409 WRITE(graphWidth
, _options
.graphWidth
);
2410 WRITE(pathAntiAliasing
, _options
.pathAntiAliasing
);
2411 WRITE(graphAntiAliasing
, _options
.graphAntiAliasing
);
2412 WRITE(elevationFilter
, _options
.elevationFilter
);
2413 WRITE(speedFilter
, _options
.speedFilter
);
2414 WRITE(heartRateFilter
, _options
.heartRateFilter
);
2415 WRITE(cadenceFilter
, _options
.cadenceFilter
);
2416 WRITE(powerFilter
, _options
.powerFilter
);
2417 WRITE(outlierEliminate
, _options
.outlierEliminate
);
2418 WRITE(automaticPause
, _options
.automaticPause
);
2419 WRITE(pauseSpeed
, _options
.pauseSpeed
);
2420 WRITE(pauseInterval
, _options
.pauseInterval
);
2421 WRITE(useReportedSpeed
, _options
.useReportedSpeed
);
2422 WRITE(dataUseDEM
, _options
.dataUseDEM
);
2423 WRITE(secondaryElevation
, _options
.showSecondaryElevation
);
2424 WRITE(secondarySpeed
, _options
.showSecondarySpeed
);
2425 WRITE(timeZone
, QVariant::fromValue(_options
.timeZone
));
2426 WRITE(useSegments
, _options
.useSegments
);
2427 WRITE(poiRadius
, _options
.poiRadius
);
2428 WRITE(demURL
, _options
.demURL
);
2429 WRITE(demAuthentication
, _options
.demAuthorization
);
2430 WRITE(demUsername
, _options
.demUsername
);
2431 WRITE(demPassword
, _options
.demPassword
);
2432 WRITE(positionPlugin(), _options
.plugin
);
2433 WRITE(positionPluginParameters
, _options
.pluginParams
);
2434 WRITE(useOpenGL
, _options
.useOpenGL
);
2435 WRITE(enableHTTP2
, _options
.enableHTTP2
);
2436 WRITE(pixmapCache
, _options
.pixmapCache
);
2437 WRITE(demCache
, _options
.demCache
);
2438 WRITE(connectionTimeout
, _options
.connectionTimeout
);
2439 WRITE(hiresPrint
, _options
.hiresPrint
);
2440 WRITE(printName
, _options
.printName
);
2441 WRITE(printDate
, _options
.printDate
);
2442 WRITE(printDistance
, _options
.printDistance
);
2443 WRITE(printTime
, _options
.printTime
);
2444 WRITE(printMovingTime
, _options
.printMovingTime
);
2445 WRITE(printItemCount
, _options
.printItemCount
);
2446 WRITE(separateGraphPage
, _options
.separateGraphPage
);
2447 WRITE(sliderColor
, _options
.sliderColor
);
2448 WRITE(outputProjection
, _options
.outputProjection
);
2449 WRITE(inputProjection
, _options
.inputProjection
);
2450 WRITE(hidpiMap
, _options
.hidpiMap
);
2451 WRITE(dataPath
, _options
.dataPath
);
2452 WRITE(mapsPath
, _options
.mapsPath
);
2453 WRITE(poiPath
, _options
.poiPath
);
2454 settings
.endGroup();
2457 void GUI::readSettings(QString
&activeMap
, QStringList
&disabledPOIs
)
2459 #define READ(name) \
2460 (Settings::name.read(settings))
2462 QSettings
settings(qApp
->applicationName(), qApp
->applicationName());
2464 #ifndef Q_OS_ANDROID
2465 settings
.beginGroup(SETTINGS_WINDOW
);
2466 restoreGeometry(READ(windowGeometry
).toByteArray());
2467 restoreState(READ(windowState
).toByteArray());
2468 settings
.endGroup();
2469 #endif // Q_OS_ANDROID
2472 settings
.beginGroup(SETTINGS_SETTINGS
);
2473 TimeType tt
= (TimeType
)READ(timeType
).toInt();
2475 _movingTimeAction
->setChecked(true);
2477 _totalTimeAction
->setChecked(true);
2480 Units u
= (Units
)READ(units
).toInt();
2482 _imperialUnitsAction
->setChecked(true);
2483 else if (u
== Nautical
)
2484 _nauticalUnitsAction
->setChecked(true);
2486 _metricUnitsAction
->setChecked(true);
2489 CoordinatesFormat cf
= (CoordinatesFormat
)READ(coordinatesFormat
).toInt();
2491 _dmsAction
->setChecked(true);
2492 else if (cf
== DegreesMinutes
)
2493 _degreesMinutesAction
->setChecked(true);
2495 _decimalDegreesAction
->setChecked(true);
2496 setCoordinatesFormat(cf
);
2498 #ifndef Q_OS_ANDROID
2499 if (READ(showToolbars
).toBool())
2500 _showToolbarsAction
->setChecked(true);
2502 showToolbars(false);
2503 #endif // Q_OS_ANDROID
2504 settings
.endGroup();
2507 settings
.beginGroup(SETTINGS_MAP
);
2508 if (READ(showMap
).toBool()) {
2509 _showMapAction
->setChecked(true);
2510 _mapView
->showMap(true);
2512 if (READ(cursorCoordinates
).toBool()) {
2513 _showCoordinatesAction
->setChecked(true);
2514 _mapView
->showCursorCoordinates(true);
2516 activeMap
= READ(activeMap
).toString();
2517 settings
.endGroup();
2520 settings
.beginGroup(SETTINGS_GRAPH
);
2521 if (READ(showGraphs
).toBool())
2522 _showGraphsAction
->setChecked(true);
2526 GraphType gt
= (GraphType
)READ(graphType
).toInt();
2528 _timeGraphAction
->setChecked(true);
2530 _distanceGraphAction
->setChecked(true);
2533 if (READ(showGrid
).toBool())
2534 _showGraphGridAction
->setChecked(true);
2536 showGraphGrids(false);
2538 if (READ(sliderInfo
).toBool())
2539 _showGraphSliderInfoAction
->setChecked(true);
2541 showGraphSliderInfo(false);
2544 if (READ(showGraphTabs
).toBool())
2545 _showGraphTabsAction
->setChecked(true);
2547 showGraphTabs(false);
2548 #endif // Q_OS_ANDROID
2549 settings
.endGroup();
2552 settings
.beginGroup(SETTINGS_POI
);
2553 if (READ(poiOverlap
).toBool()) {
2554 _overlapPOIAction
->setChecked(true);
2555 _mapView
->showOverlappedPOIs(true);
2557 if (READ(poiIcons
).toBool()) {
2558 _showPOIIconsAction
->setChecked(true);
2559 _mapView
->showPOIIcons(true);
2561 if (READ(poiLabels
).toBool()) {
2562 _showPOILabelsAction
->setChecked(true);
2563 _mapView
->showPOILabels(true);
2565 if (READ(showPoi
).toBool()) {
2566 _showPOIAction
->setChecked(true);
2567 _mapView
->showPOI(true);
2569 disabledPOIs
= READ(disabledPoiFiles
);
2570 settings
.endGroup();
2573 settings
.beginGroup(SETTINGS_DATA
);
2574 if (READ(tracks
).toBool()) {
2575 _showTracksAction
->setChecked(true);
2576 _mapView
->showTracks(true);
2577 for (int i
= 0; i
< _tabs
.count(); i
++)
2578 _tabs
.at(i
)->showTracks(true);
2580 if (READ(routes
).toBool()) {
2581 _showRoutesAction
->setChecked(true);
2582 _mapView
->showRoutes(true);
2583 for (int i
= 0; i
< _tabs
.count(); i
++)
2584 _tabs
.at(i
)->showRoutes(true);
2586 if (READ(waypoints
).toBool()) {
2587 _showWaypointsAction
->setChecked(true);
2588 _mapView
->showWaypoints(true);
2590 if (READ(areas
).toBool()) {
2591 _showAreasAction
->setChecked(true);
2592 _mapView
->showAreas(true);
2594 if (READ(waypointIcons
).toBool()) {
2595 _showWaypointIconsAction
->setChecked(true);
2596 _mapView
->showWaypointIcons(true);
2598 if (READ(waypointLabels
).toBool()) {
2599 _showWaypointLabelsAction
->setChecked(true);
2600 _mapView
->showWaypointLabels(true);
2602 if (READ(routeWaypoints
).toBool()) {
2603 _showRouteWaypointsAction
->setChecked(true);
2604 _mapView
->showRouteWaypoints(true);
2606 if (READ(pathTicks
).toBool()) {
2607 _showTicksAction
->setChecked(true);
2608 _mapView
->showTicks(true);
2610 if (READ(useStyles
).toBool()) {
2611 _useStylesAction
->setChecked(true);
2612 _mapView
->useStyles(true);
2614 if (READ(positionMarkers
).toBool()) {
2615 MarkerInfoItem::Type mt
= (MarkerInfoItem::Type
)READ(markerInfo
).toInt();
2616 if (mt
== MarkerInfoItem::Position
)
2617 _showMarkerCoordinatesAction
->setChecked(true);
2618 else if (mt
== MarkerInfoItem::Date
)
2619 _showMarkerDateAction
->setChecked(true);
2621 _showMarkersAction
->setChecked(true);
2623 _mapView
->showMarkers(true);
2624 _mapView
->showMarkerInfo(mt
);
2626 _hideMarkersAction
->setChecked(true);
2627 settings
.endGroup();
2630 settings
.beginGroup(SETTINGS_POSITION
);
2631 if (READ(showPosition
).toBool()) {
2632 _showPositionAction
->setChecked(true);
2633 _mapView
->showPosition(true);
2635 if (READ(followPosition
).toBool()) {
2636 _followPositionAction
->setChecked(true);
2637 _mapView
->followPosition(true);
2639 if (READ(positionCoordinates
).toBool()) {
2640 _showPositionCoordinatesAction
->setChecked(true);
2641 _mapView
->showPositionCoordinates(true);
2643 if (READ(motionInfo
).toBool()) {
2644 _showMotionInfoAction
->setChecked(true);
2645 _mapView
->showMotionInfo(true);
2647 settings
.endGroup();
2650 settings
.beginGroup(SETTINGS_PDF_EXPORT
);
2651 _pdfExport
.orientation
= (QPageLayout::Orientation
)READ(pdfOrientation
)
2653 _pdfExport
.resolution
= READ(pdfResolution
).toInt();
2654 _pdfExport
.paperSize
= (QPageSize::PageSizeId
)READ(pdfSize
).toInt();
2655 _pdfExport
.margins
= QMarginsF(READ(pdfMarginLeft
).toReal(),
2656 READ(pdfMarginTop
).toReal(), READ(pdfMarginRight
).toReal(),
2657 READ(pdfMarginBottom
).toReal());
2658 _pdfExport
.fileName
= READ(pdfFileName
).toString();
2659 settings
.endGroup();
2662 settings
.beginGroup(SETTINGS_PNG_EXPORT
);
2663 _pngExport
.size
= QSize(READ(pngWidth
).toInt(), READ(pngHeight
).toInt());
2664 _pngExport
.margins
= QMargins(READ(pngMarginLeft
).toInt(),
2665 READ(pngMarginTop
).toInt(), READ(pngMarginRight
).toInt(),
2666 READ(pngMarginBottom
).toInt());
2667 _pngExport
.antialiasing
= READ(pngAntialiasing
).toBool();
2668 _pngExport
.fileName
= READ(pngFileName
).toString();
2669 settings
.endGroup();
2672 settings
.beginGroup(SETTINGS_OPTIONS
);
2673 _options
.palette
= Palette(READ(paletteColor
).value
<QColor
>(),
2674 READ(paletteShift
).toDouble());
2675 _options
.mapOpacity
= READ(mapOpacity
).toInt();
2676 _options
.backgroundColor
= READ(backgroundColor
).value
<QColor
>();
2677 _options
.crosshairColor
= READ(crosshairColor
).value
<QColor
>();
2678 _options
.infoColor
= READ(infoColor
).value
<QColor
>();
2679 _options
.infoBackground
= READ(infoBackground
).toBool();
2680 _options
.trackWidth
= READ(trackWidth
).toInt();
2681 _options
.routeWidth
= READ(routeWidth
).toInt();
2682 _options
.areaWidth
= READ(areaWidth
).toInt();
2683 _options
.trackStyle
= (Qt::PenStyle
)READ(trackStyle
).toInt();
2684 _options
.routeStyle
= (Qt::PenStyle
)READ(routeStyle
).toInt();
2685 _options
.areaStyle
= (Qt::PenStyle
)READ(areaStyle
).toInt();
2686 _options
.areaOpacity
= READ(areaOpacity
).toInt();
2687 _options
.pathAntiAliasing
= READ(pathAntiAliasing
).toBool();
2688 _options
.waypointSize
= READ(waypointSize
).toInt();
2689 _options
.waypointColor
= READ(waypointColor
).value
<QColor
>();
2690 _options
.poiSize
= READ(poiSize
).toInt();
2691 _options
.poiColor
= READ(poiColor
).value
<QColor
>();
2692 _options
.graphWidth
= READ(graphWidth
).toInt();
2693 _options
.graphAntiAliasing
= READ(graphAntiAliasing
).toBool();
2694 _options
.elevationFilter
= READ(elevationFilter
).toInt();
2695 _options
.speedFilter
= READ(speedFilter
).toInt();
2696 _options
.heartRateFilter
= READ(heartRateFilter
).toInt();
2697 _options
.cadenceFilter
= READ(cadenceFilter
).toInt();
2698 _options
.powerFilter
= READ(powerFilter
).toInt();
2699 _options
.outlierEliminate
= READ(outlierEliminate
).toBool();
2700 _options
.pauseSpeed
= READ(pauseSpeed
).toFloat();
2701 _options
.automaticPause
= READ(automaticPause
).toBool();
2702 _options
.pauseInterval
= READ(pauseInterval
).toInt();
2703 _options
.useReportedSpeed
= READ(useReportedSpeed
).toBool();
2704 _options
.dataUseDEM
= READ(dataUseDEM
).toBool();
2705 _options
.showSecondaryElevation
= READ(secondaryElevation
).toBool();
2706 _options
.showSecondarySpeed
= READ(secondarySpeed
).toBool();
2707 _options
.timeZone
= READ(timeZone
).value
<TimeZoneInfo
>();
2708 _options
.useSegments
= READ(useSegments
).toBool();
2709 _options
.poiRadius
= READ(poiRadius
).toInt();
2710 _options
.demURL
= READ(demURL
).toString();
2711 _options
.demAuthorization
= READ(demAuthentication
).toBool();
2712 _options
.demUsername
= READ(demUsername
).toString();
2713 _options
.demPassword
= READ(demPassword
).toString();
2714 _options
.plugin
= READ(positionPlugin()).toString();
2715 _options
.pluginParams
= READ(positionPluginParameters
);
2716 _options
.useOpenGL
= READ(useOpenGL
).toBool();
2717 _options
.enableHTTP2
= READ(enableHTTP2
).toBool();
2718 _options
.pixmapCache
= READ(pixmapCache
).toInt();
2719 _options
.demCache
= READ(demCache
).toInt();
2720 _options
.connectionTimeout
= READ(connectionTimeout
).toInt();
2721 _options
.hiresPrint
= READ(hiresPrint
).toBool();
2722 _options
.printName
= READ(printName
).toBool();
2723 _options
.printDate
= READ(printDate
).toBool();
2724 _options
.printDistance
= READ(printDistance
).toBool();
2725 _options
.printTime
= READ(printTime
).toBool();
2726 _options
.printMovingTime
= READ(printMovingTime
).toBool();
2727 _options
.printItemCount
= READ(printItemCount
).toBool();
2728 _options
.separateGraphPage
= READ(separateGraphPage
).toBool();
2729 _options
.sliderColor
= READ(sliderColor
).value
<QColor
>();
2730 _options
.outputProjection
= READ(outputProjection
).toInt();
2731 _options
.inputProjection
= READ(inputProjection
).toInt();
2732 _options
.hidpiMap
= READ(hidpiMap
).toBool();
2733 _options
.dataPath
= READ(dataPath
).toString();
2734 _options
.mapsPath
= READ(mapsPath
).toString();
2735 _options
.poiPath
= READ(poiPath
).toString();
2736 settings
.endGroup();
2741 void GUI::loadOptions()
2743 _positionSource
= positionSource(_options
);
2744 _showPositionAction
->setEnabled(_positionSource
!= 0);
2746 _mapView
->setPalette(_options
.palette
);
2747 _mapView
->setMapOpacity(_options
.mapOpacity
);
2748 _mapView
->setBackgroundColor(_options
.backgroundColor
);
2749 _mapView
->setCrosshairColor(_options
.crosshairColor
);
2750 _mapView
->setInfoColor(_options
.infoColor
);
2751 _mapView
->drawInfoBackground(_options
.infoBackground
);
2752 _mapView
->setTrackWidth(_options
.trackWidth
);
2753 _mapView
->setRouteWidth(_options
.routeWidth
);
2754 _mapView
->setAreaWidth(_options
.areaWidth
);
2755 _mapView
->setTrackStyle(_options
.trackStyle
);
2756 _mapView
->setRouteStyle(_options
.routeStyle
);
2757 _mapView
->setAreaStyle(_options
.areaStyle
);
2758 _mapView
->setAreaOpacity(_options
.areaOpacity
);
2759 _mapView
->setWaypointSize(_options
.waypointSize
);
2760 _mapView
->setWaypointColor(_options
.waypointColor
);
2761 _mapView
->setPOISize(_options
.poiSize
);
2762 _mapView
->setPOIColor(_options
.poiColor
);
2763 _mapView
->setRenderHint(QPainter::Antialiasing
, _options
.pathAntiAliasing
);
2764 _mapView
->setMarkerColor(_options
.sliderColor
);
2765 _mapView
->useOpenGL(_options
.useOpenGL
);
2766 _mapView
->setMapConfig(CRS::projection(_options
.inputProjection
),
2767 CRS::projection(4326, _options
.outputProjection
), _options
.hidpiMap
);
2768 _mapView
->setTimeZone(_options
.timeZone
.zone());
2769 _mapView
->setPositionSource(_positionSource
);
2771 for (int i
= 0; i
< _tabs
.count(); i
++) {
2772 _tabs
.at(i
)->setPalette(_options
.palette
);
2773 _tabs
.at(i
)->setGraphWidth(_options
.graphWidth
);
2774 _tabs
.at(i
)->setRenderHint(QPainter::Antialiasing
,
2775 _options
.graphAntiAliasing
);
2776 _tabs
.at(i
)->setSliderColor(_options
.sliderColor
);
2777 if (_options
.useOpenGL
)
2778 _tabs
.at(i
)->useOpenGL(true);
2781 Track::setElevationFilter(_options
.elevationFilter
);
2782 Track::setSpeedFilter(_options
.speedFilter
);
2783 Track::setHeartRateFilter(_options
.heartRateFilter
);
2784 Track::setCadenceFilter(_options
.cadenceFilter
);
2785 Track::setPowerFilter(_options
.powerFilter
);
2786 Track::setOutlierElimination(_options
.outlierEliminate
);
2787 Track::setAutomaticPause(_options
.automaticPause
);
2788 Track::setPauseSpeed(_options
.pauseSpeed
);
2789 Track::setPauseInterval(_options
.pauseInterval
);
2790 Track::useReportedSpeed(_options
.useReportedSpeed
);
2791 Track::useDEM(_options
.dataUseDEM
);
2792 Track::showSecondaryElevation(_options
.showSecondaryElevation
);
2793 Track::showSecondarySpeed(_options
.showSecondarySpeed
);
2794 Track::useSegments(_options
.useSegments
);
2795 Route::useDEM(_options
.dataUseDEM
);
2796 Route::showSecondaryElevation(_options
.showSecondaryElevation
);
2797 Waypoint::useDEM(_options
.dataUseDEM
);
2798 Waypoint::showSecondaryElevation(_options
.showSecondaryElevation
);
2800 Downloader::enableHTTP2(_options
.enableHTTP2
);
2801 Downloader::setTimeout(_options
.connectionTimeout
);
2803 QPixmapCache::setCacheLimit(_options
.pixmapCache
* 1024);
2804 DEM::setCacheSize(_options
.demCache
* 1024);
2806 _poi
->setRadius(_options
.poiRadius
);
2808 _dem
->setUrl(_options
.demURL
);
2809 if (_options
.demAuthorization
)
2810 _dem
->setAuthorization(Authorization(_options
.demUsername
,
2811 _options
.demPassword
));
2813 _dataDir
= _options
.dataPath
;
2814 _mapDir
= _options
.mapsPath
;
2815 _poiDir
= _options
.poiPath
;
2818 void GUI::updateOptions(const Options
&options
)
2820 #define SET_VIEW_OPTION(option, action) \
2821 if (options.option != _options.option) \
2822 _mapView->action(options.option)
2823 #define SET_TAB_OPTION(option, action) \
2824 if (options.option != _options.option) \
2825 for (int i = 0; i < _tabs.count(); i++) \
2826 _tabs.at(i)->action(options.option)
2827 #define SET_TRACK_OPTION(option, action) \
2828 if (options.option != _options.option) { \
2829 Track::action(options.option); \
2832 #define SET_ROUTE_OPTION(option, action) \
2833 if (options.option != _options.option) { \
2834 Route::action(options.option); \
2837 #define SET_WAYPOINT_OPTION(option, action) \
2838 if (options.option != _options.option) { \
2839 Waypoint::action(options.option); \
2843 bool reload
= false;
2845 SET_VIEW_OPTION(palette
, setPalette
);
2846 SET_VIEW_OPTION(mapOpacity
, setMapOpacity
);
2847 SET_VIEW_OPTION(backgroundColor
, setBackgroundColor
);
2848 SET_VIEW_OPTION(trackWidth
, setTrackWidth
);
2849 SET_VIEW_OPTION(routeWidth
, setRouteWidth
);
2850 SET_VIEW_OPTION(areaWidth
, setAreaWidth
);
2851 SET_VIEW_OPTION(trackStyle
, setTrackStyle
);
2852 SET_VIEW_OPTION(routeStyle
, setRouteStyle
);
2853 SET_VIEW_OPTION(areaStyle
, setAreaStyle
);
2854 SET_VIEW_OPTION(areaOpacity
, setAreaOpacity
);
2855 SET_VIEW_OPTION(waypointSize
, setWaypointSize
);
2856 SET_VIEW_OPTION(waypointColor
, setWaypointColor
);
2857 SET_VIEW_OPTION(poiSize
, setPOISize
);
2858 SET_VIEW_OPTION(poiColor
, setPOIColor
);
2859 SET_VIEW_OPTION(pathAntiAliasing
, useAntiAliasing
);
2860 SET_VIEW_OPTION(useOpenGL
, useOpenGL
);
2861 SET_VIEW_OPTION(sliderColor
, setMarkerColor
);
2862 SET_VIEW_OPTION(crosshairColor
, setCrosshairColor
);
2863 SET_VIEW_OPTION(infoColor
, setInfoColor
);
2864 SET_VIEW_OPTION(infoBackground
, drawInfoBackground
);
2866 if (options
.plugin
!= _options
.plugin
2867 || options
.pluginParams
.value(options
.plugin
)
2868 != _options
.pluginParams
.value(_options
.plugin
)) {
2869 QGeoPositionInfoSource
*source
= positionSource(options
);
2870 _showPositionAction
->setEnabled(source
!= 0);
2871 _mapView
->setPositionSource(source
);
2872 delete _positionSource
;
2873 _positionSource
= source
;
2876 if (options
.hidpiMap
!= _options
.hidpiMap
2877 || options
.outputProjection
!= _options
.outputProjection
2878 || options
.inputProjection
!= _options
.inputProjection
)
2879 _mapView
->setMapConfig(CRS::projection(options
.inputProjection
),
2880 CRS::projection(4326, options
.outputProjection
), options
.hidpiMap
);
2882 if (options
.timeZone
!= _options
.timeZone
) {
2883 _mapView
->setTimeZone(options
.timeZone
.zone());
2884 _dateRange
.first
= _dateRange
.first
.toTimeZone(options
.timeZone
.zone());
2885 _dateRange
.second
= _dateRange
.second
.toTimeZone(options
.timeZone
.zone());
2888 SET_TAB_OPTION(palette
, setPalette
);
2889 SET_TAB_OPTION(graphWidth
, setGraphWidth
);
2890 SET_TAB_OPTION(graphAntiAliasing
, useAntiAliasing
);
2891 SET_TAB_OPTION(useOpenGL
, useOpenGL
);
2892 SET_TAB_OPTION(sliderColor
, setSliderColor
);
2894 SET_TRACK_OPTION(elevationFilter
, setElevationFilter
);
2895 SET_TRACK_OPTION(speedFilter
, setSpeedFilter
);
2896 SET_TRACK_OPTION(heartRateFilter
, setHeartRateFilter
);
2897 SET_TRACK_OPTION(cadenceFilter
, setCadenceFilter
);
2898 SET_TRACK_OPTION(powerFilter
, setPowerFilter
);
2899 SET_TRACK_OPTION(outlierEliminate
, setOutlierElimination
);
2900 SET_TRACK_OPTION(automaticPause
, setAutomaticPause
);
2901 SET_TRACK_OPTION(pauseSpeed
, setPauseSpeed
);
2902 SET_TRACK_OPTION(pauseInterval
, setPauseInterval
);
2903 SET_TRACK_OPTION(useReportedSpeed
, useReportedSpeed
);
2904 SET_TRACK_OPTION(dataUseDEM
, useDEM
);
2905 SET_TRACK_OPTION(showSecondaryElevation
, showSecondaryElevation
);
2906 SET_TRACK_OPTION(showSecondarySpeed
, showSecondarySpeed
);
2907 SET_TRACK_OPTION(useSegments
, useSegments
);
2909 SET_ROUTE_OPTION(dataUseDEM
, useDEM
);
2910 SET_ROUTE_OPTION(showSecondaryElevation
, showSecondaryElevation
);
2912 SET_WAYPOINT_OPTION(dataUseDEM
, useDEM
);
2913 SET_WAYPOINT_OPTION(showSecondaryElevation
, showSecondaryElevation
);
2915 if (options
.poiRadius
!= _options
.poiRadius
)
2916 _poi
->setRadius(options
.poiRadius
);
2918 if (options
.demURL
!= _options
.demURL
)
2919 _dem
->setUrl(options
.demURL
);
2920 if (options
.demAuthorization
!= _options
.demAuthorization
2921 || options
.demUsername
!= _options
.demUsername
2922 || options
.demPassword
!= _options
.demPassword
)
2923 _dem
->setAuthorization(options
.demAuthorization
2924 ? Authorization(options
.demUsername
, options
.demPassword
)
2927 if (options
.pixmapCache
!= _options
.pixmapCache
)
2928 QPixmapCache::setCacheLimit(options
.pixmapCache
* 1024);
2929 if (options
.demCache
!= _options
.demCache
)
2930 DEM::setCacheSize(options
.demCache
* 1024);
2932 if (options
.connectionTimeout
!= _options
.connectionTimeout
)
2933 Downloader::setTimeout(options
.connectionTimeout
);
2934 if (options
.enableHTTP2
!= _options
.enableHTTP2
)
2935 Downloader::enableHTTP2(options
.enableHTTP2
);
2937 if (options
.dataPath
!= _options
.dataPath
)
2938 _dataDir
= options
.dataPath
;
2939 if (options
.mapsPath
!= _options
.mapsPath
)
2940 _mapDir
= options
.mapsPath
;
2941 if (options
.poiPath
!= _options
.poiPath
)
2942 _poiDir
= options
.poiPath
;
2949 updateDEMDownloadAction();
2952 void GUI::loadInitialMaps(const QString
&selected
)
2955 QString
mapDir(ProgramPaths::mapDir());
2956 if (mapDir
.isNull())
2959 TreeNode
<Map
*> maps(MapList::loadMaps(mapDir
));
2960 createMapNodeMenu(createMapActionsNode(maps
), _mapMenu
, _mapsEnd
);
2962 // Select the active map according to the user settings
2963 QAction
*ma
= mapAction(selected
);
2966 _showMapAction
->setEnabled(true);
2967 _clearMapCacheAction
->setEnabled(true);
2971 void GUI::loadInitialPOIs(const QStringList
&disabled
)
2973 // Load the POI files
2974 QString
poiDir(ProgramPaths::poiDir());
2975 if (poiDir
.isNull())
2978 TreeNode
<QString
> poiFiles(_poi
->loadDir(poiDir
));
2979 createPOINodeMenu(createPOIActionsNode(poiFiles
), _poiMenu
, _poisEnd
);
2981 // Enable/disable the files according to the user settings
2982 QList
<QAction
*> poiActions(_poisActionGroup
->actions());
2983 for (int i
= 0; i
< poiActions
.count(); i
++)
2984 poiActions
.at(i
)->setChecked(true);
2985 for (int i
= 0; i
< disabled
.size(); i
++) {
2986 const QString
&file
= disabled
.at(i
);
2987 if (_poi
->enableFile(file
, false)) {
2988 for (int j
= 0; j
< poiActions
.size(); j
++)
2989 if (poiActions
.at(j
)->data().toString() == file
)
2990 poiActions
.at(j
)->setChecked(false);
2994 _selectAllPOIAction
->setEnabled(!poiActions
.isEmpty());
2995 _unselectAllPOIAction
->setEnabled(!poiActions
.isEmpty());
2998 QAction
*GUI::mapAction(const QString
&name
)
3000 QList
<QAction
*> maps(_mapsActionGroup
->actions());
3003 for (int i
= 0; i
< maps
.count(); i
++) {
3004 Map
*map
= maps
.at(i
)->data().value
<Map
*>();
3005 if (map
->name() == name
&& map
->isReady())
3010 for (int i
= 0; i
< maps
.count(); i
++) {
3011 Map
*map
= maps
.at(i
)->data().value
<Map
*>();
3019 Units
GUI::units() const
3021 return _imperialUnitsAction
->isChecked() ? Imperial
3022 : _nauticalUnitsAction
->isChecked() ? Nautical
: Metric
;
3025 qreal
GUI::distance() const
3029 if (_showTracksAction
->isChecked())
3030 dist
+= _trackDistance
;
3031 if (_showRoutesAction
->isChecked())
3032 dist
+= _routeDistance
;
3037 qreal
GUI::time() const
3039 return (_showTracksAction
->isChecked()) ? _time
: 0;
3042 qreal
GUI::movingTime() const
3044 return (_showTracksAction
->isChecked()) ? _movingTime
: 0;
3049 QMainWindow::show();
3051 QWindow
*w
= windowHandle();
3052 connect(w
->screen(), &QScreen::logicalDotsPerInchChanged
, this,
3053 &GUI::logicalDotsPerInchChanged
);
3054 connect(w
, &QWindow::screenChanged
, this, &GUI::screenChanged
);
3056 _mapView
->fitContentToSize();
3059 void GUI::screenChanged(QScreen
*screen
)
3061 _mapView
->setDevicePixelRatio(devicePixelRatioF());
3063 disconnect(SIGNAL(logicalDotsPerInchChanged(qreal
)), this,
3064 SLOT(logicalDotsPerInchChanged(qreal
)));
3065 connect(screen
, &QScreen::logicalDotsPerInchChanged
, this,
3066 &GUI::logicalDotsPerInchChanged
);
3069 void GUI::logicalDotsPerInchChanged(qreal dpi
)
3073 _mapView
->setDevicePixelRatio(devicePixelRatioF());