1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-04 06:49:16 +02:00

Compare commits

...

97 Commits
4.11 ... 4.17

Author SHA1 Message Date
53a4b45b7b Fixed broken scene centering in some resize cases 2017-12-07 21:05:00 +01:00
53229681d2 Translations update 2017-12-03 16:52:12 +01:00
b2df7d207f Version++ 2017-12-03 14:21:52 +01:00
1ff2162811 Added the "always show map" option 2017-12-03 14:18:41 +01:00
0f10c7596b Removed some more unneeded code 2017-12-03 13:37:18 +01:00
4cc3bc28e2 Do not clear the image cache between files 2017-12-03 13:07:52 +01:00
3ce1918645 Speed up the osx build 2017-12-03 12:11:54 +01:00
d70f0cf9e0 Added missing QT path on OS X 2017-12-03 12:05:21 +01:00
34c5ba4669 Fixed typos 2017-12-03 11:52:41 +01:00
afbb8c3284 Added Travis CI OS X build 2017-12-03 11:20:30 +01:00
5bdc263cda Moved all the map bounds checking where it belongs 2017-12-03 10:41:07 +01:00
179f2f1451 Removed obsolete code 2017-12-03 10:24:24 +01:00
92e772a02b Fixed some corner case map drawing issues 2017-12-03 10:17:29 +01:00
cbdfe4c105 Added slider/marker color setting 2017-12-03 00:36:52 +01:00
a20a268975 includes cleanup 2017-12-02 20:33:29 +01:00
48e972f920 Include paths unification 2017-12-02 20:28:53 +01:00
c38f50538e Do not use the alpha channel for graphs 2017-12-02 18:24:44 +01:00
53147b5e6e Code cleanup 2017-12-01 22:24:04 +01:00
6c6e384862 Some more code cleanup 2017-12-01 21:27:12 +01:00
90b780a444 Code cleanup 2017-12-01 20:52:34 +01:00
56d1ac7ff2 Fixed broken zoom handling 2017-12-01 19:54:04 +01:00
00acd48009 Fixed some more track display corner cases + refactoring 2017-12-01 00:22:16 +01:00
e30078a63e Code cleanup 2017-11-27 23:50:55 +01:00
51c0c31838 Fixed broken map scale computation 2017-11-27 08:48:37 +01:00
bc218c9f65 Moved the datums initialization where it belongs 2017-11-26 22:52:50 +01:00
56e4c80999 Project structure refactoring 2017-11-26 18:54:03 +01:00
443b916301 Optimization 2017-11-19 23:01:17 +01:00
8675a0e945 Made the Lambert azimuthal equal-area projection naming consistent with other projections namings 2017-11-14 23:30:25 +01:00
0894fb0ddf Added support for Lambert Azimuthal Equal Area projections 2017-11-14 22:17:59 +01:00
73e15f8f11 Includes cleanup 2017-11-14 22:17:09 +01:00
0fe7843e52 Added debug output for tiles 2017-11-14 22:15:46 +01:00
e76439bb6e Added support for TCX multi-sport activities 2017-10-14 22:57:03 +02:00
b54aeff369 Fixed copy&paste error, code cleanup 2017-10-13 18:15:37 +02:00
72968efeef Added support for Temperature, Cadence and Heartrate in KML files 2017-10-13 08:15:54 +02:00
ec3f529b0f Version++ 2017-10-11 22:44:33 +02:00
57a171ee8c Fixed broaken loading of KML files with multitracks and folder element outside document element 2017-10-11 22:41:01 +02:00
d3193abd0b Improved map view map init 2017-10-11 22:39:42 +02:00
6809853a8a Added OS X signing certificate 2017-10-05 22:07:31 +02:00
3155e8436b Optimization & code cleanup 2017-10-04 23:15:39 +02:00
69f9d05ccb Update gpxsee_sv.ts (#36) 2017-10-02 22:37:15 +02:00
e24a3cd99a Silenced compiler warning 2017-09-30 09:52:36 +02:00
a94fa9f0ea Translations update 2017-09-29 11:59:55 +02:00
c4f2a44410 Version++ 2017-09-29 11:44:44 +02:00
da4a51e7fa Improved graph slider info 2017-09-29 11:43:09 +02:00
bb47a34823 Translations update 2017-09-26 07:51:55 +02:00
11196c0e35 Improved graph type/time type switching 2017-09-26 07:46:46 +02:00
00ef815738 Unified average speed handling 2017-09-25 19:56:04 +02:00
64f685cf60 Removed accidentally commited files 2017-09-24 22:11:50 +02:00
7ab13ec8e5 Added missing Q_OBJECT macro 2017-09-24 20:13:13 +02:00
d3fbbecb2d Graph items are now selecteble like path items (+ tool tips) 2017-09-24 19:54:13 +02:00
7bc83603ca Fixed the 1px content offset issue on zoom/map change 2017-09-17 14:10:37 +02:00
2cd35b139e Removed obsolete strings, added missing punctuation 2017-09-15 18:59:22 +02:00
a74afa54fd Update gpxsee_sv.ts (#32) 2017-09-15 18:55:49 +02:00
753c4e8db0 Do not enable alpha channel for background colors 2017-09-15 08:30:00 +02:00
d0b3f48caf Version++ 2017-09-15 00:41:48 +02:00
e47cd1be7e Translations update 2017-09-15 00:39:59 +02:00
d1ba35f012 Updated maximal zoom for OpenTopo map 2017-09-15 00:35:11 +02:00
b9489afbfe Settings improvements and code cleanup 2017-09-15 00:07:09 +02:00
a7506cfd82 Merge branch 'master' of https://github.com/tumic0/GPXSee 2017-09-14 20:22:11 +02:00
c060abe6a7 Silenced valgrind warnings 2017-09-14 20:19:19 +02:00
b457fc430c Fixed broken parsing of TCX files with heart rate data 2017-09-14 20:18:34 +02:00
89947851fd Fixed invalid memory access 2017-09-14 20:18:02 +02:00
7d40dfddb2 Fixed broken units setting for cadence, heart rate and power graphs 2017-09-14 20:16:42 +02:00
151ae03b53 Fixed broken options layout on OS X 2017-09-10 12:53:51 +02:00
9fd8b84c3b Added waypoints/POI size/color settings 2017-09-10 12:42:49 +02:00
47683e5447 Added map background color setting.
Redesigned appearance settings tab.
2017-09-10 00:09:39 +02:00
84bcf07bd4 Translations update 2017-09-09 22:04:47 +02:00
cc694971be Added support for limiting the maximal zoom level of online map sources 2017-09-09 12:33:43 +02:00
ba856d7eb6 Adjusted the scale bar (text) size to the remaining content in plot mode 2017-09-09 10:51:19 +02:00
b14eeb58ab Fixed scale size in hi-res prints 2017-08-31 16:28:37 +02:00
8e932b966c Fixed msvc warning 2017-08-31 15:32:44 +02:00
35818ce16e Removed obsolete size guard 2017-08-31 08:10:09 +02:00
6ef7537dff Added some more paper sizes 2017-08-31 07:57:46 +02:00
abbb823890 Removed DPI dependency in print font size computation 2017-08-31 00:07:29 +02:00
0a4f8a46d4 Update gpxsee_sv.ts (#31)
* Update gpxsee_sv.ts

* Update gpxsee_sv.ts

Sorry, missed 2 strings.
2017-08-30 21:59:14 +02:00
fd2823c703 Version++ 2017-08-30 13:59:22 +02:00
d16b61051f Localization update 2017-08-30 13:56:23 +02:00
e69f17aad5 Print font size id now appropriate to the page size 2017-08-30 13:09:54 +02:00
33b1e179d3 Use the correct DPI value for zooming 2017-08-29 15:31:12 +02:00
5efb9f8a4e Added resolution setting to export dialogue. 2017-08-28 17:48:46 +02:00
ebf39f11bd Added support for hi-resolution printing 2017-08-28 15:25:45 +02:00
8b7422b70a Code cleanup 2017-08-27 12:19:33 +02:00
ef3da2e156 Removed obsolete Windows XP bug workaround 2017-08-24 21:04:01 +02:00
6e13c2b704 Translations update 2017-08-24 19:40:52 +02:00
f3e4719439 Added map opacity (brightness) settings 2017-08-24 17:29:59 +02:00
7b6789e78d Version++ 2017-08-23 15:42:00 +02:00
95442461fc Added 4UMaps to map sources 2017-08-23 15:41:23 +02:00
729cbd641c Added support for the VICGRID and VICGRID94 projections 2017-08-23 10:46:28 +02:00
2e2dad8d04 Fixed broken xy2ll computation on southern hemispheres 2017-08-23 10:45:23 +02:00
4e3b6c2eb2 Added missing error check 2017-08-22 23:14:32 +02:00
6430933a96 Use the (incorrect) scale factor of 1 in France zone projections like OziExplorer does 2017-08-22 22:59:59 +02:00
3e14d4afda Added France Zone I-IV projections support 2017-08-22 19:03:35 +02:00
ebb30a3fca Made OZF3 files parsing more robust. 2017-08-22 15:57:37 +02:00
bd20d40ba7 Fixed content margin computation.
Code cleanup.
2017-08-20 10:49:58 +02:00
77823fba14 Added missing newlines 2017-08-15 15:58:23 +02:00
dcc5cbe9bc Added appveyor build config 2017-08-15 15:49:28 +02:00
cd3c99b065 Added QT4 Travis CI build config 2017-08-15 15:42:47 +02:00
195 changed files with 4538 additions and 2180 deletions

52
.appveyor.yml Normal file
View File

@ -0,0 +1,52 @@
version: 4.17.{build}
configuration: Release
platform: Any CPU
environment:
NSISDIR: C:\Program Files (x86)\NSIS
matrix:
- QTDIR: C:\Qt\5.9\msvc2015
PLATFORM: x86
NSI: gpxsee.nsi
OPENSSLDIR: C:\OpenSSL-Win32\bin
- QTDIR: C:\Qt\5.9\msvc2015_64
PLATFORM: x86_amd64
NSI: gpxsee64.nsi
OPENSSLDIR: C:\OpenSSL-Win64\bin
install:
- cmd: >-
set PATH=%QTDIR%\bin;%NSISDIR%;%PATH%
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %PLATFORM%
build_script:
- cmd: >-
lrelease gpxsee.pro
qmake gpxsee.pro
nmake release
md installer
copy release\GPXSee.exe installer
windeployqt --no-svg --release installer\GPXSee.exe
copy pkg\%NSI% installer
copy pkg\datums.csv installer
copy pkg\ellipsoids.csv installer
copy pkg\maps.txt installer
copy licence.txt installer
copy %OPENSSLDIR%\libeay32.dll installer
copy %OPENSSLDIR%\ssleay32.dll installer
makensis.exe installer\%NSI%
artifacts:
- path: installer\GPXSee-*.exe

18
.travis.yml Normal file
View File

@ -0,0 +1,18 @@
language: c++
os:
- linux
- osx
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update; fi
install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libqt4-dev; fi
script:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then PATH=/usr/local/opt/qt/bin/:${PATH}; fi
- lrelease gpxsee.pro
- qmake gpxsee.pro
- make

BIN
cert/mac/gpxsee.cer Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
TARGET = GPXSee TARGET = GPXSee
VERSION = 4.11 VERSION = 4.17
QT += core \ QT += core \
gui \ gui \
network network
@ -7,165 +7,182 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 4): QT += printsupport greaterThan(QT_MAJOR_VERSION, 4): QT += printsupport
lessThan(QT_VERSION, 5.4): QT += opengl lessThan(QT_VERSION, 5.4): QT += opengl
macx: QT += opengl macx: QT += opengl
INCLUDEPATH += ./src
HEADERS += src/config.h \ HEADERS += src/config.h \
src/icons.h \ src/common/staticassert.h \
src/gui.h \ src/common/coordinates.h \
src/poi.h \ src/common/range.h \
src/rtree.h \ src/common/rectc.h \
src/axisitem.h \ src/common/wgs84.h \
src/keys.h \ src/GUI/app.h \
src/slideritem.h \ src/GUI/icons.h \
src/markeritem.h \ src/GUI/gui.h \
src/infoitem.h \ src/GUI/axisitem.h \
src/elevationgraph.h \ src/GUI/keys.h \
src/speedgraph.h \ src/GUI/slideritem.h \
src/sliderinfoitem.h \ src/GUI/markeritem.h \
src/filebrowser.h \ src/GUI/infoitem.h \
src/map.h \ src/GUI/elevationgraph.h \
src/onlinemap.h \ src/GUI/speedgraph.h \
src/downloader.h \ src/GUI/sliderinfoitem.h \
src/units.h \ src/GUI/filebrowser.h \
src/scaleitem.h \ src/GUI/units.h \
src/waypoint.h \ src/GUI/scaleitem.h \
src/track.h \ src/GUI/graphview.h \
src/graphview.h \ src/GUI/waypointitem.h \
src/trackpoint.h \ src/GUI/palette.h \
src/waypointitem.h \ src/GUI/heartrategraph.h \
src/palette.h \ src/GUI/trackinfo.h \
src/heartrategraph.h \ src/GUI/exportdialog.h \
src/range.h \ src/GUI/fileselectwidget.h \
src/cpuarch.h \ src/GUI/margins.h \
src/settings.h \ src/GUI/temperaturegraph.h \
src/app.h \ src/GUI/graphtab.h \
src/trackinfo.h \ src/GUI/trackitem.h \
src/exportdialog.h \ src/GUI/tooltip.h \
src/fileselectwidget.h \ src/GUI/routeitem.h \
src/margins.h \ src/GUI/graphitem.h \
src/temperaturegraph.h \ src/GUI/pathitem.h \
src/graphtab.h \ src/GUI/griditem.h \
src/misc.h \ src/GUI/format.h \
src/trackitem.h \ src/GUI/cadencegraph.h \
src/tooltip.h \ src/GUI/powergraph.h \
src/route.h \ src/GUI/optionsdialog.h \
src/routeitem.h \ src/GUI/colorbox.h \
src/graphitem.h \ src/GUI/stylecombobox.h \
src/graph.h \ src/GUI/opengl.h \
src/pathitem.h \ src/GUI/timetype.h \
src/pathview.h \ src/GUI/percentslider.h \
src/griditem.h \ src/GUI/elevationgraphitem.h \
src/data.h \ src/GUI/speedgraphitem.h \
src/gpxparser.h \ src/GUI/heartrategraphitem.h \
src/tcxparser.h \ src/GUI/temperaturegraphitem.h \
src/parser.h \ src/GUI/cadencegraphitem.h \
src/csvparser.h \ src/GUI/powergraphitem.h \
src/coordinates.h \ src/GUI/oddspinbox.h \
src/tile.h \ src/GUI/settings.h \
src/rd.h \ src/GUI/nicenum.h \
src/wgs84.h \ src/GUI/cpuarch.h \
src/kmlparser.h \ src/GUI/searchpointer.h \
src/trackdata.h \ src/GUI/mapview.h \
src/routedata.h \ src/map/projection.h \
src/fitparser.h \ src/map/ellipsoid.h \
src/format.h \ src/map/datum.h \
src/path.h \ src/map/mercator.h \
src/assert.h \ src/map/transversemercator.h \
src/cadencegraph.h \ src/map/latlon.h \
src/powergraph.h \ src/map/utm.h \
src/igcparser.h \ src/map/lambertconic.h \
src/nmeaparser.h \ src/map/lambertazimuthal.h \
src/optionsdialog.h \ src/map/albersequal.h \
src/colorbox.h \ src/map/map.h \
src/stylecombobox.h \ src/map/maplist.h \
src/opengl.h \ src/map/onlinemap.h \
src/timetype.h \ src/map/downloader.h \
src/emptymap.h \ src/map/tile.h \
src/offlinemap.h \ src/map/emptymap.h \
src/matrix.h \ src/map/offlinemap.h \
src/tar.h \ src/map/tar.h \
src/atlas.h \ src/map/ozf.h \
src/projection.h \ src/map/atlas.h \
src/mercator.h \ src/map/matrix.h \
src/transversemercator.h \ src/map/misc.h \
src/latlon.h \ src/data/graph.h \
src/utm.h \ src/data/poi.h \
src/lambertconic.h \ src/data/waypoint.h \
src/ellipsoid.h \ src/data/track.h \
src/ozf.h \ src/data/route.h \
src/datum.h \ src/data/trackpoint.h \
src/maplist.h \ src/data/data.h \
src/albersequal.h \ src/data/parser.h \
src/oddspinbox.h \ src/data/trackdata.h \
src/rectc.h \ src/data/routedata.h \
src/searchpointer.h src/data/path.h \
src/data/rtree.h \
src/data/gpxparser.h \
src/data/tcxparser.h \
src/data/csvparser.h \
src/data/kmlparser.h \
src/data/fitparser.h \
src/data/igcparser.h \
src/data/nmeaparser.h \
src/data/str2int.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/gui.cpp \ src/common/coordinates.cpp \
src/poi.cpp \ src/common/rectc.cpp \
src/axisitem.cpp \ src/common/range.cpp \
src/slideritem.cpp \ src/GUI/app.cpp \
src/markeritem.cpp \ src/GUI/gui.cpp \
src/infoitem.cpp \ src/GUI/axisitem.cpp \
src/elevationgraph.cpp \ src/GUI/slideritem.cpp \
src/speedgraph.cpp \ src/GUI/markeritem.cpp \
src/sliderinfoitem.cpp \ src/GUI/infoitem.cpp \
src/filebrowser.cpp \ src/GUI/elevationgraph.cpp \
src/onlinemap.cpp \ src/GUI/speedgraph.cpp \
src/downloader.cpp \ src/GUI/sliderinfoitem.cpp \
src/scaleitem.cpp \ src/GUI/filebrowser.cpp \
src/track.cpp \ src/GUI/scaleitem.cpp \
src/graphview.cpp \ src/GUI/graphview.cpp \
src/waypointitem.cpp \ src/GUI/waypointitem.cpp \
src/palette.cpp \ src/GUI/palette.cpp \
src/heartrategraph.cpp \ src/GUI/heartrategraph.cpp \
src/range.cpp \ src/GUI/trackinfo.cpp \
src/app.cpp \ src/GUI/exportdialog.cpp \
src/trackinfo.cpp \ src/GUI/fileselectwidget.cpp \
src/exportdialog.cpp \ src/GUI/temperaturegraph.cpp \
src/fileselectwidget.cpp \ src/GUI/trackitem.cpp \
src/temperaturegraph.cpp \ src/GUI/tooltip.cpp \
src/trackpoint.cpp \ src/GUI/routeitem.cpp \
src/misc.cpp \ src/GUI/graphitem.cpp \
src/waypoint.cpp \ src/GUI/pathitem.cpp \
src/trackitem.cpp \ src/GUI/griditem.cpp \
src/tooltip.cpp \ src/GUI/format.cpp \
src/route.cpp \ src/GUI/cadencegraph.cpp \
src/routeitem.cpp \ src/GUI/powergraph.cpp \
src/graphitem.cpp \ src/GUI/optionsdialog.cpp \
src/pathitem.cpp \ src/GUI/colorbox.cpp \
src/pathview.cpp \ src/GUI/stylecombobox.cpp \
src/griditem.cpp \ src/GUI/oddspinbox.cpp \
src/data.cpp \ src/GUI/percentslider.cpp \
src/gpxparser.cpp \ src/GUI/elevationgraphitem.cpp \
src/tcxparser.cpp \ src/GUI/speedgraphitem.cpp \
src/csvparser.cpp \ src/GUI/heartrategraphitem.cpp \
src/coordinates.cpp \ src/GUI/temperaturegraphitem.cpp \
src/kmlparser.cpp \ src/GUI/cadencegraphitem.cpp \
src/fitparser.cpp \ src/GUI/powergraphitem.cpp \
src/format.cpp \ src/GUI/nicenum.cpp \
src/graph.cpp \ src/GUI/mapview.cpp \
src/cadencegraph.cpp \ src/map/maplist.cpp \
src/powergraph.cpp \ src/map/onlinemap.cpp \
src/igcparser.cpp \ src/map/downloader.cpp \
src/path.cpp \ src/map/emptymap.cpp \
src/nmeaparser.cpp \ src/map/offlinemap.cpp \
src/optionsdialog.cpp \ src/map/tar.cpp \
src/colorbox.cpp \ src/map/atlas.cpp \
src/stylecombobox.cpp \ src/map/ozf.cpp \
src/emptymap.cpp \ src/map/matrix.cpp \
src/offlinemap.cpp \ src/map/ellipsoid.cpp \
src/matrix.cpp \ src/map/datum.cpp \
src/tar.cpp \ src/map/projection.cpp \
src/atlas.cpp \ src/map/mercator.cpp \
src/mercator.cpp \ src/map/transversemercator.cpp \
src/transversemercator.cpp \ src/map/utm.cpp \
src/utm.cpp \ src/map/lambertconic.cpp \
src/lambertconic.cpp \ src/map/albersequal.cpp \
src/ellipsoid.cpp \ src/map/lambertazimuthal.cpp \
src/ozf.cpp \ src/data/data.cpp \
src/datum.cpp \ src/data/poi.cpp \
src/maplist.cpp \ src/data/track.cpp \
src/albersequal.cpp \ src/data/route.cpp \
src/oddspinbox.cpp \ src/data/path.cpp \
src/rectc.cpp src/data/gpxparser.cpp \
src/data/tcxparser.cpp \
src/data/csvparser.cpp \
src/data/kmlparser.cpp \
src/data/fitparser.cpp \
src/data/igcparser.cpp \
src/data/nmeaparser.cpp \
src/data/str2int.cpp
RESOURCES += gpxsee.qrc RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts \ TRANSLATIONS = lang/gpxsee_cs.ts \
lang/gpxsee_sv.ts \ lang/gpxsee_sv.ts \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
; The name of the installer ; The name of the installer
Name "GPXSee" Name "GPXSee"
; Program version ; Program version
!define VERSION "4.11" !define VERSION "4.17"
; The file to write ; The file to write
OutFile "GPXSee-${VERSION}.exe" OutFile "GPXSee-${VERSION}.exe"

View File

@ -5,7 +5,7 @@
; The name of the installer ; The name of the installer
Name "GPXSee" Name "GPXSee"
; Program version ; Program version
!define VERSION "4.11" !define VERSION "4.17"
; The file to write ; The file to write
OutFile "GPXSee-${VERSION}_x64.exe" OutFile "GPXSee-${VERSION}_x64.exe"

View File

@ -1,4 +1,5 @@
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png 17
Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png 4UMaps http://4umaps.eu/$z/$x/$y.png 15
USGS Topo https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png 19
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y USGS Topo https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png 15
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y 15

109
src/GUI/app.cpp Normal file
View File

@ -0,0 +1,109 @@
#include <QtGlobal>
#include <QTranslator>
#include <QLocale>
#include <QFileOpenEvent>
#include <QNetworkProxyFactory>
#include <QLibraryInfo>
#include "map/onlinemap.h"
#include "map/downloader.h"
#include "map/ellipsoid.h"
#include "map/datum.h"
#include "opengl.h"
#include "gui.h"
#include "config.h"
#include "app.h"
App::App(int &argc, char **argv) : QApplication(argc, argv),
_argc(argc), _argv(argv)
{
QTranslator *gpxsee = new QTranslator(this);
QString locale = QLocale::system().name();
gpxsee->load(QString(":/lang/gpxsee_") + locale);
installTranslator(gpxsee);
QTranslator *qt = new QTranslator(this);
qt->load(QLocale::system(), "qt", "_", QLibraryInfo::location(
QLibraryInfo::TranslationsPath));
installTranslator(qt);
#ifdef Q_OS_MAC
setAttribute(Qt::AA_DontShowIconsInMenus);
#endif // Q_OS_MAC
QNetworkProxyFactory::setUseSystemConfiguration(true);
OnlineMap::setDownloader(new Downloader(this));
OPENGL_SET_SAMPLES(4);
loadDatums();
_gui = new GUI();
}
App::~App()
{
delete _gui;
}
void App::run()
{
_gui->show();
for (int i = 1; i < _argc; i++)
_gui->openFile(QString::fromLocal8Bit(_argv[i]));
exec();
}
bool App::event(QEvent *event)
{
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *e = static_cast<QFileOpenEvent *>(event);
return _gui->openFile(e->file());
}
return QApplication::event(event);
}
void App::loadDatums()
{
QString ef, df;
bool ok = false;
if (QFile::exists(USER_ELLIPSOID_FILE))
ef = USER_ELLIPSOID_FILE;
else if (QFile::exists(GLOBAL_ELLIPSOID_FILE))
ef = GLOBAL_ELLIPSOID_FILE;
else
qWarning("No ellipsoids file found.");
if (QFile::exists(USER_DATUM_FILE))
df = USER_DATUM_FILE;
else if (QFile::exists(GLOBAL_DATUM_FILE))
df = GLOBAL_DATUM_FILE;
else
qWarning("No datums file found.");
if (!ef.isNull() && !df.isNull()) {
if (!Ellipsoid::loadList(ef)) {
if (Ellipsoid::errorLine())
qWarning("%s: parse error on line %d: %s", qPrintable(ef),
Ellipsoid::errorLine(), qPrintable(Ellipsoid::errorString()));
else
qWarning("%s: %s", qPrintable(ef), qPrintable(
Ellipsoid::errorString()));
} else {
if (!Datum::loadList(df)) {
if (Datum::errorLine())
qWarning("%s: parse error on line %d: %s", qPrintable(ef),
Datum::errorLine(), qPrintable(Datum::errorString()));
else
qWarning("%s: %s", qPrintable(ef), qPrintable(
Datum::errorString()));
} else
ok = true;
}
}
if (!ok)
qWarning("Maps based on a datum different from WGS84 won't work.");
}

View File

@ -18,6 +18,8 @@ protected:
bool event(QEvent *event); bool event(QEvent *event);
private: private:
void loadDatums();
int &_argc; int &_argc;
char **_argv; char **_argv;
GUI *_gui; GUI *_gui;

View File

@ -1,7 +1,7 @@
#include <cmath> #include <cmath>
#include <QPainter> #include <QPainter>
#include "config.h" #include "config.h"
#include "misc.h" #include "nicenum.h"
#include "axisitem.h" #include "axisitem.h"

View File

@ -2,7 +2,7 @@
#define AXISITEM_H #define AXISITEM_H
#include <QGraphicsItem> #include <QGraphicsItem>
#include "range.h" #include "common/range.h"
class AxisItem : public QGraphicsItem class AxisItem : public QGraphicsItem
{ {

View File

@ -1,10 +1,10 @@
#include "data.h" #include "data/data.h"
#include "cadencegraphitem.h"
#include "cadencegraph.h" #include "cadencegraph.h"
CadenceGraph::CadenceGraph(QWidget *parent) : GraphTab(parent) CadenceGraph::CadenceGraph(QWidget *parent) : GraphTab(parent)
{ {
_units = Metric;
_showTracks = true; _showTracks = true;
GraphView::setYUnits(tr("1/min")); GraphView::setYUnits(tr("1/min"));
@ -28,21 +28,16 @@ void CadenceGraph::loadData(const Data &data, const QList<PathItem *> &paths)
{ {
for (int i = 0; i < data.tracks().count(); i++) { for (int i = 0; i < data.tracks().count(); i++) {
const Graph &graph = data.tracks().at(i)->cadence(); const Graph &graph = data.tracks().at(i)->cadence();
qreal sum = 0, w = 0;
if (graph.size() < 2) { if (graph.size() < 2) {
skipColor(); skipColor();
continue; continue;
} }
for (int j = 1; j < graph.size(); j++) { CadenceGraphItem *gi = new CadenceGraphItem(graph, _graphType);
qreal ds = graph.at(j).s() - graph.at(j-1).s(); GraphView::addGraph(gi, paths.at(i));
sum += graph.at(j).y() * ds;
w += ds;
}
_avg.append(QPointF(data.tracks().at(i)->distance(), sum/w));
GraphView::loadGraph(graph, paths.at(i)); _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg()));
} }
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)

View File

@ -13,7 +13,6 @@ public:
QString label() const {return tr("Cadence");} QString label() const {return tr("Cadence");}
void loadData(const Data &data, const QList<PathItem *> &paths); void loadData(const Data &data, const QList<PathItem *> &paths);
void clear(); void clear();
void setUnits(enum Units) {}
void showTracks(bool show); void showTracks(bool show);
void showRoutes(bool show) {Q_UNUSED(show);} void showRoutes(bool show) {Q_UNUSED(show);}
@ -24,7 +23,6 @@ private:
QList<QPointF> _avg; QList<QPointF> _avg;
enum Units _units;
bool _showTracks; bool _showTracks;
}; };

View File

@ -0,0 +1,26 @@
#include "tooltip.h"
#include "cadencegraphitem.h"
CadenceGraphItem::CadenceGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent) : GraphItem(graph, type, parent)
{
qreal sum = 0;
for (int j = 1; j < graph.size(); j++)
sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s());
_avg = sum/graph.last().s();
setToolTip(toolTip());
}
QString CadenceGraphItem::toolTip() const
{
ToolTip tt;
tt.insert(tr("Maximum"), QString::number(max(), 'f', 1)
+ UNIT_SPACE + tr("1/min"));
tt.insert(tr("Average"), QString::number(avg(), 'f', 1)
+ UNIT_SPACE + tr("1/min"));
return tt.toString();
}

