1 #include <QApplication>
8 #include <QPrintDialog>
10 #include <QPaintEngine>
11 #include <QPaintDevice>
13 #include <QSignalMapper>
17 #include <QActionGroup>
24 #include <QPixmapCache>
30 #include "ellipsoid.h"
35 #include "elevationgraph.h"
36 #include "speedgraph.h"
37 #include "heartrategraph.h"
38 #include "temperaturegraph.h"
39 #include "cadencegraph.h"
40 #include "powergraph.h"
42 #include "trackinfo.h"
43 #include "filebrowser.h"
65 QSplitter
*splitter
= new QSplitter();
66 splitter
->setOrientation(Qt::Vertical
);
67 splitter
->setChildrenCollapsible(false);
68 splitter
->addWidget(_pathView
);
69 splitter
->addWidget(_graphTabWidget
);
70 splitter
->setContentsMargins(0, 0, 0, 0);
71 splitter
->setStretchFactor(0, 255);
72 splitter
->setStretchFactor(1, 1);
73 setCentralWidget(splitter
);
75 setWindowIcon(QIcon(QPixmap(APP_ICON
)));
76 setWindowTitle(APP_NAME
);
77 setUnifiedTitleAndToolBarOnMac(true);
92 updateStatusBarInfo();
99 for (int i
= 0; i
< _tabs
.size(); i
++) {
100 if (_graphTabWidget
->indexOf(_tabs
.at(i
)) < 0)
105 const QString
GUI::fileFormats() const
107 return tr("Supported files (*.csv *.fit *.gpx *.igc *.kml *.nmea *.tcx)")
108 + ";;" + tr("CSV files (*.csv)") + ";;" + tr("FIT files (*.fit)") + ";;"
109 + tr("GPX files (*.gpx)") + ";;" + tr("IGC files (*.igc)") + ";;"
110 + tr("KML files (*.kml)") + ";;" + tr("NMEA files (*.nmea)") + ";;"
111 + tr("TCX files (*.tcx)") + ";;" + tr("All files (*)");
114 void GUI::createBrowser()
117 filter
<< "*.gpx" << "*.tcx" << "*.kml" << "*.fit" << "*.csv" << "*.igc"
119 _browser
= new FileBrowser(this);
120 _browser
->setFilter(filter
);
123 void GUI::loadDatums()
128 if (QFile::exists(USER_ELLIPSOID_FILE
))
129 ef
= USER_ELLIPSOID_FILE
;
130 else if (QFile::exists(GLOBAL_ELLIPSOID_FILE
))
131 ef
= GLOBAL_ELLIPSOID_FILE
;
133 qWarning("No ellipsoids file found.");
135 if (QFile::exists(USER_DATUM_FILE
))
136 df
= USER_DATUM_FILE
;
137 else if (QFile::exists(GLOBAL_DATUM_FILE
))
138 df
= GLOBAL_DATUM_FILE
;
140 qWarning("No datums file found.");
142 if (!ef
.isNull() && !df
.isNull()) {
143 if (!Ellipsoid::loadList(ef
)) {
144 if (Ellipsoid::errorLine())
145 qWarning("%s: parse error on line %d: %s", qPrintable(ef
),
146 Ellipsoid::errorLine(), qPrintable(Ellipsoid::errorString()));
148 qWarning("%s: %s", qPrintable(ef
), qPrintable(
149 Ellipsoid::errorString()));
151 if (!Datum::loadList(df
)) {
152 if (Datum::errorLine())
153 qWarning("%s: parse error on line %d: %s", qPrintable(ef
),
154 Datum::errorLine(), qPrintable(Datum::errorString()));
156 qWarning("%s: %s", qPrintable(ef
), qPrintable(
157 Datum::errorString()));
164 qWarning("Maps based on a datum different from WGS84 won't work.");
169 _ml
= new MapList(this);
171 QString offline
, online
;
173 if (QFile::exists(USER_MAP_FILE
))
174 online
= USER_MAP_FILE
;
175 else if (QFile::exists(GLOBAL_MAP_FILE
))
176 online
= GLOBAL_MAP_FILE
;
178 if (!online
.isNull() && !_ml
->loadList(online
))
179 qWarning("%s: %s", qPrintable(online
), qPrintable(_ml
->errorString()));
182 if (QFile::exists(USER_MAP_DIR
))
183 offline
= USER_MAP_DIR
;
184 else if (QFile::exists(GLOBAL_MAP_DIR
))
185 offline
= GLOBAL_MAP_DIR
;
187 if (!offline
.isNull()) {
189 QFileInfoList ml
= md
.entryInfoList(QDir::Dirs
| QDir::NoDotAndDotDot
);
191 filters
<< "*.map" << "*.tba" << "*.tar";
193 for (int i
= 0; i
< ml
.size(); i
++) {
194 QDir
dir(ml
.at(i
).absoluteFilePath());
195 QFileInfoList fl
= dir
.entryInfoList(filters
, QDir::Files
);
198 qWarning("%s: no map/atlas file found",
199 qPrintable(ml
.at(i
).absoluteFilePath()));
200 else if (fl
.size() > 1)
201 qWarning("%s: ambiguous directory content",
202 qPrintable(ml
.at(i
).absoluteFilePath()));
204 if (!_ml
->loadMap(fl
.first().absoluteFilePath()))
205 qWarning("%s: %s", qPrintable(fl
.first().absoluteFilePath()),
206 qPrintable(_ml
->errorString()));
210 _map
= _ml
->maps().isEmpty() ? new EmptyMap(this) : _ml
->maps().first();
216 QDir
userDir(USER_POI_DIR
);
217 QDir
globalDir(GLOBAL_POI_DIR
);
219 _poi
= new POI(this);
221 if (userDir
.exists())
222 list
= userDir
.entryInfoList(QStringList(), QDir::Files
);
224 list
= globalDir
.entryInfoList(QStringList(), QDir::Files
);
226 for (int i
= 0; i
< list
.size(); ++i
) {
227 if (!_poi
->loadFile(list
.at(i
).absoluteFilePath())) {
228 qWarning("Error loading POI file: %s: %s\n",
229 qPrintable(list
.at(i
).fileName()),
230 qPrintable(_poi
->errorString()));
231 if (_poi
->errorLine())
232 qWarning("Line: %d\n", _poi
->errorLine());
237 void GUI::createMapActions()
239 _mapsSignalMapper
= new QSignalMapper(this);
240 _mapsActionGroup
= new QActionGroup(this);
241 _mapsActionGroup
->setExclusive(true);
243 for (int i
= 0; i
< _ml
->maps().count(); i
++) {
244 QAction
*a
= new QAction(_ml
->maps().at(i
)->name(), this);
245 a
->setCheckable(true);
246 a
->setActionGroup(_mapsActionGroup
);
248 _mapsSignalMapper
->setMapping(a
, i
);
249 connect(a
, SIGNAL(triggered()), _mapsSignalMapper
, SLOT(map()));
251 _mapActions
.append(a
);
254 connect(_mapsSignalMapper
, SIGNAL(mapped(int)), this,
255 SLOT(mapChanged(int)));
258 void GUI::createPOIFilesActions()
260 _poiFilesSignalMapper
= new QSignalMapper(this);
262 for (int i
= 0; i
< _poi
->files().count(); i
++)
263 createPOIFileAction(i
);
265 connect(_poiFilesSignalMapper
, SIGNAL(mapped(int)), this, SLOT(poiFileChecked(int)));
268 QAction
*GUI::createPOIFileAction(int index
)
270 QAction
*a
= new QAction(QFileInfo(_poi
->files().at(index
)).fileName(),
272 a
->setCheckable(true);
274 _poiFilesSignalMapper
->setMapping(a
, index
);
275 connect(a
, SIGNAL(triggered()), _poiFilesSignalMapper
, SLOT(map()));
277 _poiFilesActions
.append(a
);
282 void GUI::createActions()
287 _fileActionGroup
= new QActionGroup(this);
288 _fileActionGroup
->setExclusive(false);
289 _fileActionGroup
->setEnabled(false);
291 _navigationActionGroup
= new QActionGroup(this);
292 _navigationActionGroup
->setEnabled(false);
295 _exitAction
= new QAction(QIcon(QPixmap(QUIT_ICON
)), tr("Quit"), this);
296 _exitAction
->setShortcut(QUIT_SHORTCUT
);
297 connect(_exitAction
, SIGNAL(triggered()), this, SLOT(close()));
298 addAction(_exitAction
);
301 _dataSourcesAction
= new QAction(tr("Data sources"), this);
302 connect(_dataSourcesAction
, SIGNAL(triggered()), this, SLOT(dataSources()));
303 _keysAction
= new QAction(tr("Keyboard controls"), this);
304 connect(_keysAction
, SIGNAL(triggered()), this, SLOT(keys()));
305 _aboutAction
= new QAction(QIcon(QPixmap(APP_ICON
)),
306 tr("About GPXSee"), this);
307 connect(_aboutAction
, SIGNAL(triggered()), this, SLOT(about()));
310 _openFileAction
= new QAction(QIcon(QPixmap(OPEN_FILE_ICON
)),
311 tr("Open..."), this);
312 _openFileAction
->setShortcut(OPEN_SHORTCUT
);
313 connect(_openFileAction
, SIGNAL(triggered()), this, SLOT(openFile()));
314 addAction(_openFileAction
);
315 _printFileAction
= new QAction(QIcon(QPixmap(PRINT_FILE_ICON
)),
316 tr("Print..."), this);
317 _printFileAction
->setActionGroup(_fileActionGroup
);
318 connect(_printFileAction
, SIGNAL(triggered()), this, SLOT(printFile()));
319 addAction(_printFileAction
);
320 _exportFileAction
= new QAction(QIcon(QPixmap(EXPORT_FILE_ICON
)),
321 tr("Export to PDF..."), this);
322 _exportFileAction
->setShortcut(EXPORT_SHORTCUT
);
323 _exportFileAction
->setActionGroup(_fileActionGroup
);
324 connect(_exportFileAction
, SIGNAL(triggered()), this, SLOT(exportFile()));
325 addAction(_exportFileAction
);
326 _closeFileAction
= new QAction(QIcon(QPixmap(CLOSE_FILE_ICON
)),
328 _closeFileAction
->setShortcut(CLOSE_SHORTCUT
);
329 _closeFileAction
->setActionGroup(_fileActionGroup
);
330 connect(_closeFileAction
, SIGNAL(triggered()), this, SLOT(closeAll()));
331 addAction(_closeFileAction
);
332 _reloadFileAction
= new QAction(QIcon(QPixmap(RELOAD_FILE_ICON
)),
334 _reloadFileAction
->setShortcut(RELOAD_SHORTCUT
);
335 _reloadFileAction
->setActionGroup(_fileActionGroup
);
336 connect(_reloadFileAction
, SIGNAL(triggered()), this, SLOT(reloadFile()));
337 addAction(_reloadFileAction
);
340 _openPOIAction
= new QAction(QIcon(QPixmap(OPEN_FILE_ICON
)),
341 tr("Load POI file..."), this);
342 connect(_openPOIAction
, SIGNAL(triggered()), this, SLOT(openPOIFile()));
343 _closePOIAction
= new QAction(QIcon(QPixmap(CLOSE_FILE_ICON
)),
344 tr("Close POI files"), this);
345 connect(_closePOIAction
, SIGNAL(triggered()), this, SLOT(closePOIFiles()));
346 _overlapPOIAction
= new QAction(tr("Overlap POIs"), this);
347 _overlapPOIAction
->setCheckable(true);
348 connect(_overlapPOIAction
, SIGNAL(triggered(bool)), _pathView
,
349 SLOT(setPOIOverlap(bool)));
350 _showPOILabelsAction
= new QAction(tr("Show POI labels"), this);
351 _showPOILabelsAction
->setCheckable(true);
352 connect(_showPOILabelsAction
, SIGNAL(triggered(bool)), _pathView
,
353 SLOT(showPOILabels(bool)));
354 _showPOIAction
= new QAction(QIcon(QPixmap(SHOW_POI_ICON
)),
355 tr("Show POIs"), this);
356 _showPOIAction
->setCheckable(true);
357 _showPOIAction
->setShortcut(SHOW_POI_SHORTCUT
);
358 connect(_showPOIAction
, SIGNAL(triggered(bool)), _pathView
,
359 SLOT(showPOI(bool)));
360 addAction(_showPOIAction
);
361 createPOIFilesActions();
364 _showMapAction
= new QAction(QIcon(QPixmap(SHOW_MAP_ICON
)), tr("Show map"),
366 _showMapAction
->setCheckable(true);
367 _showMapAction
->setShortcut(SHOW_MAP_SHORTCUT
);
368 connect(_showMapAction
, SIGNAL(triggered(bool)), _pathView
,
369 SLOT(showMap(bool)));
370 addAction(_showMapAction
);
371 _loadMapAction
= new QAction(QIcon(QPixmap(OPEN_FILE_ICON
)),
372 tr("Load map..."), this);
373 connect(_loadMapAction
, SIGNAL(triggered()), this, SLOT(loadMap()));
374 _clearMapCacheAction
= new QAction(tr("Clear tile cache"), this);
375 connect(_clearMapCacheAction
, SIGNAL(triggered()), this,
376 SLOT(clearMapCache()));
378 _nextMapAction
= new QAction(tr("Next map"), this);
379 _nextMapAction
->setShortcut(NEXT_MAP_SHORTCUT
);
380 connect(_nextMapAction
, SIGNAL(triggered()), this, SLOT(nextMap()));
381 addAction(_nextMapAction
);
382 _prevMapAction
= new QAction(tr("Next map"), this);
383 _prevMapAction
->setShortcut(PREV_MAP_SHORTCUT
);
384 connect(_prevMapAction
, SIGNAL(triggered()), this, SLOT(prevMap()));
385 addAction(_prevMapAction
);
386 if (_ml
->maps().isEmpty()) {
387 _showMapAction
->setEnabled(false);
388 _clearMapCacheAction
->setEnabled(false);
392 _showTracksAction
= new QAction(tr("Show tracks"), this);
393 _showTracksAction
->setCheckable(true);
394 connect(_showTracksAction
, SIGNAL(triggered(bool)), this,
395 SLOT(showTracks(bool)));
396 _showRoutesAction
= new QAction(tr("Show routes"), this);
397 _showRoutesAction
->setCheckable(true);
398 connect(_showRoutesAction
, SIGNAL(triggered(bool)), this,
399 SLOT(showRoutes(bool)));
400 _showWaypointsAction
= new QAction(tr("Show waypoints"), this);
401 _showWaypointsAction
->setCheckable(true);
402 connect(_showWaypointsAction
, SIGNAL(triggered(bool)), _pathView
,
403 SLOT(showWaypoints(bool)));
404 _showWaypointLabelsAction
= new QAction(tr("Waypoint labels"), this);
405 _showWaypointLabelsAction
->setCheckable(true);
406 connect(_showWaypointLabelsAction
, SIGNAL(triggered(bool)), _pathView
,
407 SLOT(showWaypointLabels(bool)));
408 _showRouteWaypointsAction
= new QAction(tr("Route waypoints"), this);
409 _showRouteWaypointsAction
->setCheckable(true);
410 connect(_showRouteWaypointsAction
, SIGNAL(triggered(bool)), _pathView
,
411 SLOT(showRouteWaypoints(bool)));
414 _showGraphsAction
= new QAction(QIcon(QPixmap(SHOW_GRAPHS_ICON
)),
415 tr("Show graphs"), this);
416 _showGraphsAction
->setCheckable(true);
417 _showGraphsAction
->setShortcut(SHOW_GRAPHS_SHORTCUT
);
418 connect(_showGraphsAction
, SIGNAL(triggered(bool)), this,
419 SLOT(showGraphs(bool)));
420 addAction(_showGraphsAction
);
421 ag
= new QActionGroup(this);
422 ag
->setExclusive(true);
423 _distanceGraphAction
= new QAction(tr("Distance"), this);
424 _distanceGraphAction
->setCheckable(true);
425 _distanceGraphAction
->setActionGroup(ag
);
426 _distanceGraphAction
->setShortcut(DISTANCE_GRAPH_SHORTCUT
);
427 connect(_distanceGraphAction
, SIGNAL(triggered()), this,
428 SLOT(setDistanceGraph()));
429 addAction(_distanceGraphAction
);
430 _timeGraphAction
= new QAction(tr("Time"), this);
431 _timeGraphAction
->setCheckable(true);
432 _timeGraphAction
->setActionGroup(ag
);
433 _timeGraphAction
->setShortcut(TIME_GRAPH_SHORTCUT
);
434 connect(_timeGraphAction
, SIGNAL(triggered()), this,
435 SLOT(setTimeGraph()));
436 addAction(_timeGraphAction
);
437 _showGraphGridAction
= new QAction(tr("Show grid"), this);
438 _showGraphGridAction
->setCheckable(true);
439 connect(_showGraphGridAction
, SIGNAL(triggered(bool)), this,
440 SLOT(showGraphGrids(bool)));
443 _showToolbarsAction
= new QAction(tr("Show toolbars"), this);
444 _showToolbarsAction
->setCheckable(true);
445 connect(_showToolbarsAction
, SIGNAL(triggered(bool)), this,
446 SLOT(showToolbars(bool)));
447 ag
= new QActionGroup(this);
448 ag
->setExclusive(true);
449 _totalTimeAction
= new QAction(tr("Total time"), this);
450 _totalTimeAction
->setCheckable(true);
451 _totalTimeAction
->setActionGroup(ag
);
452 connect(_totalTimeAction
, SIGNAL(triggered()), this,
453 SLOT(setTotalTime()));
454 _movingTimeAction
= new QAction(tr("Moving time"), this);
455 _movingTimeAction
->setCheckable(true);
456 _movingTimeAction
->setActionGroup(ag
);
457 connect(_movingTimeAction
, SIGNAL(triggered()), this,
458 SLOT(setMovingTime()));
459 ag
= new QActionGroup(this);
460 ag
->setExclusive(true);
461 _metricUnitsAction
= new QAction(tr("Metric"), this);
462 _metricUnitsAction
->setCheckable(true);
463 _metricUnitsAction
->setActionGroup(ag
);
464 connect(_metricUnitsAction
, SIGNAL(triggered()), this,
465 SLOT(setMetricUnits()));
466 _imperialUnitsAction
= new QAction(tr("Imperial"), this);
467 _imperialUnitsAction
->setCheckable(true);
468 _imperialUnitsAction
->setActionGroup(ag
);
469 connect(_imperialUnitsAction
, SIGNAL(triggered()), this,
470 SLOT(setImperialUnits()));
471 _fullscreenAction
= new QAction(QIcon(QPixmap(FULLSCREEN_ICON
)),
472 tr("Fullscreen mode"), this);
473 _fullscreenAction
->setCheckable(true);
474 _fullscreenAction
->setShortcut(FULLSCREEN_SHORTCUT
);
475 connect(_fullscreenAction
, SIGNAL(triggered(bool)), this,
476 SLOT(showFullscreen(bool)));
477 addAction(_fullscreenAction
);
478 _openOptionsAction
= new QAction(tr("Options..."), this);
479 connect(_openOptionsAction
, SIGNAL(triggered()), this,
480 SLOT(openOptions()));
482 // Navigation actions
483 _nextAction
= new QAction(QIcon(QPixmap(NEXT_FILE_ICON
)), tr("Next"), this);
484 _nextAction
->setActionGroup(_navigationActionGroup
);
485 connect(_nextAction
, SIGNAL(triggered()), this, SLOT(next()));
486 _prevAction
= new QAction(QIcon(QPixmap(PREV_FILE_ICON
)), tr("Previous"),
488 _prevAction
->setActionGroup(_navigationActionGroup
);
489 connect(_prevAction
, SIGNAL(triggered()), this, SLOT(prev()));
490 _lastAction
= new QAction(QIcon(QPixmap(LAST_FILE_ICON
)), tr("Last"), this);
491 _lastAction
->setActionGroup(_navigationActionGroup
);
492 connect(_lastAction
, SIGNAL(triggered()), this, SLOT(last()));
493 _firstAction
= new QAction(QIcon(QPixmap(FIRST_FILE_ICON
)), tr("First"),
495 _firstAction
->setActionGroup(_navigationActionGroup
);
496 connect(_firstAction
, SIGNAL(triggered()), this, SLOT(first()));
499 void GUI::createMenus()
501 QMenu
*fileMenu
= menuBar()->addMenu(tr("File"));
502 fileMenu
->addAction(_openFileAction
);
503 fileMenu
->addSeparator();
504 fileMenu
->addAction(_printFileAction
);
505 fileMenu
->addAction(_exportFileAction
);
506 fileMenu
->addSeparator();
507 fileMenu
->addAction(_reloadFileAction
);
508 fileMenu
->addSeparator();
509 fileMenu
->addAction(_closeFileAction
);
511 fileMenu
->addSeparator();
512 fileMenu
->addAction(_exitAction
);
515 _mapMenu
= menuBar()->addMenu(tr("Map"));
516 _mapMenu
->addActions(_mapActions
);
517 _mapsEnd
= _mapMenu
->addSeparator();
518 _mapMenu
->addAction(_loadMapAction
);
519 _mapMenu
->addAction(_clearMapCacheAction
);
520 _mapMenu
->addSeparator();
521 _mapMenu
->addAction(_showMapAction
);
523 QMenu
*graphMenu
= menuBar()->addMenu(tr("Graph"));
524 graphMenu
->addAction(_distanceGraphAction
);
525 graphMenu
->addAction(_timeGraphAction
);
526 graphMenu
->addSeparator();
527 graphMenu
->addAction(_showGraphGridAction
);
528 graphMenu
->addSeparator();
529 graphMenu
->addAction(_showGraphsAction
);
531 QMenu
*poiMenu
= menuBar()->addMenu(tr("POI"));
532 _poiFilesMenu
= poiMenu
->addMenu(tr("POI files"));
533 _poiFilesMenu
->addActions(_poiFilesActions
);
534 poiMenu
->addSeparator();
535 poiMenu
->addAction(_openPOIAction
);
536 poiMenu
->addAction(_closePOIAction
);
537 poiMenu
->addSeparator();
538 poiMenu
->addAction(_showPOILabelsAction
);
539 poiMenu
->addAction(_overlapPOIAction
);
540 poiMenu
->addSeparator();
541 poiMenu
->addAction(_showPOIAction
);
543 QMenu
*dataMenu
= menuBar()->addMenu(tr("Data"));
544 QMenu
*displayMenu
= dataMenu
->addMenu(tr("Display"));
545 displayMenu
->addAction(_showWaypointLabelsAction
);
546 displayMenu
->addAction(_showRouteWaypointsAction
);
547 dataMenu
->addSeparator();
548 dataMenu
->addAction(_showTracksAction
);
549 dataMenu
->addAction(_showRoutesAction
);
550 dataMenu
->addAction(_showWaypointsAction
);
552 QMenu
*settingsMenu
= menuBar()->addMenu(tr("Settings"));
553 QMenu
*timeMenu
= settingsMenu
->addMenu(tr("Time"));
554 timeMenu
->addAction(_totalTimeAction
);
555 timeMenu
->addAction(_movingTimeAction
);
556 QMenu
*unitsMenu
= settingsMenu
->addMenu(tr("Units"));
557 unitsMenu
->addAction(_metricUnitsAction
);
558 unitsMenu
->addAction(_imperialUnitsAction
);
559 settingsMenu
->addSeparator();
560 settingsMenu
->addAction(_showToolbarsAction
);
561 settingsMenu
->addAction(_fullscreenAction
);
562 settingsMenu
->addSeparator();
563 settingsMenu
->addAction(_openOptionsAction
);
565 QMenu
*helpMenu
= menuBar()->addMenu(tr("Help"));
566 helpMenu
->addAction(_dataSourcesAction
);
567 helpMenu
->addAction(_keysAction
);
568 helpMenu
->addSeparator();
569 helpMenu
->addAction(_aboutAction
);
572 void GUI::createToolBars()
575 setToolButtonStyle(Qt::ToolButtonTextUnderIcon
);
578 _fileToolBar
= addToolBar(tr("File"));
579 _fileToolBar
->addAction(_openFileAction
);
580 _fileToolBar
->addAction(_reloadFileAction
);
581 _fileToolBar
->addAction(_closeFileAction
);
582 _fileToolBar
->addAction(_printFileAction
);
584 _showToolBar
= addToolBar(tr("Show"));
585 _showToolBar
->addAction(_showPOIAction
);
586 _showToolBar
->addAction(_showMapAction
);
587 _showToolBar
->addAction(_showGraphsAction
);
589 _navigationToolBar
= addToolBar(tr("Navigation"));
590 _navigationToolBar
->addAction(_firstAction
);
591 _navigationToolBar
->addAction(_prevAction
);
592 _navigationToolBar
->addAction(_nextAction
);
593 _navigationToolBar
->addAction(_lastAction
);
596 void GUI::createPathView()
598 _pathView
= new PathView(_map
, _poi
, this);
599 _pathView
->setSizePolicy(QSizePolicy(QSizePolicy::Ignored
,
600 QSizePolicy::Expanding
));
601 _pathView
->setMinimumHeight(200);
603 _pathView
->setFrameShape(QFrame::NoFrame
);
607 void GUI::createGraphTabs()
609 _graphTabWidget
= new QTabWidget();
610 connect(_graphTabWidget
, SIGNAL(currentChanged(int)), this,
611 SLOT(graphChanged(int)));
613 _graphTabWidget
->setSizePolicy(QSizePolicy(QSizePolicy::Ignored
,
614 QSizePolicy::Preferred
));
615 _graphTabWidget
->setMinimumHeight(200);
617 _graphTabWidget
->setDocumentMode(true);
620 _tabs
.append(new ElevationGraph
);
621 _tabs
.append(new SpeedGraph
);
622 _tabs
.append(new HeartRateGraph
);
623 _tabs
.append(new CadenceGraph
);
624 _tabs
.append(new PowerGraph
);
625 _tabs
.append(new TemperatureGraph
);
627 for (int i
= 0; i
< _tabs
.count(); i
++)
628 connect(_tabs
.at(i
), SIGNAL(sliderPositionChanged(qreal
)), this,
629 SLOT(sliderPositionChanged(qreal
)));
632 void GUI::createStatusBar()
634 _fileNameLabel
= new QLabel();
635 _distanceLabel
= new QLabel();
636 _timeLabel
= new QLabel();
637 _distanceLabel
->setAlignment(Qt::AlignHCenter
);
638 _timeLabel
->setAlignment(Qt::AlignHCenter
);
640 statusBar()->addPermanentWidget(_fileNameLabel
, 8);
641 statusBar()->addPermanentWidget(_distanceLabel
, 1);
642 statusBar()->addPermanentWidget(_timeLabel
, 1);
643 statusBar()->setSizeGripEnabled(false);
648 QMessageBox
msgBox(this);
650 msgBox
.setWindowTitle(tr("About GPXSee"));
651 msgBox
.setText("<h2>" + QString(APP_NAME
) + "</h2><p><p>" + tr("Version ")
652 + APP_VERSION
+ " (" + CPU_ARCH
+ ", Qt " + QT_VERSION_STR
+ ")</p>");
653 msgBox
.setInformativeText("<table width=\"300\"><tr><td>"
654 + tr("GPXSee is distributed under the terms of the GNU General Public "
655 "License version 3. For more info about GPXSee visit the project "
656 "homepage at ") + "<a href=\"" + APP_HOMEPAGE
+ "\">" + APP_HOMEPAGE
657 + "</a>.</td></tr></table>");
659 QIcon icon
= msgBox
.windowIcon();
660 QSize size
= icon
.actualSize(QSize(64, 64));
661 msgBox
.setIconPixmap(icon
.pixmap(size
));
668 QMessageBox
msgBox(this);
670 msgBox
.setWindowTitle(tr("Keyboard controls"));
671 msgBox
.setText("<h3>" + tr("Keyboard controls") + "</h3>");
672 msgBox
.setInformativeText(
673 "<style>td {padding-right: 1.5em;}</style><div><table><tr><td>"
674 + tr("Next file") + "</td><td><i>" + QKeySequence(NEXT_KEY
).toString()
675 + "</i></td></tr><tr><td>" + tr("Previous file")
676 + "</td><td><i>" + QKeySequence(PREV_KEY
).toString()
677 + "</i></td></tr><tr><td>" + tr("First file") + "</td><td><i>"
678 + QKeySequence(FIRST_KEY
).toString() + "</i></td></tr><tr><td>"
679 + tr("Last file") + "</td><td><i>" + QKeySequence(LAST_KEY
).toString()
680 + "</i></td></tr><tr><td>" + tr("Append file")
681 + "</td><td><i>" + QKeySequence(MODIFIER
).toString() + tr("Next/Previous")
682 + "</i></td></tr><tr><td></td><td></td></tr><tr><td>" + tr("Next map")
683 + "</td><td><i>" + NEXT_MAP_SHORTCUT
.toString() + "</i></td></tr><tr><td>"
684 + tr("Previous map") + "</td><td><i>" + PREV_MAP_SHORTCUT
.toString()
685 + "</i></td></tr><tr><td></td><td></td></tr><tr><td>" + tr("Zoom in")
686 + "</td><td><i>" + QKeySequence(ZOOM_IN
).toString()
687 + "</i></td></tr><tr><td>" + tr("Zoom out") + "</td><td><i>"
688 + QKeySequence(ZOOM_OUT
).toString() + "</i></td></tr><tr><td>"
689 + tr("Digital zoom") + "</td><td><i>" + QKeySequence(MODIFIER
).toString()
690 + tr("Zoom") + "</i></td></tr></table></div>");
695 void GUI::dataSources()
697 QMessageBox
msgBox(this);
699 msgBox
.setWindowTitle(tr("Data sources"));
700 msgBox
.setText("<h3>" + tr("Data sources") + "</h3>");
701 msgBox
.setInformativeText(
702 "<h4>" + tr("Online maps") + "</h4><p>"
703 + tr("Online map URLs are read on program startup from the "
705 + "</p><p><code>" + USER_MAP_FILE
+ "</code></p><p>"
706 + tr("The file format is one map entry per line, consisting of the map "
707 "name and tiles URL delimited by a TAB character. The tile X and Y "
708 "coordinates are replaced with $x and $y in the URL and the zoom "
709 "level is replaced with $z. An example map file could look like:")
710 + "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png"
711 "<br/>Map2 http://mapserver.org/map/$z-$x-$y</code></p>"
713 + "<h4>" + tr("Offline maps") + "</h4><p>"
714 + tr("Offline maps are loaded on program startup from the following "
716 + "</p><p><code>" + USER_MAP_DIR
+ "</code></p><p>"
717 + tr("The expected structure is one map/atlas in a separate subdirectory."
718 " Supported map formats are OziExplorer maps and TrekBuddy maps/atlases"
719 " (tared and non-tared).") + "</p>"
721 + "<h4>" + tr("POIs") + "</h4><p>"
722 + tr("To make GPXSee load a POI file automatically on startup, add "
723 "the file to the following directory:")
724 + "</p><p><code>" + USER_POI_DIR
+ "</code></p>"
732 QStringList files
= QFileDialog::getOpenFileNames(this, tr("Open file"),
733 QString(), fileFormats());
734 QStringList list
= files
;
736 for (QStringList::Iterator it
= list
.begin(); it
!= list
.end(); it
++)
740 bool GUI::openFile(const QString
&fileName
)
744 if (fileName
.isEmpty() || _files
.contains(fileName
))
747 if (loadFile(fileName
)) {
748 _files
.append(fileName
);
749 _browser
->setCurrent(fileName
);
750 _fileActionGroup
->setEnabled(true);
751 _navigationActionGroup
->setEnabled(true);
753 updateNavigationActions();
754 updateStatusBarInfo();
759 if (_files
.isEmpty())
760 _fileActionGroup
->setEnabled(false);
767 bool GUI::loadFile(const QString
&fileName
)
770 QList
<PathItem
*> paths
;
772 if (data
.loadFile(fileName
)) {
773 paths
= _pathView
->loadData(data
);
774 for (int i
= 0; i
< _tabs
.count(); i
++)
775 _tabs
.at(i
)->loadData(data
, paths
);
777 for (int i
= 0; i
< data
.tracks().count(); i
++) {
778 _trackDistance
+= data
.tracks().at(i
)->distance();
779 _time
+= data
.tracks().at(i
)->time();
780 _movingTime
+= data
.tracks().at(i
)->movingTime();
781 const QDate
&date
= data
.tracks().at(i
)->date().date();
782 if (_dateRange
.first
.isNull() || _dateRange
.first
> date
)
783 _dateRange
.first
= date
;
784 if (_dateRange
.second
.isNull() || _dateRange
.second
< date
)
785 _dateRange
.second
= date
;
787 _trackCount
+= data
.tracks().count();
789 for (int i
= 0; i
< data
.routes().count(); i
++)
790 _routeDistance
+= data
.routes().at(i
)->distance();
791 _routeCount
+= data
.routes().count();
793 _waypointCount
+= data
.waypoints().count();
795 if (_pathName
.isNull()) {
796 if (data
.tracks().count() == 1 && !data
.routes().count())
797 _pathName
= data
.tracks().first()->name();
798 else if (data
.routes().count() == 1 && !data
.tracks().count())
799 _pathName
= data
.routes().first()->name();
801 _pathName
= QString();
805 updateNavigationActions();
806 updateStatusBarInfo();
811 QString error
= tr("Error loading data file:") + "\n\n"
812 + fileName
+ "\n\n" + data
.errorString();
813 if (data
.errorLine())
814 error
.append("\n" + tr("Line: %1").arg(data
.errorLine()));
815 QMessageBox::critical(this, APP_NAME
, error
);
820 void GUI::openPOIFile()
822 QStringList files
= QFileDialog::getOpenFileNames(this, tr("Open POI file"),
823 QString(), fileFormats());
824 QStringList list
= files
;
826 for (QStringList::Iterator it
= list
.begin(); it
!= list
.end(); it
++)
830 bool GUI::openPOIFile(const QString
&fileName
)
832 if (fileName
.isEmpty() || _poi
->files().contains(fileName
))
835 if (!_poi
->loadFile(fileName
)) {
836 QString error
= tr("Error loading POI file:") + "\n\n"
837 + fileName
+ "\n\n" + _poi
->errorString();
838 if (_poi
->errorLine())
839 error
.append("\n" + tr("Line: %1").arg(_poi
->errorLine()));
840 QMessageBox::critical(this, APP_NAME
, error
);
844 _pathView
->showPOI(true);
845 _showPOIAction
->setChecked(true);
846 QAction
*action
= createPOIFileAction(_poi
->files().indexOf(fileName
));
847 action
->setChecked(true);
848 _poiFilesMenu
->addAction(action
);
854 void GUI::closePOIFiles()
856 _poiFilesMenu
->clear();
858 for (int i
= 0; i
< _poiFilesActions
.count(); i
++)
859 delete _poiFilesActions
[i
];
860 _poiFilesActions
.clear();
865 void GUI::printFile()
867 QPrinter
printer(QPrinter::HighResolution
);
868 QPrintDialog
dialog(&printer
, this);
870 if (dialog
.exec() == QDialog::Accepted
)
874 void GUI::openOptions()
876 Options
options(_options
);
878 OptionsDialog
dialog(&options
, this);
879 if (dialog
.exec() != QDialog::Accepted
)
882 if (options
.palette
!= _options
.palette
) {
883 _pathView
->setPalette(options
.palette
);
884 for (int i
= 0; i
< _tabs
.count(); i
++)
885 _tabs
.at(i
)->setPalette(options
.palette
);
887 if (options
.trackWidth
!= _options
.trackWidth
)
888 _pathView
->setTrackWidth(options
.trackWidth
);
889 if (options
.routeWidth
!= _options
.routeWidth
)
890 _pathView
->setRouteWidth(options
.routeWidth
);
891 if (options
.trackStyle
!= _options
.trackStyle
)
892 _pathView
->setTrackStyle(options
.trackStyle
);
893 if (options
.routeStyle
!= _options
.routeStyle
)
894 _pathView
->setRouteStyle(options
.routeStyle
);
895 if (options
.pathAntiAliasing
!= _options
.pathAntiAliasing
)
896 _pathView
->setRenderHint(QPainter::Antialiasing
,
897 options
.pathAntiAliasing
);
898 if (options
.graphWidth
!= _options
.graphWidth
)
899 for (int i
= 0; i
< _tabs
.count(); i
++)
900 _tabs
.at(i
)->setGraphWidth(options
.graphWidth
);
901 if (options
.graphAntiAliasing
!= _options
.graphAntiAliasing
)
902 for (int i
= 0; i
< _tabs
.count(); i
++)
903 _tabs
.at(i
)->setRenderHint(QPainter::Antialiasing
,
904 options
.graphAntiAliasing
);
906 if (options
.poiRadius
!= _options
.poiRadius
)
907 _poi
->setRadius(options
.poiRadius
);
909 if (options
.useOpenGL
!= _options
.useOpenGL
) {
910 _pathView
->useOpenGL(options
.useOpenGL
);
911 for (int i
= 0; i
< _tabs
.count(); i
++)
912 _tabs
.at(i
)->useOpenGL(options
.useOpenGL
);
914 if (options
.pixmapCache
!= _options
.pixmapCache
)
915 QPixmapCache::setCacheLimit(options
.pixmapCache
* 1024);
920 void GUI::exportFile()
922 ExportDialog
dialog(&_export
, this);
923 if (dialog
.exec() != QDialog::Accepted
)
926 QPrinter
printer(QPrinter::HighResolution
);
927 printer
.setOutputFormat(QPrinter::PdfFormat
);
928 printer
.setCreator(QString(APP_NAME
) + QString(" ")
929 + QString(APP_VERSION
));
930 printer
.setOrientation(_export
.orientation
);
931 printer
.setOutputFileName(_export
.fileName
);
932 printer
.setPaperSize(_export
.paperSize
);
933 printer
.setPageMargins(_export
.margins
.left(), _export
.margins
.top(),
934 _export
.margins
.right(), _export
.margins
.bottom(), QPrinter::Millimeter
);
939 void GUI::plot(QPrinter
*printer
)
943 qreal ih
, gh
, mh
, ratio
;
944 qreal d
= distance();
946 qreal tm
= movingTime();
948 if (!_pathName
.isNull() && _options
.printName
)
949 info
.insert(tr("Name"), _pathName
);
951 if (_options
.printItemCount
) {
953 info
.insert(tr("Tracks"), QString::number(_trackCount
));
955 info
.insert(tr("Routes"), QString::number(_routeCount
));
956 if (_waypointCount
> 2)
957 info
.insert(tr("Waypoints"), QString::number(_waypointCount
));
960 if (_dateRange
.first
.isValid() && _options
.printDate
) {
961 if (_dateRange
.first
== _dateRange
.second
) {
962 QString format
= QLocale::system().dateFormat(QLocale::LongFormat
);
963 info
.insert(tr("Date"), _dateRange
.first
.toString(format
));
965 QString format
= QLocale::system().dateFormat(QLocale::ShortFormat
);
966 info
.insert(tr("Date"), QString("%1 - %2")
967 .arg(_dateRange
.first
.toString(format
),
968 _dateRange
.second
.toString(format
)));
972 if (d
> 0 && _options
.printDistance
)
973 info
.insert(tr("Distance"), Format::distance(d
, units()));
974 if (t
> 0 && _options
.printTime
)
975 info
.insert(tr("Time"), Format::timeSpan(t
));
976 if (tm
> 0 && _options
.printMovingTime
)
977 info
.insert(tr("Moving time"), Format::timeSpan(tm
));
980 ratio
= p
.paintEngine()->paintDevice()->logicalDpiX() / SCREEN_DPI
;
981 if (info
.isEmpty()) {
985 ih
= info
.contentSize().height() * ratio
;
987 info
.plot(&p
, QRectF(0, 0, printer
->width(), ih
));
989 if (_graphTabWidget
->isVisible() && !_options
.separateGraphPage
) {
990 qreal r
= (((qreal
)(printer
)->width()) / (qreal
)(printer
->height()));
991 gh
= (printer
->width() > printer
->height())
992 ? 0.15 * r
* (printer
->height() - ih
- 2*mh
)
993 : 0.15 * (printer
->height() - ih
- 2*mh
);
994 gh
= qMax(gh
, ratio
* 150);
995 GraphTab
*gt
= static_cast<GraphTab
*>(_graphTabWidget
->currentWidget());
996 gt
->plot(&p
, QRectF(0, printer
->height() - gh
, printer
->width(), gh
));
999 _pathView
->plot(&p
, QRectF(0, ih
+ mh
, printer
->width(), printer
->height()
1000 - (ih
+ 2*mh
+ gh
)));
1002 if (_graphTabWidget
->isVisible() && _options
.separateGraphPage
) {
1006 for (int i
= 0; i
< _tabs
.size(); i
++)
1007 if (_tabs
.at(i
)->count())
1010 qreal sp
= ratio
* 20;
1011 gh
= qMin((printer
->height() - ((cnt
- 1) * sp
))/(qreal
)cnt
,
1012 0.20 * printer
->height());
1015 for (int i
= 0; i
< _tabs
.size(); i
++) {
1016 if (_tabs
.at(i
)->count()) {
1017 _tabs
.at(i
)->plot(&p
, QRectF(0, y
, printer
->width(), gh
));
1024 void GUI::reloadFile()
1033 _dateRange
= DateRange(QDate(), QDate());
1034 _pathName
= QString();
1036 for (int i
= 0; i
< _tabs
.count(); i
++)
1037 _tabs
.at(i
)->clear();
1042 for (int i
= 0; i
< _files
.size(); i
++) {
1043 if (!loadFile(_files
.at(i
))) {
1049 updateStatusBarInfo();
1050 updateWindowTitle();
1053 if (_files
.isEmpty())
1054 _fileActionGroup
->setEnabled(false);
1056 _browser
->setCurrent(_files
.last());
1059 void GUI::closeFiles()
1068 _dateRange
= DateRange(QDate(), QDate());
1069 _pathName
= QString();
1073 for (int i
= 0; i
< _tabs
.count(); i
++)
1074 _tabs
.at(i
)->clear();
1080 void GUI::closeAll()
1084 _fileActionGroup
->setEnabled(false);
1085 updateStatusBarInfo();
1086 updateWindowTitle();
1091 void GUI::showGraphs(bool show
)
1093 _graphTabWidget
->setHidden(!show
);
1096 void GUI::showToolbars(bool show
)
1099 addToolBar(_fileToolBar
);
1100 addToolBar(_showToolBar
);
1101 addToolBar(_navigationToolBar
);
1102 _fileToolBar
->show();
1103 _showToolBar
->show();
1104 _navigationToolBar
->show();
1106 removeToolBar(_fileToolBar
);
1107 removeToolBar(_showToolBar
);
1108 removeToolBar(_navigationToolBar
);
1112 void GUI::showFullscreen(bool show
)
1115 _frameStyle
= _pathView
->frameStyle();
1116 _showGraphs
= _showGraphsAction
->isChecked();
1118 statusBar()->hide();
1120 showToolbars(false);
1122 _showGraphsAction
->setChecked(false);
1123 _pathView
->setFrameStyle(QFrame::NoFrame
);
1127 statusBar()->show();
1129 if (_showToolbarsAction
->isChecked())
1131 _showGraphsAction
->setChecked(_showGraphs
);
1132 if (_showGraphsAction
->isEnabled())
1133 showGraphs(_showGraphs
);
1134 _pathView
->setFrameStyle(_frameStyle
);
1140 void GUI::showTracks(bool show
)
1142 _pathView
->showTracks(show
);
1144 for (int i
= 0; i
< _tabs
.size(); i
++)
1145 _tabs
.at(i
)->showTracks(show
);
1147 updateStatusBarInfo();
1150 void GUI::showRoutes(bool show
)
1152 _pathView
->showRoutes(show
);
1154 for (int i
= 0; i
< _tabs
.size(); i
++)
1155 _tabs
.at(i
)->showRoutes(show
);
1157 updateStatusBarInfo();
1160 void GUI::showGraphGrids(bool show
)
1162 for (int i
= 0; i
< _tabs
.size(); i
++)
1163 _tabs
.at(i
)->showGrid(show
);
1168 QString fileName
= QFileDialog::getOpenFileName(this, tr("Open map file"),
1169 QString(), tr("Map files (*.map *.tba *.tar)"));
1171 if (fileName
.isEmpty())
1174 if (_ml
->loadMap(fileName
)) {
1175 QAction
*a
= new QAction(_ml
->maps().last()->name(), this);
1176 a
->setCheckable(true);
1177 a
->setActionGroup(_mapsActionGroup
);
1178 _mapsSignalMapper
->setMapping(a
, _ml
->maps().size() - 1);
1179 connect(a
, SIGNAL(triggered()), _mapsSignalMapper
, SLOT(map()));
1180 _mapActions
.append(a
);
1181 _mapMenu
->insertAction(_mapsEnd
, a
);
1182 _showMapAction
->setEnabled(true);
1183 _clearMapCacheAction
->setEnabled(true);
1184 a
->activate(QAction::Trigger
);
1186 QString error
= tr("Error loading map:") + "\n\n"
1187 + fileName
+ "\n\n" + _ml
->errorString();
1188 QMessageBox::critical(this, APP_NAME
, error
);
1192 void GUI::clearMapCache()
1195 _pathView
->redraw();
1198 void GUI::updateStatusBarInfo()
1200 if (_files
.count() == 0)
1201 _fileNameLabel
->setText(tr("No files loaded"));
1202 else if (_files
.count() == 1)
1203 _fileNameLabel
->setText(_files
.at(0));
1205 _fileNameLabel
->setText(tr("%n files", "", _files
.count()));
1208 _distanceLabel
->setText(Format::distance(distance(), units()));
1210 _distanceLabel
->clear();
1213 if (_movingTimeAction
->isChecked()) {
1214 _timeLabel
->setText(Format::timeSpan(movingTime())
1216 _timeLabel
->setToolTip(Format::timeSpan(time()));
1218 _timeLabel
->setText(Format::timeSpan(time()));
1219 _timeLabel
->setToolTip(Format::timeSpan(movingTime())
1223 _timeLabel
->clear();
1224 _timeLabel
->setToolTip(QString());
1228 void GUI::updateWindowTitle()
1230 if (_files
.count() == 1)
1231 setWindowTitle(QFileInfo(_files
.at(0)).fileName() + " - " + APP_NAME
);
1233 setWindowTitle(APP_NAME
);
1236 void GUI::mapChanged(int index
)
1238 _map
= _ml
->maps().at(index
);
1239 _pathView
->setMap(_map
);
1244 if (_ml
->maps().count() < 2)
1247 int next
= (_ml
->maps().indexOf(_map
) + 1) % _ml
->maps().count();
1248 _mapActions
.at(next
)->setChecked(true);
1254 if (_ml
->maps().count() < 2)
1257 int prev
= (_ml
->maps().indexOf(_map
) + _ml
->maps().count() - 1)
1258 % _ml
->maps().count();
1259 _mapActions
.at(prev
)->setChecked(true);
1263 void GUI::poiFileChecked(int index
)
1265 _poi
->enableFile(_poi
->files().at(index
),
1266 _poiFilesActions
.at(index
)->isChecked());
1269 void GUI::sliderPositionChanged(qreal pos
)
1274 void GUI::graphChanged(int index
)
1279 GraphTab
*gt
= static_cast<GraphTab
*>(_graphTabWidget
->widget(index
));
1280 gt
->setSliderPosition(_sliderPos
);
1283 void GUI::updateNavigationActions()
1285 if (_browser
->isLast()) {
1286 _nextAction
->setEnabled(false);
1287 _lastAction
->setEnabled(false);
1289 _nextAction
->setEnabled(true);
1290 _lastAction
->setEnabled(true);
1293 if (_browser
->isFirst()) {
1294 _prevAction
->setEnabled(false);
1295 _firstAction
->setEnabled(false);
1297 _prevAction
->setEnabled(true);
1298 _firstAction
->setEnabled(true);
1302 void GUI::updateGraphTabs()
1307 for (int i
= 0; i
< _tabs
.size(); i
++) {
1309 if (!tab
->count() && (index
= _graphTabWidget
->indexOf(tab
)) >= 0)
1310 _graphTabWidget
->removeTab(index
);
1313 for (int i
= 0; i
< _tabs
.size(); i
++) {
1315 if (tab
->count() && _graphTabWidget
->indexOf(tab
) < 0)
1316 _graphTabWidget
->insertTab(i
, tab
, _tabs
.at(i
)->label());
1319 if (_graphTabWidget
->count()) {
1320 if (_showGraphsAction
->isChecked())
1321 _graphTabWidget
->setHidden(false);
1322 _showGraphsAction
->setEnabled(true);
1324 _graphTabWidget
->setHidden(true);
1325 _showGraphsAction
->setEnabled(false);
1329 void GUI::updatePathView()
1331 _pathView
->setHidden(!(_pathView
->trackCount() + _pathView
->routeCount()
1332 + _pathView
->waypointCount()));
1335 void GUI::setTimeType(TimeType type
)
1337 for (int i
= 0; i
<_tabs
.count(); i
++)
1338 _tabs
.at(i
)->setTimeType(type
);
1340 updateStatusBarInfo();
1343 void GUI::setUnits(Units units
)
1345 _export
.units
= units
;
1346 _options
.units
= units
;
1348 _pathView
->setUnits(units
);
1349 for (int i
= 0; i
<_tabs
.count(); i
++)
1350 _tabs
.at(i
)->setUnits(units
);
1351 updateStatusBarInfo();
1354 void GUI::setGraphType(GraphType type
)
1358 for (int i
= 0; i
<_tabs
.count(); i
++) {
1359 _tabs
.at(i
)->setGraphType(type
);
1360 _tabs
.at(i
)->setSliderPosition(0);
1366 QString file
= _browser
->next();
1376 QString file
= _browser
->prev();
1386 QString file
= _browser
->last();
1396 QString file
= _browser
->first();
1404 void GUI::keyPressEvent(QKeyEvent
*event
)
1408 switch (event
->key()) {
1410 file
= _browser
->prev();
1413 file
= _browser
->next();
1416 file
= _browser
->first();
1419 file
= _browser
->last();
1422 case Qt::Key_Escape
:
1423 if (_fullscreenAction
->isChecked()) {
1424 _fullscreenAction
->setChecked(false);
1425 showFullscreen(false);
1431 if (!file
.isNull()) {
1432 if (!(event
->modifiers() & MODIFIER
))
1438 QMainWindow::keyPressEvent(event
);
1441 void GUI::closeEvent(QCloseEvent
*event
)
1447 void GUI::dragEnterEvent(QDragEnterEvent
*event
)
1449 if (!event
->mimeData()->hasUrls())
1451 if (event
->proposedAction() != Qt::CopyAction
)
1454 QList
<QUrl
> urls
= event
->mimeData()->urls();
1455 for (int i
= 0; i
< urls
.size(); i
++)
1456 if (!urls
.at(i
).isLocalFile())
1459 event
->acceptProposedAction();
1462 void GUI::dropEvent(QDropEvent
*event
)
1464 QList
<QUrl
> urls
= event
->mimeData()->urls();
1465 for (int i
= 0; i
< urls
.size(); i
++)
1466 openFile(urls
.at(i
).toLocalFile());
1469 void GUI::writeSettings()
1471 QSettings
settings(APP_NAME
, APP_NAME
);
1474 settings
.beginGroup(WINDOW_SETTINGS_GROUP
);
1475 if (size() != WINDOW_SIZE_DEFAULT
)
1476 settings
.setValue(WINDOW_SIZE_SETTING
, size());
1477 if (pos() != WINDOW_POS_DEFAULT
)
1478 settings
.setValue(WINDOW_POS_SETTING
, pos());
1479 settings
.endGroup();
1481 settings
.beginGroup(SETTINGS_SETTINGS_GROUP
);
1482 if ((_movingTimeAction
->isChecked() ? Moving
: Total
) !=
1484 settings
.setValue(TIME_TYPE_SETTING
, _movingTimeAction
->isChecked()
1486 if ((_imperialUnitsAction
->isChecked() ? Imperial
: Metric
) !=
1488 settings
.setValue(UNITS_SETTING
, _imperialUnitsAction
->isChecked()
1489 ? Imperial
: Metric
);
1490 if (_showToolbarsAction
->isChecked() != SHOW_TOOLBARS_DEFAULT
)
1491 settings
.setValue(SHOW_TOOLBARS_SETTING
,
1492 _showToolbarsAction
->isChecked());
1493 settings
.endGroup();
1495 settings
.beginGroup(MAP_SETTINGS_GROUP
);
1496 settings
.setValue(CURRENT_MAP_SETTING
, _map
->name());
1497 if (_showMapAction
->isChecked() != SHOW_MAP_DEFAULT
)
1498 settings
.setValue(SHOW_MAP_SETTING
, _showMapAction
->isChecked());
1499 settings
.endGroup();
1501 settings
.beginGroup(GRAPH_SETTINGS_GROUP
);
1502 if (_showGraphsAction
->isChecked() != SHOW_GRAPHS_DEFAULT
)
1503 settings
.setValue(SHOW_GRAPHS_SETTING
, _showGraphsAction
->isChecked());
1504 if ((_timeGraphAction
->isChecked() ? Time
: Distance
) != GRAPH_TYPE_DEFAULT
)
1505 settings
.setValue(GRAPH_TYPE_SETTING
, _timeGraphAction
->isChecked()
1507 if (_showGraphGridAction
->isChecked() != SHOW_GRAPH_GRIDS_DEFAULT
)
1508 settings
.setValue(SHOW_GRAPH_GRIDS_SETTING
,
1509 _showGraphGridAction
->isChecked());
1510 settings
.endGroup();
1512 settings
.beginGroup(POI_SETTINGS_GROUP
);
1513 if (_showPOIAction
->isChecked() != SHOW_POI_DEFAULT
)
1514 settings
.setValue(SHOW_POI_SETTING
, _showPOIAction
->isChecked());
1515 if (_overlapPOIAction
->isChecked() != OVERLAP_POI_DEFAULT
)
1516 settings
.setValue(OVERLAP_POI_SETTING
, _overlapPOIAction
->isChecked());
1519 for (int i
= 0; i
< _poiFilesActions
.count(); i
++) {
1520 if (!_poiFilesActions
.at(i
)->isChecked()) {
1522 settings
.beginWriteArray(DISABLED_POI_FILE_SETTINGS_PREFIX
);
1523 settings
.setArrayIndex(j
++);
1524 settings
.setValue(DISABLED_POI_FILE_SETTING
, _poi
->files().at(i
));
1528 settings
.endArray();
1529 settings
.endGroup();
1531 settings
.beginGroup(DATA_SETTINGS_GROUP
);
1532 if (_showTracksAction
->isChecked() != SHOW_TRACKS_DEFAULT
)
1533 settings
.setValue(SHOW_TRACKS_SETTING
, _showTracksAction
->isChecked());
1534 if (_showRoutesAction
->isChecked() != SHOW_ROUTES_DEFAULT
)
1535 settings
.setValue(SHOW_ROUTES_SETTING
, _showRoutesAction
->isChecked());
1536 if (_showWaypointsAction
->isChecked() != SHOW_WAYPOINTS_DEFAULT
)
1537 settings
.setValue(SHOW_WAYPOINTS_SETTING
,
1538 _showWaypointsAction
->isChecked());
1539 if (_showWaypointLabelsAction
->isChecked() != SHOW_WAYPOINT_LABELS_DEFAULT
)
1540 settings
.setValue(SHOW_WAYPOINT_LABELS_SETTING
,
1541 _showWaypointLabelsAction
->isChecked());
1542 if (_showRouteWaypointsAction
->isChecked() != SHOW_ROUTE_WAYPOINTS_DEFAULT
)
1543 settings
.setValue(SHOW_ROUTE_WAYPOINTS_SETTING
,
1544 _showRouteWaypointsAction
->isChecked());
1545 settings
.endGroup();
1547 settings
.beginGroup(EXPORT_SETTINGS_GROUP
);
1548 if (_export
.orientation
!= PAPER_ORIENTATION_DEFAULT
)
1549 settings
.setValue(PAPER_ORIENTATION_SETTING
, _export
.orientation
);
1550 if (_export
.paperSize
!= PAPER_SIZE_DEFAULT
)
1551 settings
.setValue(PAPER_SIZE_SETTING
, _export
.paperSize
);
1552 if (_export
.margins
.left() != MARGIN_LEFT_DEFAULT
)
1553 settings
.setValue(MARGIN_LEFT_SETTING
, _export
.margins
.left());
1554 if (_export
.margins
.top() != MARGIN_TOP_DEFAULT
)
1555 settings
.setValue(MARGIN_TOP_SETTING
, _export
.margins
.top());
1556 if (_export
.margins
.right() != MARGIN_RIGHT_DEFAULT
)
1557 settings
.setValue(MARGIN_RIGHT_SETTING
, _export
.margins
.right());
1558 if (_export
.margins
.bottom() != MARGIN_BOTTOM_DEFAULT
)
1559 settings
.setValue(MARGIN_BOTTOM_SETTING
, _export
.margins
.bottom());
1560 if (_export
.fileName
!= EXPORT_FILENAME_DEFAULT
)
1561 settings
.setValue(EXPORT_FILENAME_SETTING
, _export
.fileName
);
1562 settings
.endGroup();
1564 settings
.beginGroup(OPTIONS_SETTINGS_GROUP
);
1565 if (_options
.palette
.color() != PALETTE_COLOR_DEFAULT
)
1566 settings
.setValue(PALETTE_COLOR_SETTING
, _options
.palette
.color());
1567 if (_options
.palette
.shift() != PALETTE_SHIFT_DEFAULT
)
1568 settings
.setValue(PALETTE_SHIFT_SETTING
, _options
.palette
.shift());
1569 if (_options
.trackWidth
!= TRACK_WIDTH_DEFAULT
)
1570 settings
.setValue(TRACK_WIDTH_SETTING
, _options
.trackWidth
);
1571 if (_options
.routeWidth
!= ROUTE_WIDTH_DEFAULT
)
1572 settings
.setValue(ROUTE_WIDTH_SETTING
, _options
.routeWidth
);
1573 if (_options
.trackStyle
!= TRACK_STYLE_DEFAULT
)
1574 settings
.setValue(TRACK_STYLE_SETTING
, (int)_options
.trackStyle
);
1575 if (_options
.routeStyle
!= ROUTE_STYLE_DEFAULT
)
1576 settings
.setValue(ROUTE_STYLE_SETTING
, (int)_options
.routeStyle
);
1577 if (_options
.graphWidth
!= GRAPH_WIDTH_DEFAULT
)
1578 settings
.setValue(GRAPH_WIDTH_SETTING
, _options
.graphWidth
);
1579 if (_options
.pathAntiAliasing
!= PATH_AA_DEFAULT
)
1580 settings
.setValue(PATH_AA_SETTING
, _options
.pathAntiAliasing
);
1581 if (_options
.graphAntiAliasing
!= GRAPH_AA_DEFAULT
)
1582 settings
.setValue(GRAPH_AA_SETTING
, _options
.graphAntiAliasing
);
1583 if (_options
.poiRadius
!= POI_RADIUS_DEFAULT
)
1584 settings
.setValue(POI_RADIUS_SETTING
, _options
.poiRadius
);
1585 if (_options
.useOpenGL
!= USE_OPENGL_DEFAULT
)
1586 settings
.setValue(USE_OPENGL_SETTING
, _options
.useOpenGL
);
1587 if (_options
.pixmapCache
!= PIXMAP_CACHE_DEFAULT
)
1588 settings
.setValue(PIXMAP_CACHE_SETTING
, _options
.pixmapCache
);
1589 if (_options
.printName
!= PRINT_NAME_DEFAULT
)
1590 settings
.setValue(PRINT_NAME_SETTING
, _options
.printName
);
1591 if (_options
.printDate
!= PRINT_DATE_DEFAULT
)
1592 settings
.setValue(PRINT_DATE_SETTING
, _options
.printDate
);
1593 if (_options
.printDistance
!= PRINT_DISTANCE_DEFAULT
)
1594 settings
.setValue(PRINT_DISTANCE_SETTING
, _options
.printDistance
);
1595 if (_options
.printTime
!= PRINT_TIME_DEFAULT
)
1596 settings
.setValue(PRINT_TIME_SETTING
, _options
.printTime
);
1597 if (_options
.printMovingTime
!= PRINT_MOVING_TIME_DEFAULT
)
1598 settings
.setValue(PRINT_MOVING_TIME_SETTING
, _options
.printMovingTime
);
1599 if (_options
.printItemCount
!= PRINT_ITEM_COUNT_DEFAULT
)
1600 settings
.setValue(PRINT_ITEM_COUNT_SETTING
, _options
.printItemCount
);
1601 if (_options
.separateGraphPage
!= SEPARATE_GRAPH_PAGE_DEFAULT
)
1602 settings
.setValue(SEPARATE_GRAPH_PAGE_SETTING
,
1603 _options
.separateGraphPage
);
1604 settings
.endGroup();
1607 void GUI::readSettings()
1609 QSettings
settings(APP_NAME
, APP_NAME
);
1611 settings
.beginGroup(WINDOW_SETTINGS_GROUP
);
1612 resize(settings
.value(WINDOW_SIZE_SETTING
, WINDOW_SIZE_DEFAULT
).toSize());
1613 move(settings
.value(WINDOW_POS_SETTING
, WINDOW_POS_DEFAULT
).toPoint());
1614 settings
.endGroup();
1616 settings
.beginGroup(SETTINGS_SETTINGS_GROUP
);
1617 if (settings
.value(TIME_TYPE_SETTING
, TIME_TYPE_DEFAULT
).toInt()
1619 setTimeType(Moving
);
1620 _movingTimeAction
->setChecked(true);
1623 _totalTimeAction
->setChecked(true);
1625 if (settings
.value(UNITS_SETTING
, UNITS_DEFAULT
).toInt() == Imperial
) {
1627 _imperialUnitsAction
->setChecked(true);
1630 _metricUnitsAction
->setChecked(true);
1632 if (!settings
.value(SHOW_TOOLBARS_SETTING
, SHOW_TOOLBARS_DEFAULT
).toBool())
1633 showToolbars(false);
1635 _showToolbarsAction
->setChecked(true);
1636 settings
.endGroup();
1638 settings
.beginGroup(MAP_SETTINGS_GROUP
);
1639 if (settings
.value(SHOW_MAP_SETTING
, SHOW_MAP_DEFAULT
).toBool())
1640 _showMapAction
->setChecked(true);
1641 if (_ml
->maps().count()) {
1642 int index
= mapIndex(settings
.value(CURRENT_MAP_SETTING
).toString());
1643 _mapActions
.at(index
)->setChecked(true);
1644 _map
= _ml
->maps().at(index
);
1645 _pathView
->setMap(_map
);
1647 settings
.endGroup();
1649 settings
.beginGroup(GRAPH_SETTINGS_GROUP
);
1650 if (!settings
.value(SHOW_GRAPHS_SETTING
, SHOW_GRAPHS_DEFAULT
).toBool())
1653 _showGraphsAction
->setChecked(true);
1654 if (settings
.value(GRAPH_TYPE_SETTING
, GRAPH_TYPE_DEFAULT
).toInt()
1657 _timeGraphAction
->setChecked(true);
1659 _distanceGraphAction
->setChecked(true);
1660 if (!settings
.value(SHOW_GRAPH_GRIDS_SETTING
, SHOW_GRAPH_GRIDS_DEFAULT
)
1662 showGraphGrids(false);
1664 _showGraphGridAction
->setChecked(true);
1665 settings
.endGroup();
1667 settings
.beginGroup(POI_SETTINGS_GROUP
);
1668 if (!settings
.value(OVERLAP_POI_SETTING
, OVERLAP_POI_DEFAULT
).toBool())
1669 _pathView
->setPOIOverlap(false);
1671 _overlapPOIAction
->setChecked(true);
1672 if (!settings
.value(LABELS_POI_SETTING
, LABELS_POI_DEFAULT
).toBool())
1673 _pathView
->showPOILabels(false);
1675 _showPOILabelsAction
->setChecked(true);
1676 if (settings
.value(SHOW_POI_SETTING
, SHOW_POI_DEFAULT
).toBool())
1677 _showPOIAction
->setChecked(true);
1679 _pathView
->showPOI(false);
1680 for (int i
= 0; i
< _poiFilesActions
.count(); i
++)
1681 _poiFilesActions
.at(i
)->setChecked(true);
1682 int size
= settings
.beginReadArray(DISABLED_POI_FILE_SETTINGS_PREFIX
);
1683 for (int i
= 0; i
< size
; i
++) {
1684 settings
.setArrayIndex(i
);
1685 int index
= _poi
->files().indexOf(settings
.value(
1686 DISABLED_POI_FILE_SETTING
).toString());
1688 _poi
->enableFile(_poi
->files().at(index
), false);
1689 _poiFilesActions
.at(index
)->setChecked(false);
1692 settings
.endArray();
1693 settings
.endGroup();
1695 settings
.beginGroup(DATA_SETTINGS_GROUP
);
1696 if (!settings
.value(SHOW_TRACKS_SETTING
, SHOW_TRACKS_DEFAULT
).toBool()) {
1697 _pathView
->showTracks(false);
1698 for (int i
= 0; i
< _tabs
.count(); i
++)
1699 _tabs
.at(i
)->showTracks(false);
1701 _showTracksAction
->setChecked(true);
1702 if (!settings
.value(SHOW_ROUTES_SETTING
, SHOW_ROUTES_DEFAULT
).toBool()) {
1703 _pathView
->showRoutes(false);
1704 for (int i
= 0; i
< _tabs
.count(); i
++)
1705 _tabs
.at(i
)->showRoutes(false);
1707 _showRoutesAction
->setChecked(true);
1708 if (!settings
.value(SHOW_WAYPOINTS_SETTING
, SHOW_WAYPOINTS_DEFAULT
)
1710 _pathView
->showWaypoints(false);
1712 _showWaypointsAction
->setChecked(true);
1713 if (!settings
.value(SHOW_WAYPOINT_LABELS_SETTING
,
1714 SHOW_WAYPOINT_LABELS_DEFAULT
).toBool())
1715 _pathView
->showWaypointLabels(false);
1717 _showWaypointLabelsAction
->setChecked(true);
1718 if (!settings
.value(SHOW_ROUTE_WAYPOINTS_SETTING
,
1719 SHOW_ROUTE_WAYPOINTS_SETTING
).toBool())
1720 _pathView
->showRouteWaypoints(false);
1722 _showRouteWaypointsAction
->setChecked(true);
1723 settings
.endGroup();
1725 settings
.beginGroup(EXPORT_SETTINGS_GROUP
);
1726 _export
.orientation
= (QPrinter::Orientation
) settings
.value(
1727 PAPER_ORIENTATION_SETTING
, PAPER_ORIENTATION_DEFAULT
).toInt();
1728 _export
.paperSize
= (QPrinter::PaperSize
) settings
.value(PAPER_SIZE_SETTING
,
1729 PAPER_SIZE_DEFAULT
).toInt();
1730 qreal ml
= settings
.value(MARGIN_LEFT_SETTING
, MARGIN_LEFT_DEFAULT
)
1732 qreal mt
= settings
.value(MARGIN_TOP_SETTING
, MARGIN_TOP_DEFAULT
).toReal();
1733 qreal mr
= settings
.value(MARGIN_RIGHT_SETTING
, MARGIN_RIGHT_DEFAULT
)
1735 qreal mb
= settings
.value(MARGIN_BOTTOM_SETTING
, MARGIN_BOTTOM_DEFAULT
)
1737 _export
.margins
= MarginsF(ml
, mt
, mr
, mb
);
1738 _export
.fileName
= settings
.value(EXPORT_FILENAME_SETTING
,
1739 EXPORT_FILENAME_DEFAULT
).toString();
1740 settings
.endGroup();
1742 settings
.beginGroup(OPTIONS_SETTINGS_GROUP
);
1743 QColor pc
= settings
.value(PALETTE_COLOR_SETTING
, PALETTE_COLOR_DEFAULT
)
1745 qreal ps
= settings
.value(PALETTE_SHIFT_SETTING
, PALETTE_SHIFT_DEFAULT
)
1747 _options
.palette
= Palette(pc
, ps
);
1748 _options
.trackWidth
= settings
.value(TRACK_WIDTH_SETTING
,
1749 TRACK_WIDTH_DEFAULT
).toInt();
1750 _options
.routeWidth
= settings
.value(ROUTE_WIDTH_SETTING
,
1751 ROUTE_WIDTH_DEFAULT
).toInt();
1752 _options
.trackStyle
= (Qt::PenStyle
) settings
.value(TRACK_STYLE_SETTING
,
1753 (int)TRACK_STYLE_DEFAULT
).toInt();
1754 _options
.routeStyle
= (Qt::PenStyle
) settings
.value(ROUTE_STYLE_SETTING
,
1755 (int)ROUTE_STYLE_DEFAULT
).toInt();
1756 _options
.pathAntiAliasing
= settings
.value(PATH_AA_SETTING
, PATH_AA_DEFAULT
)
1758 _options
.graphWidth
= settings
.value(GRAPH_WIDTH_SETTING
,
1759 GRAPH_WIDTH_DEFAULT
).toInt();
1760 _options
.graphAntiAliasing
= settings
.value(GRAPH_AA_SETTING
,
1761 GRAPH_AA_DEFAULT
).toBool();
1762 _options
.poiRadius
= settings
.value(POI_RADIUS_SETTING
, POI_RADIUS_DEFAULT
)
1764 _options
.useOpenGL
= settings
.value(USE_OPENGL_SETTING
, USE_OPENGL_DEFAULT
)
1766 _options
.pixmapCache
= settings
.value(PIXMAP_CACHE_SETTING
,
1767 PIXMAP_CACHE_DEFAULT
).toInt();
1768 _options
.printName
= settings
.value(PRINT_NAME_SETTING
, PRINT_NAME_DEFAULT
)
1770 _options
.printDate
= settings
.value(PRINT_DATE_SETTING
, PRINT_DATE_DEFAULT
)
1772 _options
.printDistance
= settings
.value(PRINT_DISTANCE_SETTING
,
1773 PRINT_DISTANCE_DEFAULT
).toBool();
1774 _options
.printTime
= settings
.value(PRINT_TIME_SETTING
, PRINT_TIME_DEFAULT
)
1776 _options
.printMovingTime
= settings
.value(PRINT_MOVING_TIME_SETTING
,
1777 PRINT_MOVING_TIME_DEFAULT
).toBool();
1778 _options
.printItemCount
= settings
.value(PRINT_ITEM_COUNT_SETTING
,
1779 PRINT_ITEM_COUNT_DEFAULT
).toBool();
1780 _options
.separateGraphPage
= settings
.value(SEPARATE_GRAPH_PAGE_SETTING
,
1781 SEPARATE_GRAPH_PAGE_DEFAULT
).toBool();
1783 _pathView
->setPalette(_options
.palette
);
1784 _pathView
->setTrackWidth(_options
.trackWidth
);
1785 _pathView
->setRouteWidth(_options
.routeWidth
);
1786 _pathView
->setTrackStyle(_options
.trackStyle
);
1787 _pathView
->setRouteStyle(_options
.routeStyle
);
1788 _pathView
->setRenderHint(QPainter::Antialiasing
, _options
.pathAntiAliasing
);
1789 if (_options
.useOpenGL
)
1790 _pathView
->useOpenGL(true);
1792 for (int i
= 0; i
< _tabs
.count(); i
++) {
1793 _tabs
.at(i
)->setPalette(_options
.palette
);
1794 _tabs
.at(i
)->setGraphWidth(_options
.graphWidth
);
1795 _tabs
.at(i
)->setRenderHint(QPainter::Antialiasing
,
1796 _options
.graphAntiAliasing
);
1797 if (_options
.useOpenGL
)
1798 _tabs
.at(i
)->useOpenGL(true);
1801 _poi
->setRadius(_options
.poiRadius
);
1803 QPixmapCache::setCacheLimit(_options
.pixmapCache
* 1024);
1805 settings
.endGroup();
1808 int GUI::mapIndex(const QString
&name
)
1810 for (int i
= 0; i
< _ml
->maps().count(); i
++)
1811 if (_ml
->maps().at(i
)->name() == name
)
1817 Units
GUI::units() const
1819 return _imperialUnitsAction
->isChecked() ? Imperial
: Metric
;
1822 qreal
GUI::distance() const
1826 if (_showTracksAction
->isChecked())
1827 dist
+= _trackDistance
;
1828 if (_showRoutesAction
->isChecked())
1829 dist
+= _routeDistance
;
1834 qreal
GUI::time() const
1836 return (_showTracksAction
->isChecked()) ? _time
: 0;
1839 qreal
GUI::movingTime() const
1841 return (_showTracksAction
->isChecked()) ? _movingTime
: 0;