View File

@ -0,0 +1,23 @@
#ifndef CADENCEGRAPHITEM_H
#define CADENCEGRAPHITEM_H
#include "graphitem.h"
class CadenceGraphItem : public GraphItem
{
Q_OBJECT
public:
CadenceGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent = 0);
qreal max() const {return -bounds().top();}
qreal avg() const {return _avg;}
private:
QString toolTip() const;
qreal _avg;
};
#endif // CADENCEGRAPHITEM_H

View File

@ -9,6 +9,8 @@
ColorBox::ColorBox(QWidget *parent) : QWidget(parent) ColorBox::ColorBox(QWidget *parent) : QWidget(parent)
{ {
_color = Qt::red; _color = Qt::red;
_alpha = true;
setSizePolicy(QSizePolicy::QSizePolicy::Minimum, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::QSizePolicy::Minimum, QSizePolicy::Fixed);
} }
@ -51,9 +53,9 @@ void ColorBox::mousePressEvent(QMouseEvent *event)
{ {
if (event->button() != Qt::LeftButton) if (event->button() != Qt::LeftButton)
return; return;
QColorDialog::ColorDialogOptions options = _alpha
QColor color = QColorDialog::getColor(_color, this, QString(), ? QColorDialog::ShowAlphaChannel : (QColorDialog::ColorDialogOptions)0;
QColorDialog::ShowAlphaChannel); QColor color = QColorDialog::getColor(_color, this, QString(), options);
if (color.isValid()) { if (color.isValid()) {
_color = color; _color = color;
update(); update();

View File

@ -12,6 +12,7 @@ public:
const QColor &color() const {return _color;} const QColor &color() const {return _color;}
void setColor(const QColor &color); void setColor(const QColor &color);
void enableAlphaChannel(bool enable) {_alpha = enable;}
QSize sizeHint() const; QSize sizeHint() const;
@ -24,6 +25,7 @@ protected:
private: private:
QColor _color; QColor _color;
bool _alpha;
}; };
#endif // COLORBOX_H #endif // COLORBOX_H

View File

@ -1,6 +1,8 @@
#include <cmath> #include <cmath>
#include "data/data.h"
#include "config.h" #include "config.h"
#include "data.h" #include "tooltip.h"
#include "elevationgraphitem.h"
#include "elevationgraph.h" #include "elevationgraph.h"
@ -42,11 +44,8 @@ ElevationGraph::ElevationGraph(QWidget *parent) : GraphTab(parent)
_showRoutes = true; _showRoutes = true;
_showTracks = true; _showTracks = true;
_units = Metric; setYUnits(Metric);
setYUnits();
setYLabel(tr("Elevation")); setYLabel(tr("Elevation"));
setMinYRange(50.0); setMinYRange(50.0);
} }
@ -68,43 +67,25 @@ void ElevationGraph::setInfo()
void ElevationGraph::loadGraph(const Graph &graph, Type type, PathItem *path) void ElevationGraph::loadGraph(const Graph &graph, Type type, PathItem *path)
{ {
qreal ascent = 0, descent = 0;
qreal min, max;
if (graph.size() < 2) { if (graph.size() < 2) {
skipColor(); skipColor();
return; return;
} }
max = min = graph.at(0).y(); ElevationGraphItem *gi = new ElevationGraphItem(graph, _graphType);
for (int j = 1; j < graph.size(); j++) { GraphView::addGraph(gi, path, type);
qreal cur = graph.at(j).y();
qreal prev = graph.at(j-1).y();
if (cur > prev)
ascent += cur - prev;
if (cur < prev)
descent += prev - cur;
if (cur < min)
min = cur;
if (cur > max)
max = cur;
}
if (type == Track) { if (type == Track) {
_trackAscent += ascent; _trackAscent += gi->ascent();
_trackDescent += descent; _trackDescent += gi->descent();
_trackMax = nMax(_trackMax, max); _trackMax = nMax(_trackMax, gi->max());
_trackMin = nMin(_trackMin, min); _trackMin = nMin(_trackMin, gi->min());
} else { } else {
_routeAscent += ascent; _routeAscent += gi->ascent();
_routeDescent += descent; _routeDescent += gi->descent();
_routeMax = nMax(_routeMax, max); _routeMax = nMax(_routeMax, gi->max());
_routeMin = nMin(_routeMin, min); _routeMin = nMin(_routeMin, gi->min());
} }
GraphView::loadGraph(graph, path, type);
} }
void ElevationGraph::loadData(const Data &data, const QList<PathItem *> &paths) void ElevationGraph::loadData(const Data &data, const QList<PathItem *> &paths)
@ -135,9 +116,9 @@ void ElevationGraph::clear()
GraphView::clear(); GraphView::clear();
} }
void ElevationGraph::setYUnits() void ElevationGraph::setYUnits(Units units)
{ {
if (_units == Metric) { if (units == Metric) {
GraphView::setYUnits(tr("m")); GraphView::setYUnits(tr("m"));
setYScale(1); setYScale(1);
} else { } else {
@ -146,15 +127,12 @@ void ElevationGraph::setYUnits()
} }
} }
void ElevationGraph::setUnits(enum Units units) void ElevationGraph::setUnits(Units units)
{ {
_units = units; setYUnits(units);
setYUnits();
setInfo(); setInfo();
GraphView::setUnits(units);
redraw(); GraphView::setUnits(units);
} }
void ElevationGraph::showTracks(bool show) void ElevationGraph::showTracks(bool show)

View File

@ -25,7 +25,7 @@ private:
qreal ascent() const; qreal ascent() const;
qreal descent() const; qreal descent() const;
void setYUnits(); void setYUnits(Units units);
void setInfo(); void setInfo();
void loadGraph(const Graph &graph, Type type, PathItem *path); void loadGraph(const Graph &graph, Type type, PathItem *path);
@ -35,7 +35,6 @@ private:
qreal _trackMax, _routeMax; qreal _trackMax, _routeMax;
qreal _trackMin, _routeMin; qreal _trackMin, _routeMin;
enum Units _units;
bool _showTracks, _showRoutes; bool _showTracks, _showRoutes;
}; };

View File

@ -0,0 +1,43 @@
#include "tooltip.h"
#include "elevationgraphitem.h"
ElevationGraphItem::ElevationGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent) : GraphItem(graph, type, parent)
{
_ascent = _descent = 0;
for (int j = 1; j < graph.size(); j++) {
qreal cur = graph.at(j).y();
qreal prev = graph.at(j-1).y();
if (cur > prev)
_ascent += cur - prev;
if (cur < prev)
_descent += prev - cur;
}
setToolTip(toolTip(Metric));
}
QString ElevationGraphItem::toolTip(Units units) const
{
ToolTip tt;
qreal scale = (units == Metric) ? 1.0 : M2FT;
QString su = (units == Metric) ? tr("m") : tr("ft");
tt.insert(tr("Ascent"), QString::number(ascent() * scale, 'f', 0)
+ UNIT_SPACE + su);
tt.insert(tr("Descent"), QString::number(descent() * scale, 'f', 0)
+ UNIT_SPACE + su);
tt.insert(tr("Maximum"), QString::number(max() * scale, 'f', 0)
+ UNIT_SPACE + su);
tt.insert(tr("Minimum"), QString::number(min() * scale, 'f', 0)
+ UNIT_SPACE + su);
return tt.toString();
}
void ElevationGraphItem::setUnits(Units units)
{
setToolTip(toolTip(units));
}

View File

@ -0,0 +1,27 @@
#ifndef ELEVATIONGRAPHITEM_H
#define ELEVATIONGRAPHITEM_H
#include "graphitem.h"
class ElevationGraphItem : public GraphItem
{
Q_OBJECT
public:
ElevationGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent = 0);
qreal ascent() const {return _ascent;}
qreal descent() const {return _descent;}
qreal min() const {return -bounds().bottom();}
qreal max() const {return -bounds().top();}
void setUnits(Units units);
private:
QString toolTip(Units units) const;
qreal _ascent, _descent;
};
#endif // ELEVATIONGRAPHITEM_H

View File

@ -26,15 +26,28 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
_fileSelect->setFile(_export->fileName); _fileSelect->setFile(_export->fileName);
_paperSize = new QComboBox(); _paperSize = new QComboBox();
_paperSize->addItem("A2", QPrinter::A2);
_paperSize->addItem("A3", QPrinter::A3); _paperSize->addItem("A3", QPrinter::A3);
_paperSize->addItem("A4", QPrinter::A4); _paperSize->addItem("A4", QPrinter::A4);
_paperSize->addItem("A5", QPrinter::A5); _paperSize->addItem("A5", QPrinter::A5);
_paperSize->addItem("A6", QPrinter::A6);
_paperSize->addItem("B3", QPrinter::B3);
_paperSize->addItem("B4", QPrinter::B4);
_paperSize->addItem("B5", QPrinter::B5);
_paperSize->addItem("B6", QPrinter::B6);
_paperSize->addItem("Tabloid", QPrinter::Tabloid); _paperSize->addItem("Tabloid", QPrinter::Tabloid);
_paperSize->addItem("Legal", QPrinter::Legal); _paperSize->addItem("Legal", QPrinter::Legal);
_paperSize->addItem("Letter", QPrinter::Letter); _paperSize->addItem("Letter", QPrinter::Letter);
if ((index = _paperSize->findData(_export->paperSize)) >= 0) if ((index = _paperSize->findData(_export->paperSize)) >= 0)
_paperSize->setCurrentIndex(index); _paperSize->setCurrentIndex(index);
_resolution = new QComboBox();
_resolution->addItem("300 DPI", 300);
_resolution->addItem("600 DPI", 600);
_resolution->addItem("1200 DPI", 1200);
if ((index = _resolution->findData(_export->resolution)) >= 0)
_resolution->setCurrentIndex(index);
_portrait = new QRadioButton(tr("Portrait")); _portrait = new QRadioButton(tr("Portrait"));
_landscape = new QRadioButton(tr("Landscape")); _landscape = new QRadioButton(tr("Landscape"));
QHBoxLayout *orientationLayout = new QHBoxLayout(); QHBoxLayout *orientationLayout = new QHBoxLayout();
@ -81,6 +94,7 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
#endif // Q_OS_MAC #endif // Q_OS_MAC
QFormLayout *pageSetupLayout = new QFormLayout; QFormLayout *pageSetupLayout = new QFormLayout;
pageSetupLayout->addRow(tr("Page size:"), _paperSize); pageSetupLayout->addRow(tr("Page size:"), _paperSize);
pageSetupLayout->addRow(tr("Resolution:"), _resolution);
pageSetupLayout->addRow(tr("Orientation:"), orientationLayout); pageSetupLayout->addRow(tr("Orientation:"), orientationLayout);
pageSetupLayout->addRow(tr("Margins:"), marginsLayout); pageSetupLayout->addRow(tr("Margins:"), marginsLayout);
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
@ -161,9 +175,11 @@ void ExportDialog::accept()
? QPrinter::Portrait : QPrinter::Landscape; ? QPrinter::Portrait : QPrinter::Landscape;
QPrinter::PaperSize paperSize = static_cast<QPrinter::PaperSize> QPrinter::PaperSize paperSize = static_cast<QPrinter::PaperSize>
(_paperSize->itemData(_paperSize->currentIndex()).toInt()); (_paperSize->itemData(_paperSize->currentIndex()).toInt());
int resolution = _resolution->itemData(_resolution->currentIndex()).toInt();
_export->fileName = _fileSelect->file(); _export->fileName = _fileSelect->file();
_export->paperSize = paperSize; _export->paperSize = paperSize;
_export->resolution = resolution;
_export->orientation = orientation; _export->orientation = orientation;
if (_export->units == Imperial) if (_export->units == Imperial)
_export->margins = MarginsF(_leftMargin->value() / MM2IN, _export->margins = MarginsF(_leftMargin->value() / MM2IN,

View File

@ -16,6 +16,7 @@ struct Export {
QPrinter::PaperSize paperSize; QPrinter::PaperSize paperSize;
QPrinter::Orientation orientation; QPrinter::Orientation orientation;
MarginsF margins; MarginsF margins;
int resolution;
Units units; Units units;
}; };
@ -37,6 +38,7 @@ private:
FileSelectWidget *_fileSelect; FileSelectWidget *_fileSelect;
QComboBox *_paperSize; QComboBox *_paperSize;
QComboBox *_resolution;
QRadioButton *_portrait; QRadioButton *_portrait;
QRadioButton *_landscape; QRadioButton *_landscape;
QDoubleSpinBox *_topMargin; QDoubleSpinBox *_topMargin;

View File

@ -1,8 +1,8 @@
#include <QApplication> #include <QApplication>
#include "coordinates.h" #include "common/coordinates.h"
#include "format.h" #include "format.h"
QString Format::timeSpan(qreal time) QString Format::timeSpan(qreal time, bool full)
{ {
unsigned h, m, s; unsigned h, m, s;
@ -10,8 +10,12 @@ QString Format::timeSpan(qreal time)
m = (time - (h * 3600)) / 60; m = (time - (h * 3600)) / 60;
s = time - (h * 3600) - (m * 60); s = time - (h * 3600) - (m * 60);
return QString("%1:%2:%3").arg(h).arg(m, 2, 10, QChar('0')) if (full || h)
.arg(s, 2, 10, QChar('0')); return QString("%1:%2:%3").arg(h, 2, 10, QChar('0'))
.arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0'));
else
return QString("%1:%2").arg(m, 2, 10, QChar('0'))
.arg(s, 2, 10, QChar('0'));
} }
QString Format::distance(qreal value, Units units) QString Format::distance(qreal value, Units units)

View File

@ -8,7 +8,7 @@ class Coordinates;
namespace Format namespace Format
{ {
QString timeSpan(qreal time); QString timeSpan(qreal time, bool full = true);
QString distance(qreal value, Units units); QString distance(qreal value, Units units);
QString elevation(qreal value, Units units); QString elevation(qreal value, Units units);
QString coordinates(const Coordinates &value); QString coordinates(const Coordinates &value);

View File

@ -2,7 +2,7 @@
#include "graphitem.h" #include "graphitem.h"
GraphItem::GraphItem(const Graph &graph, QGraphicsItem *parent) GraphItem::GraphItem(const Graph &graph, GraphType type, QGraphicsItem *parent)
: QGraphicsObject(parent) : QGraphicsObject(parent)
{ {
_id = 0; _id = 0;
@ -10,7 +10,7 @@ GraphItem::GraphItem(const Graph &graph, QGraphicsItem *parent)
_pen = QPen(Qt::black, _width); _pen = QPen(Qt::black, _width);
_type = Distance; _type = type;
_graph = graph; _graph = graph;
_sx = 1.0; _sy = 1.0; _sx = 1.0; _sy = 1.0;
@ -25,7 +25,17 @@ GraphItem::GraphItem(const Graph &graph, QGraphicsItem *parent)
setZValue(1.0); setZValue(1.0);
updatePath(); updatePath();
updateShape();
updateBounds(); updateBounds();
setAcceptHoverEvents(true);
}
void GraphItem::updateShape()
{
QPainterPathStroker s;
s.setWidth(_width + 1);
_shape = s.createStroke(_path);
} }
void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
@ -46,25 +56,37 @@ void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
void GraphItem::setGraphType(GraphType type) void GraphItem::setGraphType(GraphType type)
{ {
if (type == _type)
return;
prepareGeometryChange(); prepareGeometryChange();
_type = type; _type = type;
updatePath(); updatePath();
updateShape();
updateBounds(); updateBounds();
} }
void GraphItem::setColor(const QColor &color) void GraphItem::setColor(const QColor &color)
{ {
if (_pen.color() == color)
return;
_pen.setColor(color); _pen.setColor(color);
update(); update();
} }
void GraphItem::setWidth(int width) void GraphItem::setWidth(int width)
{ {
if (width == _width)
return;
prepareGeometryChange(); prepareGeometryChange();
_width = width; _width = width;
_pen.setWidth(width); _pen.setWidth(width);
updateShape();
} }
qreal GraphItem::yAtX(qreal x) qreal GraphItem::yAtX(qreal x)
@ -143,9 +165,9 @@ void GraphItem::emitSliderPositionChanged(qreal pos)
emit sliderPositionChanged(pos); emit sliderPositionChanged(pos);
} }
void GraphItem::selected(bool selected) void GraphItem::hover(bool hover)
{ {
if (selected) { if (hover) {
_pen.setWidth(_width + 1); _pen.setWidth(_width + 1);
setZValue(zValue() + 1.0); setZValue(zValue() + 1.0);
} else { } else {
@ -165,6 +187,7 @@ void GraphItem::setScale(qreal sx, qreal sy)
_sx = sx; _sy = sy; _sx = sx; _sy = sy;
updatePath(); updatePath();
updateShape();
} }
void GraphItem::updatePath() void GraphItem::updatePath()
@ -199,3 +222,25 @@ void GraphItem::updateBounds()
_bounds = QRectF(QPointF(left, top), QPointF(right, bottom)); _bounds = QRectF(QPointF(left, top), QPointF(right, bottom));
} }
void GraphItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
_pen.setWidthF(_width + 1);
setZValue(zValue() + 1.0);
update();
emit selected(true);
}
void GraphItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
_pen.setWidthF(_width);
setZValue(zValue() - 1.0);
update();
emit selected(false);
}

View File

@ -3,41 +3,50 @@
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QPen> #include <QPen>
#include "graph.h" #include "data/graph.h"
#include "units.h"
class GraphItem : public QGraphicsObject class GraphItem : public QGraphicsObject
{ {
Q_OBJECT Q_OBJECT
public: public:
GraphItem(const Graph &graph, QGraphicsItem *parent = 0); GraphItem(const Graph &graph, GraphType type, QGraphicsItem *parent = 0);
QRectF boundingRect() const QPainterPath shape() const {return _shape;}
{return _path.boundingRect();} QRectF boundingRect() const {return _shape.boundingRect();}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget); QWidget *widget);
const QRectF &bounds() const {return _bounds;} const QRectF &bounds() const {return _bounds;}
void setScale(qreal sx, qreal sy);
void setScale(qreal sx, qreal sy);
void setGraphType(GraphType type); void setGraphType(GraphType type);
int id() const {return _id;} int id() const {return _id;}
void setId(int id) {_id = id;} void setId(int id) {_id = id;}
void setColor(const QColor &color); void setColor(const QColor &color);
void setWidth(int width); void setWidth(int width);
virtual void setUnits(Units units) {Q_UNUSED(units);}
qreal yAtX(qreal x); qreal yAtX(qreal x);
qreal distanceAtTime(qreal time); qreal distanceAtTime(qreal time);
void redraw();
signals: signals:
void sliderPositionChanged(qreal); void sliderPositionChanged(qreal);
void selected(bool);
public slots: public slots:
void emitSliderPositionChanged(qreal); void emitSliderPositionChanged(qreal);
void selected(bool selected); void hover(bool hover);
private: private:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void updatePath(); void updatePath();
void updateShape();
void updateBounds(); void updateBounds();
int _id; int _id;
@ -48,6 +57,7 @@ private:
GraphType _type; GraphType _type;
QPainterPath _path; QPainterPath _path;
QPainterPath _shape;
QRectF _bounds; QRectF _bounds;
qreal _sx, _sy; qreal _sx, _sy;

View File

@ -19,8 +19,9 @@ public:
virtual QString label() const = 0; virtual QString label() const = 0;
virtual void loadData(const Data &data, const QList<PathItem *> &paths) = 0; virtual void loadData(const Data &data, const QList<PathItem *> &paths) = 0;
virtual void clear() {} virtual void clear() {GraphView::clear();}
virtual void setUnits(enum Units units) {Q_UNUSED(units)} virtual void setUnits(enum Units units) {GraphView::setUnits(units);}
virtual void setGraphType(GraphType type) {GraphView::setGraphType(type);}
virtual void setTimeType(enum TimeType type) {Q_UNUSED(type)} virtual void setTimeType(enum TimeType type) {Q_UNUSED(type)}
virtual void showTracks(bool show) {Q_UNUSED(show)} virtual void showTracks(bool show) {Q_UNUSED(show)}
virtual void showRoutes(bool show) {Q_UNUSED(show)} virtual void showRoutes(bool show) {Q_UNUSED(show)}

View File

@ -3,6 +3,7 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QPaintEngine> #include <QPaintEngine>
#include <QPaintDevice> #include <QPaintDevice>
#include "data/graph.h"
#include "opengl.h" #include "opengl.h"
#include "config.h" #include "config.h"
#include "axisitem.h" #include "axisitem.h"
@ -10,9 +11,9 @@
#include "sliderinfoitem.h" #include "sliderinfoitem.h"
#include "infoitem.h" #include "infoitem.h"
#include "griditem.h" #include "griditem.h"
#include "graph.h"
#include "graphitem.h" #include "graphitem.h"
#include "pathitem.h" #include "pathitem.h"
#include "format.h"
#include "graphview.h" #include "graphview.h"
@ -139,7 +140,13 @@ void GraphView::setXUnits()
void GraphView::setUnits(Units units) void GraphView::setUnits(Units units)
{ {
_units = units; _units = units;
for (int i = 0; i < _graphs.count(); i++)
_graphs.at(i)->setUnits(units);
setXUnits(); setXUnits();
redraw();
} }
void GraphView::setGraphType(GraphType type) void GraphView::setGraphType(GraphType type)
@ -167,29 +174,34 @@ void GraphView::showGrid(bool show)
_grid->setVisible(show); _grid->setVisible(show);
} }
void GraphView::loadGraph(const Graph &graph, PathItem *path, int id) void GraphView::showSliderInfo(bool show)
{ {
if (graph.size() < 2) _sliderInfo->setVisible(show);
return; }
GraphItem *gi = new GraphItem(graph); void GraphView::addGraph(GraphItem *graph, PathItem *path, int id)
gi->setGraphType(_graphType); {
gi->setId(id); QColor color(_palette.nextColor());
gi->setColor(_palette.nextColor()); color.setAlpha(255);
gi->setWidth(_width);
connect(this, SIGNAL(sliderPositionChanged(qreal)), gi, graph->setUnits(_units);
graph->setId(id);
graph->setColor(color);
graph->setWidth(_width);
connect(this, SIGNAL(sliderPositionChanged(qreal)), graph,
SLOT(emitSliderPositionChanged(qreal))); SLOT(emitSliderPositionChanged(qreal)));
connect(gi, SIGNAL(sliderPositionChanged(qreal)), path, connect(graph, SIGNAL(sliderPositionChanged(qreal)), path,
SLOT(moveMarker(qreal))); SLOT(moveMarker(qreal)));
connect(path, SIGNAL(selected(bool)), gi, SLOT(selected(bool))); connect(path, SIGNAL(selected(bool)), graph, SLOT(hover(bool)));
connect(graph, SIGNAL(selected(bool)), path, SLOT(hover(bool)));
_graphs.append(gi); _graphs.append(graph);
if (!_hide.contains(id)) { if (!_hide.contains(id)) {
_visible.append(gi); _visible.append(graph);
_scene->addItem(gi); _scene->addItem(graph);
_bounds |= gi->bounds(); _bounds |= graph->bounds();
setXUnits(); setXUnits();
} }
} }
@ -227,11 +239,6 @@ void GraphView::showGraph(bool show, int id)
} }
} }
void GraphView::redraw()
{
redraw(viewport()->size() - QSizeF(MARGIN, MARGIN));
}
QRectF GraphView::bounds() const QRectF GraphView::bounds() const
{ {
QRectF br(_bounds); QRectF br(_bounds);
@ -239,6 +246,11 @@ QRectF GraphView::bounds() const
return br; return br;
} }
void GraphView::redraw()
{
redraw(viewport()->size() - QSizeF(MARGIN, MARGIN));
}
void GraphView::redraw(const QSizeF &size) void GraphView::redraw(const QSizeF &size)
{ {
QRectF r; QRectF r;
@ -326,11 +338,9 @@ void GraphView::mousePressEvent(QMouseEvent *e)
QGraphicsView::mousePressEvent(e); QGraphicsView::mousePressEvent(e);
} }
void GraphView::plot(QPainter *painter, const QRectF &target) void GraphView::plot(QPainter *painter, const QRectF &target, qreal scale)
{ {
qreal ratio = painter->paintEngine()->paintDevice()->logicalDpiX() QSizeF canvas = QSizeF(target.width() / scale, target.height() / scale);
/ SCREEN_DPI;
QSizeF canvas = QSizeF(target.width() / ratio, target.height() / ratio);
setUpdatesEnabled(false); setUpdatesEnabled(false);
redraw(canvas); redraw(canvas);
@ -374,22 +384,26 @@ void GraphView::updateSliderPosition()
_slider->setVisible(false); _slider->setVisible(false);
} }
updateSliderInfo(); if (_slider->isVisible())
updateSliderInfo();
} }
void GraphView::updateSliderInfo() void GraphView::updateSliderInfo()
{ {
_sliderInfo->setVisible(_visible.count() == 1); qreal r, y;
if (!_sliderInfo->isVisible())
return;
QRectF br(_visible.first()->bounds()); if (_visible.count() > 1) {
if (br.height() < _minYRange) r = 0;
br.adjust(0, -(_minYRange/2 - br.height()/2), 0, y = 0;
_minYRange/2 - br.height()/2); } else {
QRectF br(_visible.first()->bounds());
if (br.height() < _minYRange)
br.adjust(0, -(_minYRange/2 - br.height()/2), 0,
_minYRange/2 - br.height()/2);
qreal y = _visible.first()->yAtX(_sliderPos); y = _visible.first()->yAtX(_sliderPos);
qreal r = (y - br.bottom()) / br.height(); r = (y - br.bottom()) / br.height();
}
qreal pos = (_sliderPos / bounds().width()) * _slider->area().width(); qreal pos = (_sliderPos / bounds().width()) * _slider->area().width();
SliderInfoItem::Side s = (pos + _sliderInfo->boundingRect().width() SliderInfoItem::Side s = (pos + _sliderInfo->boundingRect().width()
@ -397,8 +411,11 @@ void GraphView::updateSliderInfo()
_sliderInfo->setSide(s); _sliderInfo->setSide(s);
_sliderInfo->setPos(QPointF(0, _slider->boundingRect().height() * r)); _sliderInfo->setPos(QPointF(0, _slider->boundingRect().height() * r));
_sliderInfo->setText(QString::number(-y * _yScale + _yOffset, 'f', _sliderInfo->setText(_graphType == Time ? Format::timeSpan(_sliderPos,
_precision)); bounds().width() > 3600) : QString::number(_sliderPos * _xScale, 'f', 1)
+ UNIT_SPACE + _xUnits, (_visible.count() > 1) ? QString()
: QString::number(-y * _yScale + _yOffset, 'f', _precision) + UNIT_SPACE
+ _yUnits);
} }
void GraphView::emitSliderPositionChanged(const QPointF &pos) void GraphView::emitSliderPositionChanged(const QPointF &pos)
@ -444,8 +461,11 @@ void GraphView::setPalette(const Palette &palette)
_palette = palette; _palette = palette;
_palette.reset(); _palette.reset();
for (int i = 0; i < _graphs.count(); i++) for (int i = 0; i < _graphs.count(); i++) {
_graphs.at(i)->setColor(_palette.nextColor()); QColor color(_palette.nextColor());
color.setAlpha(255);
_graphs.at(i)->setColor(color);
}
} }
void GraphView::setGraphWidth(int width) void GraphView::setGraphWidth(int width)
@ -454,6 +474,8 @@ void GraphView::setGraphWidth(int width)
for (int i = 0; i < _graphs.count(); i++) for (int i = 0; i < _graphs.count(); i++)
_graphs.at(i)->setWidth(width); _graphs.at(i)->setWidth(width);
redraw();
} }
void GraphView::useOpenGL(bool use) void GraphView::useOpenGL(bool use)
@ -463,3 +485,14 @@ void GraphView::useOpenGL(bool use)
else else
setViewport(new QWidget); setViewport(new QWidget);
} }
void GraphView::useAntiAliasing(bool use)
{
setRenderHint(QPainter::Antialiasing, use);
}
void GraphView::setSliderColor(const QColor &color)
{
_slider->setColor(color);
_sliderInfo->setColor(color);
}

View File

@ -4,9 +4,9 @@
#include <QGraphicsView> #include <QGraphicsView>
#include <QList> #include <QList>
#include <QSet> #include <QSet>
#include "data/graph.h"
#include "palette.h" #include "palette.h"
#include "units.h" #include "units.h"
#include "graph.h"
class AxisItem; class AxisItem;
@ -25,18 +25,30 @@ public:
GraphView(QWidget *parent = 0); GraphView(QWidget *parent = 0);
~GraphView(); ~GraphView();
void loadGraph(const Graph &graph, PathItem *path, int id = 0); bool isEmpty() const {return _graphs.isEmpty();}
int count() const {return _graphs.count();}
void redraw();
void clear(); void clear();
void plot(QPainter *painter, const QRectF &target, qreal scale);
void setPalette(const Palette &palette);
void setGraphWidth(int width);
void showGrid(bool show);
void showSliderInfo(bool show);
void useOpenGL(bool use);
void useAntiAliasing(bool use);
void setSliderPosition(qreal pos);
void setSliderColor(const QColor &color);
signals:
void sliderPositionChanged(qreal);
protected:
void addGraph(GraphItem *graph, PathItem *path, int id = 0);
void showGraph(bool show, int id = 0); void showGraph(bool show, int id = 0);
void setGraphType(GraphType type); void setGraphType(GraphType type);
void setUnits(Units units); void setUnits(Units units);
void showGrid(bool show);
void setPalette(const Palette &palette);
void setGraphWidth(int width);
const QString &yLabel() const {return _yLabel;} const QString &yLabel() const {return _yLabel;}
const QString &yUnits() const {return _yUnits;} const QString &yUnits() const {return _yUnits;}
@ -50,23 +62,16 @@ public:
void setSliderPrecision(int precision) {_precision = precision;} void setSliderPrecision(int precision) {_precision = precision;}
void setMinYRange(qreal range) {_minYRange = range;} void setMinYRange(qreal range) {_minYRange = range;}
qreal sliderPosition() const {return _sliderPos;}
void setSliderPosition(qreal pos);
void plot(QPainter *painter, const QRectF &target);
void useOpenGL(bool use);
signals:
void sliderPositionChanged(qreal);
protected:
QRectF bounds() const; QRectF bounds() const;
void redraw();
void redraw(const QSizeF &size); void redraw(const QSizeF &size);
void addInfo(const QString &key, const QString &value); void addInfo(const QString &key, const QString &value);
void clearInfo(); void clearInfo();
void skipColor() {_palette.nextColor();} void skipColor() {_palette.nextColor();}
QList<GraphItem*> _graphs;
GraphType _graphType;
private slots: private slots:
void emitSliderPositionChanged(const QPointF &pos); void emitSliderPositionChanged(const QPointF &pos);
void newSliderPosition(const QPointF &pos); void newSliderPosition(const QPointF &pos);
@ -83,6 +88,7 @@ private:
void resizeEvent(QResizeEvent *); void resizeEvent(QResizeEvent *);
void mousePressEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *);
Units _units;
qreal _xScale, _yScale; qreal _xScale, _yScale;
qreal _yOffset; qreal _yOffset;
QString _xUnits, _yUnits; QString _xUnits, _yUnits;
@ -99,15 +105,11 @@ private:
InfoItem *_info; InfoItem *_info;
GridItem *_grid; GridItem *_grid;
QList<GraphItem*> _graphs;
QList<GraphItem*> _visible; QList<GraphItem*> _visible;
QSet<int> _hide; QSet<int> _hide;
QRectF _bounds; QRectF _bounds;
Palette _palette; Palette _palette;
int _width; int _width;
Units _units;
GraphType _graphType;
}; };
#endif // GRAPHVIEW_H #endif // GRAPHVIEW_H

View File

@ -22,23 +22,20 @@
#include <QMimeData> #include <QMimeData>
#include <QUrl> #include <QUrl>
#include <QPixmapCache> #include <QPixmapCache>
#include "data/data.h"
#include "map/maplist.h"
#include "map/emptymap.h"
#include "config.h" #include "config.h"
#include "icons.h" #include "icons.h"
#include "keys.h" #include "keys.h"
#include "settings.h" #include "settings.h"
#include "data.h"
#include "ellipsoid.h"
#include "datum.h"
#include "map.h"
#include "maplist.h"
#include "emptymap.h"
#include "elevationgraph.h" #include "elevationgraph.h"
#include "speedgraph.h" #include "speedgraph.h"
#include "heartrategraph.h" #include "heartrategraph.h"
#include "temperaturegraph.h" #include "temperaturegraph.h"
#include "cadencegraph.h" #include "cadencegraph.h"
#include "powergraph.h" #include "powergraph.h"
#include "pathview.h" #include "mapview.h"
#include "trackinfo.h" #include "trackinfo.h"
#include "filebrowser.h" #include "filebrowser.h"
#include "cpuarch.h" #include "cpuarch.h"
@ -49,11 +46,10 @@
GUI::GUI() GUI::GUI()
{ {
loadDatums();
loadMaps(); loadMaps();
loadPOIs(); loadPOIs();
createPathView(); createMapView();
createGraphTabs(); createGraphTabs();
createStatusBar(); createStatusBar();
createActions(); createActions();
@ -65,7 +61,7 @@ GUI::GUI()
QSplitter *splitter = new QSplitter(); QSplitter *splitter = new QSplitter();
splitter->setOrientation(Qt::Vertical); splitter->setOrientation(Qt::Vertical);
splitter->setChildrenCollapsible(false); splitter->setChildrenCollapsible(false);
splitter->addWidget(_pathView); splitter->addWidget(_mapView);
splitter->addWidget(_graphTabWidget); splitter->addWidget(_graphTabWidget);
splitter->setContentsMargins(0, 0, 0, 0); splitter->setContentsMargins(0, 0, 0, 0);
splitter->setStretchFactor(0, 255); splitter->setStretchFactor(0, 255);
@ -87,11 +83,11 @@ GUI::GUI()
_sliderPos = 0; _sliderPos = 0;
updateGraphTabs();
updatePathView();
updateStatusBarInfo();
readSettings(); readSettings();
updateGraphTabs();
updateMapView();
updateStatusBarInfo();
} }
GUI::~GUI() GUI::~GUI()
@ -102,50 +98,6 @@ GUI::~GUI()
} }
} }
void GUI::loadDatums()
{
QString ef, df;
bool ok = false;
if (QFile::exists(USER_ELLIPSOID_FILE))
ef = USER_ELLIPSOID_FILE;
else if (QFile::exists(GLOBAL_ELLIPSOID_FILE))
ef = GLOBAL_ELLIPSOID_FILE;
else
qWarning("No ellipsoids file found.");
if (QFile::exists(USER_DATUM_FILE))
df = USER_DATUM_FILE;
else if (QFile::exists(GLOBAL_DATUM_FILE))
df = GLOBAL_DATUM_FILE;
else
qWarning("No datums file found.");
if (!ef.isNull() && !df.isNull()) {
if (!Ellipsoid::loadList(ef)) {
if (Ellipsoid::errorLine())
qWarning("%s: parse error on line %d: %s", qPrintable(ef),
Ellipsoid::errorLine(), qPrintable(Ellipsoid::errorString()));
else
qWarning("%s: %s", qPrintable(ef), qPrintable(
Ellipsoid::errorString()));
} else {
if (!Datum::loadList(df)) {
if (Datum::errorLine())
qWarning("%s: parse error on line %d: %s", qPrintable(ef),
Datum::errorLine(), qPrintable(Datum::errorString()));
else
qWarning("%s: %s", qPrintable(ef), qPrintable(
Datum::errorString()));
} else
ok = true;
}
}
if (!ok)
qWarning("Maps based on a datum different from WGS84 won't work.");
}
void GUI::loadMaps() void GUI::loadMaps()
{ {
_ml = new MapList(this); _ml = new MapList(this);
@ -187,7 +139,7 @@ void GUI::loadMaps()
} }
} }
_map = _ml->maps().isEmpty() ? new EmptyMap(this) : _ml->maps().first(); _map = new EmptyMap(this);
} }
void GUI::loadPOIs() void GUI::loadPOIs()
@ -334,17 +286,17 @@ void GUI::createActions()
connect(_closePOIAction, SIGNAL(triggered()), this, SLOT(closePOIFiles())); connect(_closePOIAction, SIGNAL(triggered()), this, SLOT(closePOIFiles()));
_overlapPOIAction = new QAction(tr("Overlap POIs"), this); _overlapPOIAction = new QAction(tr("Overlap POIs"), this);
_overlapPOIAction->setCheckable(true); _overlapPOIAction->setCheckable(true);
connect(_overlapPOIAction, SIGNAL(triggered(bool)), _pathView, connect(_overlapPOIAction, SIGNAL(triggered(bool)), _mapView,
SLOT(setPOIOverlap(bool))); SLOT(setPOIOverlap(bool)));
_showPOILabelsAction = new QAction(tr("Show POI labels"), this); _showPOILabelsAction = new QAction(tr("Show POI labels"), this);
_showPOILabelsAction->setCheckable(true); _showPOILabelsAction->setCheckable(true);
connect(_showPOILabelsAction, SIGNAL(triggered(bool)), _pathView, connect(_showPOILabelsAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showPOILabels(bool))); SLOT(showPOILabels(bool)));
_showPOIAction = new QAction(QIcon(QPixmap(SHOW_POI_ICON)), _showPOIAction = new QAction(QIcon(QPixmap(SHOW_POI_ICON)),
tr("Show POIs"), this); tr("Show POIs"), this);
_showPOIAction->setCheckable(true); _showPOIAction->setCheckable(true);
_showPOIAction->setShortcut(SHOW_POI_SHORTCUT); _showPOIAction->setShortcut(SHOW_POI_SHORTCUT);
connect(_showPOIAction, SIGNAL(triggered(bool)), _pathView, connect(_showPOIAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showPOI(bool))); SLOT(showPOI(bool)));
addAction(_showPOIAction); addAction(_showPOIAction);
createPOIFilesActions(); createPOIFilesActions();
@ -354,14 +306,14 @@ void GUI::createActions()
this); this);
_showMapAction->setCheckable(true); _showMapAction->setCheckable(true);
_showMapAction->setShortcut(SHOW_MAP_SHORTCUT); _showMapAction->setShortcut(SHOW_MAP_SHORTCUT);
connect(_showMapAction, SIGNAL(triggered(bool)), _pathView, connect(_showMapAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showMap(bool))); SLOT(showMap(bool)));
addAction(_showMapAction); addAction(_showMapAction);
_loadMapAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)), _loadMapAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)),
tr("Load map..."), this); tr("Load map..."), this);
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap())); connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this); _clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
connect(_clearMapCacheAction, SIGNAL(triggered()), this, connect(_clearMapCacheAction, SIGNAL(triggered()), _mapView,
SLOT(clearMapCache())); SLOT(clearMapCache()));
createMapActions(); createMapActions();
_nextMapAction = new QAction(tr("Next map"), this); _nextMapAction = new QAction(tr("Next map"), this);
@ -388,15 +340,15 @@ void GUI::createActions()
SLOT(showRoutes(bool))); SLOT(showRoutes(bool)));
_showWaypointsAction = new QAction(tr("Show waypoints"), this); _showWaypointsAction = new QAction(tr("Show waypoints"), this);
_showWaypointsAction->setCheckable(true); _showWaypointsAction->setCheckable(true);
connect(_showWaypointsAction, SIGNAL(triggered(bool)), _pathView, connect(_showWaypointsAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showWaypoints(bool))); SLOT(showWaypoints(bool)));
_showWaypointLabelsAction = new QAction(tr("Waypoint labels"), this); _showWaypointLabelsAction = new QAction(tr("Waypoint labels"), this);
_showWaypointLabelsAction->setCheckable(true); _showWaypointLabelsAction->setCheckable(true);
connect(_showWaypointLabelsAction, SIGNAL(triggered(bool)), _pathView, connect(_showWaypointLabelsAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showWaypointLabels(bool))); SLOT(showWaypointLabels(bool)));
_showRouteWaypointsAction = new QAction(tr("Route waypoints"), this); _showRouteWaypointsAction = new QAction(tr("Route waypoints"), this);
_showRouteWaypointsAction->setCheckable(true); _showRouteWaypointsAction->setCheckable(true);
connect(_showRouteWaypointsAction, SIGNAL(triggered(bool)), _pathView, connect(_showRouteWaypointsAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showRouteWaypoints(bool))); SLOT(showRouteWaypoints(bool)));
// Graph actions // Graph actions
@ -412,14 +364,12 @@ void GUI::createActions()
_distanceGraphAction = new QAction(tr("Distance"), this); _distanceGraphAction = new QAction(tr("Distance"), this);
_distanceGraphAction->setCheckable(true); _distanceGraphAction->setCheckable(true);
_distanceGraphAction->setActionGroup(ag); _distanceGraphAction->setActionGroup(ag);
_distanceGraphAction->setShortcut(DISTANCE_GRAPH_SHORTCUT);
connect(_distanceGraphAction, SIGNAL(triggered()), this, connect(_distanceGraphAction, SIGNAL(triggered()), this,
SLOT(setDistanceGraph())); SLOT(setDistanceGraph()));
addAction(_distanceGraphAction); addAction(_distanceGraphAction);
_timeGraphAction = new QAction(tr("Time"), this); _timeGraphAction = new QAction(tr("Time"), this);
_timeGraphAction->setCheckable(true); _timeGraphAction->setCheckable(true);
_timeGraphAction->setActionGroup(ag); _timeGraphAction->setActionGroup(ag);
_timeGraphAction->setShortcut(TIME_GRAPH_SHORTCUT);
connect(_timeGraphAction, SIGNAL(triggered()), this, connect(_timeGraphAction, SIGNAL(triggered()), this,
SLOT(setTimeGraph())); SLOT(setTimeGraph()));
addAction(_timeGraphAction); addAction(_timeGraphAction);
@ -427,6 +377,10 @@ void GUI::createActions()
_showGraphGridAction->setCheckable(true); _showGraphGridAction->setCheckable(true);
connect(_showGraphGridAction, SIGNAL(triggered(bool)), this, connect(_showGraphGridAction, SIGNAL(triggered(bool)), this,
SLOT(showGraphGrids(bool))); SLOT(showGraphGrids(bool)));
_showGraphSliderInfoAction = new QAction(tr("Show slider info"), this);
_showGraphSliderInfoAction->setCheckable(true);
connect(_showGraphSliderInfoAction, SIGNAL(triggered(bool)), this,
SLOT(showGraphSliderInfo(bool)));
// Settings actions // Settings actions
_showToolbarsAction = new QAction(tr("Show toolbars"), this); _showToolbarsAction = new QAction(tr("Show toolbars"), this);
@ -515,6 +469,7 @@ void GUI::createMenus()
graphMenu->addAction(_timeGraphAction); graphMenu->addAction(_timeGraphAction);
graphMenu->addSeparator(); graphMenu->addSeparator();
graphMenu->addAction(_showGraphGridAction); graphMenu->addAction(_showGraphGridAction);
graphMenu->addAction(_showGraphSliderInfoAction);
graphMenu->addSeparator(); graphMenu->addSeparator();
graphMenu->addAction(_showGraphsAction); graphMenu->addAction(_showGraphsAction);
@ -583,14 +538,14 @@ void GUI::createToolBars()
_navigationToolBar->addAction(_lastAction); _navigationToolBar->addAction(_lastAction);
} }
void GUI::createPathView() void GUI::createMapView()
{ {
_pathView = new PathView(_map, _poi, this); _mapView = new MapView(_map, _poi, this);
_pathView->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, _mapView->setSizePolicy(QSizePolicy(QSizePolicy::Ignored,
QSizePolicy::Expanding)); QSizePolicy::Expanding));
_pathView->setMinimumHeight(200); _mapView->setMinimumHeight(200);
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
_pathView->setFrameShape(QFrame::NoFrame); _mapView->setFrameShape(QFrame::NoFrame);
#endif // Q_OS_WIN32 #endif // Q_OS_WIN32
} }
@ -671,7 +626,12 @@ void GUI::keys()
+ tr("Last file") + "</td><td><i>" + QKeySequence(LAST_KEY).toString() + tr("Last file") + "</td><td><i>" + QKeySequence(LAST_KEY).toString()
+ "</i></td></tr><tr><td>" + tr("Append file") + "</i></td></tr><tr><td>" + tr("Append file")
+ "</td><td><i>" + QKeySequence(MODIFIER).toString() + tr("Next/Previous") + "</td><td><i>" + QKeySequence(MODIFIER).toString() + tr("Next/Previous")
+ "</i></td></tr><tr><td></td><td></td></tr><tr><td>" + tr("Next map") + "</i></td></tr><tr><td></td><td></td></tr><tr><td>"
+ tr("Toggle graph type") + "</td><td><i>"
+ QKeySequence(TOGGLE_GRAPH_TYPE_KEY).toString() + "</i></td></tr><tr><td>"
+ tr("Toggle time type") + "</td><td><i>"
+ QKeySequence(TOGGLE_TIME_TYPE_KEY).toString()
+ "<tr><td></td><td></td></tr><tr><td>" + tr("Next map")
+ "</td><td><i>" + NEXT_MAP_SHORTCUT.toString() + "</i></td></tr><tr><td>" + "</td><td><i>" + NEXT_MAP_SHORTCUT.toString() + "</i></td></tr><tr><td>"
+ tr("Previous map") + "</td><td><i>" + PREV_MAP_SHORTCUT.toString() + tr("Previous map") + "</td><td><i>" + PREV_MAP_SHORTCUT.toString()
+ "</i></td></tr><tr><td></td><td></td></tr><tr><td>" + tr("Zoom in") + "</i></td></tr><tr><td></td><td></td></tr><tr><td>" + tr("Zoom in")
@ -696,10 +656,11 @@ void GUI::dataSources()
"following file:") "following file:")
+ "</p><p><code>" + USER_MAP_FILE + "</code></p><p>" + "</p><p><code>" + USER_MAP_FILE + "</code></p><p>"
+ tr("The file format is one map entry per line, consisting of the map " + tr("The file format is one map entry per line, consisting of the map "
"name and tiles URL delimited by a TAB character. The tile X and Y " "name, tiles URL and an optional maximal zoom level delimited by "
"coordinates are replaced with $x and $y in the URL and the zoom " "a TAB character. The tile X and Y coordinates are replaced with $x "
"level is replaced with $z. An example map file could look like:") "and $y in the URL and the zoom level is replaced with $z. An example "
+ "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png" "map file could look like:")
+ "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png 15"
"<br/>Map2 http://mapserver.org/map/$z-$x-$y</code></p>" "<br/>Map2 http://mapserver.org/map/$z-$x-$y</code></p>"
+ "<h4>" + tr("Offline maps") + "</h4><p>" + "<h4>" + tr("Offline maps") + "</h4><p>"
@ -746,7 +707,7 @@ bool GUI::openFile(const QString &fileName)
updateStatusBarInfo(); updateStatusBarInfo();
updateWindowTitle(); updateWindowTitle();
updateGraphTabs(); updateGraphTabs();
updatePathView(); updateMapView();
} else { } else {
if (_files.isEmpty()) if (_files.isEmpty())
_fileActionGroup->setEnabled(false); _fileActionGroup->setEnabled(false);
@ -762,7 +723,7 @@ bool GUI::loadFile(const QString &fileName)
QList<PathItem*> paths; QList<PathItem*> paths;
if (data.loadFile(fileName)) { if (data.loadFile(fileName)) {
paths = _pathView->loadData(data); paths = _mapView->loadData(data);
for (int i = 0; i < _tabs.count(); i++) for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->loadData(data, paths); _tabs.at(i)->loadData(data, paths);
@ -798,7 +759,7 @@ bool GUI::loadFile(const QString &fileName)
updateStatusBarInfo(); updateStatusBarInfo();
updateWindowTitle(); updateWindowTitle();
updateGraphTabs(); updateGraphTabs();
updatePathView(); updateMapView();
QString error = tr("Error loading data file:") + "\n\n" QString error = tr("Error loading data file:") + "\n\n"
+ fileName + "\n\n" + data.errorString(); + fileName + "\n\n" + data.errorString();
@ -833,7 +794,7 @@ bool GUI::openPOIFile(const QString &fileName)
return false; return false;
} else { } else {
_pathView->showPOI(true); _mapView->showPOI(true);
_showPOIAction->setChecked(true); _showPOIAction->setChecked(true);
QAction *action = createPOIFileAction(_poi->files().indexOf(fileName)); QAction *action = createPOIFileAction(_poi->files().indexOf(fileName));
action->setChecked(true); action->setChecked(true);
@ -854,17 +815,21 @@ void GUI::closePOIFiles()
_poi->clear(); _poi->clear();
} }
void GUI::printFile()
{
QPrinter printer(QPrinter::HighResolution);
QPrintDialog dialog(&printer, this);
if (dialog.exec() == QDialog::Accepted)
plot(&printer);
}
void GUI::openOptions() void GUI::openOptions()
{ {
#define SET_VIEW_OPTION(option, action) \
if (options.option != _options.option) \
_mapView->action(options.option)
#define SET_TAB_OPTION(option, action) \
if (options.option != _options.option) \
for (int i = 0; i < _tabs.count(); i++) \
_tabs.at(i)->action(options.option)
#define SET_TRACK_OPTION(option, action) \
if (options.option != _options.option) { \
Track::action(options.option); \
reload = true; \
}
Options options(_options); Options options(_options);
bool reload = false; bool reload = false;
@ -872,71 +837,38 @@ void GUI::openOptions()
if (dialog.exec() != QDialog::Accepted) if (dialog.exec() != QDialog::Accepted)
return; return;
if (options.palette != _options.palette) { SET_VIEW_OPTION(palette, setPalette);
_pathView->setPalette(options.palette); SET_VIEW_OPTION(mapOpacity, setMapOpacity);
for (int i = 0; i < _tabs.count(); i++) SET_VIEW_OPTION(backgroundColor, setBackgroundColor);
_tabs.at(i)->setPalette(options.palette); SET_VIEW_OPTION(trackWidth, setTrackWidth);
} SET_VIEW_OPTION(routeWidth, setRouteWidth);
if (options.trackWidth != _options.trackWidth) SET_VIEW_OPTION(trackStyle, setTrackStyle);
_pathView->setTrackWidth(options.trackWidth); SET_VIEW_OPTION(routeStyle, setRouteStyle);
if (options.routeWidth != _options.routeWidth) SET_VIEW_OPTION(waypointSize, setWaypointSize);
_pathView->setRouteWidth(options.routeWidth); SET_VIEW_OPTION(waypointColor, setWaypointColor);
if (options.trackStyle != _options.trackStyle) SET_VIEW_OPTION(poiSize, setPOISize);
_pathView->setTrackStyle(options.trackStyle); SET_VIEW_OPTION(poiColor, setPOIColor);
if (options.routeStyle != _options.routeStyle) SET_VIEW_OPTION(pathAntiAliasing, useAntiAliasing);
_pathView->setRouteStyle(options.routeStyle); SET_VIEW_OPTION(useOpenGL, useOpenGL);
if (options.pathAntiAliasing != _options.pathAntiAliasing) SET_VIEW_OPTION(sliderColor, setMarkerColor);
_pathView->setRenderHint(QPainter::Antialiasing,
options.pathAntiAliasing);
if (options.graphWidth != _options.graphWidth)
for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->setGraphWidth(options.graphWidth);
if (options.graphAntiAliasing != _options.graphAntiAliasing)
for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->setRenderHint(QPainter::Antialiasing,
options.graphAntiAliasing);
if (options.elevationFilter != _options.elevationFilter) { SET_TAB_OPTION(palette, setPalette);
Track::setElevationFilter(options.elevationFilter); SET_TAB_OPTION(graphWidth, setGraphWidth);
reload = true; SET_TAB_OPTION(graphAntiAliasing, useAntiAliasing);
} SET_TAB_OPTION(useOpenGL, useOpenGL);
if (options.speedFilter != _options.speedFilter) { SET_TAB_OPTION(sliderColor, setSliderColor);
Track::setSpeedFilter(options.speedFilter);
reload = true; SET_TRACK_OPTION(elevationFilter, setElevationFilter);
} SET_TRACK_OPTION(speedFilter, setSpeedFilter);
if (options.heartRateFilter != _options.heartRateFilter) { SET_TRACK_OPTION(heartRateFilter, setHeartRateFilter);
Track::setHeartRateFilter(options.heartRateFilter); SET_TRACK_OPTION(cadenceFilter, setCadenceFilter);
reload = true; SET_TRACK_OPTION(powerFilter, setPowerFilter);
} SET_TRACK_OPTION(outlierEliminate, setOutlierElimination);
if (options.cadenceFilter != _options.cadenceFilter) { SET_TRACK_OPTION(pauseSpeed, setPauseSpeed);
Track::setCadenceFilter(options.cadenceFilter); SET_TRACK_OPTION(pauseInterval, setPauseInterval);
reload = true;
}
if (options.powerFilter != _options.powerFilter) {
Track::setPowerFilter(options.powerFilter);
reload = true;
}
if (options.outlierEliminate != _options.outlierEliminate) {
Track::setOutlierElimination(options.outlierEliminate);
reload = true;
}
if (options.pauseSpeed != _options.pauseSpeed) {
Track::setPauseSpeed(options.pauseSpeed);
reload = true;
}
if (options.pauseInterval != _options.pauseInterval) {
Track::setPauseInterval(options.pauseInterval);
reload = true;
}
if (options.poiRadius != _options.poiRadius) if (options.poiRadius != _options.poiRadius)
_poi->setRadius(options.poiRadius); _poi->setRadius(options.poiRadius);
if (options.useOpenGL != _options.useOpenGL) {
_pathView->useOpenGL(options.useOpenGL);
for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->useOpenGL(options.useOpenGL);
}
if (options.pixmapCache != _options.pixmapCache) if (options.pixmapCache != _options.pixmapCache)
QPixmapCache::setCacheLimit(options.pixmapCache * 1024); QPixmapCache::setCacheLimit(options.pixmapCache * 1024);
@ -944,6 +876,17 @@ void GUI::openOptions()
reloadFile(); reloadFile();
_options = options; _options = options;
updateMapView();
}
void GUI::printFile()
{
QPrinter printer(QPrinter::HighResolution);
QPrintDialog dialog(&printer, this);
if (dialog.exec() == QDialog::Accepted)
plot(&printer);
} }
void GUI::exportFile() void GUI::exportFile()
@ -956,6 +899,7 @@ void GUI::exportFile()
printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFormat(QPrinter::PdfFormat);
printer.setCreator(QString(APP_NAME) + QString(" ") printer.setCreator(QString(APP_NAME) + QString(" ")
+ QString(APP_VERSION)); + QString(APP_VERSION));
printer.setResolution(_export.resolution);
printer.setOrientation(_export.orientation); printer.setOrientation(_export.orientation);
printer.setOutputFileName(_export.fileName); printer.setOutputFileName(_export.fileName);
printer.setPaperSize(_export.paperSize); printer.setPaperSize(_export.paperSize);
@ -978,11 +922,11 @@ void GUI::plot(QPrinter *printer)
info.insert(tr("Name"), _pathName); info.insert(tr("Name"), _pathName);
if (_options.printItemCount) { if (_options.printItemCount) {
if (_trackCount > 1) if (_showTracksAction->isChecked() && _trackCount > 1)
info.insert(tr("Tracks"), QString::number(_trackCount)); info.insert(tr("Tracks"), QString::number(_trackCount));
if (_routeCount > 1) if (_showRoutesAction->isChecked() && _routeCount > 1)
info.insert(tr("Routes"), QString::number(_routeCount)); info.insert(tr("Routes"), QString::number(_routeCount));
if (_waypointCount > 2) if (_showWaypointsAction->isChecked() && _waypointCount > 2)
info.insert(tr("Waypoints"), QString::number(_waypointCount)); info.insert(tr("Waypoints"), QString::number(_waypointCount));
} }
@ -1005,35 +949,36 @@ void GUI::plot(QPrinter *printer)
if (tm > 0 && _options.printMovingTime) if (tm > 0 && _options.printMovingTime)
info.insert(tr("Moving time"), Format::timeSpan(tm)); info.insert(tr("Moving time"), Format::timeSpan(tm));
qreal fsr = 1085.0 / (qMax(printer->width(), printer->height())
ratio = p.paintEngine()->paintDevice()->logicalDpiX() / SCREEN_DPI; / (qreal)printer->resolution());
ratio = p.paintEngine()->paintDevice()->logicalDpiX() / fsr;
if (info.isEmpty()) { if (info.isEmpty()) {
ih = 0; ih = 0;
mh = 0; mh = 0;
} else { } else {
ih = info.contentSize().height() * ratio; ih = info.contentSize().height() * ratio;
mh = ih / 2; mh = ih / 2;
info.plot(&p, QRectF(0, 0, printer->width(), ih)); info.plot(&p, QRectF(0, 0, printer->width(), ih), ratio);
} }
if (_graphTabWidget->isVisible() && !_options.separateGraphPage) { if (_graphTabWidget->isVisible() && !_options.separateGraphPage) {
qreal r = (((qreal)(printer)->width()) / (qreal)(printer->height())); qreal r = (((qreal)(printer)->width()) / (qreal)(printer->height()));
gh = (printer->width() > printer->height()) gh = (printer->width() > printer->height())
? 0.15 * r * (printer->height() - ih - 2*mh) ? 0.15 * r * (printer->height() - ih - 2*mh)
: 0.15 * (printer->height() - ih - 2*mh); : 0.15 * (printer->height() - ih - 2*mh);
gh = qMax(gh, ratio * 150);
GraphTab *gt = static_cast<GraphTab*>(_graphTabWidget->currentWidget()); GraphTab *gt = static_cast<GraphTab*>(_graphTabWidget->currentWidget());
gt->plot(&p, QRectF(0, printer->height() - gh, printer->width(), gh)); gt->plot(&p, QRectF(0, printer->height() - gh, printer->width(), gh),
ratio);
} else } else
gh = 0; gh = 0;
_pathView->plot(&p, QRectF(0, ih + mh, printer->width(), printer->height() _mapView->plot(&p, QRectF(0, ih + mh, printer->width(), printer->height()
- (ih + 2*mh + gh))); - (ih + 2*mh + gh)), ratio, _options.hiresPrint);
if (_graphTabWidget->isVisible() && _options.separateGraphPage) { if (_graphTabWidget->isVisible() && _options.separateGraphPage) {
printer->newPage(); printer->newPage();
int cnt = 0; int cnt = 0;
for (int i = 0; i < _tabs.size(); i++) for (int i = 0; i < _tabs.size(); i++)
if (_tabs.at(i)->count()) if (!_tabs.at(i)->isEmpty())
cnt++; cnt++;
qreal sp = ratio * 20; qreal sp = ratio * 20;
@ -1042,8 +987,9 @@ void GUI::plot(QPrinter *printer)
qreal y = 0; qreal y = 0;
for (int i = 0; i < _tabs.size(); i++) { for (int i = 0; i < _tabs.size(); i++) {
if (_tabs.at(i)->count()) { if (!_tabs.at(i)->isEmpty()) {
_tabs.at(i)->plot(&p, QRectF(0, y, printer->width(), gh)); _tabs.at(i)->plot(&p, QRectF(0, y, printer->width(), gh),
ratio);
y += gh + sp; y += gh + sp;
} }
} }
@ -1064,7 +1010,7 @@ void GUI::reloadFile()
for (int i = 0; i < _tabs.count(); i++) for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->clear(); _tabs.at(i)->clear();
_pathView->clear(); _mapView->clear();
_sliderPos = 0; _sliderPos = 0;
@ -1078,7 +1024,7 @@ void GUI::reloadFile()
updateStatusBarInfo(); updateStatusBarInfo();
updateWindowTitle(); updateWindowTitle();
updateGraphTabs(); updateGraphTabs();
updatePathView(); updateMapView();
if (_files.isEmpty()) if (_files.isEmpty())
_fileActionGroup->setEnabled(false); _fileActionGroup->setEnabled(false);
else else
@ -1101,7 +1047,7 @@ void GUI::closeFiles()
for (int i = 0; i < _tabs.count(); i++) for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->clear(); _tabs.at(i)->clear();
_pathView->clear(); _mapView->clear();
_files.clear(); _files.clear();
} }
@ -1114,7 +1060,7 @@ void GUI::closeAll()
updateStatusBarInfo(); updateStatusBarInfo();
updateWindowTitle(); updateWindowTitle();
updateGraphTabs(); updateGraphTabs();
updatePathView(); updateMapView();
} }
void GUI::showGraphs(bool show) void GUI::showGraphs(bool show)
@ -1141,7 +1087,7 @@ void GUI::showToolbars(bool show)
void GUI::showFullscreen(bool show) void GUI::showFullscreen(bool show)
{ {
if (show) { if (show) {
_frameStyle = _pathView->frameStyle(); _frameStyle = _mapView->frameStyle();
_showGraphs = _showGraphsAction->isChecked(); _showGraphs = _showGraphsAction->isChecked();
statusBar()->hide(); statusBar()->hide();
@ -1149,7 +1095,7 @@ void GUI::showFullscreen(bool show)
showToolbars(false); showToolbars(false);
showGraphs(false); showGraphs(false);
_showGraphsAction->setChecked(false); _showGraphsAction->setChecked(false);
_pathView->setFrameStyle(QFrame::NoFrame); _mapView->setFrameStyle(QFrame::NoFrame);
showFullScreen(); showFullScreen();
} else { } else {
@ -1160,7 +1106,7 @@ void GUI::showFullscreen(bool show)
_showGraphsAction->setChecked(_showGraphs); _showGraphsAction->setChecked(_showGraphs);
if (_showGraphsAction->isEnabled()) if (_showGraphsAction->isEnabled())
showGraphs(_showGraphs); showGraphs(_showGraphs);
_pathView->setFrameStyle(_frameStyle); _mapView->setFrameStyle(_frameStyle);
showNormal(); showNormal();
} }
@ -1168,22 +1114,24 @@ void GUI::showFullscreen(bool show)
void GUI::showTracks(bool show) void GUI::showTracks(bool show)
{ {
_pathView->showTracks(show); _mapView->showTracks(show);
for (int i = 0; i < _tabs.size(); i++) for (int i = 0; i < _tabs.size(); i++)
_tabs.at(i)->showTracks(show); _tabs.at(i)->showTracks(show);
updateStatusBarInfo(); updateStatusBarInfo();
updateGraphTabs();
} }
void GUI::showRoutes(bool show) void GUI::showRoutes(bool show)
{ {
_pathView->showRoutes(show); _mapView->showRoutes(show);
for (int i = 0; i < _tabs.size(); i++) for (int i = 0; i < _tabs.size(); i++)
_tabs.at(i)->showRoutes(show); _tabs.at(i)->showRoutes(show);
updateStatusBarInfo(); updateStatusBarInfo();
updateGraphTabs();
} }
void GUI::showGraphGrids(bool show) void GUI::showGraphGrids(bool show)
@ -1192,6 +1140,12 @@ void GUI::showGraphGrids(bool show)
_tabs.at(i)->showGrid(show); _tabs.at(i)->showGrid(show);
} }
void GUI::showGraphSliderInfo(bool show)
{
for (int i = 0; i < _tabs.size(); i++)
_tabs.at(i)->showSliderInfo(show);
}
void GUI::loadMap() void GUI::loadMap()
{ {
QString fileName = QFileDialog::getOpenFileName(this, tr("Open map file"), QString fileName = QFileDialog::getOpenFileName(this, tr("Open map file"),
@ -1221,12 +1175,6 @@ void GUI::loadMap()
} }
} }
void GUI::clearMapCache()
{
_map->clearCache();
_pathView->redraw();
}
void GUI::updateStatusBarInfo() void GUI::updateStatusBarInfo()
{ {
if (_files.count() == 0) if (_files.count() == 0)
@ -1268,7 +1216,7 @@ void GUI::updateWindowTitle()
void GUI::mapChanged(int index) void GUI::mapChanged(int index)
{ {
_map = _ml->maps().at(index); _map = _ml->maps().at(index);
_pathView->setMap(_map); _mapView->setMap(_map);
} }
void GUI::nextMap() void GUI::nextMap()
@ -1338,17 +1286,19 @@ void GUI::updateGraphTabs()
for (int i = 0; i < _tabs.size(); i++) { for (int i = 0; i < _tabs.size(); i++) {
tab = _tabs.at(i); tab = _tabs.at(i);
if (!tab->count() && (index = _graphTabWidget->indexOf(tab)) >= 0) if (tab->isEmpty() && (index = _graphTabWidget->indexOf(tab)) >= 0)
_graphTabWidget->removeTab(index); _graphTabWidget->removeTab(index);
} }
for (int i = 0; i < _tabs.size(); i++) { for (int i = 0; i < _tabs.size(); i++) {
tab = _tabs.at(i); tab = _tabs.at(i);
if (tab->count() && _graphTabWidget->indexOf(tab) < 0) if (!tab->isEmpty() && _graphTabWidget->indexOf(tab) < 0)
_graphTabWidget->insertTab(i, tab, _tabs.at(i)->label()); _graphTabWidget->insertTab(i, tab, _tabs.at(i)->label());
} }
if (_graphTabWidget->count()) { if (_graphTabWidget->count() &&
((_showTracksAction->isChecked() && _trackCount)
|| (_showRoutesAction->isChecked() && _routeCount))) {
if (_showGraphsAction->isChecked()) if (_showGraphsAction->isChecked())
_graphTabWidget->setHidden(false); _graphTabWidget->setHidden(false);
_showGraphsAction->setEnabled(true); _showGraphsAction->setEnabled(true);
@ -1358,10 +1308,12 @@ void GUI::updateGraphTabs()
} }
} }
void GUI::updatePathView() void GUI::updateMapView()
{ {
_pathView->setHidden(!(_pathView->trackCount() + _pathView->routeCount() if (_options.alwaysShowMap)
+ _pathView->waypointCount())); _mapView->setHidden(false);
else
_mapView->setHidden(!(_trackCount + _routeCount + _waypointCount));
} }
void GUI::setTimeType(TimeType type) void GUI::setTimeType(TimeType type)
@ -1377,7 +1329,7 @@ void GUI::setUnits(Units units)
_export.units = units; _export.units = units;
_options.units = units; _options.units = units;
_pathView->setUnits(units); _mapView->setUnits(units);
for (int i = 0; i <_tabs.count(); i++) for (int i = 0; i <_tabs.count(); i++)
_tabs.at(i)->setUnits(units); _tabs.at(i)->setUnits(units);
updateStatusBarInfo(); updateStatusBarInfo();
@ -1451,6 +1403,19 @@ void GUI::keyPressEvent(QKeyEvent *event)
file = _browser->last(); file = _browser->last();
break; break;
case TOGGLE_GRAPH_TYPE_KEY:
if (_timeGraphAction->isChecked())
_distanceGraphAction->activate(QAction::Trigger);
else
_timeGraphAction->activate(QAction::Trigger);
break;
case TOGGLE_TIME_TYPE_KEY:
if (_movingTimeAction->isChecked())
_totalTimeAction->activate(QAction::Trigger);
else
_movingTimeAction->activate(QAction::Trigger);
break;
case Qt::Key_Escape: case Qt::Key_Escape:
if (_fullscreenAction->isChecked()) { if (_fullscreenAction->isChecked()) {
_fullscreenAction->setChecked(false); _fullscreenAction->setChecked(false);
@ -1539,6 +1504,10 @@ void GUI::writeSettings()
if (_showGraphGridAction->isChecked() != SHOW_GRAPH_GRIDS_DEFAULT) if (_showGraphGridAction->isChecked() != SHOW_GRAPH_GRIDS_DEFAULT)
settings.setValue(SHOW_GRAPH_GRIDS_SETTING, settings.setValue(SHOW_GRAPH_GRIDS_SETTING,
_showGraphGridAction->isChecked()); _showGraphGridAction->isChecked());
if (_showGraphSliderInfoAction->isChecked()
!= SHOW_GRAPH_SLIDER_INFO_DEFAULT)
settings.setValue(SHOW_GRAPH_SLIDER_INFO_SETTING,
_showGraphSliderInfoAction->isChecked());
settings.endGroup(); settings.endGroup();
settings.beginGroup(POI_SETTINGS_GROUP); settings.beginGroup(POI_SETTINGS_GROUP);
@ -1579,6 +1548,8 @@ void GUI::writeSettings()
settings.beginGroup(EXPORT_SETTINGS_GROUP); settings.beginGroup(EXPORT_SETTINGS_GROUP);
if (_export.orientation != PAPER_ORIENTATION_DEFAULT) if (_export.orientation != PAPER_ORIENTATION_DEFAULT)
settings.setValue(PAPER_ORIENTATION_SETTING, _export.orientation); settings.setValue(PAPER_ORIENTATION_SETTING, _export.orientation);
if (_export.resolution != RESOLUTION_DEFAULT)
settings.setValue(RESOLUTION_SETTING, _export.resolution);
if (_export.paperSize != PAPER_SIZE_DEFAULT) if (_export.paperSize != PAPER_SIZE_DEFAULT)
settings.setValue(PAPER_SIZE_SETTING, _export.paperSize); settings.setValue(PAPER_SIZE_SETTING, _export.paperSize);
if (_export.margins.left() != MARGIN_LEFT_DEFAULT) if (_export.margins.left() != MARGIN_LEFT_DEFAULT)
@ -1598,6 +1569,10 @@ void GUI::writeSettings()
settings.setValue(PALETTE_COLOR_SETTING, _options.palette.color()); settings.setValue(PALETTE_COLOR_SETTING, _options.palette.color());
if (_options.palette.shift() != PALETTE_SHIFT_DEFAULT) if (_options.palette.shift() != PALETTE_SHIFT_DEFAULT)
settings.setValue(PALETTE_SHIFT_SETTING, _options.palette.shift()); settings.setValue(PALETTE_SHIFT_SETTING, _options.palette.shift());
if (_options.mapOpacity != MAP_OPACITY_DEFAULT)
settings.setValue(MAP_OPACITY_SETTING, _options.mapOpacity);
if (_options.backgroundColor != BACKGROUND_COLOR_DEFAULT)
settings.setValue(BACKGROUND_COLOR_SETTING, _options.backgroundColor);
if (_options.trackWidth != TRACK_WIDTH_DEFAULT) if (_options.trackWidth != TRACK_WIDTH_DEFAULT)
settings.setValue(TRACK_WIDTH_SETTING, _options.trackWidth); settings.setValue(TRACK_WIDTH_SETTING, _options.trackWidth);
if (_options.routeWidth != ROUTE_WIDTH_DEFAULT) if (_options.routeWidth != ROUTE_WIDTH_DEFAULT)
@ -1606,6 +1581,14 @@ void GUI::writeSettings()
settings.setValue(TRACK_STYLE_SETTING, (int)_options.trackStyle); settings.setValue(TRACK_STYLE_SETTING, (int)_options.trackStyle);
if (_options.routeStyle != ROUTE_STYLE_DEFAULT) if (_options.routeStyle != ROUTE_STYLE_DEFAULT)
settings.setValue(ROUTE_STYLE_SETTING, (int)_options.routeStyle); settings.setValue(ROUTE_STYLE_SETTING, (int)_options.routeStyle);
if (_options.waypointSize != WAYPOINT_SIZE_DEFAULT)
settings.setValue(WAYPOINT_SIZE_SETTING, _options.waypointSize);
if (_options.waypointColor != WAYPOINT_COLOR_DEFAULT)
settings.setValue(WAYPOINT_COLOR_SETTING, _options.waypointColor);
if (_options.poiSize != POI_SIZE_DEFAULT)
settings.setValue(POI_SIZE_SETTING, _options.poiSize);
if (_options.poiColor != POI_COLOR_DEFAULT)
settings.setValue(POI_COLOR_SETTING, _options.poiColor);
if (_options.graphWidth != GRAPH_WIDTH_DEFAULT) if (_options.graphWidth != GRAPH_WIDTH_DEFAULT)
settings.setValue(GRAPH_WIDTH_SETTING, _options.graphWidth); settings.setValue(GRAPH_WIDTH_SETTING, _options.graphWidth);
if (_options.pathAntiAliasing != PATH_AA_DEFAULT) if (_options.pathAntiAliasing != PATH_AA_DEFAULT)
@ -1634,6 +1617,8 @@ void GUI::writeSettings()
settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL); settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL);
if (_options.pixmapCache != PIXMAP_CACHE_DEFAULT) if (_options.pixmapCache != PIXMAP_CACHE_DEFAULT)
settings.setValue(PIXMAP_CACHE_SETTING, _options.pixmapCache); settings.setValue(PIXMAP_CACHE_SETTING, _options.pixmapCache);
if (_options.hiresPrint != HIRES_PRINT_DEFAULT)
settings.setValue(HIRES_PRINT_SETTING, _options.hiresPrint);
if (_options.printName != PRINT_NAME_DEFAULT) if (_options.printName != PRINT_NAME_DEFAULT)
settings.setValue(PRINT_NAME_SETTING, _options.printName); settings.setValue(PRINT_NAME_SETTING, _options.printName);
if (_options.printDate != PRINT_DATE_DEFAULT) if (_options.printDate != PRINT_DATE_DEFAULT)
@ -1649,6 +1634,10 @@ void GUI::writeSettings()
if (_options.separateGraphPage != SEPARATE_GRAPH_PAGE_DEFAULT) if (_options.separateGraphPage != SEPARATE_GRAPH_PAGE_DEFAULT)
settings.setValue(SEPARATE_GRAPH_PAGE_SETTING, settings.setValue(SEPARATE_GRAPH_PAGE_SETTING,
_options.separateGraphPage); _options.separateGraphPage);
if (_options.sliderColor != SLIDER_COLOR_DEFAULT)
settings.setValue(SLIDER_COLOR_SETTING, _options.sliderColor);
if (_options.alwaysShowMap != ALWAYS_SHOW_MAP_DEFAULT)
settings.setValue(ALWAYS_SHOW_MAP_SETTING, _options.alwaysShowMap);
settings.endGroup(); settings.endGroup();
} }
@ -1688,9 +1677,7 @@ void GUI::readSettings()
_showMapAction->setChecked(true); _showMapAction->setChecked(true);
if (_ml->maps().count()) { if (_ml->maps().count()) {
int index = mapIndex(settings.value(CURRENT_MAP_SETTING).toString()); int index = mapIndex(settings.value(CURRENT_MAP_SETTING).toString());
_mapActions.at(index)->setChecked(true); _mapActions.at(index)->trigger();
_map = _ml->maps().at(index);
_pathView->setMap(_map);
} }
settings.endGroup(); settings.endGroup();
@ -1710,21 +1697,26 @@ void GUI::readSettings()
showGraphGrids(false); showGraphGrids(false);
else else
_showGraphGridAction->setChecked(true); _showGraphGridAction->setChecked(true);
if (!settings.value(SHOW_GRAPH_SLIDER_INFO_SETTING,
SHOW_GRAPH_SLIDER_INFO_DEFAULT).toBool())
showGraphSliderInfo(false);
else
_showGraphSliderInfoAction->setChecked(true);
settings.endGroup(); settings.endGroup();
settings.beginGroup(POI_SETTINGS_GROUP); settings.beginGroup(POI_SETTINGS_GROUP);
if (!settings.value(OVERLAP_POI_SETTING, OVERLAP_POI_DEFAULT).toBool()) if (!settings.value(OVERLAP_POI_SETTING, OVERLAP_POI_DEFAULT).toBool())
_pathView->setPOIOverlap(false); _mapView->setPOIOverlap(false);
else else
_overlapPOIAction->setChecked(true); _overlapPOIAction->setChecked(true);
if (!settings.value(LABELS_POI_SETTING, LABELS_POI_DEFAULT).toBool()) if (!settings.value(LABELS_POI_SETTING, LABELS_POI_DEFAULT).toBool())
_pathView->showPOILabels(false); _mapView->showPOILabels(false);
else else
_showPOILabelsAction->setChecked(true); _showPOILabelsAction->setChecked(true);
if (settings.value(SHOW_POI_SETTING, SHOW_POI_DEFAULT).toBool()) if (settings.value(SHOW_POI_SETTING, SHOW_POI_DEFAULT).toBool())
_showPOIAction->setChecked(true); _showPOIAction->setChecked(true);
else else
_pathView->showPOI(false); _mapView->showPOI(false);
for (int i = 0; i < _poiFilesActions.count(); i++) for (int i = 0; i < _poiFilesActions.count(); i++)
_poiFilesActions.at(i)->setChecked(true); _poiFilesActions.at(i)->setChecked(true);
int size = settings.beginReadArray(DISABLED_POI_FILE_SETTINGS_PREFIX); int size = settings.beginReadArray(DISABLED_POI_FILE_SETTINGS_PREFIX);
@ -1742,30 +1734,30 @@ void GUI::readSettings()
settings.beginGroup(DATA_SETTINGS_GROUP); settings.beginGroup(DATA_SETTINGS_GROUP);
if (!settings.value(SHOW_TRACKS_SETTING, SHOW_TRACKS_DEFAULT).toBool()) { if (!settings.value(SHOW_TRACKS_SETTING, SHOW_TRACKS_DEFAULT).toBool()) {
_pathView->showTracks(false); _mapView->showTracks(false);
for (int i = 0; i < _tabs.count(); i++) for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->showTracks(false); _tabs.at(i)->showTracks(false);
} else } else
_showTracksAction->setChecked(true); _showTracksAction->setChecked(true);
if (!settings.value(SHOW_ROUTES_SETTING, SHOW_ROUTES_DEFAULT).toBool()) { if (!settings.value(SHOW_ROUTES_SETTING, SHOW_ROUTES_DEFAULT).toBool()) {
_pathView->showRoutes(false); _mapView->showRoutes(false);
for (int i = 0; i < _tabs.count(); i++) for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->showRoutes(false); _tabs.at(i)->showRoutes(false);
} else } else
_showRoutesAction->setChecked(true); _showRoutesAction->setChecked(true);
if (!settings.value(SHOW_WAYPOINTS_SETTING, SHOW_WAYPOINTS_DEFAULT) if (!settings.value(SHOW_WAYPOINTS_SETTING, SHOW_WAYPOINTS_DEFAULT)
.toBool()) .toBool())
_pathView->showWaypoints(false); _mapView->showWaypoints(false);
else else
_showWaypointsAction->setChecked(true); _showWaypointsAction->setChecked(true);
if (!settings.value(SHOW_WAYPOINT_LABELS_SETTING, if (!settings.value(SHOW_WAYPOINT_LABELS_SETTING,
SHOW_WAYPOINT_LABELS_DEFAULT).toBool()) SHOW_WAYPOINT_LABELS_DEFAULT).toBool())
_pathView->showWaypointLabels(false); _mapView->showWaypointLabels(false);
else else
_showWaypointLabelsAction->setChecked(true); _showWaypointLabelsAction->setChecked(true);
if (!settings.value(SHOW_ROUTE_WAYPOINTS_SETTING, if (!settings.value(SHOW_ROUTE_WAYPOINTS_SETTING,
SHOW_ROUTE_WAYPOINTS_SETTING).toBool()) SHOW_ROUTE_WAYPOINTS_SETTING).toBool())
_pathView->showRouteWaypoints(false); _mapView->showRouteWaypoints(false);
else else
_showRouteWaypointsAction->setChecked(true); _showRouteWaypointsAction->setChecked(true);
settings.endGroup(); settings.endGroup();
@ -1773,6 +1765,8 @@ void GUI::readSettings()
settings.beginGroup(EXPORT_SETTINGS_GROUP); settings.beginGroup(EXPORT_SETTINGS_GROUP);
_export.orientation = (QPrinter::Orientation) settings.value( _export.orientation = (QPrinter::Orientation) settings.value(
PAPER_ORIENTATION_SETTING, PAPER_ORIENTATION_DEFAULT).toInt(); PAPER_ORIENTATION_SETTING, PAPER_ORIENTATION_DEFAULT).toInt();
_export.resolution = settings.value(RESOLUTION_SETTING, RESOLUTION_DEFAULT)
.toInt();
_export.paperSize = (QPrinter::PaperSize) settings.value(PAPER_SIZE_SETTING, _export.paperSize = (QPrinter::PaperSize) settings.value(PAPER_SIZE_SETTING,
PAPER_SIZE_DEFAULT).toInt(); PAPER_SIZE_DEFAULT).toInt();
qreal ml = settings.value(MARGIN_LEFT_SETTING, MARGIN_LEFT_DEFAULT) qreal ml = settings.value(MARGIN_LEFT_SETTING, MARGIN_LEFT_DEFAULT)
@ -1793,6 +1787,10 @@ void GUI::readSettings()
qreal ps = settings.value(PALETTE_SHIFT_SETTING, PALETTE_SHIFT_DEFAULT) qreal ps = settings.value(PALETTE_SHIFT_SETTING, PALETTE_SHIFT_DEFAULT)
.toDouble(); .toDouble();
_options.palette = Palette(pc, ps); _options.palette = Palette(pc, ps);
_options.mapOpacity = settings.value(MAP_OPACITY_SETTING,
MAP_OPACITY_DEFAULT).toInt();
_options.backgroundColor = settings.value(BACKGROUND_COLOR_SETTING,
BACKGROUND_COLOR_DEFAULT).value<QColor>();
_options.trackWidth = settings.value(TRACK_WIDTH_SETTING, _options.trackWidth = settings.value(TRACK_WIDTH_SETTING,
TRACK_WIDTH_DEFAULT).toInt(); TRACK_WIDTH_DEFAULT).toInt();
_options.routeWidth = settings.value(ROUTE_WIDTH_SETTING, _options.routeWidth = settings.value(ROUTE_WIDTH_SETTING,
@ -1803,6 +1801,14 @@ void GUI::readSettings()
(int)ROUTE_STYLE_DEFAULT).toInt(); (int)ROUTE_STYLE_DEFAULT).toInt();
_options.pathAntiAliasing = settings.value(PATH_AA_SETTING, PATH_AA_DEFAULT) _options.pathAntiAliasing = settings.value(PATH_AA_SETTING, PATH_AA_DEFAULT)
.toBool(); .toBool();
_options.waypointSize = settings.value(WAYPOINT_SIZE_SETTING,
WAYPOINT_SIZE_DEFAULT).toInt();
_options.waypointColor = settings.value(WAYPOINT_COLOR_SETTING,
WAYPOINT_COLOR_DEFAULT).value<QColor>();
_options.poiSize = settings.value(POI_SIZE_SETTING, POI_SIZE_DEFAULT)
.toInt();
_options.poiColor = settings.value(POI_COLOR_SETTING, POI_COLOR_DEFAULT)
.value<QColor>();
_options.graphWidth = settings.value(GRAPH_WIDTH_SETTING, _options.graphWidth = settings.value(GRAPH_WIDTH_SETTING,
GRAPH_WIDTH_DEFAULT).toInt(); GRAPH_WIDTH_DEFAULT).toInt();
_options.graphAntiAliasing = settings.value(GRAPH_AA_SETTING, _options.graphAntiAliasing = settings.value(GRAPH_AA_SETTING,
@ -1829,6 +1835,8 @@ void GUI::readSettings()
.toBool(); .toBool();
_options.pixmapCache = settings.value(PIXMAP_CACHE_SETTING, _options.pixmapCache = settings.value(PIXMAP_CACHE_SETTING,
PIXMAP_CACHE_DEFAULT).toInt(); PIXMAP_CACHE_DEFAULT).toInt();
_options.hiresPrint = settings.value(HIRES_PRINT_SETTING,
HIRES_PRINT_DEFAULT).toBool();
_options.printName = settings.value(PRINT_NAME_SETTING, PRINT_NAME_DEFAULT) _options.printName = settings.value(PRINT_NAME_SETTING, PRINT_NAME_DEFAULT)
.toBool(); .toBool();
_options.printDate = settings.value(PRINT_DATE_SETTING, PRINT_DATE_DEFAULT) _options.printDate = settings.value(PRINT_DATE_SETTING, PRINT_DATE_DEFAULT)
@ -1843,21 +1851,33 @@ void GUI::readSettings()
PRINT_ITEM_COUNT_DEFAULT).toBool(); PRINT_ITEM_COUNT_DEFAULT).toBool();
_options.separateGraphPage = settings.value(SEPARATE_GRAPH_PAGE_SETTING, _options.separateGraphPage = settings.value(SEPARATE_GRAPH_PAGE_SETTING,
SEPARATE_GRAPH_PAGE_DEFAULT).toBool(); SEPARATE_GRAPH_PAGE_DEFAULT).toBool();
_options.sliderColor = settings.value(SLIDER_COLOR_SETTING,
SLIDER_COLOR_DEFAULT).value<QColor>();
_options.alwaysShowMap = settings.value(ALWAYS_SHOW_MAP_SETTING,
ALWAYS_SHOW_MAP_DEFAULT).toBool();
_pathView->setPalette(_options.palette); _mapView->setPalette(_options.palette);
_pathView->setTrackWidth(_options.trackWidth); _mapView->setMapOpacity(_options.mapOpacity);
_pathView->setRouteWidth(_options.routeWidth); _mapView->setBackgroundColor(_options.backgroundColor);
_pathView->setTrackStyle(_options.trackStyle); _mapView->setTrackWidth(_options.trackWidth);
_pathView->setRouteStyle(_options.routeStyle); _mapView->setRouteWidth(_options.routeWidth);
_pathView->setRenderHint(QPainter::Antialiasing, _options.pathAntiAliasing); _mapView->setTrackStyle(_options.trackStyle);
_mapView->setRouteStyle(_options.routeStyle);
_mapView->setWaypointSize(_options.waypointSize);
_mapView->setWaypointColor(_options.waypointColor);
_mapView->setPOISize(_options.poiSize);
_mapView->setPOIColor(_options.poiColor);
_mapView->setRenderHint(QPainter::Antialiasing, _options.pathAntiAliasing);
_mapView->setMarkerColor(_options.sliderColor);
if (_options.useOpenGL) if (_options.useOpenGL)
_pathView->useOpenGL(true); _mapView->useOpenGL(true);
for (int i = 0; i < _tabs.count(); i++) { for (int i = 0; i < _tabs.count(); i++) {
_tabs.at(i)->setPalette(_options.palette); _tabs.at(i)->setPalette(_options.palette);
_tabs.at(i)->setGraphWidth(_options.graphWidth); _tabs.at(i)->setGraphWidth(_options.graphWidth);
_tabs.at(i)->setRenderHint(QPainter::Antialiasing, _tabs.at(i)->setRenderHint(QPainter::Antialiasing,
_options.graphAntiAliasing); _options.graphAntiAliasing);
_tabs.at(i)->setSliderColor(_options.sliderColor);
if (_options.useOpenGL) if (_options.useOpenGL)
_tabs.at(i)->useOpenGL(true); _tabs.at(i)->useOpenGL(true);
} }

View File

@ -6,14 +6,13 @@
#include <QList> #include <QList>
#include <QDate> #include <QDate>
#include <QPrinter> #include <QPrinter>
#include "data/graph.h"
#include "data/poi.h"
#include "units.h" #include "units.h"
#include "timetype.h" #include "timetype.h"
#include "graph.h"
#include "poi.h"
#include "exportdialog.h" #include "exportdialog.h"
#include "optionsdialog.h" #include "optionsdialog.h"
class QMenu; class QMenu;
class QToolBar; class QToolBar;
class QTabWidget; class QTabWidget;
@ -24,7 +23,7 @@ class QSignalMapper;
class QPrinter; class QPrinter;
class FileBrowser; class FileBrowser;
class GraphTab; class GraphTab;
class PathView; class MapView;
class Map; class Map;
class MapList; class MapList;
@ -51,12 +50,12 @@ private slots:
void closePOIFiles(); void closePOIFiles();
void showGraphs(bool show); void showGraphs(bool show);
void showGraphGrids(bool show); void showGraphGrids(bool show);
void showGraphSliderInfo(bool show);
void showToolbars(bool show); void showToolbars(bool show);
void showFullscreen(bool show); void showFullscreen(bool show);
void showTracks(bool show); void showTracks(bool show);
void showRoutes(bool show); void showRoutes(bool show);
void loadMap(); void loadMap();
void clearMapCache();
void nextMap(); void nextMap();
void prevMap(); void prevMap();
void openOptions(); void openOptions();
@ -82,7 +81,6 @@ private slots:
private: private:
typedef QPair<QDate, QDate> DateRange; typedef QPair<QDate, QDate> DateRange;
void loadDatums();
void loadMaps(); void loadMaps();
void loadPOIs(); void loadPOIs();
void closeFiles(); void closeFiles();
@ -95,7 +93,7 @@ private:
void createMenus(); void createMenus();
void createToolBars(); void createToolBars();
void createStatusBar(); void createStatusBar();
void createPathView(); void createMapView();
void createGraphTabs(); void createGraphTabs();
void createBrowser(); void createBrowser();
@ -106,7 +104,7 @@ private:
void updateWindowTitle(); void updateWindowTitle();
void updateNavigationActions(); void updateNavigationActions();
void updateGraphTabs(); void updateGraphTabs();
void updatePathView(); void updateMapView();
TimeType timeType() const; TimeType timeType() const;
Units units() const; Units units() const;
@ -156,6 +154,7 @@ private:
QAction *_clearMapCacheAction; QAction *_clearMapCacheAction;
QAction *_showGraphsAction; QAction *_showGraphsAction;
QAction *_showGraphGridAction; QAction *_showGraphGridAction;
QAction *_showGraphSliderInfoAction;
QAction *_distanceGraphAction; QAction *_distanceGraphAction;
QAction *_timeGraphAction; QAction *_timeGraphAction;
QAction *_showToolbarsAction; QAction *_showToolbarsAction;
@ -186,17 +185,17 @@ private:
QLabel *_distanceLabel; QLabel *_distanceLabel;
QLabel *_timeLabel; QLabel *_timeLabel;
PathView *_pathView; MapView *_mapView;
QTabWidget *_graphTabWidget; QTabWidget *_graphTabWidget;
QList<GraphTab*> _tabs; QList<GraphTab*> _tabs;
POI *_poi; POI *_poi;
MapList *_ml; MapList *_ml;
Map *_map;
FileBrowser *_browser; FileBrowser *_browser;
QList<QString> _files; QList<QString> _files;
Map *_map;
int _trackCount; int _trackCount;
int _routeCount; int _routeCount;
int _waypointCount; int _waypointCount;

View File

@ -1,10 +1,10 @@
#include "data.h" #include "data/data.h"
#include "heartrategraphitem.h"
#include "heartrategraph.h" #include "heartrategraph.h"
HeartRateGraph::HeartRateGraph(QWidget *parent) : GraphTab(parent) HeartRateGraph::HeartRateGraph(QWidget *parent) : GraphTab(parent)
{ {
_units = Metric;
_showTracks = true; _showTracks = true;
GraphView::setYUnits(tr("1/min")); GraphView::setYUnits(tr("1/min"));
@ -28,21 +28,16 @@ void HeartRateGraph::loadData(const Data &data, const QList<PathItem *> &paths)
{ {
for (int i = 0; i < data.tracks().count(); i++) { for (int i = 0; i < data.tracks().count(); i++) {
const Graph &graph = data.tracks().at(i)->heartRate(); const Graph &graph = data.tracks().at(i)->heartRate();
qreal sum = 0, w = 0;
if (graph.size() < 2) { if (graph.size() < 2) {
skipColor(); skipColor();
continue; continue;
} }
for (int j = 1; j < graph.size(); j++) { HeartRateGraphItem *gi = new HeartRateGraphItem(graph, _graphType);
qreal ds = graph.at(j).s() - graph.at(j-1).s(); GraphView::addGraph(gi, paths.at(i));
sum += graph.at(j).y() * ds;
w += ds;
}
_avg.append(QPointF(data.tracks().at(i)->distance(), sum/w));
GraphView::loadGraph(graph, paths.at(i)); _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg()));
} }
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)

View File

@ -22,7 +22,6 @@ private:
QList<QPointF> _avg; QList<QPointF> _avg;
enum Units _units;
bool _showTracks; bool _showTracks;
}; };

View File

@ -0,0 +1,26 @@
#include "tooltip.h"
#include "heartrategraphitem.h"
HeartRateGraphItem::HeartRateGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent) : GraphItem(graph, type, parent)
{
qreal sum = 0;
for (int j = 1; j < graph.size(); j++)
sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s());
_avg = sum/graph.last().s();
setToolTip(toolTip());
}
QString HeartRateGraphItem::toolTip() const
{
ToolTip tt;
tt.insert(tr("Maximum"), QString::number(max(), 'f', 0)
+ UNIT_SPACE + tr("1/min"));
tt.insert(tr("Average"), QString::number(avg(), 'f', 0)
+ UNIT_SPACE + tr("1/min"));
return tt.toString();
}

View File

@ -0,0 +1,23 @@
#ifndef HEARTRATEGRAPHITEM_H
#define HEARTRATEGRAPHITEM_H
#include "graphitem.h"
class HeartRateGraphItem : public GraphItem
{
Q_OBJECT
public:
HeartRateGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent = 0);
qreal max() const {return -bounds().top();}
qreal avg() const {return _avg;}
private:
QString toolTip() const;
qreal _avg;
};
#endif // HEARTRATEGRAPHITEM_H

View File

@ -13,6 +13,9 @@
#define ZOOM_IN QKeySequence::ZoomIn #define ZOOM_IN QKeySequence::ZoomIn
#define ZOOM_OUT QKeySequence::ZoomOut #define ZOOM_OUT QKeySequence::ZoomOut
#define TOGGLE_GRAPH_TYPE_KEY Qt::Key_X
#define TOGGLE_TIME_TYPE_KEY Qt::Key_T
#define QUIT_SHORTCUT QKeySequence(QKeySequence::Quit) #define QUIT_SHORTCUT QKeySequence(QKeySequence::Quit)
#define OPEN_SHORTCUT QKeySequence(QKeySequence::Open) #define OPEN_SHORTCUT QKeySequence(QKeySequence::Open)
#define CLOSE_SHORTCUT QKeySequence(QKeySequence::Close) #define CLOSE_SHORTCUT QKeySequence(QKeySequence::Close)
@ -23,8 +26,6 @@
#define NEXT_MAP_SHORTCUT QKeySequence(QKeySequence::Forward) #define NEXT_MAP_SHORTCUT QKeySequence(QKeySequence::Forward)
#define PREV_MAP_SHORTCUT QKeySequence(QKeySequence::Back) #define PREV_MAP_SHORTCUT QKeySequence(QKeySequence::Back)
#define SHOW_GRAPHS_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_G) #define SHOW_GRAPHS_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_G)
#define DISTANCE_GRAPH_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_D)
#define TIME_GRAPH_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_T)
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#define FULLSCREEN_SHORTCUT QKeySequence(Qt::META + Qt::CTRL + Qt::Key_F) #define FULLSCREEN_SHORTCUT QKeySequence(Qt::META + Qt::CTRL + Qt::Key_F)

View File

@ -3,25 +3,25 @@
#include <QWheelEvent> #include <QWheelEvent>
#include <QApplication> #include <QApplication>
#include <QPixmapCache> #include <QPixmapCache>
#include <QScrollBar>
#include "data/poi.h"
#include "data/data.h"
#include "map/map.h"
#include "opengl.h" #include "opengl.h"
#include "misc.h"
#include "poi.h"
#include "data.h"
#include "map.h"
#include "trackitem.h" #include "trackitem.h"
#include "routeitem.h" #include "routeitem.h"
#include "waypointitem.h" #include "waypointitem.h"
#include "scaleitem.h" #include "scaleitem.h"
#include "keys.h" #include "keys.h"
#include "pathview.h" #include "mapview.h"
#define MAX_DIGITAL_ZOOM 1 #define MAX_DIGITAL_ZOOM 2
#define MIN_DIGITAL_ZOOM -3 #define MIN_DIGITAL_ZOOM -3
#define MARGIN 10.0 #define MARGIN 10.0
#define SCALE_OFFSET 7 #define SCALE_OFFSET 7
PathView::PathView(Map *map, POI *poi, QWidget *parent) MapView::MapView(Map *map, POI *poi, QWidget *parent)
: QGraphicsView(parent) : QGraphicsView(parent)
{ {
Q_ASSERT(map != 0); Q_ASSERT(map != 0);
@ -39,13 +39,19 @@ PathView::PathView(Map *map, POI *poi, QWidget *parent)
_mapScale = new ScaleItem(); _mapScale = new ScaleItem();
_mapScale->setZValue(2.0); _mapScale->setZValue(2.0);
_scene->addItem(_mapScale);
_map = map; _map = map;
_map->load();
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
_poi = poi; _poi = poi;
connect(_map, SIGNAL(loaded()), this, SLOT(redraw()));
connect(_poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI())); connect(_poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI()));
_units = Metric; _units = Metric;
_opacity = 1.0;
_backgroundColor = Qt::white;
_markerColor = Qt::red;
_showMap = true; _showMap = true;
_showTracks = true; _showTracks = true;
@ -60,21 +66,39 @@ PathView::PathView(Map *map, POI *poi, QWidget *parent)
_routeWidth = 3; _routeWidth = 3;
_trackStyle = Qt::SolidLine; _trackStyle = Qt::SolidLine;
_routeStyle = Qt::DashLine; _routeStyle = Qt::DashLine;
_waypointSize = 8;
_waypointColor = Qt::black;
_poiSize = 8;
_poiColor = Qt::black;
_plot = false; _plot = false;
_digitalZoom = 0; _digitalZoom = 0;
_map->setBackgroundColor(_backgroundColor);
_scene->setSceneRect(_map->bounds()); _scene->setSceneRect(_map->bounds());
_res = _map->resolution(_scene->sceneRect().center());
centerOn(_scene->sceneRect().center());
} }
PathView::~PathView() void MapView::centerOn(const QPointF &pos)
{ {
if (_mapScale->scene() != _scene) QGraphicsView::centerOn(pos);
delete _mapScale;
/* Fix the offset caused by QGraphicsView::centerOn() approximation */
QPointF center = mapToScene(viewport()->rect().center());
QPoint offset((int)(pos.x() - center.x()), (int)(pos.y() - center.y()));
if (qAbs(offset.x()) == 1)
horizontalScrollBar()->setValue(horizontalScrollBar()->value()
+ offset.x());
if (qAbs(offset.y()) == 1)
verticalScrollBar()->setValue(verticalScrollBar()->value()
+ offset.y());
_res = _map->resolution(pos);
_mapScale->setResolution(_res);
} }
PathItem *PathView::addTrack(const Track &track) PathItem *MapView::addTrack(const Track &track)
{ {
if (track.isNull()) { if (track.isNull()) {
_palette.nextColor(); _palette.nextColor();
@ -90,14 +114,16 @@ PathItem *PathView::addTrack(const Track &track)
ti->setUnits(_units); ti->setUnits(_units);
ti->setVisible(_showTracks); ti->setVisible(_showTracks);
ti->setDigitalZoom(_digitalZoom); ti->setDigitalZoom(_digitalZoom);
ti->setMarkerColor(_markerColor);
_scene->addItem(ti); _scene->addItem(ti);
addPOI(_poi->points(ti->path())); if (_showTracks)
addPOI(_poi->points(ti->path()));
return ti; return ti;
} }
PathItem *PathView::addRoute(const Route &route) PathItem *MapView::addRoute(const Route &route)
{ {
if (route.isNull()) { if (route.isNull()) {
_palette.nextColor(); _palette.nextColor();
@ -115,36 +141,41 @@ PathItem *PathView::addRoute(const Route &route)
ri->showWaypoints(_showRouteWaypoints); ri->showWaypoints(_showRouteWaypoints);
ri->showWaypointLabels(_showWaypointLabels); ri->showWaypointLabels(_showWaypointLabels);
ri->setDigitalZoom(_digitalZoom); ri->setDigitalZoom(_digitalZoom);
ri->setMarkerColor(_markerColor);
_scene->addItem(ri); _scene->addItem(ri);
addPOI(_poi->points(ri->path())); if (_showRoutes)
addPOI(_poi->points(ri->path()));
return ri; return ri;
} }
void PathView::addWaypoints(const QList<Waypoint> &waypoints) void MapView::addWaypoints(const QList<Waypoint> &waypoints)
{ {
for (int i = 0; i < waypoints.count(); i++) { for (int i = 0; i < waypoints.count(); i++) {
const Waypoint &w = waypoints.at(i); const Waypoint &w = waypoints.at(i);
WaypointItem *wi = new WaypointItem(w, _map); WaypointItem *wi = new WaypointItem(w, _map);
_waypoints.append(wi); _waypoints.append(wi);
updateWaypointsBoundingRect(wi->waypoint().coordinates()); _wr.unite(wi->waypoint().coordinates());
wi->setZValue(1); wi->setZValue(1);
wi->setSize(_waypointSize);
wi->setColor(_waypointColor);
wi->showLabel(_showWaypointLabels); wi->showLabel(_showWaypointLabels);
wi->setUnits(_units); wi->setUnits(_units);
wi->setVisible(_showWaypoints); wi->setVisible(_showWaypoints);
wi->setDigitalZoom(_digitalZoom); wi->setDigitalZoom(_digitalZoom);
_scene->addItem(wi); _scene->addItem(wi);
}
addPOI(_poi->points(waypoints)); if (_showWaypoints)
addPOI(_poi->points(w));
}
} }
QList<PathItem *> PathView::loadData(const Data &data) QList<PathItem *> MapView::loadData(const Data &data)
{ {
QList<PathItem *> paths; QList<PathItem *> paths;
qreal scale = _map->zoom(); qreal zoom = _map->zoom();
for (int i = 0; i < data.tracks().count(); i++) for (int i = 0; i < data.tracks().count(); i++)
paths.append(addTrack(*(data.tracks().at(i)))); paths.append(addTrack(*(data.tracks().at(i))));
@ -155,45 +186,33 @@ QList<PathItem *> PathView::loadData(const Data &data)
if (_tracks.empty() && _routes.empty() && _waypoints.empty()) if (_tracks.empty() && _routes.empty() && _waypoints.empty())
return paths; return paths;
if (mapScale() != scale) if (mapZoom() != zoom)
rescale(); rescale();
else else
updatePOIVisibility(); updatePOIVisibility();
QPointF center = contentCenter(); centerOn(contentCenter());
centerOn(center);
_res = _map->resolution(center);
_mapScale->setResolution(_res);
if (_mapScale->scene() != _scene)
_scene->addItem(_mapScale);
return paths; return paths;
} }
void PathView::updateWaypointsBoundingRect(const Coordinates &wp) qreal MapView::mapZoom() const
{
if (_wr.isNull())
_wr = RectC(wp, wp);
else
_wr.unite(wp);
}
qreal PathView::mapScale() const
{ {
RectC br = _tr | _rr | _wr; RectC br = _tr | _rr | _wr;
return _map->zoomFit(viewport()->size() - QSize(MARGIN/2, MARGIN/2), br); return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
br.isNull() ? RectC(_map->xy2ll(sceneRect().topLeft()),
_map->xy2ll(sceneRect().bottomRight())) : br);
} }
QPointF PathView::contentCenter() const QPointF MapView::contentCenter() const
{ {
RectC br = _tr | _rr | _wr; RectC br = _tr | _rr | _wr;
return _map->ll2xy(br.center()); return br.isNull() ? sceneRect().center() : _map->ll2xy(br.center());
} }
void PathView::updatePOIVisibility() void MapView::updatePOIVisibility()
{ {
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it, jt; QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it, jt;
@ -214,7 +233,7 @@ void PathView::updatePOIVisibility()
} }
} }
void PathView::rescale() void MapView::rescale()
{ {
_scene->setSceneRect(_map->bounds()); _scene->setSceneRect(_map->bounds());
resetCachedContent(); resetCachedContent();
@ -233,7 +252,7 @@ void PathView::rescale()
updatePOIVisibility(); updatePOIVisibility();
} }
void PathView::setPalette(const Palette &palette) void MapView::setPalette(const Palette &palette)
{ {
_palette = palette; _palette = palette;
_palette.reset(); _palette.reset();
@ -244,20 +263,21 @@ void PathView::setPalette(const Palette &palette)
_routes.at(i)->setColor(_palette.nextColor()); _routes.at(i)->setColor(_palette.nextColor());
} }
void PathView::setMap(Map *map) void MapView::setMap(Map *map)
{ {
QPointF pos = mapToScene(viewport()->rect().center()); QPointF pos = mapToScene(viewport()->rect().center());
Coordinates center = _map->xy2ll(pos); Coordinates center = _map->xy2ll(pos);
qreal resolution = _map->resolution(pos); qreal resolution = _map->resolution(pos);
_map->unload(); _map->unload();
disconnect(_map, SIGNAL(loaded()), this, SLOT(redraw())); disconnect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
_map = map; _map = map;
_map->load(); _map->load();
connect(_map, SIGNAL(loaded()), this, SLOT(redraw())); _map->setBackgroundColor(_backgroundColor);
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
resetDigitalZoom(); digitalZoom(0);
_map->zoomFit(resolution, center); _map->zoomFit(resolution, center);
_scene->setSceneRect(_map->bounds()); _scene->setSceneRect(_map->bounds());
@ -274,17 +294,13 @@ void PathView::setMap(Map *map)
it.value()->setMap(_map); it.value()->setMap(_map);
updatePOIVisibility(); updatePOIVisibility();
pos = _map->ll2xy(center); centerOn(_map->ll2xy(center));
centerOn(pos);
_res = _map->resolution(pos);
_mapScale->setResolution(_res);
resetCachedContent(); resetCachedContent();
QPixmapCache::clear(); QPixmapCache::clear();
} }
void PathView::setPOI(POI *poi) void MapView::setPOI(POI *poi)
{ {
disconnect(_poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI())); disconnect(_poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI()));
connect(poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI())); connect(poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI()));
@ -294,7 +310,7 @@ void PathView::setPOI(POI *poi)
updatePOI(); updatePOI();
} }
void PathView::updatePOI() void MapView::updatePOI()
{ {
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it; QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
@ -304,16 +320,20 @@ void PathView::updatePOI()
} }
_pois.clear(); _pois.clear();
for (int i = 0; i < _tracks.size(); i++) if (_showTracks)
addPOI(_poi->points(_tracks.at(i)->path())); for (int i = 0; i < _tracks.size(); i++)
for (int i = 0; i < _routes.size(); i++) addPOI(_poi->points(_tracks.at(i)->path()));
addPOI(_poi->points(_routes.at(i)->path())); if (_showRoutes)
addPOI(_poi->points(_waypoints)); for (int i = 0; i < _routes.size(); i++)
addPOI(_poi->points(_routes.at(i)->path()));
if (_showWaypoints)
for (int i = 0; i< _waypoints.size(); i++)
addPOI(_poi->points(_waypoints.at(i)->waypoint()));
updatePOIVisibility(); updatePOIVisibility();
} }
void PathView::addPOI(const QVector<Waypoint> &waypoints) void MapView::addPOI(const QList<Waypoint> &waypoints)
{ {
for (int i = 0; i < waypoints.size(); i++) { for (int i = 0; i < waypoints.size(); i++) {
const Waypoint &w = waypoints.at(i); const Waypoint &w = waypoints.at(i);
@ -323,6 +343,8 @@ void PathView::addPOI(const QVector<Waypoint> &waypoints)
WaypointItem *pi = new WaypointItem(w, _map); WaypointItem *pi = new WaypointItem(w, _map);
pi->setZValue(1); pi->setZValue(1);
pi->setSize(_poiSize);
pi->setColor(_poiColor);
pi->showLabel(_showPOILabels); pi->showLabel(_showPOILabels);
pi->setVisible(_showPOI); pi->setVisible(_showPOI);
pi->setDigitalZoom(_digitalZoom); pi->setDigitalZoom(_digitalZoom);
@ -332,7 +354,7 @@ void PathView::addPOI(const QVector<Waypoint> &waypoints)
} }
} }
void PathView::setUnits(enum Units units) void MapView::setUnits(enum Units units)
{ {
_units = units; _units = units;
@ -350,36 +372,23 @@ void PathView::setUnits(enum Units units)
it.value()->setUnits(units); it.value()->setUnits(units);
} }
void PathView::redraw() void MapView::clearMapCache()
{ {
_map->clearCache();
resetCachedContent(); resetCachedContent();
} }
void PathView::resetDigitalZoom() void MapView::digitalZoom(int zoom)
{ {
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it; QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
_digitalZoom = 0; if (zoom) {
resetTransform(); _digitalZoom += zoom;
scale(pow(2, zoom), pow(2, zoom));
for (int i = 0; i < _tracks.size(); i++) } else {
_tracks.at(i)->setDigitalZoom(0); _digitalZoom = 0;
for (int i = 0; i < _routes.size(); i++) resetTransform();
_routes.at(i)->setDigitalZoom(0); }
for (int i = 0; i < _waypoints.size(); i++)
_waypoints.at(i)->setDigitalZoom(0);
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
it.value()->setDigitalZoom(0);
_mapScale->setDigitalZoom(0);
}
void PathView::digitalZoom(int zoom)
{
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
_digitalZoom += zoom;
scale(pow(2, zoom), pow(2, zoom));
for (int i = 0; i < _tracks.size(); i++) for (int i = 0; i < _tracks.size(); i++)
_tracks.at(i)->setDigitalZoom(_digitalZoom); _tracks.at(i)->setDigitalZoom(_digitalZoom);
@ -393,7 +402,7 @@ void PathView::digitalZoom(int zoom)
_mapScale->setDigitalZoom(_digitalZoom); _mapScale->setDigitalZoom(_digitalZoom);
} }
void PathView::zoom(int zoom, const QPoint &pos, const Coordinates &c) void MapView::zoom(int zoom, const QPoint &pos, const Coordinates &c)
{ {
bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier; bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier;
@ -410,15 +419,8 @@ void PathView::zoom(int zoom, const QPoint &pos, const Coordinates &c)
ns = (zoom > 0) ? _map->zoomIn() : _map->zoomOut(); ns = (zoom > 0) ? _map->zoomIn() : _map->zoomOut();
if (ns != os) { if (ns != os) {
QPoint offset = pos - viewport()->rect().center();
rescale(); rescale();
centerOn(_map->ll2xy(c) - (pos - viewport()->rect().center()));
QPointF center = _map->ll2xy(c) - offset;
centerOn(center);
_res = _map->resolution(center);
_mapScale->setResolution(_res);
} else { } else {
if (shift) if (shift)
digitalZoom(zoom); digitalZoom(zoom);
@ -426,7 +428,7 @@ void PathView::zoom(int zoom, const QPoint &pos, const Coordinates &c)
} }
} }
void PathView::wheelEvent(QWheelEvent *event) void MapView::wheelEvent(QWheelEvent *event)
{ {
static int deg = 0; static int deg = 0;
@ -439,7 +441,7 @@ void PathView::wheelEvent(QWheelEvent *event)
zoom((event->delta() > 0) ? 1 : -1, event->pos(), c); zoom((event->delta() > 0) ? 1 : -1, event->pos(), c);
} }
void PathView::mouseDoubleClickEvent(QMouseEvent *event) void MapView::mouseDoubleClickEvent(QMouseEvent *event)
{ {
if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton) if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton)
return; return;
@ -448,7 +450,7 @@ void PathView::mouseDoubleClickEvent(QMouseEvent *event)
zoom((event->button() == Qt::LeftButton) ? 1 : -1, event->pos(), c); zoom((event->button() == Qt::LeftButton) ? 1 : -1, event->pos(), c);
} }
void PathView::keyPressEvent(QKeyEvent *event) void MapView::keyPressEvent(QKeyEvent *event)
{ {
int z; int z;
@ -460,7 +462,7 @@ void PathView::keyPressEvent(QKeyEvent *event)
else if (event->matches(ZOOM_OUT)) else if (event->matches(ZOOM_OUT))
z = -1; z = -1;
else if (_digitalZoom && event->key() == Qt::Key_Escape) { else if (_digitalZoom && event->key() == Qt::Key_Escape) {
resetDigitalZoom(); digitalZoom(0);
return; return;
} else { } else {
QGraphicsView::keyPressEvent(event); QGraphicsView::keyPressEvent(event);
@ -470,13 +472,23 @@ void PathView::keyPressEvent(QKeyEvent *event)
zoom(z, pos, c); zoom(z, pos, c);
} }
void PathView::plot(QPainter *painter, const QRectF &target) void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
bool hires)
{ {
QRect orig, adj; QRect orig, adj;
qreal ratio, diff; qreal ratio, diff, origRes, q;
QPointF origScene, origPos;
Coordinates origLL;
// Enter plot mode
setUpdatesEnabled(false);
_plot = true;
_map->setBlockingMode(true);
// Compute sizes & ratios
orig = viewport()->rect(); orig = viewport()->rect();
origPos = _mapScale->pos();
if (orig.height() * (target.width() / target.height()) - orig.width() < 0) { if (orig.height() * (target.width() / target.height()) - orig.width() < 0) {
ratio = target.height() / target.width(); ratio = target.height() / target.width();
@ -487,71 +499,106 @@ void PathView::plot(QPainter *painter, const QRectF &target)
diff = (orig.height() * ratio) - orig.width(); diff = (orig.height() * ratio) - orig.width();
adj = orig.adjusted(-diff/2, 0, diff/2, 0); adj = orig.adjusted(-diff/2, 0, diff/2, 0);
} }
q = (target.width() / scale) / adj.width();
setUpdatesEnabled(false); // Adjust the view for printing
_plot = true; if (hires) {
_map->setBlockingMode(true); origScene = mapToScene(orig.center());
origLL = _map->xy2ll(origScene);
origRes = _map->resolution(origScene);
QPointF pos = _mapScale->pos(); QPointF s(painter->device()->logicalDpiX()
_mapScale->setPos(mapToScene(QPoint(adj.bottomRight() + QPoint( / (qreal)metric(QPaintDevice::PdmDpiX),
-(SCALE_OFFSET + _mapScale->boundingRect().width()), painter->device()->logicalDpiY()
-(SCALE_OFFSET + _mapScale->boundingRect().height()))))); / (qreal)metric(QPaintDevice::PdmDpiY));
adj = QRect(0, 0, adj.width() * s.x(), adj.height() * s.y());
_map->zoomFit(adj.size(), _tr | _rr | _wr);
rescale();
QPointF center = contentCenter();
centerOn(center);
adj.moveCenter(mapFromScene(center));
_mapScale->setDigitalZoom(-log2(s.x() / q));
_mapScale->setPos(mapToScene(QPoint(adj.bottomRight() + QPoint(
-(SCALE_OFFSET + _mapScale->boundingRect().width()) * (s.x() / q),
-(SCALE_OFFSET + _mapScale->boundingRect().height()) * (s.x() / q)))));
} else {
_mapScale->setDigitalZoom(-log2(1.0 / q));
_mapScale->setPos(mapToScene(QPoint(adj.bottomRight() + QPoint(
-(SCALE_OFFSET + _mapScale->boundingRect().width()) / q ,
-(SCALE_OFFSET + _mapScale->boundingRect().height()) / q))));
}
// Print the view
render(painter, target, adj); render(painter, target, adj);
_mapScale->setPos(pos); // Revert view changes to display mode
if (hires) {
_map->zoomFit(origRes, origLL);
rescale();
centerOn(origScene);
}
_mapScale->setDigitalZoom(0);
_mapScale->setPos(origPos);
// Exit plot mode
_map->setBlockingMode(false); _map->setBlockingMode(false);
_plot = false; _plot = false;
setUpdatesEnabled(true); setUpdatesEnabled(true);
} }
void PathView::clear() void MapView::clear()
{ {
if (_mapScale->scene() == _scene)
_scene->removeItem(_mapScale);
_pois.clear(); _pois.clear();
_tracks.clear(); _tracks.clear();
_routes.clear(); _routes.clear();
_waypoints.clear(); _waypoints.clear();
_scene->removeItem(_mapScale);
_scene->clear(); _scene->clear();
_scene->addItem(_mapScale);
_palette.reset(); _palette.reset();
_tr = RectC(); _tr = RectC();
_rr = RectC(); _rr = RectC();
_wr = RectC(); _wr = RectC();
resetDigitalZoom(); digitalZoom(0);
resetCachedContent();
QPixmapCache::clear();
} }
void PathView::showTracks(bool show) void MapView::showTracks(bool show)
{ {
_showTracks = show; _showTracks = show;
for (int i = 0; i < _tracks.count(); i++) for (int i = 0; i < _tracks.count(); i++)
_tracks.at(i)->setVisible(show); _tracks.at(i)->setVisible(show);
updatePOI();
} }
void PathView::showRoutes(bool show) void MapView::showRoutes(bool show)
{ {
_showRoutes = show; _showRoutes = show;
for (int i = 0; i < _routes.count(); i++) for (int i = 0; i < _routes.count(); i++)
_routes.at(i)->setVisible(show); _routes.at(i)->setVisible(show);
updatePOI();
} }
void PathView::showWaypoints(bool show) void MapView::showWaypoints(bool show)
{ {
_showWaypoints = show; _showWaypoints = show;
for (int i = 0; i < _waypoints.count(); i++) for (int i = 0; i < _waypoints.count(); i++)
_waypoints.at(i)->setVisible(show); _waypoints.at(i)->setVisible(show);
updatePOI();
} }
void PathView::showWaypointLabels(bool show) void MapView::showWaypointLabels(bool show)
{ {
_showWaypointLabels = show; _showWaypointLabels = show;
@ -562,7 +609,7 @@ void PathView::showWaypointLabels(bool show)
_routes.at(i)->showWaypointLabels(show); _routes.at(i)->showWaypointLabels(show);
} }
void PathView::showRouteWaypoints(bool show) void MapView::showRouteWaypoints(bool show)
{ {
_showRouteWaypoints = show; _showRouteWaypoints = show;
@ -570,13 +617,13 @@ void PathView::showRouteWaypoints(bool show)
_routes.at(i)->showWaypoints(show); _routes.at(i)->showWaypoints(show);
} }
void PathView::showMap(bool show) void MapView::showMap(bool show)
{ {
_showMap = show; _showMap = show;
resetCachedContent(); resetCachedContent();
} }
void PathView::showPOI(bool show) void MapView::showPOI(bool show)
{ {
_showPOI = show; _showPOI = show;
@ -587,7 +634,7 @@ void PathView::showPOI(bool show)
updatePOIVisibility(); updatePOIVisibility();
} }
void PathView::showPOILabels(bool show) void MapView::showPOILabels(bool show)
{ {
_showPOILabels = show; _showPOILabels = show;
@ -598,14 +645,14 @@ void PathView::showPOILabels(bool show)
updatePOIVisibility(); updatePOIVisibility();
} }
void PathView::setPOIOverlap(bool overlap) void MapView::setPOIOverlap(bool overlap)
{ {
_overlapPOIs = overlap; _overlapPOIs = overlap;
updatePOIVisibility(); updatePOIVisibility();
} }
void PathView::setTrackWidth(int width) void MapView::setTrackWidth(int width)
{ {
_trackWidth = width; _trackWidth = width;
@ -613,7 +660,7 @@ void PathView::setTrackWidth(int width)
_tracks.at(i)->setWidth(width); _tracks.at(i)->setWidth(width);
} }
void PathView::setRouteWidth(int width) void MapView::setRouteWidth(int width)
{ {
_routeWidth = width; _routeWidth = width;
@ -621,7 +668,7 @@ void PathView::setRouteWidth(int width)
_routes.at(i)->setWidth(width); _routes.at(i)->setWidth(width);
} }
void PathView::setTrackStyle(Qt::PenStyle style) void MapView::setTrackStyle(Qt::PenStyle style)
{ {
_trackStyle = style; _trackStyle = style;
@ -629,7 +676,7 @@ void PathView::setTrackStyle(Qt::PenStyle style)
_tracks.at(i)->setStyle(style); _tracks.at(i)->setStyle(style);
} }
void PathView::setRouteStyle(Qt::PenStyle style) void MapView::setRouteStyle(Qt::PenStyle style)
{ {
_routeStyle = style; _routeStyle = style;
@ -637,30 +684,82 @@ void PathView::setRouteStyle(Qt::PenStyle style)
_routes.at(i)->setStyle(style); _routes.at(i)->setStyle(style);
} }
void PathView::drawBackground(QPainter *painter, const QRectF &rect) void MapView::setWaypointSize(int size)
{ {
if (_showMap) _waypointSize = size;
_map->draw(painter, rect);
else for (int i = 0; i < _waypoints.size(); i++)
painter->fillRect(rect, Qt::white); _waypoints.at(i)->setSize(size);
} }
void PathView::resizeEvent(QResizeEvent *event) void MapView::setWaypointColor(const QColor &color)
{ {
qreal scale = _map->zoom(); _waypointColor = color;
if (mapScale() != scale)
for (int i = 0; i < _waypoints.size(); i++)
_waypoints.at(i)->setColor(color);
}
void MapView::setPOISize(int size)
{
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
_poiSize = size;
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
it.value()->setSize(size);
}
void MapView::setPOIColor(const QColor &color)
{
QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
_poiColor = color;
for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
it.value()->setColor(color);
}
void MapView::setMapOpacity(int opacity)
{
_opacity = opacity / 100.0;
resetCachedContent();
}
void MapView::setBackgroundColor(const QColor &color)
{
_backgroundColor = color;
_map->setBackgroundColor(color);
resetCachedContent();
}
void MapView::drawBackground(QPainter *painter, const QRectF &rect)
{
if (_showMap) {
QRectF ir = rect.intersected(_map->bounds());
if (_opacity < 1.0 || ir != rect)
painter->fillRect(rect, _backgroundColor);
if (_opacity < 1.0)
painter->setOpacity(_opacity);
_map->draw(painter, ir);
} else
painter->fillRect(rect, _backgroundColor);
}
void MapView::resizeEvent(QResizeEvent *event)
{
QGraphicsView::resizeEvent(event);
qreal zoom = _map->zoom();
if (mapZoom() != zoom)
rescale(); rescale();
QPointF center = contentCenter(); centerOn(contentCenter());
centerOn(center);
_res = _map->resolution(center);
_mapScale->setResolution(_res);
QGraphicsView::resizeEvent(event);
} }
void PathView::paintEvent(QPaintEvent *event) void MapView::paintEvent(QPaintEvent *event)
{ {
QPointF scenePos = mapToScene(rect().bottomRight() + QPoint( QPointF scenePos = mapToScene(rect().bottomRight() + QPoint(
-(SCALE_OFFSET + _mapScale->boundingRect().width()), -(SCALE_OFFSET + _mapScale->boundingRect().width()),
@ -671,7 +770,7 @@ void PathView::paintEvent(QPaintEvent *event)
QGraphicsView::paintEvent(event); QGraphicsView::paintEvent(event);
} }
void PathView::scrollContentsBy(int dx, int dy) void MapView::scrollContentsBy(int dx, int dy)
{ {
QGraphicsView::scrollContentsBy(dx, dy); QGraphicsView::scrollContentsBy(dx, dy);
@ -684,10 +783,30 @@ void PathView::scrollContentsBy(int dx, int dy)
} }
} }
void PathView::useOpenGL(bool use) void MapView::useOpenGL(bool use)
{ {
if (use) if (use)
setViewport(new OPENGL_WIDGET); setViewport(new OPENGL_WIDGET);
else else
setViewport(new QWidget); setViewport(new QWidget);
} }
void MapView::useAntiAliasing(bool use)
{
setRenderHint(QPainter::Antialiasing, use);
}
void MapView::setMarkerColor(const QColor &color)
{
_markerColor = color;
for (int i = 0; i < _tracks.size(); i++)
_tracks.at(i)->setMarkerColor(color);
for (int i = 0; i < _routes.size(); i++)
_routes.at(i)->setMarkerColor(color);
}
void MapView::reloadMap()
{
resetCachedContent();
}

View File

@ -1,15 +1,15 @@
#ifndef TRACKVIEW_H #ifndef MAPVIEW_H
#define TRACKVIEW_H #define MAPVIEW_H
#include <QGraphicsView> #include <QGraphicsView>
#include <QVector> #include <QVector>
#include <QHash> #include <QHash>
#include <QList> #include <QList>
#include "common/rectc.h"
#include "data/waypoint.h"
#include "searchpointer.h"
#include "units.h" #include "units.h"
#include "palette.h" #include "palette.h"
#include "waypoint.h"
#include "rectc.h"
#include "searchpointer.h"
class Data; class Data;
class POI; class POI;
@ -22,13 +22,12 @@ class WaypointItem;
class ScaleItem; class ScaleItem;
class PathItem; class PathItem;
class PathView : public QGraphicsView class MapView : public QGraphicsView
{ {
Q_OBJECT Q_OBJECT
public: public:
PathView(Map *map, POI *poi, QWidget *parent = 0); MapView(Map *map, POI *poi, QWidget *parent = 0);
~PathView();
QList<PathItem*> loadData(const Data &data); QList<PathItem*> loadData(const Data &data);
@ -37,19 +36,25 @@ public:
void setMap(Map *map); void setMap(Map *map);
void setUnits(enum Units units); void setUnits(enum Units units);
void plot(QPainter *painter, const QRectF &target); void plot(QPainter *painter, const QRectF &target, qreal scale, bool hires);
int trackCount() const {return _tracks.count();}
int routeCount() const {return _routes.count();}
int waypointCount() const {return _waypoints.count();}
void clear(); void clear();
void setTrackWidth(int width);
void setRouteWidth(int width);
void setTrackStyle(Qt::PenStyle style);
void setRouteStyle(Qt::PenStyle style);
void setWaypointSize(int size);
void setWaypointColor(const QColor &color);
void setPOISize(int size);
void setPOIColor(const QColor &color);
void setMapOpacity(int opacity);
void setBackgroundColor(const QColor &color);
void useOpenGL(bool use); void useOpenGL(bool use);
void useAntiAliasing(bool use);
void setMarkerColor(const QColor &color);
public slots: public slots:
void redraw();
void showMap(bool show); void showMap(bool show);
void showPOI(bool show); void showPOI(bool show);
void setPOIOverlap(bool overlap); void setPOIOverlap(bool overlap);
@ -59,30 +64,27 @@ public slots:
void showRoutes(bool show); void showRoutes(bool show);
void showWaypoints(bool show); void showWaypoints(bool show);
void showRouteWaypoints(bool show); void showRouteWaypoints(bool show);
void setTrackWidth(int width); void clearMapCache();
void setRouteWidth(int width);
void setTrackStyle(Qt::PenStyle style);
void setRouteStyle(Qt::PenStyle style);
private slots: private slots:
void updatePOI(); void updatePOI();
void reloadMap();
private: private:
PathItem *addTrack(const Track &track); PathItem *addTrack(const Track &track);
PathItem *addRoute(const Route &route); PathItem *addRoute(const Route &route);
void addWaypoints(const QList<Waypoint> &waypoints); void addWaypoints(const QList<Waypoint> &waypoints);
void addPOI(const QVector<Waypoint> &waypoints); void addPOI(const QList<Waypoint> &waypoints);
void loadPOI(); void loadPOI();
void clearPOI(); void clearPOI();
qreal mapScale() const; qreal mapZoom() const;
QPointF contentCenter() const; QPointF contentCenter() const;
void rescale(); void rescale();
void centerOn(const QPointF &pos);
void zoom(int zoom, const QPoint &pos, const Coordinates &c); void zoom(int zoom, const QPoint &pos, const Coordinates &c);
void digitalZoom(int zoom); void digitalZoom(int zoom);
void resetDigitalZoom();
void updatePOIVisibility(); void updatePOIVisibility();
void updateWaypointsBoundingRect(const Coordinates &wp);
void mouseDoubleClickEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
@ -107,6 +109,8 @@ private:
Palette _palette; Palette _palette;
Units _units; Units _units;
qreal _opacity;
QColor _backgroundColor;
bool _showMap; bool _showMap;
bool _showTracks; bool _showTracks;
bool _showRoutes; bool _showRoutes;
@ -120,9 +124,14 @@ private:
int _routeWidth; int _routeWidth;
Qt::PenStyle _trackStyle; Qt::PenStyle _trackStyle;
Qt::PenStyle _routeStyle; Qt::PenStyle _routeStyle;
int _waypointSize;
int _poiSize;
QColor _waypointColor;
QColor _poiColor;
QColor _markerColor;
int _digitalZoom; int _digitalZoom;
bool _plot; bool _plot;
}; };
#endif // TRACKVIEW_H #endif // MAPVIEW_H

View File

@ -7,7 +7,7 @@
MarkerItem::MarkerItem(QGraphicsItem *parent) : QGraphicsItem(parent) MarkerItem::MarkerItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{ {
_color = Qt::red;
} }
QRectF MarkerItem::boundingRect() const QRectF MarkerItem::boundingRect() const
@ -22,9 +22,15 @@ void MarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
Q_UNUSED(widget); Q_UNUSED(widget);
painter->setRenderHint(QPainter::Antialiasing, false); painter->setRenderHint(QPainter::Antialiasing, false);
painter->setPen(QPen(Qt::red, WIDTH)); painter->setPen(QPen(_color, WIDTH));
painter->drawLine(-SIZE/2, 0, SIZE/2, 0); painter->drawLine(-SIZE/2, 0, SIZE/2, 0);
painter->drawLine(0, -SIZE/2, 0, SIZE/2); painter->drawLine(0, -SIZE/2, 0, SIZE/2);
// painter->drawRect(boundingRect()); // painter->drawRect(boundingRect());
} }
void MarkerItem::setColor(const QColor &color)
{
_color = color;
update();
}

View File

@ -2,6 +2,7 @@
#define MARKERITEM_H #define MARKERITEM_H
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QColor>
class MarkerItem : public QGraphicsItem class MarkerItem : public QGraphicsItem
{ {
@ -11,6 +12,11 @@ public:
QRectF boundingRect() const; QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget); QWidget *widget);
void setColor(const QColor &color);
private:
QColor _color;
}; };
#endif // MARKERITEM_H #endif // MARKERITEM_H

View File

@ -1,7 +1,5 @@
#include <cmath> #include <cmath>
#include <cctype> #include "nicenum.h"
#include "misc.h"
double niceNum(double x, int round) double niceNum(double x, int round)
{ {
@ -34,23 +32,3 @@ double niceNum(double x, int round)
return nf * pow(10.0, expv); return nf * pow(10.0, expv);
} }
int str2int(const char *str, int len)
{
int res = 0;
for (const char *sp = str; sp < str + len; sp++) {
if (::isdigit(*sp))
res = res * 10 + *sp - '0';
else
return -1;
}
return res;
}
QRectF scaled(const QRectF &rect, qreal factor)
{
return QRectF(QPointF(rect.left() * factor, rect.top() * factor),
QSizeF(rect.width() * factor, rect.height() * factor));
}

6
src/GUI/nicenum.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef MISC_H
#define MISC_H
double niceNum(double x, int round);
#endif // MISC_H

View File

@ -9,6 +9,7 @@
#include <QGroupBox> #include <QGroupBox>
#include <QCheckBox> #include <QCheckBox>
#include <QComboBox> #include <QComboBox>
#include <QRadioButton>
#include <QLabel> #include <QLabel>
#include <QSysInfo> #include <QSysInfo>
#include "config.h" #include "config.h"
@ -16,14 +17,49 @@
#include "colorbox.h" #include "colorbox.h"
#include "stylecombobox.h" #include "stylecombobox.h"
#include "oddspinbox.h" #include "oddspinbox.h"
#include "percentslider.h"
#include "optionsdialog.h" #include "optionsdialog.h"
#define MENU_MARGIN 20 #define MENU_MARGIN 20
#define MENU_ICON_SIZE 32 #define MENU_ICON_SIZE 32
#ifdef Q_OS_MAC
static QFrame *line()
{
QFrame *l = new QFrame();
l->setFrameShape(QFrame::HLine);
l->setFrameShadow(QFrame::Sunken);
return l;
}
#endif
QWidget *OptionsDialog::createGeneralPage()
{
_alwaysShowMap = new QCheckBox(tr("Always show the map"));
_alwaysShowMap->setChecked(_options->alwaysShowMap);
_alwaysShowMap->setToolTip("<p>" +
tr("Show the map even when no files are loaded.") + "</p>");
QFormLayout *showMapLayout = new QFormLayout();
showMapLayout->addWidget(_alwaysShowMap);
QWidget *generalTab = new QWidget();
QVBoxLayout *generalTabLayout = new QVBoxLayout();
generalTabLayout->addLayout(showMapLayout);
generalTabLayout->addStretch();
generalTab->setLayout(generalTabLayout);
QTabWidget *generalPage = new QTabWidget();
generalPage->addTab(generalTab, tr("General"));
return generalPage;
}
QWidget *OptionsDialog::createAppearancePage() QWidget *OptionsDialog::createAppearancePage()
{ {
// Paths
_baseColor = new ColorBox(); _baseColor = new ColorBox();
_baseColor->setColor(_options->palette.color()); _baseColor->setColor(_options->palette.color());
_colorOffset = new QDoubleSpinBox(); _colorOffset = new QDoubleSpinBox();
@ -31,14 +67,13 @@ QWidget *OptionsDialog::createAppearancePage()
_colorOffset->setMaximum(1.0); _colorOffset->setMaximum(1.0);
_colorOffset->setSingleStep(0.01); _colorOffset->setSingleStep(0.01);
_colorOffset->setValue(_options->palette.shift()); _colorOffset->setValue(_options->palette.shift());
QFormLayout *paletteLayout = new QFormLayout(); QFormLayout *paletteLayout = new QFormLayout();
paletteLayout->addRow(tr("Base color:"), _baseColor); paletteLayout->addRow(tr("Base color:"), _baseColor);
paletteLayout->addRow(tr("Palette shift:"), _colorOffset); paletteLayout->addRow(tr("Palette shift:"), _colorOffset);
#ifndef Q_OS_MAC
QWidget *colorTab = new QWidget(); QGroupBox *colorBox = new QGroupBox(tr("Colors"));
colorTab->setLayout(paletteLayout); colorBox->setLayout(paletteLayout);
#endif // Q_OS_MAC
_trackWidth = new QSpinBox(); _trackWidth = new QSpinBox();
_trackWidth->setValue(_options->trackWidth); _trackWidth->setValue(_options->trackWidth);
@ -46,12 +81,15 @@ QWidget *OptionsDialog::createAppearancePage()
_trackStyle = new StyleComboBox(); _trackStyle = new StyleComboBox();
_trackStyle->setValue(_options->trackStyle); _trackStyle->setValue(_options->trackStyle);
QFormLayout *trackLayout = new QFormLayout(); QFormLayout *trackLayout = new QFormLayout();
#ifdef Q_OS_MAC
trackLayout->addRow(tr("Track width:"), _trackWidth); trackLayout->addRow(tr("Track width:"), _trackWidth);
trackLayout->addRow(tr("Track style:"), _trackStyle); trackLayout->addRow(tr("Track style:"), _trackStyle);
#ifndef Q_OS_MAC #else // Q_OS_MAC
trackLayout->addRow(tr("Width:"), _trackWidth);
trackLayout->addRow(tr("Style:"), _trackStyle);
QGroupBox *trackBox = new QGroupBox(tr("Tracks")); QGroupBox *trackBox = new QGroupBox(tr("Tracks"));
trackBox->setLayout(trackLayout); trackBox->setLayout(trackLayout);
#endif #endif // Q_OS_MAC
_routeWidth = new QSpinBox(); _routeWidth = new QSpinBox();
_routeWidth->setValue(_options->routeWidth); _routeWidth->setValue(_options->routeWidth);
@ -59,9 +97,12 @@ QWidget *OptionsDialog::createAppearancePage()
_routeStyle = new StyleComboBox(); _routeStyle = new StyleComboBox();
_routeStyle->setValue(_options->routeStyle); _routeStyle->setValue(_options->routeStyle);
QFormLayout *routeLayout = new QFormLayout(); QFormLayout *routeLayout = new QFormLayout();
#ifdef Q_OS_MAC
routeLayout->addRow(tr("Route width:"), _routeWidth); routeLayout->addRow(tr("Route width:"), _routeWidth);
routeLayout->addRow(tr("Route style:"), _routeStyle); routeLayout->addRow(tr("Route style:"), _routeStyle);
#ifndef Q_OS_MAC #else // Q_OS_MAC
routeLayout->addRow(tr("Width:"), _routeWidth);
routeLayout->addRow(tr("Style:"), _routeStyle);
QGroupBox *routeBox = new QGroupBox(tr("Routes")); QGroupBox *routeBox = new QGroupBox(tr("Routes"));
routeBox->setLayout(routeLayout); routeBox->setLayout(routeLayout);
#endif // Q_OS_MAC #endif // Q_OS_MAC
@ -74,18 +115,14 @@ QWidget *OptionsDialog::createAppearancePage()
QWidget *pathTab = new QWidget(); QWidget *pathTab = new QWidget();
QVBoxLayout *pathTabLayout = new QVBoxLayout(); QVBoxLayout *pathTabLayout = new QVBoxLayout();
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
QFrame *l1 = new QFrame(); pathTabLayout->addLayout(paletteLayout);
l1->setFrameShape(QFrame::HLine); pathTabLayout->addWidget(line());
l1->setFrameShadow(QFrame::Sunken);
QFrame *l2 = new QFrame();
l2->setFrameShape(QFrame::HLine);
l2->setFrameShadow(QFrame::Sunken);
pathTabLayout->addLayout(trackLayout); pathTabLayout->addLayout(trackLayout);
pathTabLayout->addWidget(l1); pathTabLayout->addWidget(line());
pathTabLayout->addLayout(routeLayout); pathTabLayout->addLayout(routeLayout);
pathTabLayout->addWidget(l2); pathTabLayout->addWidget(line());
#else // Q_OS_MAC #else // Q_OS_MAC
pathTabLayout->addWidget(colorBox);
pathTabLayout->addWidget(trackBox); pathTabLayout->addWidget(trackBox);
pathTabLayout->addWidget(routeBox); pathTabLayout->addWidget(routeBox);
#endif // Q_OS_MAC #endif // Q_OS_MAC
@ -93,18 +130,70 @@ QWidget *OptionsDialog::createAppearancePage()
pathTabLayout->addStretch(); pathTabLayout->addStretch();
pathTab->setLayout(pathTabLayout); pathTab->setLayout(pathTabLayout);
// Waypoints
_waypointSize = new QSpinBox();
_waypointSize->setMinimum(1);
_waypointSize->setValue(_options->waypointSize);
_waypointColor = new ColorBox();
_waypointColor->setColor(_options->waypointColor);
QFormLayout *waypointLayout = new QFormLayout();
#ifdef Q_OS_MAC
waypointLayout->addRow(tr("Waypoint color:"), _waypointColor);
waypointLayout->addRow(tr("Waypoint size:"), _waypointSize);
#else // Q_OS_MAC
waypointLayout->addRow(tr("Color:"), _waypointColor);
waypointLayout->addRow(tr("Size:"), _waypointSize);
QGroupBox *waypointBox = new QGroupBox(tr("Waypoints"));
waypointBox->setLayout(waypointLayout);
#endif // Q_OS_MAC
_poiSize = new QSpinBox();
_poiSize->setMinimum(1);
_poiSize->setValue(_options->poiSize);
_poiColor = new ColorBox();
_poiColor->setColor(_options->poiColor);
QFormLayout *poiLayout = new QFormLayout();
#ifdef Q_OS_MAC
poiLayout->addRow(tr("POI color:"), _poiColor);
poiLayout->addRow(tr("POI size:"), _poiSize);
#else // Q_OS_MAC
poiLayout->addRow(tr("Color:"), _poiColor);
poiLayout->addRow(tr("Size:"), _poiSize);
QGroupBox *poiBox = new QGroupBox(tr("POIs"));
poiBox->setLayout(poiLayout);
#endif // Q_OS_MAC
QWidget *pointTab = new QWidget();
QVBoxLayout *pointTabLayout = new QVBoxLayout();
#ifdef Q_OS_MAC
pointTabLayout->addLayout(waypointLayout);
pointTabLayout->addWidget(line());
pointTabLayout->addLayout(poiLayout);
#else // Q_OS_MAC
pointTabLayout->addWidget(waypointBox);
pointTabLayout->addWidget(poiBox);
#endif // Q_OS_MAC
pointTabLayout->addStretch();
pointTab->setLayout(pointTabLayout);
// Graphs
_sliderColor = new ColorBox();
_sliderColor->setColor(_options->sliderColor);
_graphWidth = new QSpinBox(); _graphWidth = new QSpinBox();
_graphWidth->setValue(_options->graphWidth); _graphWidth->setValue(_options->graphWidth);
_graphWidth->setMinimum(1); _graphWidth->setMinimum(1);
QFormLayout *graphLayout = new QFormLayout(); QFormLayout *graphLayout = new QFormLayout();
graphLayout->addRow(tr("Line width:"), _graphWidth); graphLayout->addRow(tr("Line width:"), _graphWidth);
graphLayout->addRow(tr("Slider color:"), _sliderColor);
_graphAA = new QCheckBox(tr("Use anti-aliasing")); _graphAA = new QCheckBox(tr("Use anti-aliasing"));
_graphAA->setChecked(_options->graphAntiAliasing); _graphAA->setChecked(_options->graphAntiAliasing);
QFormLayout *graphAALayout = new QFormLayout(); QFormLayout *graphAALayout = new QFormLayout();
graphAALayout->addWidget(_graphAA); graphAALayout->addWidget(_graphAA);
QWidget *graphTab = new QWidget(); QWidget *graphTab = new QWidget();
QVBoxLayout *graphTabLayout = new QVBoxLayout(); QVBoxLayout *graphTabLayout = new QVBoxLayout();
graphTabLayout->addLayout(graphLayout); graphTabLayout->addLayout(graphLayout);
@ -112,10 +201,29 @@ QWidget *OptionsDialog::createAppearancePage()
graphTabLayout->addStretch(); graphTabLayout->addStretch();
graphTab->setLayout(graphTabLayout); graphTab->setLayout(graphTabLayout);
// Map
_mapOpacity = new PercentSlider();
_mapOpacity->setValue(_options->mapOpacity);
_backgroundColor = new ColorBox();
_backgroundColor->setColor(_options->backgroundColor);
_backgroundColor->enableAlphaChannel(false);
QFormLayout *mapLayout = new QFormLayout();
mapLayout->addRow(tr("Background color:"), _backgroundColor);
mapLayout->addRow(tr("Map opacity:"), _mapOpacity);
QWidget *mapTab = new QWidget();
QVBoxLayout *mapTabLayout = new QVBoxLayout();
mapTabLayout->addLayout(mapLayout);
mapTabLayout->addStretch();
mapTab->setLayout(mapTabLayout);
QTabWidget *appearancePage = new QTabWidget(); QTabWidget *appearancePage = new QTabWidget();
appearancePage->addTab(colorTab, tr("Colors"));
appearancePage->addTab(pathTab, tr("Paths")); appearancePage->addTab(pathTab, tr("Paths"));
appearancePage->addTab(pointTab, tr("Points"));
appearancePage->addTab(graphTab, tr("Graphs")); appearancePage->addTab(graphTab, tr("Graphs"));
appearancePage->addTab(mapTab, tr("Map"));
return appearancePage; return appearancePage;
} }
@ -164,14 +272,9 @@ QWidget *OptionsDialog::createDataPage()
QWidget *filterTab = new QWidget(); QWidget *filterTab = new QWidget();
QVBoxLayout *filterTabLayout = new QVBoxLayout(); QVBoxLayout *filterTabLayout = new QVBoxLayout();
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
QLabel *label = new QLabel(tr("Smoothing:")); filterTabLayout->addWidget(new QLabel(tr("Smoothing:")));
QFrame *line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
filterTabLayout->addWidget(label);
filterTabLayout->addLayout(smoothLayout); filterTabLayout->addLayout(smoothLayout);
filterTabLayout->addWidget(line); filterTabLayout->addWidget(line());
filterTabLayout->addLayout(outlierLayout); filterTabLayout->addLayout(outlierLayout);
#else // Q_OS_MAC #else // Q_OS_MAC
filterTabLayout->addWidget(smoothBox); filterTabLayout->addWidget(smoothBox);
@ -239,6 +342,36 @@ QWidget *OptionsDialog::createPOIPage()
QWidget *OptionsDialog::createExportPage() QWidget *OptionsDialog::createExportPage()
{ {
_wysiwyg = new QRadioButton(tr("WYSIWYG"));
_hires = new QRadioButton(tr("High-Resolution"));
if (_options->hiresPrint)
_hires->setChecked(true);
else
_wysiwyg->setChecked(true);
QLabel *lw = new QLabel(tr("The printed area is approximately the display"
" area. The map zoom level does not change."));
QLabel *lh = new QLabel(tr("The zoom level will be changed so that"
" the whole content (tracks/waypoints) fits to the printed area and"
" the map resolution is as close as possible to the print resolution."));
QFont f = lw->font();
f.setPointSize(f.pointSize() - 1);
lw->setWordWrap(true);
lh->setWordWrap(true);
lw->setFont(f);
lh->setFont(f);
QVBoxLayout *modeTabLayout = new QVBoxLayout();
modeTabLayout->addWidget(_wysiwyg);
modeTabLayout->addWidget(lw);
modeTabLayout->addSpacing(10);
modeTabLayout->addWidget(_hires);
modeTabLayout->addWidget(lh);
modeTabLayout->addStretch();
QWidget *modeTab = new QWidget();
modeTab->setLayout(modeTabLayout);
_name = new QCheckBox(tr("Name")); _name = new QCheckBox(tr("Name"));
_name->setChecked(_options->printName); _name->setChecked(_options->printName);
_date = new QCheckBox(tr("Date")); _date = new QCheckBox(tr("Date"));
@ -274,6 +407,7 @@ QWidget *OptionsDialog::createExportPage()
QTabWidget *exportPage = new QTabWidget(); QTabWidget *exportPage = new QTabWidget();
exportPage->addTab(modeTab, tr("Print mode"));
exportPage->addTab(headerTab, tr("Header")); exportPage->addTab(headerTab, tr("Header"));
exportPage->addTab(graphTab, tr("Graphs")); exportPage->addTab(graphTab, tr("Graphs"));
@ -283,12 +417,6 @@ QWidget *OptionsDialog::createExportPage()
QWidget *OptionsDialog::createSystemPage() QWidget *OptionsDialog::createSystemPage()
{ {
_useOpenGL = new QCheckBox(tr("Use OpenGL")); _useOpenGL = new QCheckBox(tr("Use OpenGL"));
#ifdef Q_OS_WIN32
if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) {
_useOpenGL->setChecked(false);
_useOpenGL->setEnabled(false);
} else
#endif // Q_OS_WIN32
_useOpenGL->setChecked(_options->useOpenGL); _useOpenGL->setChecked(_options->useOpenGL);
_pixmapCache = new QSpinBox(); _pixmapCache = new QSpinBox();
@ -320,6 +448,7 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
: QDialog(parent), _options(options) : QDialog(parent), _options(options)
{ {
QStackedWidget *pages = new QStackedWidget(); QStackedWidget *pages = new QStackedWidget();
pages->addWidget(createGeneralPage());
pages->addWidget(createAppearancePage()); pages->addWidget(createAppearancePage());
pages->addWidget(createDataPage()); pages->addWidget(createDataPage());
pages->addWidget(createPOIPage()); pages->addWidget(createPOIPage());
@ -328,6 +457,7 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
QListWidget *menu = new QListWidget(); QListWidget *menu = new QListWidget();
menu->setIconSize(QSize(MENU_ICON_SIZE, MENU_ICON_SIZE)); menu->setIconSize(QSize(MENU_ICON_SIZE, MENU_ICON_SIZE));
new QListWidgetItem(QIcon(QPixmap(APP_ICON)), tr("General"), menu);
new QListWidgetItem(QIcon(QPixmap(APPEARANCE_ICON)), tr("Appearance"), new QListWidgetItem(QIcon(QPixmap(APPEARANCE_ICON)), tr("Appearance"),
menu); menu);
new QListWidgetItem(QIcon(QPixmap(DATA_ICON)), tr("Data"), menu); new QListWidgetItem(QIcon(QPixmap(DATA_ICON)), tr("Data"), menu);
@ -367,8 +497,12 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
void OptionsDialog::accept() void OptionsDialog::accept()
{ {
_options->alwaysShowMap = _alwaysShowMap->isChecked();
_options->palette.setColor(_baseColor->color()); _options->palette.setColor(_baseColor->color());
_options->palette.setShift(_colorOffset->value()); _options->palette.setShift(_colorOffset->value());
_options->mapOpacity = _mapOpacity->value();
_options->backgroundColor = _backgroundColor->color();
_options->trackWidth = _trackWidth->value(); _options->trackWidth = _trackWidth->value();
_options->trackStyle = (Qt::PenStyle) _trackStyle->itemData( _options->trackStyle = (Qt::PenStyle) _trackStyle->itemData(
_trackStyle->currentIndex()).toInt(); _trackStyle->currentIndex()).toInt();
@ -376,7 +510,12 @@ void OptionsDialog::accept()
_options->routeStyle = (Qt::PenStyle) _routeStyle->itemData( _options->routeStyle = (Qt::PenStyle) _routeStyle->itemData(
_routeStyle->currentIndex()).toInt(); _routeStyle->currentIndex()).toInt();
_options->pathAntiAliasing = _pathAA->isChecked(); _options->pathAntiAliasing = _pathAA->isChecked();
_options->waypointSize = _waypointSize->value();
_options->waypointColor = _waypointColor->color();
_options->poiSize = _poiSize->value();
_options->poiColor = _poiColor->color();
_options->graphWidth = _graphWidth->value(); _options->graphWidth = _graphWidth->value();
_options->sliderColor = _sliderColor->color();
_options->graphAntiAliasing = _graphAA->isChecked(); _options->graphAntiAliasing = _graphAA->isChecked();
_options->elevationFilter = _elevationFilter->value(); _options->elevationFilter = _elevationFilter->value();
@ -385,16 +524,21 @@ void OptionsDialog::accept()
_options->cadenceFilter = _cadenceFilter->value(); _options->cadenceFilter = _cadenceFilter->value();
_options->powerFilter = _powerFilter->value(); _options->powerFilter = _powerFilter->value();
_options->outlierEliminate = _outlierEliminate->isChecked(); _options->outlierEliminate = _outlierEliminate->isChecked();
_options->pauseSpeed = (_options->units == Imperial) qreal pauseSpeed = (_options->units == Imperial)
? _pauseSpeed->value() / MS2MIH : _pauseSpeed->value() / MS2KMH; ? _pauseSpeed->value() / MS2MIH : _pauseSpeed->value() / MS2KMH;
if (qAbs(pauseSpeed - _options->pauseSpeed) > 0.01)
_options->pauseSpeed = pauseSpeed;
_options->pauseInterval = _pauseInterval->value(); _options->pauseInterval = _pauseInterval->value();
_options->poiRadius = (_options->units == Imperial) qreal poiRadius = (_options->units == Imperial)
? _poiRadius->value() * MIINM : _poiRadius->value() * KMINM; ? _poiRadius->value() * MIINM : _poiRadius->value() * KMINM;
if (qAbs(poiRadius - _options->poiRadius) > 0.01)
_options->poiRadius = poiRadius;
_options->useOpenGL = _useOpenGL->isChecked(); _options->useOpenGL = _useOpenGL->isChecked();
_options->pixmapCache = _pixmapCache->value(); _options->pixmapCache = _pixmapCache->value();
_options->hiresPrint = _hires->isChecked();
_options->printName = _name->isChecked(); _options->printName = _name->isChecked();
_options->printDate = _date->isChecked(); _options->printDate = _date->isChecked();
_options->printDistance = _distance->isChecked(); _options->printDistance = _distance->isChecked();

View File

@ -12,17 +12,28 @@ class QSpinBox;
class QDoubleSpinBox; class QDoubleSpinBox;
class QComboBox; class QComboBox;
class QCheckBox; class QCheckBox;
class QRadioButton;
class PercentSlider;
struct Options { struct Options {
// General
bool alwaysShowMap;
// Appearance // Appearance
Palette palette; Palette palette;
int trackWidth; int trackWidth;
int routeWidth; int routeWidth;
Qt::PenStyle trackStyle; Qt::PenStyle trackStyle;
Qt::PenStyle routeStyle; Qt::PenStyle routeStyle;
QColor waypointColor;
QColor poiColor;
int waypointSize;
int poiSize;
int graphWidth; int graphWidth;
QColor sliderColor;
bool pathAntiAliasing; bool pathAntiAliasing;
bool graphAntiAliasing; bool graphAntiAliasing;
int mapOpacity;
QColor backgroundColor;
// Data // Data
int elevationFilter; int elevationFilter;
int speedFilter; int speedFilter;
@ -38,6 +49,7 @@ struct Options {
bool useOpenGL; bool useOpenGL;
int pixmapCache; int pixmapCache;
// Print/Export // Print/Export
bool hiresPrint;
bool printName; bool printName;
bool printDate; bool printDate;
bool printDistance; bool printDistance;
@ -60,6 +72,7 @@ public slots:
void accept(); void accept();
private: private:
QWidget *createGeneralPage();
QWidget *createAppearancePage(); QWidget *createAppearancePage();
QWidget *createDataPage(); QWidget *createDataPage();
QWidget *createPOIPage(); QWidget *createPOIPage();
@ -68,15 +81,24 @@ private:
Options *_options; Options *_options;
// General
QCheckBox *_alwaysShowMap;
// Appearance // Appearance
ColorBox *_baseColor; ColorBox *_baseColor;
QDoubleSpinBox *_colorOffset; QDoubleSpinBox *_colorOffset;
PercentSlider *_mapOpacity;
ColorBox *_backgroundColor;
QSpinBox *_trackWidth; QSpinBox *_trackWidth;
StyleComboBox *_trackStyle; StyleComboBox *_trackStyle;
QSpinBox *_routeWidth; QSpinBox *_routeWidth;
StyleComboBox *_routeStyle; StyleComboBox *_routeStyle;
QCheckBox *_pathAA; QCheckBox *_pathAA;
QSpinBox *_waypointSize;
ColorBox *_waypointColor;
QSpinBox *_poiSize;
ColorBox *_poiColor;
QSpinBox *_graphWidth; QSpinBox *_graphWidth;
ColorBox *_sliderColor;
QCheckBox *_graphAA; QCheckBox *_graphAA;
// Data // Data
OddSpinBox *_elevationFilter; OddSpinBox *_elevationFilter;
@ -93,6 +115,8 @@ private:
QSpinBox *_pixmapCache; QSpinBox *_pixmapCache;
QCheckBox *_useOpenGL; QCheckBox *_useOpenGL;
// Print/Export // Print/Export
QRadioButton *_wysiwyg;
QRadioButton *_hires;
QCheckBox *_name; QCheckBox *_name;
QCheckBox *_date; QCheckBox *_date;
QCheckBox *_distance; QCheckBox *_distance;

View File

@ -2,9 +2,9 @@
#include <QApplication> #include <QApplication>
#include <QCursor> #include <QCursor>
#include <QPainter> #include <QPainter>
#include "map/map.h"
#include "tooltip.h" #include "tooltip.h"
#include "map.h" #include "nicenum.h"
#include "misc.h"
#include "pathitem.h" #include "pathitem.h"
@ -66,9 +66,10 @@ void PathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
void PathItem::setMap(Map *map) void PathItem::setMap(Map *map)
{ {
_map = map;
prepareGeometryChange(); prepareGeometryChange();
_map = map;
updatePainterPath(map); updatePainterPath(map);
updateShape(); updateShape();
@ -77,12 +78,18 @@ void PathItem::setMap(Map *map)
void PathItem::setColor(const QColor &color) void PathItem::setColor(const QColor &color)
{ {
if (_pen.color() == color)
return;
_pen.setColor(color); _pen.setColor(color);
update(); update();
} }
void PathItem::setWidth(qreal width) void PathItem::setWidth(qreal width)
{ {
if (_width == width)
return;
prepareGeometryChange(); prepareGeometryChange();
_width = width; _width = width;
@ -93,12 +100,18 @@ void PathItem::setWidth(qreal width)
void PathItem::setStyle(Qt::PenStyle style) void PathItem::setStyle(Qt::PenStyle style)
{ {
if (_pen.style() == style)
return;
_pen.setStyle(style); _pen.setStyle(style);
update(); update();
} }
void PathItem::setDigitalZoom(int zoom) void PathItem::setDigitalZoom(int zoom)
{ {
if (_digitalZoom == zoom)
return;
prepareGeometryChange(); prepareGeometryChange();
_digitalZoom = zoom; _digitalZoom = zoom;
@ -154,6 +167,24 @@ void PathItem::moveMarker(qreal distance)
_marker->setVisible(false); _marker->setVisible(false);
} }
void PathItem::setMarkerColor(const QColor &color)
{
_marker->setColor(color);
}
void PathItem::hover(bool hover)
{
if (hover) {
_pen.setWidth(_width + 1);
setZValue(zValue() + 1.0);
} else {
_pen.setWidth(_width);
setZValue(zValue() - 1.0);
}
update();
}
void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);

View File

@ -3,9 +3,8 @@
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QPen> #include <QPen>
#include "data/path.h"
#include "markeritem.h" #include "markeritem.h"
#include "path.h"
class Map; class Map;
@ -29,9 +28,11 @@ public:
void setWidth(qreal width); void setWidth(qreal width);
void setStyle(Qt::PenStyle style); void setStyle(Qt::PenStyle style);
void setDigitalZoom(int zoom); void setDigitalZoom(int zoom);
void setMarkerColor(const QColor &color);
public slots: public slots:
void moveMarker(qreal distance); void moveMarker(qreal distance);
void hover(bool hover);
signals: signals:
void selected(bool); void selected(bool);

48
src/GUI/percentslider.cpp Normal file
View File

@ -0,0 +1,48 @@
#include <QSlider>
#include <QLabel>
#include <QHBoxLayout>
#include "units.h"
#include "percentslider.h"
static QString format(int value)
{
return QString::number(value) + UNIT_SPACE + QString("%");
}
PercentSlider::PercentSlider(QWidget *parent) : QWidget(parent)
{
_slider = new QSlider(Qt::Horizontal);
_label = new QLabel();
_slider->setMinimum(0);
_slider->setMaximum(100);
QFontMetrics fm(_label->font());
_label->setFixedWidth(fm.boundingRect(format(_slider->maximum())).width());
_label->setAlignment(Qt::AlignRight);
connect(_slider, SIGNAL(sliderMoved(int)), this, SLOT(updateLabel(int)));
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(_slider);
layout->addWidget(_label);
setLayout(layout);
}
void PercentSlider::updateLabel(int value)
{
_label->setText(format(value));
}
int PercentSlider::value() const
{
return _slider->value();
}
void PercentSlider::setValue(int value)
{
_slider->setValue(value);
_label->setText(format(value));
}

29
src/GUI/percentslider.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef PERCENTSLIDER_H
#define PERCENTSLIDER_H
#include <QWidget>
class QSlider;
class QLabel;
class PercentSlider : public QWidget
{
Q_OBJECT
public:
PercentSlider(QWidget *parent = 0);
int value() const;
public slots:
void setValue(int value);
private slots:
void updateLabel(int value);
private:
QSlider *_slider;
QLabel *_label;
};
#endif // PERCENTSLIDER_H

View File

@ -1,10 +1,10 @@
#include "data.h" #include "data/data.h"
#include "powergraphitem.h"
#include "powergraph.h" #include "powergraph.h"
PowerGraph::PowerGraph(QWidget *parent) : GraphTab(parent) PowerGraph::PowerGraph(QWidget *parent) : GraphTab(parent)
{ {
_units = Metric;
_showTracks = true; _showTracks = true;
GraphView::setYUnits(tr("W")); GraphView::setYUnits(tr("W"));
@ -28,21 +28,16 @@ void PowerGraph::loadData(const Data &data, const QList<PathItem *> &paths)
{ {
for (int i = 0; i < data.tracks().count(); i++) { for (int i = 0; i < data.tracks().count(); i++) {
const Graph &graph = data.tracks().at(i)->power(); const Graph &graph = data.tracks().at(i)->power();
qreal sum = 0, w = 0;
if (graph.size() < 2) { if (graph.size() < 2) {
skipColor(); skipColor();
continue; continue;
} }
for (int j = 1; j < graph.size(); j++) { PowerGraphItem *gi = new PowerGraphItem(graph, _graphType);
qreal ds = graph.at(j).s() - graph.at(j-1).s(); GraphView::addGraph(gi, paths.at(i));
sum += graph.at(j).y() * ds;
w += ds;
}
_avg.append(QPointF(data.tracks().at(i)->distance(), sum/w));
GraphView::loadGraph(graph, paths.at(i)); _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg()));
} }
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)

View File

@ -22,7 +22,6 @@ private:
QList<QPointF> _avg; QList<QPointF> _avg;
enum Units _units;
bool _showTracks; bool _showTracks;
}; };

View File

@ -0,0 +1,26 @@
#include "tooltip.h"
#include "powergraphitem.h"
PowerGraphItem::PowerGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent) : GraphItem(graph, type, parent)
{
qreal sum = 0;
for (int j = 1; j < graph.size(); j++)
sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s());
_avg = sum/graph.last().s();
setToolTip(toolTip());
}
QString PowerGraphItem::toolTip() const
{
ToolTip tt;
tt.insert(tr("Maximum"), QString::number(max(), 'f', 1)
+ UNIT_SPACE + tr("1/min"));
tt.insert(tr("Average"), QString::number(avg(), 'f', 1)
+ UNIT_SPACE + tr("1/min"));
return tt.toString();
}

23
src/GUI/powergraphitem.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef POWERGRAPHITEM_H
#define POWERGRAPHITEM_H
#include "graphitem.h"
class PowerGraphItem : public GraphItem
{
Q_OBJECT
public:
PowerGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent = 0);
qreal max() const {return -bounds().top();}
qreal avg() const {return _avg;}
private:
QString toolTip() const;
qreal _avg;
};
#endif // POWERGRAPHITEM_H

View File

@ -1,13 +1,13 @@
#include <QPainter> #include <QPainter>
#include "data/waypoint.h"
#include "map/map.h"
#include "format.h" #include "format.h"
#include "waypoint.h"
#include "waypointitem.h" #include "waypointitem.h"
#include "tooltip.h" #include "tooltip.h"
#include "map.h"
#include "routeitem.h" #include "routeitem.h"
QString RouteItem::toolTip(Units units) QString RouteItem::toolTip(Units units) const
{ {
ToolTip tt; ToolTip tt;

View File

@ -1,8 +1,8 @@
#ifndef ROUTEITEM_H #ifndef ROUTEITEM_H
#define ROUTEITEM_H #define ROUTEITEM_H
#include "data/route.h"
#include "pathitem.h" #include "pathitem.h"
#include "route.h"
#include "units.h" #include "units.h"
class Map; class Map;
@ -14,7 +14,6 @@ class RouteItem : public PathItem
public: public:
RouteItem(const Route &route, Map *map, QGraphicsItem *parent = 0); RouteItem(const Route &route, Map *map, QGraphicsItem *parent = 0);
//void setScale(qreal scale);
void setMap(Map *map); void setMap(Map *map);
void setUnits(Units units); void setUnits(Units units);
@ -22,7 +21,7 @@ public:
void showWaypointLabels(bool show); void showWaypointLabels(bool show);
private: private:
QString toolTip(Units units); QString toolTip(Units units) const;
QString _name; QString _name;
QString _desc; QString _desc;

View File

@ -1,7 +1,7 @@
#include <cmath> #include <cmath>
#include <QPainter> #include <QPainter>
#include "config.h" #include "config.h"
#include "misc.h" #include "nicenum.h"
#include "scaleitem.h" #include "scaleitem.h"
@ -132,7 +132,7 @@ void ScaleItem::setUnits(enum Units units)
update(); update();
} }
void ScaleItem::setDigitalZoom(int zoom) void ScaleItem::setDigitalZoom(qreal zoom)
{ {
prepareGeometryChange(); prepareGeometryChange();
_digitalZoom = zoom; _digitalZoom = zoom;

View File

@ -15,7 +15,7 @@ public:
void setResolution(qreal res); void setResolution(qreal res);
void setUnits(enum Units units); void setUnits(enum Units units);
void setDigitalZoom(int zoom); void setDigitalZoom(qreal zoom);
private: private:
void updateBoundingRect(); void updateBoundingRect();
@ -28,7 +28,7 @@ private:
Units _units; Units _units;
bool _scale; bool _scale;
int _digitalZoom; qreal _digitalZoom;
QRectF _boundingRect; QRectF _boundingRect;
}; };

View File

@ -25,6 +25,8 @@
#define GRAPH_TYPE_DEFAULT Distance #define GRAPH_TYPE_DEFAULT Distance
#define SHOW_GRAPH_GRIDS_SETTING "grid" #define SHOW_GRAPH_GRIDS_SETTING "grid"
#define SHOW_GRAPH_GRIDS_DEFAULT true #define SHOW_GRAPH_GRIDS_DEFAULT true
#define SHOW_GRAPH_SLIDER_INFO_SETTING "sliderInfo"
#define SHOW_GRAPH_SLIDER_INFO_DEFAULT true
#define MAP_SETTINGS_GROUP "Map" #define MAP_SETTINGS_GROUP "Map"
#define CURRENT_MAP_SETTING "map" #define CURRENT_MAP_SETTING "map"
@ -70,12 +72,18 @@
#define EXPORT_FILENAME_SETTING "fileName" #define EXPORT_FILENAME_SETTING "fileName"
#define EXPORT_FILENAME_DEFAULT QString("%1/export.pdf"). \ #define EXPORT_FILENAME_DEFAULT QString("%1/export.pdf"). \
arg(QDir::currentPath()) arg(QDir::currentPath())
#define RESOLUTION_SETTING "resolution"
#define RESOLUTION_DEFAULT 600
#define OPTIONS_SETTINGS_GROUP "Options" #define OPTIONS_SETTINGS_GROUP "Options"
#define PALETTE_COLOR_SETTING "paletteColor" #define PALETTE_COLOR_SETTING "paletteColor"
#define PALETTE_COLOR_DEFAULT QColor(Qt::blue) #define PALETTE_COLOR_DEFAULT QColor(Qt::blue)
#define PALETTE_SHIFT_SETTING "paletteShift" #define PALETTE_SHIFT_SETTING "paletteShift"
#define PALETTE_SHIFT_DEFAULT 0.62 #define PALETTE_SHIFT_DEFAULT 0.62
#define MAP_OPACITY_SETTING "mapOpacity"
#define MAP_OPACITY_DEFAULT 100
#define BACKGROUND_COLOR_SETTING "backgroundColor"
#define BACKGROUND_COLOR_DEFAULT QColor(Qt::white)
#define TRACK_WIDTH_SETTING "trackWidth" #define TRACK_WIDTH_SETTING "trackWidth"
#define TRACK_WIDTH_DEFAULT 3 #define TRACK_WIDTH_DEFAULT 3
#define ROUTE_WIDTH_SETTING "routeWidth" #define ROUTE_WIDTH_SETTING "routeWidth"
@ -84,6 +92,14 @@
#define TRACK_STYLE_DEFAULT Qt::SolidLine #define TRACK_STYLE_DEFAULT Qt::SolidLine
#define ROUTE_STYLE_SETTING "routeStyle" #define ROUTE_STYLE_SETTING "routeStyle"
#define ROUTE_STYLE_DEFAULT Qt::DotLine #define ROUTE_STYLE_DEFAULT Qt::DotLine
#define WAYPOINT_SIZE_SETTING "waypointSize"
#define WAYPOINT_SIZE_DEFAULT 8
#define WAYPOINT_COLOR_SETTING "waypointColor"
#define WAYPOINT_COLOR_DEFAULT QColor(Qt::black)
#define POI_SIZE_SETTING "poiSize"
#define POI_SIZE_DEFAULT 8
#define POI_COLOR_SETTING "poiColor"
#define POI_COLOR_DEFAULT QColor(Qt::black)
#define GRAPH_WIDTH_SETTING "graphWidth" #define GRAPH_WIDTH_SETTING "graphWidth"
#define GRAPH_WIDTH_DEFAULT 1 #define GRAPH_WIDTH_DEFAULT 1
#define PATH_AA_SETTING "pathAntiAliasing" #define PATH_AA_SETTING "pathAntiAliasing"
@ -112,6 +128,8 @@
#define USE_OPENGL_DEFAULT false #define USE_OPENGL_DEFAULT false
#define PIXMAP_CACHE_SETTING "pixmapCache" #define PIXMAP_CACHE_SETTING "pixmapCache"
#define PIXMAP_CACHE_DEFAULT 64 /* MB */ #define PIXMAP_CACHE_DEFAULT 64 /* MB */
#define HIRES_PRINT_SETTING "hiresPrint"
#define HIRES_PRINT_DEFAULT false
#define PRINT_NAME_SETTING "printName" #define PRINT_NAME_SETTING "printName"
#define PRINT_NAME_DEFAULT true #define PRINT_NAME_DEFAULT true
#define PRINT_DATE_SETTING "printDate" #define PRINT_DATE_SETTING "printDate"
@ -126,5 +144,9 @@
#define PRINT_ITEM_COUNT_DEFAULT true #define PRINT_ITEM_COUNT_DEFAULT true
#define SEPARATE_GRAPH_PAGE_SETTING "separateGraphPage" #define SEPARATE_GRAPH_PAGE_SETTING "separateGraphPage"
#define SEPARATE_GRAPH_PAGE_DEFAULT false #define SEPARATE_GRAPH_PAGE_DEFAULT false
#define SLIDER_COLOR_SETTING "sliderColor"
#define SLIDER_COLOR_DEFAULT QColor(Qt::red)
#define ALWAYS_SHOW_MAP_SETTING "alwaysShowMap"
#define ALWAYS_SHOW_MAP_DEFAULT true
#endif // SETTINGS_H #endif // SETTINGS_H

View File

@ -0,0 +1,97 @@
#include <QPainter>
#include "config.h"
#include "sliderinfoitem.h"
#define SIZE 5
SliderInfoItem::SliderInfoItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{
_side = Right;
_color = Qt::red;
}
void SliderInfoItem::updateBoundingRect()
{
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
QFontMetrics fm(font);
qreal width = qMax(fm.width(_x), fm.width(_y));
qreal height = 2 * fm.height() - 2*fm.descent();
_boundingRect = (_side == Right)
? QRectF(-SIZE/2, -height/2, width + 1.5*SIZE, height)
: QRectF(-(width + SIZE), -height/2, width + 1.5*SIZE, height);
}
void SliderInfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem
*option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
QFontMetrics fm(font);
QRectF rx, ry;
qreal width = qMax(fm.width(_x), fm.width(_y));
if (_side == Right) {
ry = QRectF(SIZE, -fm.height() + fm.descent(), fm.width(_y),
fm.height() - fm.descent());
rx = QRectF(SIZE, 0, fm.width(_x), fm.height()
- fm.descent());
} else {
ry = QRectF(-(width + SIZE), -fm.height() + fm.descent(), fm.width(_y),
fm.height() - fm.descent());
rx = QRectF(-(width + SIZE), 0, fm.width(_x), fm.height()
- fm.descent());
}
painter->setPen(Qt::NoPen);
painter->setBrush(QBrush(QColor(255, 255, 255, 196)));
painter->drawRect(ry);
painter->drawRect(rx);
painter->setBrush(Qt::NoBrush);
painter->setFont(font);
painter->setRenderHint(QPainter::Antialiasing, false);
painter->setPen(_color);
if (_side == Right) {
painter->drawText(SIZE, -fm.descent()/2, _y);
painter->drawText(SIZE, fm.height() - fm.descent()*1.5, _x);
} else {
painter->drawText(-(width + SIZE), -fm.descent()/2, _y);
painter->drawText(-(width + SIZE), fm.height() - fm.descent()*1.5, _x);
}
painter->drawLine(QPointF(-SIZE/2, 0), QPointF(SIZE/2, 0));
//painter->drawRect(boundingRect());
}
void SliderInfoItem::setText(const QString &x, const QString &y)
{
prepareGeometryChange();
_x = x; _y = y;
updateBoundingRect();
}
void SliderInfoItem::setSide(Side side)
{
if (side == _side)
return;
prepareGeometryChange();
_side = side;
updateBoundingRect();
}
void SliderInfoItem::setColor(const QColor &color)
{
_color = color;
update();
}

View File

@ -14,15 +14,17 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget); QWidget *widget);
void setText(const QString &text); void setText(const QString &x, const QString &y);
void setSide(Side side); void setSide(Side side);
void setColor(const QColor &color);
private: private:
void updateBoundingRect(); void updateBoundingRect();
Side _side; Side _side;
QString _text; QString _x, _y;
QRectF _boundingRect; QRectF _boundingRect;
QColor _color;
}; };
#endif // SLIDERINFOITEM_H #endif // SLIDERINFOITEM_H

View File

@ -8,6 +8,8 @@ SliderItem::SliderItem(QGraphicsItem *parent) : QGraphicsObject(parent)
{ {
setFlag(ItemIsMovable); setFlag(ItemIsMovable);
setFlag(ItemSendsGeometryChanges); setFlag(ItemSendsGeometryChanges);
_color = Qt::red;
} }
QRectF SliderItem::boundingRect() const QRectF SliderItem::boundingRect() const
@ -22,7 +24,7 @@ void SliderItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
Q_UNUSED(widget); Q_UNUSED(widget);
painter->setRenderHint(QPainter::Antialiasing, false); painter->setRenderHint(QPainter::Antialiasing, false);
painter->setPen(Qt::red); painter->setPen(_color);
painter->drawLine(0, 0, 0, -_area.height()); painter->drawLine(0, 0, 0, -_area.height());
// painter->drawRect(boundingRect()); // painter->drawRect(boundingRect());
@ -59,3 +61,9 @@ void SliderItem::setArea(const QRectF &area)
prepareGeometryChange(); prepareGeometryChange();
_area = area; _area = area;
} }
void SliderItem::setColor(const QColor &color)
{
_color = color;
update();
}

View File

@ -3,6 +3,8 @@
#include <QGraphicsObject> #include <QGraphicsObject>
class QColor;
class SliderItem : public QGraphicsObject class SliderItem : public QGraphicsObject
{ {
Q_OBJECT Q_OBJECT
@ -17,6 +19,8 @@ public:
const QRectF &area() const {return _area;} const QRectF &area() const {return _area;}
void setArea(const QRectF &area); void setArea(const QRectF &area);
void setColor(const QColor &color);
void clear(); void clear();
signals: signals:
@ -27,6 +31,7 @@ protected:
private: private:
QRectF _area; QRectF _area;
QColor _color;
}; };
#endif // SLIDERITEM_H #endif // SLIDERITEM_H

View File

@ -1,15 +1,16 @@
#include "data/data.h"
#include "config.h" #include "config.h"
#include "data.h" #include "tooltip.h"
#include "speedgraphitem.h"
#include "speedgraph.h" #include "speedgraph.h"
SpeedGraph::SpeedGraph(QWidget *parent) : GraphTab(parent) SpeedGraph::SpeedGraph(QWidget *parent) : GraphTab(parent)
{ {
_units = Metric;
_timeType = Total; _timeType = Total;
_showTracks = true; _showTracks = true;
setYUnits(); setYUnits(Metric);
setYLabel(tr("Speed")); setYLabel(tr("Speed"));
setSliderPrecision(1); setSliderPrecision(1);
@ -29,18 +30,21 @@ void SpeedGraph::setInfo()
void SpeedGraph::loadData(const Data &data, const QList<PathItem *> &paths) void SpeedGraph::loadData(const Data &data, const QList<PathItem *> &paths)
{ {
for (int i = 0; i < data.tracks().count(); i++) { for (int i = 0; i < data.tracks().count(); i++) {
const Graph &graph = data.tracks().at(i)->speed(); const Track *track = data.tracks().at(i);
const Graph &graph = track->speed();
if (graph.size() < 2) { if (graph.size() < 2) {
skipColor(); skipColor();
continue; continue;
} }
_avg.append(QPointF(data.tracks().at(i)->distance(), SpeedGraphItem *gi = new SpeedGraphItem(graph, _graphType,
data.tracks().at(i)->distance() / data.tracks().at(i)->time())); track->movingTime());
_avgM.append(QPointF(data.tracks().at(i)->distance(), gi->setTimeType(_timeType);
data.tracks().at(i)->distance() / data.tracks().at(i)->movingTime())); GraphView::addGraph(gi, paths.at(i));
GraphView::loadGraph(graph, paths.at(i)); _avg.append(QPointF(track->distance(), gi->avg()));
_mavg.append(QPointF(track->distance(), gi->mavg()));
} }
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)
@ -55,7 +59,7 @@ qreal SpeedGraph::avg() const
{ {
qreal sum = 0, w = 0; qreal sum = 0, w = 0;
QList<QPointF>::const_iterator it; QList<QPointF>::const_iterator it;
const QList<QPointF> &list = (_timeType == Moving) ? _avgM : _avg; const QList<QPointF> &list = (_timeType == Moving) ? _mavg : _avg;
for (it = list.begin(); it != list.end(); it++) { for (it = list.begin(); it != list.end(); it++) {
sum += it->y() * it->x(); sum += it->y() * it->x();
@ -68,14 +72,14 @@ qreal SpeedGraph::avg() const
void SpeedGraph::clear() void SpeedGraph::clear()
{ {
_avg.clear(); _avg.clear();
_avgM.clear(); _mavg.clear();
GraphView::clear(); GraphView::clear();
} }
void SpeedGraph::setYUnits() void SpeedGraph::setYUnits(Units units)
{ {
if (_units == Metric) { if (units == Metric) {
GraphView::setYUnits(tr("km/h")); GraphView::setYUnits(tr("km/h"));
setYScale(MS2KMH); setYScale(MS2KMH);
} else { } else {
@ -84,21 +88,21 @@ void SpeedGraph::setYUnits()
} }
} }
void SpeedGraph::setUnits(enum Units units) void SpeedGraph::setUnits(Units units)
{ {
_units = units; setYUnits(units);
setYUnits();
setInfo(); setInfo();
GraphView::setUnits(units);
redraw(); GraphView::setUnits(units);
} }
void SpeedGraph::setTimeType(enum TimeType type) void SpeedGraph::setTimeType(enum TimeType type)
{ {
_timeType = type; _timeType = type;
for (int i = 0; i < _graphs.size(); i++)
static_cast<SpeedGraphItem*>(_graphs.at(i))->setTimeType(type);
setInfo(); setInfo();
redraw(); redraw();
} }

View File

@ -14,20 +14,19 @@ public:
QString label() const {return tr("Speed");} QString label() const {return tr("Speed");}
void loadData(const Data &data, const QList<PathItem *> &paths); void loadData(const Data &data, const QList<PathItem *> &paths);
void clear(); void clear();
void setUnits(enum Units units); void setUnits(Units units);
void setTimeType(enum TimeType type); void setTimeType(TimeType type);
void showTracks(bool show); void showTracks(bool show);
private: private:
qreal avg() const; qreal avg() const;
qreal max() const {return bounds().bottom();} qreal max() const {return bounds().bottom();}
void setYUnits(); void setYUnits(Units units);
void setInfo(); void setInfo();
QList<QPointF> _avg; QList<QPointF> _avg;
QList<QPointF> _avgM; QList<QPointF> _mavg;
enum Units _units;
enum TimeType _timeType; enum TimeType _timeType;
bool _showTracks; bool _showTracks;
}; };

View File

@ -0,0 +1,40 @@
#include "tooltip.h"
#include "speedgraphitem.h"
SpeedGraphItem::SpeedGraphItem(const Graph &graph, GraphType type,
qreal movingTime, QGraphicsItem *parent) : GraphItem(graph, type, parent)
{
_units = Metric;
_timeType = Total;
_avg = graph.last().s() / graph.last().t();
_mavg = graph.last().s() / movingTime;
setToolTip(toolTip());
}
QString SpeedGraphItem::toolTip() const
{
ToolTip tt;
qreal scale = (_units == Metric) ? MS2KMH : MS2MIH;
QString su = (_units == Metric) ? tr("km/h") : tr("mi/h");
tt.insert(tr("Maximum"), QString::number(max() * scale, 'f', 1)
+ UNIT_SPACE + su);
tt.insert(tr("Average"), QString::number((_timeType == Total)
? avg() * scale : mavg() * scale, 'f', 1) + UNIT_SPACE + su);
return tt.toString();
}
void SpeedGraphItem::setUnits(Units units)
{
_units = units;
setToolTip(toolTip());
}
void SpeedGraphItem::setTimeType(TimeType type)
{
_timeType = type;
setToolTip(toolTip());
}

31
src/GUI/speedgraphitem.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef SPEEDGRAPHITEM_H
#define SPEEDGRAPHITEM_H
#include "timetype.h"
#include "graphitem.h"
class SpeedGraphItem : public GraphItem
{
Q_OBJECT
public:
SpeedGraphItem(const Graph &graph, GraphType type, qreal movingTime,
QGraphicsItem *parent = 0);
qreal max() const {return -bounds().top();}
qreal avg() const {return _avg;}
qreal mavg() const {return _mavg;}
void setUnits(Units units);
void setTimeType(TimeType type);
private:
QString toolTip() const;
qreal _avg, _mavg;
Units _units;
TimeType _timeType;
};
#endif // SPEEDGRAPHITEM_H

View File

@ -1,13 +1,13 @@
#include "data.h" #include "data/data.h"
#include "temperaturegraphitem.h"
#include "temperaturegraph.h" #include "temperaturegraph.h"
TemperatureGraph::TemperatureGraph(QWidget *parent) : GraphTab(parent) TemperatureGraph::TemperatureGraph(QWidget *parent) : GraphTab(parent)
{ {
_units = Metric;
_showTracks = true; _showTracks = true;
setYUnits(); setYUnits(Metric);
setYLabel(tr("Temperature")); setYLabel(tr("Temperature"));
setSliderPrecision(1); setSliderPrecision(1);
@ -30,21 +30,16 @@ void TemperatureGraph::loadData(const Data &data, const QList<PathItem *> &paths
{ {
for (int i = 0; i < data.tracks().count(); i++) { for (int i = 0; i < data.tracks().count(); i++) {
const Graph &graph = data.tracks().at(i)->temperature(); const Graph &graph = data.tracks().at(i)->temperature();
qreal sum = 0, w = 0;
if (graph.size() < 2) { if (graph.size() < 2) {
skipColor(); skipColor();
continue; continue;
} }
for (int j = 1; j < graph.size(); j++) { TemperatureGraphItem *gi = new TemperatureGraphItem(graph, _graphType);
qreal ds = graph.at(j).s() - graph.at(j-1).s(); GraphView::addGraph(gi, paths.at(i));
sum += graph.at(j).y() * ds;
w += ds;
}
_avg.append(QPointF(data.tracks().at(i)->distance(), sum/w));
GraphView::loadGraph(graph, paths.at(i)); _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg()));
} }
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)
@ -75,9 +70,9 @@ void TemperatureGraph::clear()
GraphView::clear(); GraphView::clear();
} }
void TemperatureGraph::setYUnits() void TemperatureGraph::setYUnits(Units units)
{ {
if (_units == Metric) { if (units == Metric) {
GraphView::setYUnits(QChar(0x00B0) + tr("C")); GraphView::setYUnits(QChar(0x00B0) + tr("C"));
setYScale(1); setYScale(1);
setYOffset(0); setYOffset(0);
@ -88,15 +83,12 @@ void TemperatureGraph::setYUnits()
} }
} }
void TemperatureGraph::setUnits(enum Units units) void TemperatureGraph::setUnits(Units units)
{ {
_units = units; setYUnits(units);
setYUnits();
setInfo(); setInfo();
GraphView::setUnits(units);
redraw(); GraphView::setUnits(units);
} }
void TemperatureGraph::showTracks(bool show) void TemperatureGraph::showTracks(bool show)

View File

@ -20,12 +20,11 @@ private:
qreal avg() const; qreal avg() const;
qreal min() const {return bounds().top();} qreal min() const {return bounds().top();}
qreal max() const {return bounds().bottom();} qreal max() const {return bounds().bottom();}
void setYUnits(); void setYUnits(Units units);
void setInfo(); void setInfo();
QList<QPointF> _avg; QList<QPointF> _avg;
enum Units _units;
bool _showTracks; bool _showTracks;
}; };

View File

@ -0,0 +1,37 @@
#include "tooltip.h"
#include "temperaturegraphitem.h"
TemperatureGraphItem::TemperatureGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent) : GraphItem(graph, type, parent)
{
qreal sum = 0;
for (int j = 1; j < graph.size(); j++)
sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s());
_avg = sum/graph.last().s();
setToolTip(toolTip(Metric));
}
QString TemperatureGraphItem::toolTip(Units units) const
{
ToolTip tt;
qreal scale = (units == Metric) ? 1.0 : C2FS;
qreal offset = (units == Metric) ? 0 : C2FO;
QString su = (units == Metric) ?
QChar(0x00B0) + tr("C") : QChar(0x00B0) + tr("F");
tt.insert(tr("Average"), QString::number(avg() * scale + offset, 'f', 1)
+ UNIT_SPACE + su);
tt.insert(tr("Maximum"), QString::number(max() * scale + offset, 'f', 1)
+ UNIT_SPACE + su);
tt.insert(tr("Minimum"), QString::number(min() * scale + offset, 'f', 1)
+ UNIT_SPACE + su);
return tt.toString();
}
void TemperatureGraphItem::setUnits(Units units)
{
setToolTip(toolTip(units));
}

View File

@ -0,0 +1,26 @@
#ifndef TEMPERATUREGRAPHITEM_H
#define TEMPERATUREGRAPHITEM_H
#include "graphitem.h"
class TemperatureGraphItem : public GraphItem
{
Q_OBJECT
public:
TemperatureGraphItem(const Graph &graph, GraphType type,
QGraphicsItem *parent = 0);
qreal max() const {return -bounds().top();}
qreal min() const {return -bounds().bottom();}
qreal avg() const {return _avg;}
void setUnits(Units units);
private:
QString toolTip(Units units) const;
qreal _avg;
};
#endif // TEMPERATUREGRAPHITEM_H

View File

@ -16,11 +16,9 @@ void TrackInfo::insert(const QString &key, const QString &value)
_info->insert(key, value); _info->insert(key, value);
} }
void TrackInfo::plot(QPainter *painter, const QRectF &target) void TrackInfo::plot(QPainter *painter, const QRectF &target, qreal scale)
{ {
qreal ratio = painter->paintEngine()->paintDevice()->logicalDpiX() QSizeF canvas = QSizeF(target.width() / scale, target.height() / scale);
/ SCREEN_DPI;
QSizeF canvas = QSizeF(target.width() / ratio, target.height() / ratio);
QSizeF diff = QSizeF(qAbs(canvas.width() - sceneRect().width()), QSizeF diff = QSizeF(qAbs(canvas.width() - sceneRect().width()),
qAbs(canvas.height() - sceneRect().height())); qAbs(canvas.height() - sceneRect().height()));
QRectF adj = sceneRect().adjusted(0, -diff.height()/2, diff.width(), QRectF adj = sceneRect().adjusted(0, -diff.height()/2, diff.width(),

View File

@ -13,7 +13,7 @@ public:
TrackInfo(QObject *parent = 0); TrackInfo(QObject *parent = 0);
void insert(const QString &key, const QString &value); void insert(const QString &key, const QString &value);
void plot(QPainter *painter, const QRectF &target); void plot(QPainter *painter, const QRectF &target, qreal scale);
bool isEmpty() const; bool isEmpty() const;
QSizeF contentSize() const; QSizeF contentSize() const;

View File

@ -1,11 +1,11 @@
#include <QPainter> #include <QPainter>
#include "map/map.h"
#include "format.h" #include "format.h"
#include "tooltip.h" #include "tooltip.h"
#include "map.h"
#include "trackitem.h" #include "trackitem.h"
QString TrackItem::toolTip(Units units) QString TrackItem::toolTip(Units units) const
{ {
ToolTip tt; ToolTip tt;

Some files were not shown because too many files have changed in this diff Show More