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

Compare commits

...

349 Commits
7.21 ... 7.37

Author SHA1 Message Date
609e73256a Back to the original graph tab layout/style on OS X 2020-11-24 21:11:32 +01:00
50c43dc0b7 Merge branch 'origin/master' into Weblate. 2020-11-23 22:28:18 +01:00
b6194d535e Version++ 2020-11-23 22:28:11 +01:00
a4906050b8 Merge branch 'origin/master' into Weblate. 2020-11-23 22:26:47 +01:00
d1d0341ce5 Fixed PNG export when the file has not a ".png" extension 2020-11-23 22:26:15 +01:00
1b27be6173 Draw the graph tabs area more style aware 2020-11-23 22:20:06 +01:00
2eed9884a5 Fixed graph lines start/end exceeding the graph area 2020-11-23 22:17:19 +01:00
afee454b92 Merge branch 'origin/master' into Weblate. 2020-11-23 00:10:05 +01:00
8ade76b9f4 Improved form layout on OS X 2020-11-23 00:09:17 +01:00
45ca0f306c Merge branch 'origin/master' into Weblate. 2020-11-22 23:42:33 +01:00
faf445d708 Fixed broken label bounding box computation 2020-11-22 23:41:58 +01:00
7ed4821e81 Merge branch 'origin/master' into Weblate. 2020-11-22 14:52:06 +01:00
524a854d35 Code cleanup 2020-11-22 14:51:57 +01:00
800189cec5 Merge branch 'origin/master' into Weblate. 2020-11-22 14:39:44 +01:00
dc209bd96e Yet another graph zoom improvement
(and yet not ideal...)
2020-11-22 14:38:52 +01:00
d71b9f5e19 Merge branch 'origin/master' into Weblate. 2020-11-21 20:38:49 +01:00
781bc8c38f Improved graph zooming
(however, still not perfect...)
2020-11-21 20:37:22 +01:00
a49c2cd7c2 Merge branch 'origin/master' into Weblate. 2020-11-19 21:48:55 +01:00
75bd542feb A more sane (and usefull) angular units compare 2020-11-19 21:47:45 +01:00
c43a68c3b0 Inform about the whole parameter combination that failed to load 2020-11-19 21:46:25 +01:00
d211371ed0 Translated using Weblate (Hungarian)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-11-18 10:29:05 +01:00
eaed49786a Merge branch 'origin/master' into Weblate. 2020-11-15 22:38:30 +01:00
baf574b68b Process all the ll2xy operations in parallel 2020-11-15 22:38:22 +01:00
f4561ba0b5 Merge branch 'origin/master' into Weblate. 2020-11-15 20:10:15 +01:00
c120ad9715 Translated using Weblate (Ukrainian)
Currently translated at 99.7% (375 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-11-15 20:10:15 +01:00
0f49beeff5 Translated using Weblate (Turkish)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-11-15 20:10:15 +01:00
f2bfd5711b Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.7% (375 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-11-15 20:10:14 +01:00
3d43a0e472 Translated using Weblate (Russian)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-11-15 20:10:14 +01:00
049ca264b2 Translated using Weblate (Finnish)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-11-15 20:10:14 +01:00
3635a7dfdc Specified GPL license version 2020-11-15 20:10:08 +01:00
2ae572ba88 Translated using Weblate (Swedish)
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-11-15 19:12:20 +01:00
5fac30c962 Localization update 2020-11-15 12:26:53 +01:00
4e29801d9a Explicitly specify the NIMA source code based files 2020-11-14 22:36:17 +01:00
0ace6da8a3 Fixed Qt4 build 2020-11-13 23:43:52 +01:00
cfcaa72cd2 Added licenses info 2020-11-13 23:00:30 +01:00
1b1f706c5c Added R-tree implementation info/license 2020-11-13 22:45:29 +01:00
b4d240d8fe Added "copy coordinates to clipboard"
closes #291
2020-11-13 20:15:17 +01:00
ed9ebfffac Use the propper type in friend declaration 2020-11-11 23:15:12 +01:00
fa03ecd419 Use the propper array delete operator 2020-11-11 18:47:34 +01:00
609202fe57 Fixed broken QObject parenting 2020-11-11 18:46:26 +01:00
f55d6d8501 API cleanup 2020-11-10 20:14:59 +01:00
731b309ac9 Remove the special timestamps check from the FIT parser
(Use the common logic in the Track class instead)
2020-11-10 20:07:46 +01:00
f85977d881 Merge branch 'origin/master' into Weblate. 2020-11-10 01:04:34 +01:00
12e395270b Version++ 2020-11-10 01:04:28 +01:00
45b637ba17 Merge branch 'origin/master' into Weblate. 2020-11-10 00:58:58 +01:00
f139d33502 Huffman encoded labels
+ more or less related fixes/refactoring
2020-11-10 00:58:19 +01:00
63e7735abe Translated using Weblate (French)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fr/
2020-11-03 15:20:23 +01:00
27122f94ef Merge branch 'origin/master' into Weblate. 2020-11-02 20:16:38 +01:00
0644bb72a0 Broken subdivs are more common than one would expect... 2020-11-02 20:16:02 +01:00
a4d14511de Merge branch 'origin/master' into Weblate. 2020-11-02 00:19:09 +01:00
1225d350d4 Allow broken subdiv bounds produced by mkgmap 2020-11-02 00:18:27 +01:00
a1d93cc548 Merge branch 'origin/master' into Weblate. 2020-11-01 23:48:14 +01:00
80f5bbfbce Print a warning on invalid subdiv bounds 2020-11-01 23:47:44 +01:00
70c9431ee4 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-10-28 14:26:59 +01:00
de7664ccc7 Added PNG export info 2020-10-28 12:15:46 +01:00
9bd79a4104 Fixed broken tile bounds 2020-10-27 20:52:29 +01:00
f9abf21e6d Fixed warious bounds wrapping issues 2020-10-27 16:46:09 +01:00
fb4af33d89 Version++ 2020-10-27 11:49:07 +01:00
9eb95daf09 Translated using Weblate (Russian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-10-24 01:05:33 +02:00
d291e55bdb Fixed label pointer parsing 2020-10-22 20:32:12 +02:00
b5893cf506 Fixed label text parsing
(use only space as whitespace separator)
2020-10-22 20:30:11 +02:00
8507fe3b52 Added missing collision detection 2020-10-22 01:16:23 +02:00
79edd6e09d Fixed missing reference 2020-10-21 21:21:35 +02:00
491c6c9a98 Do not let the OS rescale(blur) the windows installer 2020-10-21 21:19:15 +02:00
3c36db9f5a Use antialiased graphs as the default 2020-10-21 21:18:26 +02:00
c4a750f5d4 Merge branch 'origin/master' into Weblate. 2020-10-17 21:00:43 +02:00
e4d7f45103 Remove the right item from the list 2020-10-17 20:59:58 +02:00
c85b90d56d Merge branch 'origin/master' into Weblate. 2020-10-17 14:30:20 +02:00
7babf734bf Fixed memory leak 2020-10-17 14:30:06 +02:00
25ac235414 Merge branch 'origin/master' into Weblate. 2020-10-17 14:27:33 +02:00
630a5cea83 Improved polygon labels layout logic 2020-10-17 14:26:59 +02:00
a0de7f25c3 Merge branch 'origin/master' into Weblate. 2020-10-16 22:46:13 +02:00
7c6174a8ee Some more IMG POI style tweaking 2020-10-16 22:45:51 +02:00
0f512d1269 Merge branch 'origin/master' into Weblate. 2020-10-16 00:04:02 +02:00
246b46ffcb Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.7% (373 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-10-16 00:04:02 +02:00
cc4cbcbeda Various IMG style enchancements 2020-10-16 00:03:26 +02:00
64e0b492e6 Merge branch 'origin/master' into Weblate. 2020-10-14 22:06:05 +02:00
52a8b1de5b Cosmetics 2020-10-14 22:05:48 +02:00
5045c03953 Merge branch 'origin/master' into Weblate. 2020-10-14 22:04:52 +02:00
515f1aeb27 Use propper structure names 2020-10-14 22:04:32 +02:00
dbb82d6f44 Translated using Weblate (Ukrainian)
Currently translated at 98.6% (369 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-10-13 03:39:03 +02:00
307a03d46c Translated using Weblate (Finnish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-10-13 03:39:02 +02:00
b7c03b4b9e Merge branch 'origin/master' into Weblate. 2020-10-12 21:18:14 +02:00
2d1e0934ce Silenced clang indentation warning 2020-10-12 21:17:18 +02:00
0ff66bc897 Merge branch 'origin/master' into Weblate. 2020-10-12 20:05:30 +02:00
3b68f497fe Fixed ODR (One Definition Rule) violation 2020-10-12 20:05:17 +02:00
a04293b411 Merge branch 'origin/master' into Weblate. 2020-10-11 21:35:42 +02:00
5a4de1cef0 Accept case insensitive authorities names 2020-10-11 21:33:19 +02:00
99d3d8fd0a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-10-10 15:26:41 +02:00
d579ce3482 Translated using Weblate (Russian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-10-09 05:22:55 +02:00
67ce176b74 Version++ 2020-10-09 05:12:19 +02:00
1a88527c60 Fixed icon paths 2020-10-08 23:16:09 +02:00
9d6a2cce45 Merge branch 'origin/master' into Weblate. 2020-10-07 22:57:53 +02:00
7a5f67790e Translated using Weblate (Hungarian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-10-07 22:57:53 +02:00
704c66449f Fixed shorcuts duplicity 2020-10-07 22:57:30 +02:00
42e1331678 Merge branch 'origin/master' into Weblate. 2020-10-07 09:04:54 +02:00
ad3b666a19 Code cleanup 2020-10-07 09:04:40 +02:00
3dd253828e Merge branch 'origin/master' into Weblate. 2020-10-07 08:57:48 +02:00
bb5e50b009 Translated using Weblate (Swedish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-10-07 08:57:48 +02:00
69384ca315 Some more Export dialogs polishing 2020-10-07 08:57:24 +02:00
676c82b7a4 Merge branch 'origin/master' into Weblate. 2020-10-07 00:23:48 +02:00
5a2be6ff07 Translated using Weblate (Turkish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-10-07 00:23:48 +02:00
454e725587 Layout polishing 2020-10-07 00:23:24 +02:00
b9d9ab85b2 Merge branch 'origin/master' into Weblate. 2020-10-06 22:12:52 +02:00
15a2df12bd Localization update 2020-10-06 22:12:35 +02:00
db7a75088a Merge branch 'origin/master' into Weblate. 2020-10-06 22:03:15 +02:00
378da395fb Fixed margins operators + print margins now in cm 2020-10-06 22:02:26 +02:00
da7d0fe32d Merge branch 'origin/master' into Weblate. 2020-10-06 21:42:09 +02:00
789f314ae8 Margins widget refactoring 2020-10-06 21:41:23 +02:00
0986864c6c Translated using Weblate (Russian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-10-06 14:26:41 +02:00
83ac0b5ed7 Translated using Weblate (Finnish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-10-06 14:26:41 +02:00
a1be73fbba Use the propper spin box widget 2020-10-04 22:37:24 +02:00
7761935c29 Translated using Weblate (Hungarian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-10-03 23:41:01 +02:00
4da0e8a1c7 Translated using Weblate (Turkish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-10-03 23:41:01 +02:00
066736b3d2 Translated using Weblate (Swedish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-10-03 23:41:01 +02:00
fdcbc4c6c2 Polished czech translation 2020-10-02 09:36:42 +02:00
b894df26d3 Added missing localization 2020-10-02 09:35:05 +02:00
5a5c0ef68a Localization update 2020-10-02 09:13:49 +02:00
56b7014eaf Unify unsupported data handling 2020-09-29 22:03:26 +02:00
1f52dad1c6 Fixed PNG export layout 2020-09-29 19:49:33 +02:00
0f8859dd20 Code cleanup 2020-09-29 18:53:49 +02:00
398eb152f6 Version++ 2020-09-29 00:04:42 +02:00
38ab835898 Translated using Weblate (Hungarian)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-09-28 20:41:10 +02:00
927740a196 Translated using Weblate (Ukrainian)
Currently translated at 98.9% (369 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-09-28 20:41:10 +02:00
4d8b7aa8ae Translated using Weblate (Turkish)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-09-28 20:41:09 +02:00
49c94d34b3 Translated using Weblate (Norwegian Bokmål)
Currently translated at 92.2% (344 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-09-28 20:41:09 +02:00
5c2ac54bb4 Translated using Weblate (Russian)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-09-28 20:41:09 +02:00
003947263f Translated using Weblate (Finnish)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-09-28 20:41:08 +02:00
6a70e5ea00 Fixed map plot logic 2020-09-27 22:52:04 +02:00
e83be4d553 Fixed/tweaked export output layout 2020-09-27 22:36:08 +02:00
ce38077281 Translated using Weblate (Russian)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-09-27 20:18:12 +02:00
e75a2882a5 Translated using Weblate (Russian)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-09-27 20:18:12 +02:00
8add7b428f Translated using Weblate (Swedish)
Currently translated at 100.0% (373 of 373 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-09-27 06:32:52 +02:00
846f864bd4 Merge branch 'origin/master' into Weblate. 2020-09-27 00:49:06 +02:00
8683254155 Translations update 2020-09-27 00:48:53 +02:00
ef2ffd9fc4 Merge branch 'origin/master' into Weblate. 2020-09-27 00:34:53 +02:00
a9c86fd580 Added PNG export 2020-09-27 00:34:38 +02:00
fe360a2578 Merge branch 'origin/master' into Weblate. 2020-09-26 19:05:50 +02:00
a09a58eece Some more code cleanup 2020-09-26 19:05:35 +02:00
abd1817d83 Merge branch 'origin/master' into Weblate. 2020-09-26 18:56:43 +02:00
7c90174751 Cosmetics 2020-09-26 18:56:26 +02:00
b24f27cf79 Merge branch 'origin/master' into Weblate. 2020-09-26 16:12:41 +02:00
98f88db3cf Properly align the NOD file structure 2020-09-26 16:12:10 +02:00
f2ddfa6fb7 Merge branch 'origin/master' into Weblate. 2020-09-26 16:02:46 +02:00
54ed0ca9f6 Fixed/improved error handling 2020-09-26 16:02:14 +02:00
477b32f444 Merge branch 'origin/master' into Weblate. 2020-09-26 12:24:06 +02:00
1fb6aad50f A better segment copy 2020-09-26 12:23:41 +02:00
4fa9aac917 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-09-24 09:40:58 +02:00
03db87535a Translated using Weblate (Russian)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-09-24 09:40:57 +02:00
92145c8445 Translated using Weblate (Finnish)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-09-24 09:40:57 +02:00
5e8479707b Translated using Weblate (Hungarian)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-09-22 12:39:53 +02:00
2039105ba5 Translated using Weblate (Swedish)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-09-21 06:57:20 +02:00
2605e1abeb Translated using Weblate (Czech)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2020-09-20 23:24:26 +02:00
8fd17badda Merge branch 'origin/master' into Weblate. 2020-09-20 23:05:55 +02:00
7d62ef038c Version++ 2020-09-20 23:05:38 +02:00
138e0e9505 Merge branch 'origin/master' into Weblate. 2020-09-20 22:32:56 +02:00
5dffb2714b Translated using Weblate (Turkish)
Currently translated at 100.0% (360 of 360 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-09-20 22:32:55 +02:00
5d8330a68a Use a Qt<5.5 compatible vector append 2020-09-20 22:31:56 +02:00
ff30163175 Merge branch 'origin/master' into Weblate. 2020-09-20 22:19:21 +02:00
743fb20a95 Localization update 2020-09-20 22:19:05 +02:00
50f483663c Added configurable segments usage 2020-09-20 22:18:35 +02:00
96997ffa35 Merge branch 'origin/master' into Weblate. 2020-09-18 20:57:49 +02:00
d738ad7b5a Level 0 2020-09-18 20:56:00 +02:00
01d69a4f2a Merge branch 'origin/master' into Weblate. 2020-09-14 16:34:15 +02:00
0e026d6a96 Properly parse TCX trackpoint extensions 2020-09-14 16:33:44 +02:00
07825e5701 Merge branch 'origin/master' into Weblate. 2020-08-30 20:39:45 +02:00
03e7d092c4 Code cleanup 2020-08-26 18:20:15 +02:00
0b5d01a1f6 A little bit more sane subfile interface 2020-08-26 17:58:21 +02:00
08aa087f61 Translated using Weblate (Polish)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pl/
2020-07-23 19:41:57 +02:00
6604f85f4a Translated using Weblate (Polish)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pl/
2020-07-23 19:41:56 +02:00
5343a1a922 "multi-size" app icons on linux
+ icon structure cleanup
2020-07-10 00:57:31 +02:00
d6e0757364 Fixed object interconnection 2020-07-06 23:19:42 +02:00
51becc4bf1 Dummy non-class callback functions are not needed 2020-07-02 23:51:15 +02:00
29a821f8b2 Code cleanup 2020-07-02 00:17:41 +02:00
14f4dead76 Merge branch 'origin/master' into Weblate. 2020-06-29 23:46:00 +02:00
96bb3bbdbb Removed obsolete stuff 2020-06-29 23:46:06 +02:00
22d18b6d4e Merge branch 'origin/master' into Weblate. 2020-06-28 21:02:09 +02:00
c1b79217a9 Update gpxsee_en.ts (#296) 2020-06-28 21:02:05 +02:00
e67a14b072 Merge branch 'origin/master' into Weblate. 2020-06-28 19:52:37 +02:00
473d03cf1f Fixed broken extended objects segment fetching 2020-06-28 19:51:59 +02:00
a339706293 Version++ 2020-06-27 22:51:53 +02:00
39c414ca73 Merge branch 'origin/master' into Weblate. 2020-06-27 22:51:44 +02:00
c59d60faed Merge branch 'origin/master' into Weblate. 2020-06-27 22:50:15 +02:00
32d3eab10e Initial (and partial) IMG links support
+ various IMG fixes (RGN parsing, IMG parsing)
2020-06-27 22:46:26 +02:00
e7729e8745 Added missing Italian localization stuff 2020-06-27 18:05:50 +02:00
bf145c9eb5 Merge branch 'origin/master' into Weblate. 2020-06-27 18:05:48 +02:00
de0a6b0397 Merge branch 'origin/master' into Weblate. 2020-06-27 18:00:07 +02:00
8cf89a580f Removed Arabic translation stub as noone is evidently gona use it despite
the Weblate request...
2020-06-27 17:59:15 +02:00
152e2a8a09 Merge branch 'origin/master' into Weblate. 2020-06-27 17:57:23 +02:00
6b860fe18c added italian translation (#295)
Added italian translation
2020-06-27 17:57:18 +02:00
95f138f5f0 Translated using Weblate (German)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2020-06-11 13:41:42 +02:00
1fc4dbbb73 Cosmetics 2020-05-30 17:10:13 +02:00
0999cdcba2 Fixed Qt version with time zones support
+ reverted broken Qt version check for opengl
2020-05-30 17:06:06 +02:00
cc16c9e79b Merge branch 'origin/master' into Weblate. 2020-05-30 14:20:58 +02:00
1990c85fd7 Updated Antarctica map URL 2020-05-30 14:20:20 +02:00
58f70fa833 Merge branch 'origin/master' into Weblate. 2020-05-30 14:00:01 +02:00
0f6c50d588 Added missing support for nested KML Documents 2020-05-30 13:59:34 +02:00
89dce5152e Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-05-29 01:41:40 +02:00
8bce6a44ed Translated using Weblate (French)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fr/
2020-05-29 01:41:40 +02:00
59ecd3fdf0 Translated using Weblate (Turkish)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-05-26 12:41:37 +02:00
a10c729e52 Merge branch 'origin/master' into Weblate. 2020-05-21 20:07:40 +02:00
369601f102 Translated using Weblate (Hungarian)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-05-21 20:07:39 +02:00
47d0feeb46 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-05-21 20:07:39 +02:00
58a0acc718 Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.4% (357 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-05-21 20:07:39 +02:00
c466527625 Translated using Weblate (Russian)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-05-21 20:07:38 +02:00
9cd00075c7 Translated using Weblate (Finnish)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-05-21 20:07:38 +02:00
6f72d46d6c Merge branch 'master' of github.com:tumic0/GPXSee 2020-05-21 20:07:29 +02:00
54467e6d45 Fixed build with Qt < 5.2 2020-05-21 20:06:49 +02:00
3d2e33361d Merge branch 'origin/master' into Weblate. 2020-05-20 23:56:01 +02:00
f91df0d026 Translated using Weblate (Swedish)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-05-20 23:56:01 +02:00
9bd004359d Fixed OS X build 2020-05-20 23:45:06 +02:00
e170f92e79 Translated using Weblate (Czech)
Currently translated at 100.0% (359 of 359 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2020-05-20 21:13:48 +02:00
0fb5d8dae6 Czech translation 2020-05-20 21:10:32 +02:00
5ff931bb5e Localization update 2020-05-20 21:02:33 +02:00
5bd744a8ed Added time zone settings 2020-05-20 21:00:36 +02:00
035883aab2 Added github FUNDING.yml file 2020-05-03 11:26:43 +02:00
571ed087e3 Back to the original modified Z-score treshold (5) 2020-05-02 20:44:24 +02:00
c461b2e549 Added support for non-standard 8-parts CRSs 2020-05-02 09:48:30 +02:00
26b5411465 Version++ 2020-04-30 21:48:07 +02:00
8965f450ce 32 layers ought to be enough for anybody 2020-04-30 21:46:41 +02:00
a958544667 Added support for IMG maps overlays 2020-04-26 15:46:42 +02:00
ddf865834a Remove unused consructor 2020-04-26 02:01:25 +02:00
a4abed8f1f Code cleanup 2020-04-26 01:17:54 +02:00
56061c93cb Merge branch 'origin/master' into Weblate. 2020-04-22 22:31:14 +02:00
7385b08262 Added Arabic translations file stub 2020-04-22 22:30:45 +02:00
9d79bd9a9d Merge branch 'origin/master' into Weblate. 2020-04-22 00:47:40 +02:00
159e5aeae9 Fixed error handling 2020-04-22 00:47:12 +02:00
d8beaed876 Merge branch 'origin/master' into Weblate. 2020-04-21 23:28:08 +02:00
c1584f30d2 Limit the map bounds properly based on projection, not a magic height 2020-04-21 23:26:35 +02:00
efcefe8fec Merge branch 'origin/master' into Weblate. 2020-04-19 14:52:45 +02:00
cbe312d9c8 Version++ 2020-04-19 14:52:40 +02:00
5322ee96c8 Merge branch 'origin/master' into Weblate. 2020-04-19 11:36:41 +02:00
08334d7fde Move the world maps bounds limit hack to the propper place 2020-04-19 11:36:17 +02:00
51d4e04343 Merge branch 'origin/master' into Weblate. 2020-04-18 00:01:28 +02:00
33bbd6a592 Yet another special case 2020-04-18 00:00:48 +02:00
0f96bc602c Merge branch 'origin/master' into Weblate. 2020-04-15 22:48:54 +02:00
7811527239 Rather show less road shields than more 2020-04-15 22:48:28 +02:00
31da4e1906 Some more default IMG style tweaking 2020-04-15 22:48:02 +02:00
cb6a82a10a Merge branch 'origin/master' into Weblate. 2020-04-09 10:17:58 +02:00
652cbd7c11 Fixed Qt4 build 2020-04-09 10:17:30 +02:00
ff0711c620 Merge branch 'origin/master' into Weblate. 2020-04-08 22:28:54 +02:00
eb0ff84379 Code cleanup 2020-04-08 22:28:35 +02:00
74775b2c62 Merge branch 'origin/master' into Weblate. 2020-04-08 00:55:02 +02:00
6ee3a8ea8d Added support for FIT course points 2020-04-08 00:54:35 +02:00
ee3d43e249 A slightly darker white 2020-04-08 00:00:43 +02:00
a6fbae38b8 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-04-07 15:09:42 +02:00
242babb741 Improved default IMG style
("less green")
2020-04-07 00:54:31 +02:00
e26d1abd5a Version++ 2020-04-05 10:50:24 +02:00
e80d16bec5 Merge branch 'origin/master' into Weblate. 2020-04-05 10:39:16 +02:00
412ae74bfa Fixed broken map enable condition
(falsly enabled map can crash)
2020-04-05 10:38:16 +02:00
1c472e47b9 Translated using Weblate (Hungarian)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-04-04 20:09:37 +02:00
4a725375e2 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-04-02 12:09:36 +02:00
383a196414 Translated using Weblate (Russian)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-04-02 12:09:36 +02:00
f05b51efa6 Translated using Weblate (Finnish)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-04-02 12:09:36 +02:00
a56c02953f Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.4% (354 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-03-29 20:05:00 +02:00
00d3849e4f Translated using Weblate (French)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fr/
2020-03-29 20:05:00 +02:00
c9244c0684 Fixed broken graph color change when secondary graphs present 2020-03-28 23:28:39 +01:00
d94938261a Version++ 2020-03-28 19:50:39 +01:00
d5fc06d9d1 Fixed remaining qWarning() format warning 2020-03-28 19:15:03 +01:00
9e7ebe930e Do not rescale the map on tile cache reload
(we do not reload the map parameters any more)
2020-03-28 16:12:15 +01:00
19bc509043 Merge remote-tracking branch 'weblate/master' 2020-03-27 23:30:44 +01:00
335794ee21 Translated using Weblate (German)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2020-03-27 23:10:10 +01:00
2404107d87 Translated using Weblate (German)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2020-03-27 23:10:09 +01:00
9447addd19 German translation 2020-03-27 23:09:43 +01:00
b1647d944c Silenced clang warnings 2020-03-27 23:09:13 +01:00
77ac919b83 Fixed broken error path reporting 2020-03-27 23:03:11 +01:00
4d652aeaff Merge branch 'origin/master' into Weblate. 2020-03-27 20:48:18 +01:00
3ef2361523 Removed obsolete stuff 2020-03-27 20:47:45 +01:00
e2b1c2c778 Merge branch 'origin/master' into Weblate. 2020-03-27 00:12:15 +01:00
1f5ecdfc38 Use a unicode character constant that works on all OSs (Windows) 2020-03-27 00:11:12 +01:00
c55b4f1217 Translated using Weblate (Swedish)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-03-26 18:47:50 +01:00
fd71a4c7ce Translated using Weblate (Czech)
Currently translated at 100.0% (356 of 356 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2020-03-26 18:47:49 +01:00
0b6b09f226 Merge branch 'origin/master' into Weblate. 2020-03-25 23:33:35 +01:00
517ca89814 Localization update 2020-03-25 23:33:12 +01:00
455ec3a54b Merge branch 'origin/master' into Weblate. 2020-03-25 23:20:03 +01:00
8cb8d97ee2 Use the standard value of 3.5 in the outlier test 2020-03-25 23:19:30 +01:00
40e520d3bf Merge branch 'origin/master' into Weblate. 2020-03-25 23:12:37 +01:00
6b75442312 Removed obsolete code 2020-03-25 23:12:21 +01:00
cbc5b2466e Merge branch 'origin/master' into Weblate. 2020-03-25 23:10:04 +01:00
19a847c7d4 Enable simultaneous display of GPS and DEM data 2020-03-25 23:08:26 +01:00
f9e5cb206f Merge branch 'origin/master' into Weblate. 2020-03-24 22:06:34 +01:00
441c738d0f Allow IGC files with an A header of size 6 2020-03-24 22:06:03 +01:00
0bf6d41de6 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (354 of 354 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-03-23 04:48:54 +01:00
b7869e985d Translated using Weblate (Russian)
Currently translated at 100.0% (354 of 354 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-03-18 16:45:24 +01:00
5152d5eb0b Translated using Weblate (Ukrainian)
Currently translated at 100.0% (354 of 354 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-03-18 16:45:23 +01:00
c0653ab0a8 Translated using Weblate (Finnish)
Currently translated at 100.0% (354 of 354 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-03-18 16:45:22 +01:00
41d27cabe2 Translated using Weblate (Swedish)
Currently translated at 100.0% (354 of 354 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-03-18 16:45:12 +01:00
e2f2e9700f Localization update 2020-03-17 21:13:21 +01:00
654bfcd058 Version++ 2020-03-17 21:10:45 +01:00
82c0c1f8a7 Asynchronous WMS/WMTS map loading
(also fixes crash on OS X)
2020-03-17 21:06:51 +01:00
9ce6e16b60 Fixed graph axis ticks when range < min range and units != m
Fixes #278
2020-03-14 23:55:57 +01:00
98cd3c3922 Merge branch 'master' of https://github.com/tumic0/GPXSee 2020-03-12 09:37:55 +01:00
a776f1d30e Added missing button group on OS X
fixes #276
2020-03-12 09:36:23 +01:00
aea17c9fed Added support for GPX comments (cmt tag)
Closes #272
2020-03-09 20:04:13 +01:00
23c18d4acd Optimization 2020-03-07 19:24:39 +01:00
eb8fc7b540 Merge branch 'origin/master' into Weblate. 2020-03-04 19:49:27 +01:00
bf0dd1b24a Version++ 2020-03-04 19:49:11 +01:00
9b687bb830 Merge branch 'origin/master' into Weblate. 2020-03-04 19:48:15 +01:00
9859608115 Added missing support for URLs defined in OnlineResources 2020-03-04 19:47:23 +01:00
3d66b2fbb6 Merge branch 'origin/master' into Weblate. 2020-03-03 09:39:27 +01:00
9f62b7114e The service parameter is expected in the GetMap request by some servers
(The WMS specification is not 100% clear here)
2020-03-03 09:38:18 +01:00
c8f7e6f691 Merge branch 'origin/master' into Weblate. 2020-03-03 09:29:47 +01:00
c85f404d28 Enable specifiing of format parameters 2020-03-03 09:29:16 +01:00
273a0f0f27 Merge branch 'origin/master' into Weblate. 2020-03-01 14:39:44 +01:00
bb6d6a4044 Version++ 2020-03-01 14:39:40 +01:00
bd3a3b90bc Merge branch 'origin/master' into Weblate. 2020-03-01 13:59:42 +01:00
521369a6ec Make the WMS tile size configurable 2020-03-01 13:59:15 +01:00
440a5736f6 Merge branch 'origin/master' into Weblate. 2020-03-01 13:26:52 +01:00
45a6cdeda0 Strip the format parameters for format comparsion 2020-03-01 13:26:19 +01:00
f73c27c39c Merge branch 'origin/master' into Weblate. 2020-03-01 11:46:52 +01:00
12827edcb2 Removed obsolete include 2020-03-01 11:46:44 +01:00
3ec5c37fd5 Merge branch 'origin/master' into Weblate. 2020-03-01 11:43:41 +01:00
ee24bd54f1 Fixed tile cache reload issues 2020-03-01 11:43:08 +01:00
cc22df3bf2 Cosmetics 2020-03-01 10:30:00 +01:00
ef017edbf6 Merge branch 'origin/master' into Weblate. 2020-02-29 21:40:28 +01:00
d7f0cda4b2 Properly parse the ScaleHint tag 2020-02-29 21:40:13 +01:00
dc03ab91d6 Merge branch 'origin/master' into Weblate. 2020-02-29 20:12:26 +01:00
a898ff2807 Use 72dpi in the ScaleHint to scaleDenominator transformation 2020-02-29 20:11:49 +01:00
497017091f Merge branch 'origin/master' into Weblate. 2020-02-29 13:48:19 +01:00
9dd4e117f6 Added missing WMS 1.1 ScaleHint handling 2020-02-29 13:47:27 +01:00
86535021aa Merge branch 'origin/master' into Weblate. 2020-02-23 12:45:59 +01:00
92deaaaf2b Use the latest xmlns 2020-02-23 12:45:36 +01:00
86a943d143 Translated using Weblate (Polish)
Currently translated at 98.5% (346 of 351 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pl/
2020-02-20 12:42:26 +01:00
015a9187a0 Fixed memory leak
(formal only, the data is allocated during the whole application life anyway)
2020-02-20 09:02:01 +01:00
1de9c6ef5d Version++ 2020-02-17 20:19:11 +01:00
54b6225c6c Fixed "rect inversion" problems 2020-02-17 19:23:36 +01:00
48c7299ba6 Improved railroad lines default style 2020-02-17 19:21:36 +01:00
c284b9fa7c Back to lon, lat order to not correspond with all the APIs 2020-02-17 19:20:18 +01:00
2c503a2406 Enable world basemap projection in web mercator projection 2020-02-17 09:47:47 +01:00
27edc4d6b5 Properly handle IMG basemaps (gmapbmap.img) 2020-02-17 09:19:15 +01:00
f333a76ef7 Some more regions/countries rendering improvement 2020-02-16 20:31:09 +01:00
2c114f43c5 Code cleanup 2020-02-16 15:59:51 +01:00
29e29591f8 Fixed typo 2020-02-16 13:59:19 +01:00
e4ac9fda0e Improved country names labels handling 2020-02-16 12:57:40 +01:00
26229e5871 Fixed tile bounds exceeding map bounds 2020-02-16 08:43:37 +01:00
64bee2f2f4 Use a beter default min zoom value 2020-02-15 21:58:29 +01:00
e4288ee95c Remove devel code 2020-02-15 21:51:47 +01:00
c9b3c2eedd Compute the min map zoom from the tiles 2020-02-15 21:49:00 +01:00
42e4b0769f Fixed broken tile/subdivs/polygon bounds/coordinates
+ do the coordinates left shift in a C++ standard defined way
2020-02-15 11:46:16 +01:00
ce043ef8fa Do not try to open the user style file when it is not set 2020-02-14 20:00:42 +01:00
8c7050e273 Fixed broken subdiv bounds 2020-02-14 09:20:10 +01:00
d670107a11 Fixed gap between the basemap and normal map tiles on some maps 2020-02-13 22:49:15 +01:00
7b03c4d852 Fixed error handling 2020-02-13 22:48:47 +01:00
2002b828dd Version++ 2020-02-12 20:35:59 +01:00
71f0e1d0ac Cleanup the data loading code 2020-02-12 20:33:23 +01:00
eb9767f2dd Cleanup the map loading code 2020-02-12 20:32:57 +01:00
8d06ab6208 Enable loading of GMAP maps when Garmin BaseCamp has associated them 2020-02-12 09:37:03 +01:00
187cb77858 Added missing Hungarian localization copy 2020-02-12 08:36:56 +01:00
8167a995f6 Added GMAP support info 2020-02-11 23:31:51 +01:00
217 changed files with 15538 additions and 7933 deletions

View File

@ -1,4 +1,4 @@
version: 7.21.{build}
version: 7.37.{build}
configuration:
- Release

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
github: tumic0

View File

@ -4,12 +4,12 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common G
## Features
* Opens GPX, TCX, FIT, KML, NMEA, IGC, CUP, SIGMA SLF, Suunto SML, LOC, GeoJSON, OziExplorer (PLT, RTE, WPT), Garmin GPI&CSV and geotagged JPEG files.
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS, QuadTiles).
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, Garmin IMG & JNX maps, TwoNav RMaps, GeoTIFF images).
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, Garmin IMG/GMAP & JNX maps, TwoNav RMaps, GeoTIFF images).
* Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts graphs.
* Support for DEM files (SRTM HGT).
* Support for multiple tracks in one view.
* Support for POI files.
* Print/export to PDF.
* Print/export to PDF/PNG.
* Full-screen mode.
* HiDPI/Retina displays & maps support.
* Native GUI for Windows, Mac OS X and Linux.
@ -43,3 +43,14 @@ make # nmake on windows
## Translations
GPXSee uses [Weblate](https://hosted.weblate.org/projects/gpxsee/translations/) for translations.
## License
GPXSee is licensed under GPL-3.0 (only). However, some 3rd party parts are using different, GPL compatible,
licenses:
* [Oxygen icons](icons/GUI) - LGPLv3
* [Mapbox Maki icons](icons/POI) - CC0
* [RTree implementation](src/common/rtree.h) - Public domain
* [Albers](src/map/albersequal.cpp), [Geocentric](src/map/geocentric.cpp), [LCC](src/map/lambertconic.cpp),
[Mercator](src/map/mercator.cpp), [Polar Stereographic](src/map/polarstereographic.cpp)
and [Transverse Mercator](src/map/transversemercator.cpp) projections - NIMA Source Code Disclaimer
* [Projection parameters CSV files](pkg/csv) - BSD/EPSG/Public domain

View File

@ -3,7 +3,7 @@ unix:!macx {
} else {
TARGET = GPXSee
}
VERSION = 7.21
VERSION = 7.37
QT += core \
gui \
@ -19,7 +19,10 @@ equals(QT_MAJOR_VERSION, 5) : lessThan(QT_MINOR_VERSION, 4) {QT += opengl}
INCLUDEPATH += ./src
HEADERS += src/common/config.h \
src/GUI/axislabelitem.h \
src/GUI/graphicsscene.h \
src/GUI/mapaction.h \
src/GUI/marginswidget.h \
src/GUI/popup.h \
src/common/garmin.h \
src/common/staticassert.h \
@ -52,7 +55,6 @@ HEADERS += src/common/config.h \
src/GUI/palette.h \
src/GUI/heartrategraph.h \
src/GUI/trackinfo.h \
src/GUI/exportdialog.h \
src/GUI/fileselectwidget.h \
src/GUI/margins.h \
src/GUI/temperaturegraph.h \
@ -92,9 +94,13 @@ HEADERS += src/common/config.h \
src/map/IMG/bitstream.h \
src/map/IMG/deltastream.h \
src/map/IMG/gmap.h \
src/map/IMG/huffmanbuffer.h \
src/map/IMG/huffmanstream.h \
src/map/IMG/huffmantable.h \
src/map/IMG/huffmantext.h \
src/map/IMG/nodfile.h \
src/map/IMG/mapdata.h \
src/map/IMG/rastertile.h \
src/map/IMG/textpathitem.h \
src/map/IMG/textpointitem.h \
src/map/projection.h \
@ -195,8 +201,12 @@ HEADERS += src/common/config.h \
src/data/cupparser.h \
src/data/gpiparser.h \
src/data/address.h \
src/data/smlparser.h
src/data/smlparser.h \
src/GUI/pdfexportdialog.h \
src/GUI/pngexportdialog.h
SOURCES += src/main.cpp \
src/GUI/axislabelitem.cpp \
src/GUI/marginswidget.cpp \
src/GUI/popup.cpp \
src/common/coordinates.cpp \
src/common/rectc.cpp \
@ -221,7 +231,6 @@ SOURCES += src/main.cpp \
src/GUI/palette.cpp \
src/GUI/heartrategraph.cpp \
src/GUI/trackinfo.cpp \
src/GUI/exportdialog.cpp \
src/GUI/fileselectwidget.cpp \
src/GUI/temperaturegraph.cpp \
src/GUI/trackitem.cpp \
@ -248,13 +257,18 @@ SOURCES += src/main.cpp \
src/GUI/gearratiographitem.cpp \
src/GUI/mapview.cpp \
src/GUI/areaitem.cpp \
src/data/waypoint.cpp \
src/map/IMG/bitmapline.cpp \
src/map/IMG/bitstream.cpp \
src/map/IMG/deltastream.cpp \
src/map/IMG/gmap.cpp \
src/map/IMG/huffmanbuffer.cpp \
src/map/IMG/huffmanstream.cpp \
src/map/IMG/huffmantable.cpp \
src/map/IMG/huffmantext.cpp \
src/map/IMG/nodfile.cpp \
src/map/IMG/mapdata.cpp \
src/map/IMG/rastertile.cpp \
src/map/IMG/textpathitem.cpp \
src/map/IMG/textpointitem.cpp \
src/map/maplist.cpp \
@ -338,12 +352,17 @@ SOURCES += src/main.cpp \
src/data/cupparser.cpp \
src/GUI/graphicsscene.cpp \
src/data/gpiparser.cpp \
src/data/smlparser.cpp
src/data/smlparser.cpp \
src/GUI/pdfexportdialog.cpp \
src/GUI/pngexportdialog.cpp
greaterThan(QT_MAJOR_VERSION, 4) {
HEADERS += src/data/geojsonparser.h
SOURCES += src/data/geojsonparser.cpp
}
equals(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 4) {
HEADERS += src/GUI/timezoneinfo.h
}
DEFINES += APP_VERSION=\\\"$$VERSION\\\" \
QT_NO_DEPRECATED_WARNINGS
@ -364,10 +383,11 @@ TRANSLATIONS = lang/gpxsee_en.ts \
lang/gpxsee_es.ts \
lang/gpxsee_pt_BR.ts \
lang/gpxsee_uk.ts \
lang/gpxsee_hu.ts
lang/gpxsee_hu.ts \
lang/gpxsee_it.ts
macx {
ICON = icons/gpxsee.icns
ICON = icons/app/gpxsee.icns
QMAKE_INFO_PLIST = pkg/Info.plist
locale.path = Contents/Resources/translations
locale.files = lang/gpxsee_en.qm \
@ -383,7 +403,9 @@ macx {
lang/gpxsee_tr.qm \
lang/gpxsee_es.qm \
lang/gpxsee_pt_BR.qm \
lang/gpxsee_uk.qm
lang/gpxsee_uk.qm \
lang/gpxsee_hu.qm \
lang/gpxsee_it.qm
csv.path = Contents/Resources
csv.files = pkg/csv
maps.path = Contents/Resources
@ -408,7 +430,7 @@ macx {
}
win32 {
RC_ICONS = icons/gpxsee.ico \
RC_ICONS = icons/app/gpxsee.ico \
icons/formats/gpx.ico \
icons/formats/tcx.ico \
icons/formats/kml.ico \
@ -438,8 +460,8 @@ unix:!macx {
csv.path = $$PREFIX/share/gpxsee/csv
locale.files = lang/*.qm
locale.path = $$PREFIX/share/gpxsee/translations
icon.files = icons/gpxsee.png
icon.path = $$PREFIX/share/pixmaps
icon.files = icons/app/hicolor/*
icon.path = $$PREFIX/share/icons/hicolor
desktop.files = pkg/gpxsee.desktop
desktop.path = $$PREFIX/share/applications
mime.files = pkg/gpxsee.xml

View File

@ -1,8 +1,8 @@
<RCC>
<qresource prefix="/">
<!-- GUI -->
<file alias="gpxsee.png">icons/gpxsee.png</file>
<file alias="gpxsee@2x.png">icons/gpxsee@2x.png</file>
<file alias="gpxsee.png">icons/app/gpxsee.png</file>
<file alias="gpxsee@2x.png">icons/app/gpxsee@2x.png</file>
<file alias="dialog-close.png">icons/GUI/dialog-close.png</file>
<file alias="dialog-close@2x.png">icons/GUI/dialog-close@2x.png</file>
<file alias="document-open.png">icons/GUI/document-open.png</file>
@ -67,10 +67,12 @@
<file alias="cinema-11.png">icons/POI/cinema-11.png</file>
<file alias="clothing-store-11.png">icons/POI/clothing-store-11.png</file>
<file alias="communications-tower-11.png">icons/POI/communications-tower-11.png</file>
<file alias="convenience-11.png">icons/POI/convenience-11.png</file>
<file alias="dam-11.png">icons/POI/dam-11.png</file>
<file alias="danger-11.png">icons/POI/danger-11.png</file>
<file alias="drinking-water-11.png">icons/POI/drinking-water-11.png</file>
<file alias="fast-food-11.png">icons/POI/fast-food-11.png</file>
<file alias="entrance-alt1-11.png">icons/POI/entrance-alt1-11.png</file>
<file alias="fire-station-11.png">icons/POI/fire-station-11.png</file>
<file alias="fitness-centre-11.png">icons/POI/fitness-centre-11.png</file>
<file alias="fuel-11.png">icons/POI/fuel-11.png</file>
@ -97,7 +99,6 @@
<file alias="place-of-worship-11.png">icons/POI/place-of-worship-11.png</file>
<file alias="police-11.png">icons/POI/police-11.png</file>
<file alias="post-11.png">icons/POI/post-11.png</file>
<file alias="prison-11.png">icons/POI/prison-11.png</file>
<file alias="religious-christian-11.png">icons/POI/religious-christian-11.png</file>
<file alias="religious-jewish-11.png">icons/POI/religious-jewish-11.png</file>
<file alias="religious-muslim-11.png">icons/POI/religious-muslim-11.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 B

BIN
icons/app/gpxsee.dia Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg width="6cm" height="6cm" viewBox="47 79 119 119" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<rect style="fill: #ffffff" x="47.729" y="79.875" width="118.071" height="118.071" rx="10" ry="10"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2.35099e-37; stroke-linejoin: round; stroke: #ffffff" x="47.729" y="79.875" width="118.071" height="118.071" rx="10" ry="10"/>
</g>
<g>
<ellipse style="fill: #000000" cx="113" cy="90.875" rx="7.021" ry="7.021"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke-linejoin: round; stroke: #000000" cx="113" cy="90.875" rx="7.021" ry="7.021"/>
</g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 4; stroke: #000000" points="61.5289,182.479 73.5,125.854 96,151.875 113,90.875 136.5,172.375 151.658,157.199 "/>
<g>
<ellipse style="fill: #000000" cx="73.5" cy="125.854" rx="7.021" ry="7.021"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="73.5" cy="125.854" rx="7.021" ry="7.021"/>
</g>
<g>
<ellipse style="fill: #000000" cx="136.5" cy="172.375" rx="7.021" ry="7.021"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="136.5" cy="172.375" rx="7.021" ry="7.021"/>
</g>
<g>
<ellipse style="fill: #000000" cx="60.7" cy="186.4" rx="7.021" ry="7.021"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="60.7" cy="186.4" rx="7.021" ry="7.021"/>
</g>
<g>
<ellipse style="fill: #000000" cx="154.5" cy="154.354" rx="7.021" ry="7.021"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="154.5" cy="154.354" rx="7.021" ry="7.021"/>
</g>
<g>
<ellipse style="fill: #000000" cx="96" cy="151.875" rx="7.021" ry="7.021"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="96" cy="151.875" rx="7.021" ry="7.021"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

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

@ -1,4 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>GUI</name>
<message numerus="yes">
<location filename="../src/GUI/gui.cpp" line="1392"/>
<source>%n files</source>
<translation>
<numerusform>%n file</numerusform>
<numerusform>%n files</numerusform>
</translation>
</message>
</context>
</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

File diff suppressed because it is too large Load Diff

2028
lang/gpxsee_it.ts Normal file

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.21"
!define VERSION "7.37"
; The file to write
OutFile "GPXSee-${VERSION}.exe"
@ -17,6 +17,9 @@ SetCompressor /SOLID lzma
; Required execution level
RequestExecutionLevel admin
; Don't let the OS scale(blur) the installer GUI
ManifestDPIAware true
; The default installation directory
InstallDir "$PROGRAMFILES\GPXSee"
@ -177,6 +180,7 @@ SectionGroup "Localization" SEC_LOCALIZATION
!insertmacro LOCALIZATION "French" "fr"
!insertmacro LOCALIZATION "German" "de"
!insertmacro LOCALIZATION "Hungarian" "hu"
!insertmacro LOCALIZATION "Italian" "it"
!insertmacro LOCALIZATION "Norwegian" "nb"
!insertmacro LOCALIZATION "Polish" "pl"
!insertmacro LOCALIZATION "Portuguese (Brazil)" "pt_BR"

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.21"
!define VERSION "7.37"
; The file to write
OutFile "GPXSee-${VERSION}_x64.exe"
@ -17,6 +17,9 @@ SetCompressor /SOLID lzma
; Required execution level
RequestExecutionLevel admin
; Don't let the OS scale(blur) the installer GUI
ManifestDPIAware true
; The default installation directory
InstallDir "$PROGRAMFILES64\GPXSee"
@ -184,6 +187,7 @@ SectionGroup "Localization" SEC_LOCALIZATION
!insertmacro LOCALIZATION "French" "fr"
!insertmacro LOCALIZATION "German" "de"
!insertmacro LOCALIZATION "Hungarian" "hu"
!insertmacro LOCALIZATION "Italian" "it"
!insertmacro LOCALIZATION "Norwegian" "nb"
!insertmacro LOCALIZATION "Polish" "pl"
!insertmacro LOCALIZATION "Portuguese (Brazil)" "pt_BR"

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.gpxsee.org/map/1.3">
<map xmlns="http://www.gpxsee.org/map/1.4">
<name>4UMaps</name>
<url>https://tileserver.4umaps.com/$z/$x/$y.png</url>
<zoom min="2" max="15"/>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.gpxsee.org/map/1.3" type="WMTS">
<map xmlns="http://www.gpxsee.org/map/1.4" type="WMTS">
<name>Antarctica</name>
<url type="REST">https://gis.ngdc.noaa.gov/arcgis/rest/services/antarctic/antarctic_basemap/MapServer/WMTS/1.0.0/WMTSCapabilities.xml</url>
<url type="REST">https://tiles.arcgis.com/tiles/C8EMgrsFcRFL6LrL/arcgis/rest/services/Antarctic_Basemap/MapServer/WMTS/1.0.0/WMTSCapabilities.xml</url>
<copyright>NOAA National Centers for Environmental Information (NCEI); International Bathymetric Chart of the Southern Ocean (IBCSO); General Bathymetric Chart of the Oceans (GEBCO); Natural Earth</copyright>
<layer>antarctic_antarctic_basemap</layer>
<layer>Antarctic_Basemap</layer>
<set>default028mm</set>
</map>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.gpxsee.org/map/1.3">
<map xmlns="http://www.gpxsee.org/map/1.4">
<name>Open Street Map</name>
<url>https://tile.openstreetmap.org/$z/$x/$y.png</url>
<copyright>Map data: © OpenStreetMap contributors (ODbL) | Rendering: © OpenStreetMap (CC-BY-SA)</copyright>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.gpxsee.org/map/1.3">
<map xmlns="http://www.gpxsee.org/map/1.4">
<name>Open Topo Map</name>
<url>https://a.tile.opentopomap.org/$z/$x/$y.png</url>
<zoom max="17"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.gpxsee.org/map/1.3">
<map xmlns="http://www.gpxsee.org/map/1.4">
<name>USGS Imagery</name>
<url>https://basemap.nationalmap.gov/ArcGIS/rest/services/USGSImageryOnly/MapServer/tile/$z/$y/$x</url>
<zoom min="2" max="15"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.gpxsee.org/map/1.3">
<map xmlns="http://www.gpxsee.org/map/1.4">
<name>USGS Topo</name>
<url>https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/$z/$y/$x</url>
<zoom min="2" max="15"/>

View File

@ -41,6 +41,7 @@ AxisItem::AxisItem(Type type, QGraphicsItem *parent)
{
_type = type;
_size = 0;
_zoom = 1.0;
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
@ -52,8 +53,10 @@ void AxisItem::setRange(const RangeF &range)
_range = range;
QFontMetrics fm(_font);
Ticks ticks(_range.min(), _range.max(), (_type == X) ? XTICKS : YTICKS);
Ticks ticks(_range.min(), _range.max(),
(_type == X) ? XTICKS * _zoom : YTICKS * _zoom);
_ticks = QVector<Tick>(ticks.count());
for (int i = 0; i < ticks.count(); i++) {
Tick &t = _ticks[i];
t.value = ticks.val(i);
@ -72,34 +75,23 @@ void AxisItem::setSize(qreal size)
update();
}
void AxisItem::setLabel(const QString& label)
{
prepareGeometryChange();
QFontMetrics fm(_font);
_label = label;
_labelBB = fm.tightBoundingRect(label);
updateBoundingRect();
update();
}
void AxisItem::updateBoundingRect()
{
QFontMetrics fm(_font);
QRect es = _ticks.isEmpty() ? QRect() : _ticks.last().boundingBox;
QRect ss = _ticks.isEmpty() ? QRect() : _ticks.first().boundingBox;
QRect ls(_labelBB);
if (_type == X) {
_boundingRect = QRectF(-ss.width()/2, -TICK/2, _size + es.width()/2
+ ss.width()/2, ls.height() + es.height() - fm.descent() + TICK
+ 2*PADDING + 1);
+ ss.width()/2, es.height() - 2*fm.descent() + TICK + 2*PADDING);
} else {
int mtw = 0;
for (int i = 0; i < _ticks.count(); i++)
mtw = qMax(_ticks.at(i).boundingBox.width(), mtw);
_boundingRect = QRectF(-(ls.height() + mtw + 2*PADDING + TICK/2),
-(_size + es.height()/2 + fm.descent()), ls.height() + mtw + 2*PADDING
+ TICK, _size + es.height()/2 + fm.descent() + ss.height()/2);
_boundingRect = QRectF(-(mtw + 2*PADDING + TICK/2 - fm.descent()),
-(_size + es.height()/2 + fm.descent()), mtw + 2*PADDING
+ TICK - fm.descent(), _size + es.height()/2 + fm.descent()
+ ss.height()/2);
}
}
@ -108,7 +100,6 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFontMetrics fm(_font);
QRect ts;
painter->setRenderHint(QPainter::Antialiasing, false);
@ -130,9 +121,6 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- (ts.width()/2), ts.height() + TICK/2 + PADDING,
_locale.toString(val));
}
painter->drawText(_size/2 - _labelBB.width()/2, _labelBB.height()
+ ts.height() - 2*fm.descent() + TICK/2 + 2*PADDING, _label);
} else {
painter->drawLine(0, 0, 0, -_size);
@ -149,17 +137,10 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
-((_size/_range.size()) * (val - _range.min())) + (ts.height()/2),
_locale.toString(val));
}
painter->rotate(-90);
painter->drawText(_size/2 - _labelBB.width()/2, -(mtw + 2*PADDING
+ TICK/2), _label);
painter->rotate(90);
}
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}
QSizeF AxisItem::margin() const
@ -168,15 +149,15 @@ QSizeF AxisItem::margin() const
QRect es = _ticks.isEmpty() ? QRect() : _ticks.last().boundingBox;
if (_type == X) {
return QSizeF(es.width()/2, _labelBB.height() + es.height()
- fm.descent() + TICK/2 + 2*PADDING);
return QSizeF(es.width()/2, es.height() - 2*fm.descent() + TICK/2
+ 2*PADDING);
} else {
int mtw = 0;
for (int i = 0; i < _ticks.count(); i++)
mtw = qMax(_ticks.at(i).boundingBox.width(), mtw);
return QSizeF(_labelBB.height() -fm.descent() + mtw + 2*PADDING
+ TICK/2, es.height()/2 + fm.descent());
return QSizeF(mtw + 2*PADDING + TICK/2 - fm.descent(),
es.height()/2 + fm.descent());
}
}

View File

@ -13,13 +13,15 @@ public:
AxisItem(Type type, QGraphicsItem *parent = 0);
/* Note: The items position is at the 0 point of the axis line, not at the
top-left point of the bounding rect as usual */
QRectF boundingRect() const {return _boundingRect;}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setRange(const RangeF &range);
void setSize(qreal size);
void setLabel(const QString& label);
void setZoom(qreal zoom) {_zoom = zoom;}
QSizeF margin() const;
QList<qreal> ticks() const;
@ -35,12 +37,11 @@ private:
Type _type;
RangeF _range;
qreal _size;
QString _label;
QRect _labelBB;
QVector<Tick> _ticks;
QRectF _boundingRect;
QFont _font;
QLocale _locale;
qreal _zoom;
};
#endif // AXISITEM_H

54
src/GUI/axislabelitem.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <QPainter>
#include <QFontMetrics>
#include "font.h"
#include "axislabelitem.h"
AxisLabelItem::AxisLabelItem(Type type, QGraphicsItem *parent)
: QGraphicsItem(parent), _type(type)
{
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
}
void AxisLabelItem::setLabel(const QString& label, const QString &units)
{
prepareGeometryChange();
QFontMetrics fm(_font);
_label = QString("%1 [%2]").arg(label, units.isEmpty() ? "-" : units);
_labelBB = fm.tightBoundingRect(_label);
updateBoundingRect();
update();
}
void AxisLabelItem::updateBoundingRect()
{
QFontMetrics fm(_font);
if (_type == X)
_boundingRect = QRectF(0, 0, _labelBB.width(), fm.height());
else
_boundingRect = QRectF(0, 0, fm.height(), _labelBB.width());
}
void AxisLabelItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFontMetrics fm(_font);
painter->setFont(_font);
if (_type == X) {
painter->drawText(0, fm.height() - fm.descent(), _label);
} else {
painter->rotate(-90);
painter->drawText(-_labelBB.width(), fm.height() - fm.descent(), _label);
painter->rotate(90);
}
//painter->setRenderHint(QPainter::Antialiasing, false);
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}

30
src/GUI/axislabelitem.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef AXISLABELITEM_H
#define AXISLABELITEM_H
#include <QGraphicsItem>
#include <QFont>
class AxisLabelItem : public QGraphicsItem
{
public:
enum Type {X, Y};
AxisLabelItem(Type type, QGraphicsItem *parent = 0);
QRectF boundingRect() const {return _boundingRect;}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setLabel(const QString& label, const QString &units);
private:
void updateBoundingRect();
Type _type;
QString _label;
QFont _font;
QRect _labelBB;
QRectF _boundingRect;
};
#endif // AXISLABELITEM_H

View File

@ -5,7 +5,7 @@
CadenceGraphItem::CadenceGraphItem(const Graph &graph, GraphType type,
int width, const QColor &color, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
: GraphItem(graph, type, width, color, Qt::SolidLine, parent)
{
}

View File

@ -15,6 +15,8 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
CoordinatesFormat format() const {return _format;}
void setCoordinates(const Coordinates &c);
void setFormat(const CoordinatesFormat &format);
void setDigitalZoom(qreal zoom);

View File

@ -65,35 +65,38 @@ void ElevationGraph::setInfo()
}
}
GraphItem *ElevationGraph::loadGraph(const Graph &graph, Type type)
GraphItem *ElevationGraph::loadGraph(const Graph &graph, PathType type,
const QColor &color, bool primary)
{
if (!graph.isValid()) {
_palette.nextColor();
if (!graph.isValid())
return 0;
}
ElevationGraphItem *gi = new ElevationGraphItem(graph, _graphType, _width,
_palette.nextColor());
color, primary ? Qt::SolidLine : Qt::DashLine);
gi->setUnits(_units);
if (type == Track) {
if (type == TrackPath) {
_tracks.append(gi);
if (_showTracks)
addGraph(gi);
_trackAscent += gi->ascent();
_trackDescent += gi->descent();
_trackMax = nMax(_trackMax, gi->max());
_trackMin = nMin(_trackMin, gi->min());
if (primary) {
_trackAscent += gi->ascent();
_trackDescent += gi->descent();
_trackMax = nMax(_trackMax, gi->max());
_trackMin = nMin(_trackMin, gi->min());
}
} else {
_routes.append(gi);
if (_showRoutes)
addGraph(gi);
_routeAscent += gi->ascent();
_routeDescent += gi->descent();
_routeMax = nMax(_routeMax, gi->max());
_routeMin = nMin(_routeMin, gi->min());
if (primary) {
_routeAscent += gi->ascent();
_routeDescent += gi->descent();
_routeMax = nMax(_routeMax, gi->max());
_routeMin = nMin(_routeMin, gi->min());
}
}
return gi;
@ -102,11 +105,32 @@ GraphItem *ElevationGraph::loadGraph(const Graph &graph, Type type)
QList<GraphItem*> ElevationGraph::loadData(const Data &data)
{
QList<GraphItem*> graphs;
GraphItem *primary, *secondary;
for (int i = 0; i < data.tracks().count(); i++)
graphs.append(loadGraph(data.tracks().at(i).elevation(), Track));
for (int i = 0; i < data.routes().count(); i++)
graphs.append(loadGraph(data.routes().at(i).elevation(), Route));
for (int i = 0; i < data.tracks().count(); i++) {
QColor color(_palette.nextColor());
const GraphPair &gp = data.tracks().at(i).elevation();
primary = loadGraph(gp.primary(), TrackPath, color, true);
secondary = primary
? loadGraph(gp.secondary(), TrackPath, color, false) : 0;
if (primary && secondary)
primary->setSecondaryGraph(secondary);
graphs.append(primary);
}
for (int i = 0; i < data.routes().count(); i++) {
QColor color(_palette.nextColor());
const GraphPair &gp = data.routes().at(i).elevation();
primary = loadGraph(gp.primary(), RoutePath, color, true);
secondary = primary
? loadGraph(gp.secondary(), RoutePath, color, false) : 0;
if (primary && secondary)
primary->setSecondaryGraph(secondary);
graphs.append(primary);
}
for (int i = 0; i < data.areas().count(); i++)
_palette.nextColor();

View File

@ -21,7 +21,7 @@ public:
void showRoutes(bool show);
private:
enum Type {Track, Route};
enum PathType {TrackPath, RoutePath};
qreal max() const;
qreal min() const;
@ -31,7 +31,8 @@ private:
void setYUnits(Units units);
void setInfo();
GraphItem *loadGraph(const Graph &graph, Type type);
GraphItem *loadGraph(const Graph &graph, PathType type, const QColor &color,
bool primary);
void showItems(const QList<ElevationGraphItem *> &list, bool show);
qreal _trackAscent, _trackDescent;

View File

@ -4,8 +4,8 @@
ElevationGraphItem::ElevationGraphItem(const Graph &graph, GraphType type,
int width, const QColor &color, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
int width, const QColor &color, Qt::PenStyle style, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, style, parent)
{
_min = GraphItem::min();
_max = GraphItem::max();
@ -42,5 +42,6 @@ QString ElevationGraphItem::info() const
tt.insert(tr("Minimum"), l.toString(min() * scale, 'f', 0)
+ UNIT_SPACE + su);
return tt.toString();
}

View File

@ -8,8 +8,10 @@ class ElevationGraphItem : public GraphItem
Q_OBJECT
public:
enum DataType {GPS, DEM};
ElevationGraphItem(const Graph &graph, GraphType type, int width,
const QColor &color, QGraphicsItem *parent = 0);
const QColor &color, Qt::PenStyle style, QGraphicsItem *parent = 0);
qreal ascent() const {return _ascent;}
qreal descent() const {return _descent;}

View File

@ -12,7 +12,8 @@ FileSelectWidget::FileSelectWidget(QWidget *parent) : QWidget(parent)
{
QFontMetrics fm(QApplication::font());
_edit = new QLineEdit();
_edit->setMinimumWidth(fm.boundingRect(QDir::homePath()).width());
_edit->setMinimumWidth(fm.averageCharWidth() * (QDir::homePath().length()
+ 12));
#ifdef Q_OS_WIN32
_button = new QPushButton("...");
_button->setMaximumWidth(_button->sizeHint().width() / 2);
@ -41,3 +42,33 @@ void FileSelectWidget::browse()
if (!fileName.isEmpty())
_edit->setText(fileName);
}
bool FileSelectWidget::checkFile(QString &error) const
{
if (_edit->text().isEmpty()) {
error = tr("No output file selected.");
return false;
}
QFile file(_edit->text());
QFileInfo fi(file);
bool exists = fi.exists();
bool opened = false;
if (exists && fi.isDir()) {
error = tr("%1 is a directory.").arg(file.fileName());
return false;
} else if ((exists && !fi.isWritable())
|| !(opened = file.open(QFile::Append))) {
error = tr("%1 is not writable.").arg(file.fileName());
return false;
}
if (opened) {
file.close();
if (!exists)
file.remove();
}
return true;
}

View File

@ -14,9 +14,10 @@ class FileSelectWidget : public QWidget
public:
FileSelectWidget(QWidget *parent = 0);
QString file() {return _edit->text();}
QString file() const {return _edit->text();}
void setFile(const QString &file) {_edit->setText(file);}
void setFilter(const QString &filter) {_filter = filter;}
bool checkFile(QString &error) const;
private slots:
void browse();

View File

@ -6,7 +6,7 @@
GearRatioGraphItem::GearRatioGraphItem(const Graph &graph, GraphType type,
int width, const QColor &color, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
: GraphItem(graph, type, width, color, Qt::SolidLine, parent)
{
for (int i = 0; i < graph.size(); i++) {
const GraphSegment &segment = graph.at(i);

View File

@ -5,13 +5,13 @@
GraphItem::GraphItem(const Graph &graph, GraphType type, int width,
const QColor &color, QGraphicsItem *parent)
: GraphicsItem(parent), _graph(graph), _type(type)
const QColor &color, Qt::PenStyle style, QGraphicsItem *parent)
: GraphicsItem(parent), _graph(graph), _type(type), _secondaryGraph(0)
{
Q_ASSERT(_graph.isValid());
_units = Metric;
_pen = QPen(color, width);
_pen = QPen(color, width, style, Qt::FlatCap);
_sx = 0; _sy = 0;
_time = _graph.hasTime();
setZValue(2.0);

View File

@ -12,8 +12,8 @@ class GraphItem : public QObject, public GraphicsItem
Q_OBJECT
public:
GraphItem(const Graph &graph, GraphType type, int width, const QColor &color,
QGraphicsItem *parent = 0);
GraphItem(const Graph &graph, GraphType type, int width,
const QColor &color, Qt::PenStyle style, QGraphicsItem *parent = 0);
virtual ~GraphItem() {}
virtual QString info() const = 0;
@ -35,6 +35,9 @@ public:
void setWidth(int width);
void setUnits(Units units) {_units = units;}
GraphItem *secondaryGraph() const {return _secondaryGraph;}
void setSecondaryGraph(GraphItem *graph) {_secondaryGraph = graph;}
qreal yAtX(qreal x);
qreal distanceAtTime(qreal time);
@ -69,6 +72,8 @@ private:
qreal _sx, _sy;
QPen _pen;
bool _time;
GraphItem *_secondaryGraph;
};
#endif // GRAPHITEM_H

View File

@ -14,8 +14,7 @@ class GraphTab : public GraphView
Q_OBJECT
public:
GraphTab(QWidget *parent = 0) : GraphView(parent)
{setFrameShape(QFrame::NoFrame);}
GraphTab(QWidget *parent = 0) : GraphView(parent) {}
virtual ~GraphTab() {}
virtual QString label() const = 0;

View File

@ -1,3 +1,4 @@
#include <QSet>
#include <QGraphicsScene>
#include <QEvent>
#include <QMouseEvent>
@ -8,6 +9,7 @@
#include "data/graph.h"
#include "opengl.h"
#include "axisitem.h"
#include "axislabelitem.h"
#include "slideritem.h"
#include "sliderinfoitem.h"
#include "infoitem.h"
@ -21,6 +23,9 @@
#define MARGIN 10.0
#define IW(item) ((item)->boundingRect().width())
#define IH(item) ((item)->boundingRect().height())
GraphView::GraphView(QWidget *parent)
: QGraphicsView(parent)
{
@ -37,6 +42,10 @@ GraphView::GraphView(QWidget *parent)
_xAxis->setZValue(1.0);
_yAxis = new AxisItem(AxisItem::Y);
_yAxis->setZValue(1.0);
_xAxisLabel = new AxisLabelItem(AxisLabelItem::X);
_xAxisLabel->setZValue(1.0);
_yAxisLabel = new AxisLabelItem(AxisLabelItem::Y);
_yAxisLabel->setZValue(1.0);
_slider = new SliderItem();
_slider->setZValue(4.0);
_sliderInfo = new SliderInfoItem(_slider);
@ -72,34 +81,24 @@ GraphView::~GraphView()
{
delete _xAxis;
delete _yAxis;
delete _xAxisLabel;
delete _yAxisLabel;
delete _slider;
delete _info;
delete _grid;
delete _message;
}
void GraphView::createXLabel()
{
_xAxis->setLabel(QString("%1 [%2]").arg(_xLabel,
_xUnits.isEmpty() ? "-" : _xUnits));
}
void GraphView::createYLabel()
{
_yAxis->setLabel(QString("%1 [%2]").arg(_yLabel,
_yUnits.isEmpty() ? "-" : _yUnits));
}
void GraphView::setYLabel(const QString &label)
{
_yLabel = label;
createYLabel();
_yAxisLabel->setLabel(_yLabel, _yUnits);
}
void GraphView::setYUnits(const QString &units)
{
_yUnits = units;
createYLabel();
_yAxisLabel->setLabel(_yLabel, _yUnits);
}
void GraphView::setXUnits()
@ -143,7 +142,7 @@ void GraphView::setXUnits()
}
}
createXLabel();
_xAxisLabel->setLabel(_xLabel, _xUnits);
}
void GraphView::setUnits(Units units)
@ -162,6 +161,7 @@ void GraphView::setGraphType(GraphType type)
{
_graphType = type;
_bounds = QRectF();
_zoom = 1.0;
for (int i = 0; i < _graphs.count(); i++) {
GraphItem *gi = _graphs.at(i);
@ -256,6 +256,8 @@ void GraphView::redraw(const QSizeF &size)
if (_bounds.isNull()) {
removeItem(_xAxis);
removeItem(_yAxis);
removeItem(_xAxisLabel);
removeItem(_yAxisLabel);
removeItem(_slider);
removeItem(_info);
removeItem(_grid);
@ -267,6 +269,8 @@ void GraphView::redraw(const QSizeF &size)
removeItem(_message);
addItem(_xAxis);
addItem(_yAxis);
addItem(_xAxisLabel);
addItem(_yAxisLabel);
addItem(_slider);
addItem(_info);
addItem(_grid);
@ -274,10 +278,12 @@ void GraphView::redraw(const QSizeF &size)
rx = RangeF(bounds().left() * _xScale, bounds().right() * _xScale);
ry = RangeF(bounds().top() * _yScale + _yOffset, bounds().bottom() * _yScale
+ _yOffset);
if (ry.size() < _minYRange)
ry.resize(_minYRange);
if (ry.size() < _minYRange * _yScale)
ry.resize(_minYRange * _yScale);
_xAxis->setZoom(_zoom);
_xAxis->setRange(rx);
_xAxis->setZoom(_zoom);
_yAxis->setRange(ry);
mx = _xAxis->margin();
my = _yAxis->margin();
@ -287,9 +293,10 @@ void GraphView::redraw(const QSizeF &size)
r.adjust(0, -(_minYRange/2 - r.height()/2), 0,
_minYRange/2 - r.height()/2);
sx = (size.width() - (my.width() + mx.width())) / r.width();
sx = (size.width() - (my.width() + mx.width()) - IW(_yAxisLabel))
/ r.width();
sy = (size.height() - (mx.height() + my.height())
- _info->boundingRect().height()) / r.height();
- IH(_info) - IH(_xAxisLabel)) / r.height();
sx *= _zoom;
for (int i = 0; i < _graphs.size(); i++)
@ -315,10 +322,12 @@ void GraphView::redraw(const QSizeF &size)
_slider->setArea(r);
updateSliderPosition();
r |= _xAxis->sceneBoundingRect();
r |= _yAxis->sceneBoundingRect();
_info->setPos(r.topLeft() + QPointF(r.width()/2
- _info->boundingRect().width()/2, -_info->boundingRect().height()));
_info->setPos(QPointF(r.width()/2 - IW(_info)/2 - (IW(_yAxisLabel)
+ IW(_yAxis))/2, r.top() - IH(_info) - my.height()));
_xAxisLabel->setPos(QPointF(r.width()/2 - IW(_xAxisLabel)/2,
r.bottom() + mx.height()));
_yAxisLabel->setPos(QPointF(r.left() - my.width() - IW(_yAxisLabel),
r.bottom() - (r.height()/2 + IH(_yAxisLabel)/2)));
_scene->setSceneRect(_scene->itemsBoundingRect());
}
@ -366,8 +375,10 @@ void GraphView::wheelEvent(QWheelEvent *e)
void GraphView::paintEvent(QPaintEvent *e)
{
QRectF viewRect(mapToScene(rect()).boundingRect());
_info->setPos(QPointF(viewRect.left() + (viewRect.width()
- _info->boundingRect().width())/2.0, _info->pos().y()));
_info->setPos(QPointF(viewRect.left() + (viewRect.width() - IW(_info))/2.0,
_info->pos().y()));
_xAxisLabel->setPos(QPointF(viewRect.left() + (viewRect.width()
- IW(_xAxisLabel))/2.0, _xAxisLabel->pos().y()));
QGraphicsView::paintEvent(e);
}
@ -419,14 +430,16 @@ void GraphView::updateSliderInfo()
{
QLocale l(QLocale::system());
qreal r = 0, y = 0;
GraphItem *cardinal = (_graphs.count() == 1 || (_graphs.count() == 2
&& _graphs.first()->secondaryGraph())) ? _graphs.first() : 0;
if (_graphs.count() == 1) {
QRectF br(_graphs.first()->bounds());
if (cardinal) {
QRectF br(_bounds);
if (br.height() < _minYRange)
br.adjust(0, -(_minYRange/2 - br.height()/2), 0,
_minYRange/2 - br.height()/2);
y = _graphs.first()->yAtX(_sliderPos);
y = cardinal->yAtX(_sliderPos);
r = (y - br.bottom()) / br.height();
}
@ -436,11 +449,17 @@ void GraphView::updateSliderInfo()
_sliderInfo->setSide(s);
_sliderInfo->setPos(QPointF(0, _slider->boundingRect().height() * r));
_sliderInfo->setText(_graphType == Time ? Format::timeSpan(_sliderPos,
QString xText(_graphType == Time ? Format::timeSpan(_sliderPos,
bounds().width() > 3600) : l.toString(_sliderPos * _xScale, 'f', 1)
+ UNIT_SPACE + _xUnits, (_graphs.count() > 1) ? QString()
: l.toString(-y * _yScale + _yOffset, 'f', _precision) + UNIT_SPACE
+ _yUnits);
+ UNIT_SPACE + _xUnits);
QString yText((!cardinal) ? QString() : l.toString(-y * _yScale + _yOffset,
'f', _precision) + UNIT_SPACE + _yUnits);
if (cardinal && cardinal->secondaryGraph()) {
qreal delta = y - cardinal->secondaryGraph()->yAtX(_sliderPos);
yText += " " + QChar(0x0394) + l.toString(-delta * _yScale + _yOffset,
'f', _precision) + UNIT_SPACE + _yUnits;
}
_sliderInfo->setText(xText, yText);
}
void GraphView::emitSliderPositionChanged(const QPointF &pos)
@ -486,8 +505,23 @@ void GraphView::setPalette(const Palette &palette)
_palette = palette;
_palette.reset();
for (int i = 0; i < _graphs.count(); i++)
_graphs.at(i)->setColor(_palette.nextColor());
QSet<GraphItem*> secondary;
for (int i = 0; i < _graphs.count(); i++) {
GraphItem *g = _graphs[i];
if (g->secondaryGraph())
secondary.insert(g->secondaryGraph());
}
for (int i = 0; i < _graphs.count(); i++) {
GraphItem *g = _graphs[i];
if (secondary.contains(g))
continue;
QColor color(_palette.nextColor());
g->setColor(color);
if (g->secondaryGraph())
g->secondaryGraph()->setColor(color);
}
}
void GraphView::setGraphWidth(int width)

View File

@ -3,7 +3,6 @@
#include <QGraphicsView>
#include <QList>
#include <QSet>
#include "data/graph.h"
#include "palette.h"
#include "units.h"
@ -11,6 +10,7 @@
class AxisItem;
class AxisLabelItem;
class SliderItem;
class SliderInfoItem;
class GraphItem;
@ -87,8 +87,6 @@ private slots:
private:
void redraw(const QSizeF &size);
void setXUnits();
void createXLabel();
void createYLabel();
void updateSliderPosition();
void updateSliderInfo();
void removeItem(QGraphicsItem *item);
@ -97,6 +95,7 @@ private:
GraphicsScene *_scene;
AxisItem *_xAxis, *_yAxis;
AxisLabelItem *_xAxisLabel, *_yAxisLabel;
SliderItem *_slider;
SliderInfoItem *_sliderInfo;
InfoItem *_info;

View File

@ -23,10 +23,8 @@ void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->drawLine(0, -_yTicks.at(i), boundingRect().width(),
-_yTicks.at(i));
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}
void GridItem::setTicks(const QList<qreal> &x, const QList<qreal> &y)

View File

@ -51,6 +51,7 @@
#include "graphtab.h"
#include "graphitem.h"
#include "pathitem.h"
#include "mapaction.h"
#include "gui.h"
@ -58,7 +59,6 @@
GUI::GUI()
{
loadMaps();
loadPOIs();
createMapView();
@ -106,24 +106,13 @@ GUI::GUI()
updateStatusBarInfo();
}
void GUI::loadMaps()
{
_ml = new MapList(this);
QString mapDir(ProgramPaths::mapDir());
if (!mapDir.isNull() && !_ml->loadDir(mapDir))
qWarning("%s", qPrintable(_ml->errorString()));
_map = new EmptyMap(this);
}
void GUI::loadPOIs()
{
_poi = new POI(this);
QString poiDir(ProgramPaths::poiDir());
if (!poiDir.isNull() && !_poi->loadDir(poiDir))
qWarning("%s", qPrintable(_poi->errorString()));
QString poiDir(ProgramPaths::poiDir());
if (!poiDir.isNull())
_poi->loadDir(poiDir);
}
void GUI::createBrowser()
@ -134,40 +123,55 @@ void GUI::createBrowser()
void GUI::createMapActions()
{
_mapsSignalMapper = new QSignalMapper(this);
_mapsActionGroup = new QActionGroup(this);
_mapsActionGroup->setExclusive(true);
for (int i = 0; i < _ml->maps().count(); i++)
createMapAction(_ml->maps().at(i));
QString mapDir(ProgramPaths::mapDir());
if (mapDir.isNull())
return;
connect(_mapsSignalMapper, SIGNAL(mapped(int)), this,
SLOT(mapChanged(int)));
QString unused;
QList<Map*> maps(MapList::loadMaps(mapDir, unused));
for (int i = 0; i < maps.count(); i++) {
MapAction *a = createMapAction(maps.at(i));
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
}
}
QAction *GUI::createMapAction(const Map *map)
MapAction *GUI::createMapAction(Map *map)
{
QAction *a = new QAction(map->name(), this);
MapAction *a = new MapAction(map, _mapsActionGroup);
a->setMenuRole(QAction::NoRole);
a->setCheckable(true);
a->setActionGroup(_mapsActionGroup);
_mapActions.append(a);
_mapsSignalMapper->setMapping(a, _mapActions.size() - 1);
connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map()));
connect(a, SIGNAL(triggered()), this, SLOT(mapChanged()));
return a;
}
void GUI::mapInitialized()
{
MapAction *action = static_cast<MapAction*>(QObject::sender());
Map *map = action->data().value<Map*>();
if (map->isValid()) {
if (!_mapsActionGroup->checkedAction())
action->trigger();
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
qWarning("%s: %s", qPrintable(map->name()), qPrintable(map->errorString()));
action->deleteLater();
}
}
void GUI::createPOIFilesActions()
{
_poiFilesSignalMapper = new QSignalMapper(this);
connect(_poiFilesSignalMapper, SIGNAL(mapped(int)), this,
SLOT(poiFileChecked(int)));
for (int i = 0; i < _poi->files().count(); i++)
createPOIFileAction(_poi->files().at(i));
connect(_poiFilesSignalMapper, SIGNAL(mapped(int)), this,
SLOT(poiFileChecked(int)));
}
QAction *GUI::createPOIFileAction(const QString &fileName)
@ -225,13 +229,20 @@ void GUI::createActions()
_printFileAction->setActionGroup(_fileActionGroup);
connect(_printFileAction, SIGNAL(triggered()), this, SLOT(printFile()));
addAction(_printFileAction);
_exportFileAction = new QAction(QIcon(EXPORT_FILE_ICON),
_exportPDFFileAction = new QAction(QIcon(EXPORT_FILE_ICON),
tr("Export to PDF..."), this);
_exportFileAction->setMenuRole(QAction::NoRole);
_exportFileAction->setShortcut(EXPORT_SHORTCUT);
_exportFileAction->setActionGroup(_fileActionGroup);
connect(_exportFileAction, SIGNAL(triggered()), this, SLOT(exportFile()));
addAction(_exportFileAction);
_exportPDFFileAction->setMenuRole(QAction::NoRole);
_exportPDFFileAction->setShortcut(PDF_EXPORT_SHORTCUT);
_exportPDFFileAction->setActionGroup(_fileActionGroup);
connect(_exportPDFFileAction, SIGNAL(triggered()), this, SLOT(exportPDFFile()));
addAction(_exportPDFFileAction);
_exportPNGFileAction = new QAction(QIcon(EXPORT_FILE_ICON),
tr("Export to PNG..."), this);
_exportPNGFileAction->setMenuRole(QAction::NoRole);
_exportPNGFileAction->setShortcut(PNG_EXPORT_SHORTCUT);
_exportPNGFileAction->setActionGroup(_fileActionGroup);
connect(_exportPNGFileAction, SIGNAL(triggered()), this, SLOT(exportPNGFile()));
addAction(_exportPNGFileAction);
_closeFileAction = new QAction(QIcon(CLOSE_FILE_ICON), tr("Close"), this);
_closeFileAction->setMenuRole(QAction::NoRole);
_closeFileAction->setShortcut(CLOSE_SHORTCUT);
@ -243,7 +254,7 @@ void GUI::createActions()
_reloadFileAction->setMenuRole(QAction::NoRole);
_reloadFileAction->setShortcut(RELOAD_SHORTCUT);
_reloadFileAction->setActionGroup(_fileActionGroup);
connect(_reloadFileAction, SIGNAL(triggered()), this, SLOT(reloadFile()));
connect(_reloadFileAction, SIGNAL(triggered()), this, SLOT(reloadFiles()));
addAction(_reloadFileAction);
_statisticsAction = new QAction(tr("Statistics..."), this);
_statisticsAction->setMenuRole(QAction::NoRole);
@ -281,8 +292,10 @@ void GUI::createActions()
createPOIFilesActions();
// Map actions
createMapActions();
_showMapAction = new QAction(QIcon(SHOW_MAP_ICON), tr("Show map"),
this);
_showMapAction->setEnabled(false);
_showMapAction->setMenuRole(QAction::NoRole);
_showMapAction->setCheckable(true);
_showMapAction->setShortcut(SHOW_MAP_SHORTCUT);
@ -294,10 +307,10 @@ void GUI::createActions()
_loadMapAction->setMenuRole(QAction::NoRole);
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
_clearMapCacheAction->setEnabled(false);
_clearMapCacheAction->setMenuRole(QAction::NoRole);
connect(_clearMapCacheAction, SIGNAL(triggered()), _mapView,
SLOT(clearMapCache()));
createMapActions();
_nextMapAction = new QAction(tr("Next map"), this);
_nextMapAction->setMenuRole(QAction::NoRole);
_nextMapAction->setShortcut(NEXT_MAP_SHORTCUT);
@ -308,10 +321,6 @@ void GUI::createActions()
_prevMapAction->setShortcut(PREV_MAP_SHORTCUT);
connect(_prevMapAction, SIGNAL(triggered()), this, SLOT(prevMap()));
addAction(_prevMapAction);
if (_ml->maps().isEmpty()) {
_showMapAction->setEnabled(false);
_clearMapCacheAction->setEnabled(false);
}
_showCoordinatesAction = new QAction(tr("Show cursor coordinates"), this);
_showCoordinatesAction->setMenuRole(QAction::NoRole);
_showCoordinatesAction->setCheckable(true);
@ -494,7 +503,8 @@ void GUI::createMenus()
fileMenu->addAction(_openFileAction);
fileMenu->addSeparator();
fileMenu->addAction(_printFileAction);
fileMenu->addAction(_exportFileAction);
fileMenu->addAction(_exportPDFFileAction);
fileMenu->addAction(_exportPNGFileAction);
fileMenu->addSeparator();
fileMenu->addAction(_statisticsAction);
fileMenu->addSeparator();
@ -506,7 +516,7 @@ void GUI::createMenus()
#endif // Q_OS_MAC
_mapMenu = menuBar()->addMenu(tr("&Map"));
_mapMenu->addActions(_mapActions);
_mapMenu->addActions(_mapsActionGroup->actions());
_mapsEnd = _mapMenu->addSeparator();
_mapMenu->addAction(_loadMapAction);
_mapMenu->addAction(_clearMapCacheAction);
@ -608,6 +618,7 @@ void GUI::createToolBars()
void GUI::createMapView()
{
_map = new EmptyMap(this);
_mapView = new MapView(_map, _poi, this);
_mapView->setSizePolicy(QSizePolicy(QSizePolicy::Ignored,
QSizePolicy::Expanding));
@ -620,15 +631,15 @@ void GUI::createMapView()
void GUI::createGraphTabs()
{
_graphTabWidget = new QTabWidget();
connect(_graphTabWidget, SIGNAL(currentChanged(int)), this,
SLOT(graphChanged(int)));
_graphTabWidget->setSizePolicy(QSizePolicy(QSizePolicy::Ignored,
QSizePolicy::Preferred));
_graphTabWidget->setMinimumHeight(200);
#ifdef Q_OS_WIN32
#ifndef Q_OS_MAC
_graphTabWidget->setDocumentMode(true);
#endif // Q_OS_WIN32
#endif // Q_OS_MAC
connect(_graphTabWidget, SIGNAL(currentChanged(int)), this,
SLOT(graphChanged(int)));
_tabs.append(new ElevationGraph(_graphTabWidget));
_tabs.append(new SpeedGraph(_graphTabWidget));
@ -638,9 +649,13 @@ void GUI::createGraphTabs()
_tabs.append(new TemperatureGraph(_graphTabWidget));
_tabs.append(new GearRatioGraph(_graphTabWidget));
for (int i = 0; i < _tabs.count(); i++)
for (int i = 0; i < _tabs.count(); i++) {
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
_tabs.at(i)->setFrameShape(QFrame::NoFrame);
#endif // Q_OS_WIN32 || Q_OS_MAC
connect(_tabs.at(i), SIGNAL(sliderPositionChanged(qreal)), this,
SLOT(sliderPositionChanged(qreal)));
}
}
void GUI::createStatusBar()
@ -709,7 +724,10 @@ void GUI::keys()
+ "</i></td></tr><tr><td>" + tr("Zoom out") + "</td><td><i>"
+ QKeySequence(ZOOM_OUT).toString() + "</i></td></tr><tr><td>"
+ tr("Digital zoom") + "</td><td><i>" + QKeySequence(MODIFIER).toString()
+ tr("Zoom") + "</i></td></tr></table></div>");
+ tr("Zoom") + "</i></td></tr><tr><td></td><td></td></tr><tr><td>"
+ tr("Copy coordinates") + "</td><td><i>"
+ QKeySequence(MODIFIER).toString() + tr("Left Click")
+ "</i></td></tr></table></div>");
msgBox.exec();
}
@ -787,7 +805,12 @@ bool GUI::loadFile(const QString &fileName)
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
const QDate &date = track.date().date();
#ifdef ENABLE_TIMEZONES
const QDateTime date = track.date().toTimeZone(
_options.timeZone.zone());
#else // ENABLE_TIMEZONES
const QDateTime &date = track.date();
#endif // ENABLE_TIMEZONES
if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date;
if (_dateRange.second.isNull() || _dateRange.second < date)
@ -905,16 +928,21 @@ void GUI::openOptions()
Track::action(options.option); \
reload = true; \
}
#define SET_DATA_OPTION(option, action) \
#define SET_ROUTE_OPTION(option, action) \
if (options.option != _options.option) { \
Data::action(options.option); \
Route::action(options.option); \
reload = true; \
}
#define SET_WAYPOINT_OPTION(option, action) \
if (options.option != _options.option) { \
Waypoint::action(options.option); \
reload = true; \
}
Options options(_options);
bool reload = false;
OptionsDialog dialog(&options, this);
OptionsDialog dialog(options, _units, this);
if (dialog.exec() != QDialog::Accepted)
return;
@ -953,13 +981,19 @@ void GUI::openOptions()
SET_TRACK_OPTION(pauseSpeed, setPauseSpeed);
SET_TRACK_OPTION(pauseInterval, setPauseInterval);
SET_TRACK_OPTION(useReportedSpeed, useReportedSpeed);
SET_TRACK_OPTION(dataUseDEM, useDEM);
SET_TRACK_OPTION(showSecondaryElevation, showSecondaryElevation);
SET_TRACK_OPTION(showSecondarySpeed, showSecondarySpeed);
SET_TRACK_OPTION(useSegments, useSegments);
SET_DATA_OPTION(dataUseDEM, useDEM);
SET_ROUTE_OPTION(dataUseDEM, useDEM);
SET_ROUTE_OPTION(showSecondaryElevation, showSecondaryElevation);
SET_WAYPOINT_OPTION(dataUseDEM, useDEM);
SET_WAYPOINT_OPTION(showSecondaryElevation, showSecondaryElevation);
if (options.poiRadius != _options.poiRadius)
_poi->setRadius(options.poiRadius);
if (options.poiUseDEM != _options.poiUseDEM)
_poi->useDEM(options.poiUseDEM);
if (options.pixmapCache != _options.pixmapCache)
QPixmapCache::setCacheLimit(options.pixmapCache * 1024);
@ -976,9 +1010,16 @@ void GUI::openOptions()
_mapView->setDevicePixelRatio(devicePixelRatioF(),
options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENABLE_HIDPI
#ifdef ENABLE_TIMEZONES
if (options.timeZone != _options.timeZone) {
_mapView->setTimeZone(options.timeZone.zone());
_dateRange.first = _dateRange.first.toTimeZone(options.timeZone.zone());
_dateRange.second = _dateRange.second.toTimeZone(options.timeZone.zone());
}
#endif // ENABLE_TIMEZONES
if (reload)
reloadFile();
reloadFiles();
_options = options;
}
@ -992,9 +1033,9 @@ void GUI::printFile()
plot(&printer);
}
void GUI::exportFile()
void GUI::exportPDFFile()
{
ExportDialog dialog(&_export, this);
PDFExportDialog dialog(_pdfExport, _units, this);
if (dialog.exec() != QDialog::Accepted)
return;
@ -1002,16 +1043,53 @@ void GUI::exportFile()
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setCreator(QString(APP_NAME) + QString(" ")
+ QString(APP_VERSION));
printer.setResolution(_export.resolution);
printer.setOrientation(_export.orientation);
printer.setOutputFileName(_export.fileName);
printer.setPaperSize(_export.paperSize);
printer.setPageMargins(_export.margins.left(), _export.margins.top(),
_export.margins.right(), _export.margins.bottom(), QPrinter::Millimeter);
printer.setResolution(_pdfExport.resolution);
printer.setOrientation(_pdfExport.orientation);
printer.setOutputFileName(_pdfExport.fileName);
printer.setPaperSize(_pdfExport.paperSize);
printer.setPageMargins(_pdfExport.margins.left(), _pdfExport.margins.top(),
_pdfExport.margins.right(), _pdfExport.margins.bottom(),
QPrinter::Millimeter);
plot(&printer);
}
void GUI::exportPNGFile()
{
PNGExportDialog dialog(_pngExport, this);
if (dialog.exec() != QDialog::Accepted)
return;
QImage img(_pngExport.size, QImage::Format_ARGB32_Premultiplied);
QPainter p(&img);
QRectF rect(0, 0, img.width(), img.height());
QRectF contentRect(rect.adjusted(_pngExport.margins.left(),
_pngExport.margins.top(), -_pngExport.margins.right(),
-_pngExport.margins.bottom()));
if (_pngExport.antialiasing)
p.setRenderHint(QPainter::Antialiasing);
p.fillRect(rect, Qt::white);
plotMainPage(&p, contentRect, 1.0, true);
img.save(_pngExport.fileName, "png");
if (!_tabs.isEmpty() && _options.separateGraphPage) {
QImage img2(_pngExport.size.width(), (int)graphPlotHeight(rect, 1)
+ _pngExport.margins.bottom(), QImage::Format_ARGB32_Premultiplied);
QPainter p2(&img2);
QRectF rect2(0, 0, img2.width(), img2.height());
if (_pngExport.antialiasing)
p2.setRenderHint(QPainter::Antialiasing);
p2.fillRect(rect2, Qt::white);
plotGraphsPage(&p2, contentRect, 1);
QFileInfo fi(_pngExport.fileName);
img2.save(fi.absolutePath() + "/" + fi.baseName() + "-graphs."
+ fi.suffix(), "png");
}
}
void GUI::statistics()
{
QLocale l(QLocale::system());
@ -1083,12 +1161,13 @@ void GUI::statistics()
msgBox.exec();
}
void GUI::plot(QPrinter *printer)
void GUI::plotMainPage(QPainter *painter, const QRectF &rect, qreal ratio,
bool expand)
{
QLocale l(QLocale::system());
QPainter p(printer);
TrackInfo info;
qreal ih, gh, mh, ratio;
qreal ih, gh, mh;
int sc;
if (!_pathName.isNull() && _options.printName)
@ -1124,54 +1203,92 @@ void GUI::plot(QPrinter *printer)
if (movingTime() > 0 && _options.printMovingTime)
info.insert(tr("Moving time"), Format::timeSpan(movingTime()));
qreal fsr = 1085.0 / (qMax(printer->width(), printer->height())
/ (qreal)printer->resolution());
ratio = p.paintEngine()->paintDevice()->logicalDpiX() / fsr;
if (info.isEmpty()) {
ih = 0;
mh = 0;
} else {
ih = info.contentSize().height() * ratio;
mh = ih / 2;
info.plot(&p, QRectF(0, 0, printer->width(), ih), ratio);
info.plot(painter, QRectF(rect.x(), rect.y(), rect.width(), ih), ratio);
}
if (_graphTabWidget->isVisible() && !_options.separateGraphPage) {
qreal r = (((qreal)(printer)->width()) / (qreal)(printer->height()));
gh = (printer->width() > printer->height())
? 0.15 * r * (printer->height() - ih - 2*mh)
: 0.15 * (printer->height() - ih - 2*mh);
qreal r = rect.width() / rect.height();
gh = (rect.width() > rect.height())
? 0.15 * r * (rect.height() - ih - 2*mh)
: 0.15 * (rect.height() - ih - 2*mh);
if (gh < 150)
gh = 150;
sc = 2;
GraphTab *gt = static_cast<GraphTab*>(_graphTabWidget->currentWidget());
gt->plot(&p, QRectF(0, printer->height() - gh, printer->width(), gh),
ratio);
} else
gt->plot(painter, QRectF(rect.x(), rect.y() + rect.height() - gh,
rect.width(), gh), ratio);
} else {
gh = 0;
_mapView->plot(&p, QRectF(0, ih + mh, printer->width(), printer->height()
- (ih + 2*mh + gh)), ratio, _options.hiresPrint);
sc = 1;
}
if (_graphTabWidget->isVisible() && _options.separateGraphPage) {
printer->newPage();
MapView::PlotFlags flags = MapView::NoFlags;
if (_options.hiresPrint)
flags |= MapView::HiRes;
if (expand)
flags |= MapView::Expand;
int cnt = 0;
for (int i = 0; i < _tabs.size(); i++)
if (!_tabs.at(i)->isEmpty())
cnt++;
_mapView->plot(painter, QRectF(rect.x(), rect.y() + ih + mh, rect.width(),
rect.height() - (ih + sc*mh + gh)), ratio, flags);
}
qreal sp = ratio * 20;
gh = qMin((printer->height() - ((cnt - 1) * sp))/(qreal)cnt,
0.20 * printer->height());
void GUI::plotGraphsPage(QPainter *painter, const QRectF &rect, qreal ratio)
{
int cnt = 0;
for (int i = 0; i < _tabs.size(); i++)
if (!_tabs.at(i)->isEmpty())
cnt++;
qreal y = 0;
for (int i = 0; i < _tabs.size(); i++) {
if (!_tabs.at(i)->isEmpty()) {
_tabs.at(i)->plot(&p, QRectF(0, y, printer->width(), gh),
ratio);
y += gh + sp;
}
qreal sp = ratio * 20;
qreal gh = qMin((rect.height() - ((cnt - 1) * sp))/(qreal)cnt,
0.20 * rect.height());
qreal y = 0;
for (int i = 0; i < _tabs.size(); i++) {
if (!_tabs.at(i)->isEmpty()) {
_tabs.at(i)->plot(painter, QRectF(rect.x(), rect.y() + y,
rect.width(), gh), ratio);
y += gh + sp;
}
}
}
void GUI::reloadFile()
qreal GUI::graphPlotHeight(const QRectF &rect, qreal ratio)
{
int cnt = 0;
for (int i = 0; i < _tabs.size(); i++)
if (!_tabs.at(i)->isEmpty())
cnt++;
qreal sp = ratio * 20;
qreal gh = qMin((rect.height() - ((cnt - 1) * sp))/(qreal)cnt,
0.20 * rect.height());
return cnt * gh + (cnt - 1) * sp;
}
void GUI::plot(QPrinter *printer)
{
QPainter p(printer);
qreal fsr = 1085.0 / (qMax(printer->width(), printer->height())
/ (qreal)printer->resolution());
qreal ratio = p.paintEngine()->paintDevice()->logicalDpiX() / fsr;
QRectF rect(0, 0, printer->width(), printer->height());
plotMainPage(&p, rect, ratio);
if (!_tabs.isEmpty() && _options.separateGraphPage) {
printer->newPage();
plotGraphsPage(&p, rect, ratio);
}
}
void GUI::reloadFiles()
{
_trackCount = 0;
_routeCount = 0;
@ -1181,7 +1298,7 @@ void GUI::reloadFile()
_routeDistance = 0;
_time = 0;
_movingTime = 0;
_dateRange = DateRange(QDate(), QDate());
_dateRange = DateTimeRange(QDateTime(), QDateTime());
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
@ -1215,7 +1332,7 @@ void GUI::closeFiles()
_routeDistance = 0;
_time = 0;
_movingTime = 0;
_dateRange = DateRange(QDate(), QDate());
_dateRange = DateTimeRange(QDateTime(), QDateTime());
_pathName = QString();
_sliderPos = 0;
@ -1322,22 +1439,49 @@ void GUI::loadMap()
bool GUI::loadMap(const QString &fileName)
{
// On OS X fileName may be a directory!
if (fileName.isEmpty())
return false;
if (_ml->loadFile(fileName)) {
QAction *a = createMapAction(_ml->maps().last());
QString error;
QList<Map*> maps = MapList::loadMaps(fileName, error);
if (maps.isEmpty()) {
error = tr("Error loading map:") + "\n\n"
+ fileName + "\n\n" + error;
QMessageBox::critical(this, APP_NAME, error);
return false;
}
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a = createMapAction(map);
_mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) {
a->trigger();
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded()));
}
return true;
}
void GUI::mapLoaded()
{
MapAction *action = static_cast<MapAction*>(QObject::sender());
Map *map = action->data().value<Map*>();
if (map->isValid()) {
action->trigger();
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
a->trigger();
return true;
} else {
QString error = tr("Error loading map:") + "\n\n"
+ fileName + "\n\n" + _ml->errorString();
+ map->name() + "\n\n" + map->errorString();
QMessageBox::critical(this, APP_NAME, error);
return false;
action->deleteLater();
}
}
@ -1379,31 +1523,42 @@ void GUI::updateWindowTitle()
setWindowTitle(APP_NAME);
}
void GUI::mapChanged(int index)
void GUI::mapChanged()
{
_map = _ml->maps().at(index);
_map = _mapsActionGroup->checkedAction()->data().value<Map*>();
_mapView->setMap(_map);
}
void GUI::nextMap()
{
if (_ml->maps().count() < 2)
QAction *checked = _mapsActionGroup->checkedAction();
if (!checked)
return;
int next = (_ml->maps().indexOf(_map) + 1) % _ml->maps().count();
_mapActions.at(next)->setChecked(true);
mapChanged(next);
QList<QAction*> maps = _mapsActionGroup->actions();
for (int i = 1; i < maps.size(); i++) {
int next = (maps.indexOf(checked) + i) % maps.count();
if (maps.at(next)->isEnabled()) {
maps.at(next)->trigger();
break;
}
}
}
void GUI::prevMap()
{
if (_ml->maps().count() < 2)
QAction *checked = _mapsActionGroup->checkedAction();
if (!checked)
return;
int prev = (_ml->maps().indexOf(_map) + _ml->maps().count() - 1)
% _ml->maps().count();
_mapActions.at(prev)->setChecked(true);
mapChanged(prev);
QList<QAction*> maps = _mapsActionGroup->actions();
for (int i = 1; i < maps.size(); i++) {
int prev = (maps.indexOf(checked) + maps.count() - i) % maps.count();
if (maps.at(prev)->isEnabled()) {
maps.at(prev)->trigger();
break;
}
}
}
void GUI::poiFileChecked(int index)
@ -1487,8 +1642,7 @@ void GUI::setTimeType(TimeType type)
void GUI::setUnits(Units units)
{
_export.units = units;
_options.units = units;
_units = units;
_mapView->setUnits(units);
for (int i = 0; i <_tabs.count(); i++)
@ -1731,23 +1885,42 @@ void GUI::writeSettings()
_showTicksAction->isChecked());
settings.endGroup();
settings.beginGroup(EXPORT_SETTINGS_GROUP);
if (_export.orientation != PAPER_ORIENTATION_DEFAULT)
settings.setValue(PAPER_ORIENTATION_SETTING, _export.orientation);
if (_export.resolution != RESOLUTION_DEFAULT)
settings.setValue(RESOLUTION_SETTING, _export.resolution);
if (_export.paperSize != PAPER_SIZE_DEFAULT)
settings.setValue(PAPER_SIZE_SETTING, _export.paperSize);
if (_export.margins.left() != MARGIN_LEFT_DEFAULT)
settings.setValue(MARGIN_LEFT_SETTING, _export.margins.left());
if (_export.margins.top() != MARGIN_TOP_DEFAULT)
settings.setValue(MARGIN_TOP_SETTING, _export.margins.top());
if (_export.margins.right() != MARGIN_RIGHT_DEFAULT)
settings.setValue(MARGIN_RIGHT_SETTING, _export.margins.right());
if (_export.margins.bottom() != MARGIN_BOTTOM_DEFAULT)
settings.setValue(MARGIN_BOTTOM_SETTING, _export.margins.bottom());
if (_export.fileName != EXPORT_FILENAME_DEFAULT)
settings.setValue(EXPORT_FILENAME_SETTING, _export.fileName);
settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP);
if (_pdfExport.orientation != PAPER_ORIENTATION_DEFAULT)
settings.setValue(PAPER_ORIENTATION_SETTING, _pdfExport.orientation);
if (_pdfExport.resolution != RESOLUTION_DEFAULT)
settings.setValue(RESOLUTION_SETTING, _pdfExport.resolution);
if (_pdfExport.paperSize != PAPER_SIZE_DEFAULT)
settings.setValue(PAPER_SIZE_SETTING, _pdfExport.paperSize);
if (_pdfExport.margins.left() != PDF_MARGIN_LEFT_DEFAULT)
settings.setValue(PDF_MARGIN_LEFT_SETTING, _pdfExport.margins.left());
if (_pdfExport.margins.top() != PDF_MARGIN_TOP_DEFAULT)
settings.setValue(PDF_MARGIN_TOP_SETTING, _pdfExport.margins.top());
if (_pdfExport.margins.right() != PDF_MARGIN_RIGHT_DEFAULT)
settings.setValue(PDF_MARGIN_RIGHT_SETTING, _pdfExport.margins.right());
if (_pdfExport.margins.bottom() != PDF_MARGIN_BOTTOM_DEFAULT)
settings.setValue(PDF_MARGIN_BOTTOM_SETTING, _pdfExport.margins.bottom());
if (_pdfExport.fileName != PDF_FILENAME_DEFAULT)
settings.setValue(PDF_FILENAME_SETTING, _pdfExport.fileName);
settings.endGroup();
settings.beginGroup(PNG_EXPORT_SETTINGS_GROUP);
if (_pngExport.size.width() != PNG_WIDTH_DEFAULT)
settings.setValue(PNG_WIDTH_SETTING, _pngExport.size.width());
if (_pngExport.size.height() != PNG_HEIGHT_DEFAULT)
settings.setValue(PNG_HEIGHT_SETTING, _pngExport.size.height());
if (_pngExport.margins.left() != PNG_MARGIN_LEFT_DEFAULT)
settings.setValue(PNG_MARGIN_LEFT_SETTING, _pngExport.margins.left());
if (_pngExport.margins.top() != PNG_MARGIN_TOP_DEFAULT)
settings.setValue(PNG_MARGIN_TOP_SETTING, _pngExport.margins.top());
if (_pngExport.margins.right() != PNG_MARGIN_RIGHT_DEFAULT)
settings.setValue(PNG_MARGIN_RIGHT_SETTING, _pngExport.margins.right());
if (_pngExport.margins.bottom() != PNG_MARGIN_BOTTOM_DEFAULT)
settings.setValue(PNG_MARGIN_BOTTOM_SETTING, _pngExport.margins.bottom());
if (_pngExport.antialiasing != PNG_ANTIALIASING_DEFAULT)
settings.setValue(PNG_ANTIALIASING_SETTING, _pngExport.antialiasing);
if (_pngExport.fileName != PNG_FILENAME_DEFAULT)
settings.setValue(PNG_FILENAME_SETTING, _pngExport.fileName);
settings.endGroup();
settings.beginGroup(OPTIONS_SETTINGS_GROUP);
@ -1809,10 +1982,21 @@ void GUI::writeSettings()
settings.setValue(USE_REPORTED_SPEED_SETTING, _options.useReportedSpeed);
if (_options.dataUseDEM != DATA_USE_DEM_DEFAULT)
settings.setValue(DATA_USE_DEM_SETTING, _options.dataUseDEM);
if (_options.showSecondaryElevation != SHOW_SECONDARY_ELEVATION_DEFAULT)
settings.setValue(SHOW_SECONDARY_ELEVATION_SETTING,
_options.showSecondaryElevation);
if (_options.showSecondarySpeed != SHOW_SECONDARY_SPEED_DEFAULT)
settings.setValue(SHOW_SECONDARY_SPEED_SETTING,
_options.showSecondarySpeed);
#ifdef ENABLE_TIMEZONES
if (_options.timeZone != TimeZoneInfo())
settings.setValue(TIME_ZONE_SETTING, QVariant::fromValue(
_options.timeZone));
#endif // ENABLE_TIMEZONES
if (_options.useSegments != USE_SEGMENTS_DEFAULT)
settings.setValue(USE_SEGMENTS_SETTING, _options.useSegments);
if (_options.poiRadius != POI_RADIUS_DEFAULT)
settings.setValue(POI_RADIUS_SETTING, _options.poiRadius);
if (_options.poiUseDEM != POI_USE_DEM_DEFAULT)
settings.setValue(POI_USE_DEM_SETTING, _options.poiUseDEM);
if (_options.useOpenGL != USE_OPENGL_DEFAULT)
settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL);
#ifdef ENABLE_HTTP2
@ -1896,9 +2080,11 @@ void GUI::readSettings()
_showMapAction->setChecked(true);
else
_mapView->showMap(false);
if (_ml->maps().count()) {
int index = mapIndex(settings.value(CURRENT_MAP_SETTING).toString());
_mapActions.at(index)->trigger();
QAction *ma = mapAction(settings.value(CURRENT_MAP_SETTING).toString());
if (ma) {
ma->trigger();
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
}
if (settings.value(SHOW_COORDINATES_SETTING, SHOW_COORDINATES_DEFAULT)
.toBool()) {
@ -2000,23 +2186,42 @@ void GUI::readSettings()
}
settings.endGroup();
settings.beginGroup(EXPORT_SETTINGS_GROUP);
_export.orientation = (QPrinter::Orientation) settings.value(
settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP);
_pdfExport.orientation = (QPrinter::Orientation) settings.value(
PAPER_ORIENTATION_SETTING, PAPER_ORIENTATION_DEFAULT).toInt();
_export.resolution = settings.value(RESOLUTION_SETTING, RESOLUTION_DEFAULT)
_pdfExport.resolution = settings.value(RESOLUTION_SETTING,
RESOLUTION_DEFAULT).toInt();
_pdfExport.paperSize = (QPrinter::PaperSize) settings.value(
PAPER_SIZE_SETTING, PAPER_SIZE_DEFAULT).toInt();
qreal ml = settings.value(PDF_MARGIN_LEFT_SETTING, PDF_MARGIN_LEFT_DEFAULT)
.toReal();
qreal mt = settings.value(PDF_MARGIN_TOP_SETTING, PDF_MARGIN_TOP_DEFAULT)
.toReal();
qreal mr = settings.value(PDF_MARGIN_RIGHT_SETTING,
PDF_MARGIN_RIGHT_DEFAULT).toReal();
qreal mb = settings.value(PDF_MARGIN_BOTTOM_SETTING,
PDF_MARGIN_BOTTOM_DEFAULT).toReal();
_pdfExport.margins = MarginsF(ml, mt, mr, mb);
_pdfExport.fileName = settings.value(PDF_FILENAME_SETTING,
PDF_FILENAME_DEFAULT).toString();
settings.endGroup();
settings.beginGroup(PNG_EXPORT_SETTINGS_GROUP);
_pngExport.size = QSize(settings.value(PNG_WIDTH_SETTING, PNG_WIDTH_DEFAULT)
.toInt(), settings.value(PNG_HEIGHT_SETTING, PNG_HEIGHT_DEFAULT).toInt());
int mli = settings.value(PNG_MARGIN_LEFT_SETTING, PNG_MARGIN_LEFT_DEFAULT)
.toInt();
_export.paperSize = (QPrinter::PaperSize) settings.value(PAPER_SIZE_SETTING,
PAPER_SIZE_DEFAULT).toInt();
qreal ml = settings.value(MARGIN_LEFT_SETTING, MARGIN_LEFT_DEFAULT)
.toReal();
qreal mt = settings.value(MARGIN_TOP_SETTING, MARGIN_TOP_DEFAULT).toReal();
qreal mr = settings.value(MARGIN_RIGHT_SETTING, MARGIN_RIGHT_DEFAULT)
.toReal();
qreal mb = settings.value(MARGIN_BOTTOM_SETTING, MARGIN_BOTTOM_DEFAULT)
.toReal();
_export.margins = MarginsF(ml, mt, mr, mb);
_export.fileName = settings.value(EXPORT_FILENAME_SETTING,
EXPORT_FILENAME_DEFAULT).toString();
int mti = settings.value(PNG_MARGIN_TOP_SETTING, PNG_MARGIN_TOP_DEFAULT)
.toInt();
int mri = settings.value(PNG_MARGIN_RIGHT_SETTING, PNG_MARGIN_RIGHT_DEFAULT)
.toInt();
int mbi = settings.value(PNG_MARGIN_BOTTOM_SETTING, PNG_MARGIN_BOTTOM_DEFAULT)
.toInt();
_pngExport.margins = QMargins(mli, mti, mri, mbi);
_pngExport.antialiasing = settings.value(PNG_ANTIALIASING_SETTING,
PNG_ANTIALIASING_DEFAULT).toBool();
_pngExport.fileName = settings.value(PNG_FILENAME_SETTING,
PNG_FILENAME_DEFAULT).toString();
settings.endGroup();
settings.beginGroup(OPTIONS_SETTINGS_GROUP);
@ -2075,14 +2280,23 @@ void GUI::readSettings()
USE_REPORTED_SPEED_DEFAULT).toBool();
_options.dataUseDEM = settings.value(DATA_USE_DEM_SETTING,
DATA_USE_DEM_DEFAULT).toBool();
_options.showSecondaryElevation = settings.value(
SHOW_SECONDARY_ELEVATION_SETTING,
SHOW_SECONDARY_ELEVATION_DEFAULT).toBool();
_options.showSecondarySpeed = settings.value(
SHOW_SECONDARY_SPEED_SETTING,
SHOW_SECONDARY_SPEED_DEFAULT).toBool();
#ifdef ENABLE_TIMEZONES
_options.timeZone = settings.value(TIME_ZONE_SETTING).value<TimeZoneInfo>();
#endif // ENABLE_TIMEZONES
_options.useSegments = settings.value(USE_SEGMENTS_SETTING,
USE_SEGMENTS_DEFAULT).toBool();
_options.automaticPause = settings.value(AUTOMATIC_PAUSE_SETTING,
AUTOMATIC_PAUSE_DEFAULT).toBool();
_options.pauseInterval = settings.value(PAUSE_INTERVAL_SETTING,
PAUSE_INTERVAL_DEFAULT).toInt();
_options.poiRadius = settings.value(POI_RADIUS_SETTING, POI_RADIUS_DEFAULT)
.toInt();
_options.poiUseDEM = settings.value(POI_USE_DEM_SETTING,
POI_USE_DEM_DEFAULT).toBool();
_options.useOpenGL = settings.value(USE_OPENGL_SETTING, USE_OPENGL_DEFAULT)
.toBool();
#ifdef ENABLE_HTTP2
@ -2141,6 +2355,9 @@ void GUI::readSettings()
_options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENABLE_HIDPI
_mapView->setProjection(_options.projection);
#ifdef ENABLE_TIMEZONES
_mapView->setTimeZone(_options.timeZone.zone());
#endif // ENABLE_TIMEZONES
for (int i = 0; i < _tabs.count(); i++) {
_tabs.at(i)->setPalette(_options.palette);
@ -2162,21 +2379,39 @@ void GUI::readSettings()
Track::setPauseSpeed(_options.pauseSpeed);
Track::setPauseInterval(_options.pauseInterval);
Track::useReportedSpeed(_options.useReportedSpeed);
Data::useDEM(_options.dataUseDEM);
Track::useDEM(_options.dataUseDEM);
Track::showSecondaryElevation(_options.showSecondaryElevation);
Track::showSecondarySpeed(_options.showSecondarySpeed);
Track::useSegments(_options.useSegments);
Route::useDEM(_options.dataUseDEM);
Route::showSecondaryElevation(_options.showSecondaryElevation);
Waypoint::useDEM(_options.dataUseDEM);
Waypoint::showSecondaryElevation(_options.showSecondaryElevation);
_poi->setRadius(_options.poiRadius);
_poi->useDEM(_options.poiUseDEM);
QPixmapCache::setCacheLimit(_options.pixmapCache * 1024);
settings.endGroup();
}
int GUI::mapIndex(const QString &name)
QAction *GUI::mapAction(const QString &name)
{
for (int i = 0; i < _ml->maps().count(); i++)
if (_ml->maps().at(i)->name() == name)
return i;
QList<QAction *> maps = _mapsActionGroup->actions();
// Last map
for (int i = 0; i < maps.count(); i++) {
Map *map = maps.at(i)->data().value<Map*>();
if (map->name() == name && map->isReady())
return maps.at(i);
}
// Any usable map
for (int i = 0; i < maps.count(); i++) {
Map *map = maps.at(i)->data().value<Map*>();
if (map->isReady())
return maps.at(i);
}
return 0;
}

View File

@ -10,7 +10,8 @@
#include "units.h"
#include "timetype.h"
#include "format.h"
#include "exportdialog.h"
#include "pdfexportdialog.h"
#include "pngexportdialog.h"
#include "optionsdialog.h"
class QMenu;
@ -26,9 +27,9 @@ class FileBrowser;
class GraphTab;
class MapView;
class Map;
class MapList;
class POI;
class QScreen;
class MapAction;
class GUI : public QMainWindow
{
@ -45,10 +46,11 @@ private slots:
void keys();
void paths();
void printFile();
void exportFile();
void exportPDFFile();
void exportPNGFile();
void openFile();
void closeAll();
void reloadFile();
void reloadFiles();
void statistics();
void openPOIFile();
void closePOIFiles();
@ -64,7 +66,7 @@ private slots:
void prevMap();
void openOptions();
void mapChanged(int);
void mapChanged();
void graphChanged(int);
void poiFileChecked(int);
@ -88,16 +90,22 @@ private slots:
void screenChanged(QScreen *screen);
void logicalDotsPerInchChanged(qreal dpi);
private:
typedef QPair<QDate, QDate> DateRange;
void mapLoaded();
void mapInitialized();
private:
typedef QPair<QDateTime, QDateTime> DateTimeRange;
void loadMaps();
void loadPOIs();
void closeFiles();
void plot(QPrinter *printer);
void plotMainPage(QPainter *painter, const QRectF &rect, qreal ratio,
bool expand = false);
void plotGraphsPage(QPainter *painter, const QRectF &rect, qreal ratio);
qreal graphPlotHeight(const QRectF &rect, qreal ratio);
QAction *createPOIFileAction(const QString &fileName);
QAction *createMapAction(const Map *map);
MapAction *createMapAction(Map *map);
void createPOIFilesActions();
void createMapActions();
void createActions();
@ -111,7 +119,6 @@ private:
bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName);
bool loadMap(const QString &fileName);
void exportFile(const QString &fileName);
void updateStatusBarInfo();
void updateWindowTitle();
void updateNavigationActions();
@ -127,7 +134,7 @@ private:
qreal distance() const;
qreal time() const;
qreal movingTime() const;
int mapIndex(const QString &name);
QAction *mapAction(const QString &name);
void readSettings();
void writeSettings();
@ -151,7 +158,8 @@ private:
QAction *_aboutAction;
QAction *_aboutQtAction;
QAction *_printFileAction;
QAction *_exportFileAction;
QAction *_exportPDFFileAction;
QAction *_exportPNGFileAction;
QAction *_openFileAction;
QAction *_closeFileAction;
QAction *_reloadFileAction;
@ -196,11 +204,9 @@ private:
QAction *_showCoordinatesAction;
QAction *_openOptionsAction;
QAction *_mapsEnd;
QList<QAction*> _mapActions;
QList<QAction*> _poiFilesActions;
QList<QAction*> _poiFilesActions;
QSignalMapper *_poiFilesSignalMapper;
QSignalMapper *_mapsSignalMapper;
QLabel *_fileNameLabel;
QLabel *_distanceLabel;
@ -212,7 +218,6 @@ private:
QList<GraphTab*> _tabs;
POI *_poi;
MapList *_ml;
Map *_map;
FileBrowser *_browser;
@ -221,7 +226,7 @@ private:
int _trackCount, _routeCount, _areaCount, _waypointCount;
qreal _trackDistance, _routeDistance;
qreal _time, _movingTime;
DateRange _dateRange;
DateTimeRange _dateRange;
QString _pathName;
qreal _sliderPos;
@ -229,10 +234,13 @@ private:
QList<QByteArray> _windowStates;
int _frameStyle;
Export _export;
PDFExport _pdfExport;
PNGExport _pngExport;
Options _options;
QString _dataDir, _mapDir, _poiDir;
Units _units;
};
#endif // GUI_H

View File

@ -5,7 +5,7 @@
HeartRateGraphItem::HeartRateGraphItem(const Graph &graph, GraphType type,
int width, const QColor &color, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
: GraphItem(graph, type, width, color, Qt::SolidLine, parent)
{
}

View File

@ -53,10 +53,8 @@ void InfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
}
}
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
//painter->setPen(Qt::red);
//painter->drawRect(boundingRect());
}
void InfoItem::insert(const QString &key, const QString &value)

View File

@ -8,6 +8,7 @@
#define PREV_KEY Qt::Key_Backspace
#define FIRST_KEY Qt::Key_Home
#define LAST_KEY Qt::Key_End
#define MODIFIER_KEY Qt::Key_Shift
#define MODIFIER Qt::ShiftModifier
#define ZOOM_IN Qt::Key_Plus
#define ZOOM_OUT Qt::Key_Minus
@ -18,7 +19,8 @@
#define OPEN_SHORTCUT QKeySequence(QKeySequence::Open)
#define CLOSE_SHORTCUT QKeySequence(QKeySequence::Close)
#define RELOAD_SHORTCUT QKeySequence(QKeySequence::Refresh)
#define EXPORT_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_E)
#define PDF_EXPORT_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_E)
#define PNG_EXPORT_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_X)
#define SHOW_POI_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_P)
#define SHOW_MAP_SHORTCUT QKeySequence(Qt::CTRL + Qt::Key_M)
#define NEXT_MAP_SHORTCUT QKeySequence(QKeySequence::Forward)

32
src/GUI/mapaction.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef MAPACTION_H
#define MAPACTION_H
#include <QAction>
#include "map/map.h"
class MapAction : public QAction
{
Q_OBJECT
public:
MapAction(Map *map, QObject *parent = 0) : QAction(map->name(), parent)
{
map->setParent(this);
setData(QVariant::fromValue(map));
setEnabled(map->isReady());
connect(map, SIGNAL(mapLoaded()), this, SLOT(mapLoaded()));
}
signals:
void loaded();
private slots:
void mapLoaded()
{
Map *map = data().value<Map*>();
setEnabled(map->isValid());
emit loaded();
}
};
#endif // MAPACTION_H

View File

@ -2,8 +2,8 @@
#include <QGraphicsScene>
#include <QWheelEvent>
#include <QApplication>
#include <QPixmapCache>
#include <QScrollBar>
#include <QClipboard>
#include "data/poi.h"
#include "data/data.h"
#include "map/map.h"
@ -55,13 +55,11 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_map = map;
_map->load();
_map->setProjection(_projection);
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
_poi = poi;
connect(_poi, SIGNAL(pointsChanged()), this, SLOT(updatePOI()));
_units = Metric;
_coordinatesFormat = DecimalDegrees;
_mapOpacity = 1.0;
_backgroundColor = Qt::white;
_markerColor = Qt::red;
@ -123,7 +121,6 @@ PathItem *MapView::addTrack(const Track &track)
ti->setColor(_palette.nextColor());
ti->setWidth(_trackWidth);
ti->setStyle(_trackStyle);
ti->setUnits(_units);
ti->setVisible(_showTracks);
ti->setDigitalZoom(_digitalZoom);
ti->setMarkerColor(_markerColor);
@ -150,8 +147,6 @@ PathItem *MapView::addRoute(const Route &route)
ri->setColor(_palette.nextColor());
ri->setWidth(_routeWidth);
ri->setStyle(_routeStyle);
ri->setUnits(_units);
ri->setCoordinatesFormat(_coordinatesFormat);
ri->setVisible(_showRoutes);
ri->showWaypoints(_showRouteWaypoints);
ri->showWaypointLabels(_showWaypointLabels);
@ -201,7 +196,6 @@ void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
wi->setSize(_waypointSize);
wi->setColor(_waypointColor);
wi->showLabel(_showWaypointLabels);
wi->setToolTipFormat(_units, _coordinatesFormat);
wi->setVisible(_showWaypoints);
wi->setDigitalZoom(_digitalZoom);
_scene->addItem(wi);
@ -317,7 +311,7 @@ void MapView::setMap(Map *map)
RectC cr(_map->xy2ll(vr.topLeft()), _map->xy2ll(vr.bottomRight()));
_map->unload();
disconnect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
disconnect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
_map = map;
_map->load();
@ -325,7 +319,7 @@ void MapView::setMap(Map *map)
#ifdef ENABLE_HIDPI
_map->setDevicePixelRatio(_deviceRatio, _mapRatio);
#endif // ENABLE_HIDPI
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
digitalZoom(0);
@ -351,7 +345,6 @@ void MapView::setMap(Map *map)
centerOn(nc);
reloadMap();
QPixmapCache::clear();
}
void MapView::setPOI(POI *poi)
@ -403,7 +396,6 @@ void MapView::addPOI(const QList<Waypoint> &waypoints)
pi->showLabel(_showPOILabels);
pi->setVisible(_showPOI);
pi->setDigitalZoom(_digitalZoom);
pi->setToolTipFormat(_units, _coordinatesFormat);
_scene->addItem(pi);
_pois.insert(SearchPointer<Waypoint>(&(pi->waypoint())), pi);
@ -412,51 +404,38 @@ void MapView::addPOI(const QList<Waypoint> &waypoints)
void MapView::setUnits(Units units)
{
if (_units == units)
return;
_units = units;
_mapScale->setUnits(_units);
WaypointItem::setUnits(units);
PathItem::setUnits(units);
for (int i = 0; i < _tracks.count(); i++)
_tracks[i]->setUnits(_units);
_tracks[i]->updateTicks();
for (int i = 0; i < _routes.count(); i++)
_routes[i]->setUnits(_units);
for (int i = 0; i < _waypoints.size(); i++)
_waypoints.at(i)->setToolTipFormat(_units, _coordinatesFormat);
_routes[i]->updateTicks();
for (POIHash::const_iterator it = _pois.constBegin();
it != _pois.constEnd(); it++)
it.value()->setToolTipFormat(_units, _coordinatesFormat);
_mapScale->setUnits(units);
}
void MapView::setCoordinatesFormat(CoordinatesFormat format)
{
if (_coordinatesFormat == format)
return;
WaypointItem::setCoordinatesFormat(format);
_coordinatesFormat = format;
_coordinates->setFormat(format);
}
_coordinates->setFormat(_coordinatesFormat);
for (int i = 0; i < _waypoints.count(); i++)
_waypoints.at(i)->setToolTipFormat(_units, _coordinatesFormat);
for (int i = 0; i < _routes.count(); i++)
_routes[i]->setCoordinatesFormat(_coordinatesFormat);
for (POIHash::const_iterator it = _pois.constBegin();
it != _pois.constEnd(); it++)
it.value()->setToolTipFormat(_units, _coordinatesFormat);
void MapView::setTimeZone(const QTimeZone &zone)
{
#ifdef ENABLE_TIMEZONES
WaypointItem::setTimeZone(zone);
PathItem::setTimeZone(zone);
#else // ENABLE_TIMEZONES
Q_UNUSED(zone);
#endif // ENABLE_TIMEZONES
}
void MapView::clearMapCache()
{
_map->clearCache();
fitMapZoom();
rescale();
centerOn(contentCenter());
reloadMap();
}
void MapView::digitalZoom(int zoom)
@ -544,7 +523,12 @@ void MapView::keyPressEvent(QKeyEvent *event)
else if (_digitalZoom && event->key() == Qt::Key_Escape) {
digitalZoom(0);
return;
} else {
} else {
if (event->key() == MODIFIER_KEY) {
_cursor = viewport()->cursor();
viewport()->setCursor(Qt::CrossCursor);
}
QGraphicsView::keyPressEvent(event);
return;
}
@ -552,8 +536,26 @@ void MapView::keyPressEvent(QKeyEvent *event)
zoom(z, pos);
}
void MapView::keyReleaseEvent(QKeyEvent *event)
{
if (event->key() == MODIFIER_KEY
&& viewport()->cursor().shape() == Qt::CrossCursor)
viewport()->setCursor(_cursor);
QGraphicsView::keyReleaseEvent(event);
}
void MapView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->modifiers() & MODIFIER)
QApplication::clipboard()->setText(Format::coordinates(
_map->xy2ll(mapToScene(event->pos())), _coordinates->format()));
else
QGraphicsView::mousePressEvent(event);
}
void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
bool hires)
PlotFlags flags)
{
QRect orig, adj;
qreal ratio, diff, q;
@ -581,10 +583,18 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
diff = (orig.height() * ratio) - orig.width();
adj = orig.adjusted(-diff/2, 0, diff/2, 0);
}
q = (target.width() / scale) / adj.width();
// Expand the view if plotting into a bitmap
if (flags & Expand) {
qreal xdiff = (target.width() - adj.width()) / 2.0;
qreal ydiff = (target.height() - adj.height()) / 2.0;
adj.adjust(-xdiff, -ydiff, xdiff, ydiff);
q = 1.0;
} else
q = (target.width() / scale) / adj.width();
// Adjust the view for printing
if (hires) {
if (flags & HiRes) {
zoom = _map->zoom();
QRectF vr(mapToScene(orig).boundingRect());
origScene = vr.center();
@ -616,7 +626,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
render(painter, target, adj);
// Revert view changes to display mode
if (hires) {
if (flags & HiRes) {
_map->setZoom(zoom);
rescale();
centerOn(origScene);
@ -982,7 +992,6 @@ void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
_deviceRatio = deviceRatio;
_mapRatio = mapRatio;
QPixmapCache::clear();
QRectF vr(mapToScene(viewport()->rect()).boundingRect()
.intersected(_map->bounds()));

View File

@ -5,6 +5,7 @@
#include <QVector>
#include <QHash>
#include <QList>
#include <QFlags>
#include "common/rectc.h"
#include "common/config.h"
#include "data/waypoint.h"
@ -31,12 +32,20 @@ class GraphItem;
class AreaItem;
class Area;
class GraphicsScene;
class QTimeZone;
class MapView : public QGraphicsView
{
Q_OBJECT
public:
enum Flag {
NoFlags = 0,
HiRes = 1,
Expand = 2
};
Q_DECLARE_FLAGS(PlotFlags, Flag)
MapView(Map *map, POI *poi, QWidget *parent = 0);
QList<PathItem *> loadData(const Data &data);
@ -45,7 +54,8 @@ public:
void setPOI(POI *poi);
void setMap(Map *map);
void plot(QPainter *painter, const QRectF &target, qreal scale, bool hires);
void plot(QPainter *painter, const QRectF &target, qreal scale,
PlotFlags flags);
void clear();
@ -83,6 +93,7 @@ public slots:
void showTicks(bool show);
void clearMapCache();
void setCoordinatesFormat(CoordinatesFormat format);
void setTimeZone(const QTimeZone &zone);
void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void setProjection(int id);
@ -112,13 +123,15 @@ private:
void updatePOIVisibility();
void skipColor() {_palette.nextColor();}
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void drawBackground(QPainter *painter, const QRectF &rect);
void paintEvent(QPaintEvent *event);
void scrollContentsBy(int dx, int dy);
void mouseMoveEvent(QMouseEvent *event);
void leaveEvent(QEvent *event);
GraphicsScene *_scene;
@ -137,8 +150,6 @@ private:
POI *_poi;
Palette _palette;
Units _units;
CoordinatesFormat _coordinatesFormat;
qreal _mapOpacity;
Projection _projection;
@ -154,6 +165,7 @@ private:
int _digitalZoom;
bool _plot;
QCursor _cursor;
#ifdef ENABLE_HIDPI
qreal _deviceRatio;

View File

@ -16,15 +16,22 @@ public:
qreal right() const {return _right;}
qreal bottom() const {return _bottom;}
qreal &rleft() {return _left;}
qreal &rtop() {return _top;}
qreal &rright() {return _right;}
qreal &rbottom() {return _bottom;}
private:
qreal _left, _top, _right, _bottom;
};
inline MarginsF operator*(const MarginsF &margins, qreal factor)
{
return MarginsF(margins.left() * factor, margins.top() * factor,
margins.right() * factor, margins.bottom() * factor);
}
inline MarginsF operator/(const MarginsF &margins, qreal factor)
{
return MarginsF(margins.left() / factor, margins.top() / factor,
margins.right() / factor, margins.bottom() / factor);
}
#ifndef QT_NO_DEBUG
inline QDebug operator<<(QDebug dbg, const MarginsF &margins)
{

111
src/GUI/marginswidget.cpp Normal file
View File

@ -0,0 +1,111 @@
#include <QSpinBox>
#include <QGridLayout>
#include "units.h"
#include "marginswidget.h"
MarginsWidget::MarginsWidget(QWidget *parent) : QWidget(parent)
{
_top = new QSpinBox();
_bottom = new QSpinBox();
_left = new QSpinBox();
_right = new QSpinBox();
_top->setMaximumWidth(_top->sizeHint().width());
_bottom->setMaximumWidth(_bottom->sizeHint().width());
_left->setMaximumWidth(_left->sizeHint().width());
_right->setMaximumWidth(_right->sizeHint().width());
QGridLayout *layout = new QGridLayout();
layout->addWidget(_top, 0, 0, 1, 2, Qt::AlignCenter);
layout->addWidget(_left, 1, 0, 1, 1, Qt::AlignRight);
layout->addWidget(_right, 1, 1, 1, 1, Qt::AlignLeft);
layout->addWidget(_bottom, 2, 0, 1, 2, Qt::AlignCenter);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setLayout(layout);
}
void MarginsWidget::setValue(const QMargins &value)
{
_top->setValue(value.top());
_bottom->setValue(value.bottom());
_left->setValue(value.left());
_right->setValue(value.right());
}
void MarginsWidget::setUnits(const QString &units)
{
_top->setSuffix(UNIT_SPACE + units);
_bottom->setSuffix(UNIT_SPACE + units);
_left->setSuffix(UNIT_SPACE + units);
_right->setSuffix(UNIT_SPACE + units);
_top->setMaximumWidth(_top->sizeHint().width());
_bottom->setMaximumWidth(_bottom->sizeHint().width());
_left->setMaximumWidth(_left->sizeHint().width());
_right->setMaximumWidth(_right->sizeHint().width());
}
QMargins MarginsWidget::value() const
{
return QMargins(_left->value(), _top->value(), _right->value(),
_bottom->value());
}
MarginsFWidget::MarginsFWidget(QWidget *parent) : QWidget(parent)
{
_top = new QDoubleSpinBox();
_bottom = new QDoubleSpinBox();
_left = new QDoubleSpinBox();
_right = new QDoubleSpinBox();
_top->setMaximumWidth(_top->sizeHint().width());
_bottom->setMaximumWidth(_bottom->sizeHint().width());
_left->setMaximumWidth(_left->sizeHint().width());
_right->setMaximumWidth(_right->sizeHint().width());
QGridLayout *layout = new QGridLayout();
layout->addWidget(_top, 0, 0, 1, 2, Qt::AlignCenter);
layout->addWidget(_left, 1, 0, 1, 1, Qt::AlignRight);
layout->addWidget(_right, 1, 1, 1, 1, Qt::AlignLeft);
layout->addWidget(_bottom, 2, 0, 1, 2, Qt::AlignCenter);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setLayout(layout);
}
void MarginsFWidget::setValue(const MarginsF &value)
{
_top->setValue(value.top());
_bottom->setValue(value.bottom());
_left->setValue(value.left());
_right->setValue(value.right());
}
void MarginsFWidget::setUnits(const QString &units)
{
_top->setSuffix(UNIT_SPACE + units);
_bottom->setSuffix(UNIT_SPACE + units);
_left->setSuffix(UNIT_SPACE + units);
_right->setSuffix(UNIT_SPACE + units);
_top->setMaximumWidth(_top->sizeHint().width());
_bottom->setMaximumWidth(_bottom->sizeHint().width());
_left->setMaximumWidth(_left->sizeHint().width());
_right->setMaximumWidth(_right->sizeHint().width());
}
void MarginsFWidget::setSingleStep(qreal step)
{
_top->setSingleStep(step);
_bottom->setSingleStep(step);
_left->setSingleStep(step);
_right->setSingleStep(step);
}
MarginsF MarginsFWidget::value() const
{
return MarginsF(_left->value(), _top->value(), _right->value(),
_bottom->value());
}

48
src/GUI/marginswidget.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef MARGINSWIDGET_H
#define MARGINSWIDGET_H
#include <QWidget>
#include <QMargins>
#include "margins.h"
class QSpinBox;
class QDoubleSpinBox;
class MarginsWidget : public QWidget
{
Q_OBJECT
public:
MarginsWidget(QWidget *parent = 0);
QMargins value() const;
void setValue(const QMargins &value);
void setUnits(const QString &units);
private:
QSpinBox *_top;
QSpinBox *_bottom;
QSpinBox *_left;
QSpinBox *_right;
};
class MarginsFWidget : public QWidget
{
Q_OBJECT
public:
MarginsFWidget(QWidget *parent = 0);
MarginsF value() const;
void setValue(const MarginsF &value);
void setUnits(const QString &units);
void setSingleStep(qreal step);
private:
QDoubleSpinBox *_top;
QDoubleSpinBox *_bottom;
QDoubleSpinBox *_left;
QDoubleSpinBox *_right;
};
#endif // MARGINSWIDGET_H

View File

@ -12,6 +12,7 @@
#include <QRadioButton>
#include <QLabel>
#include <QSysInfo>
#include <QButtonGroup>
#include "map/pcs.h"
#include "icons.h"
#include "colorbox.h"
@ -55,12 +56,12 @@ QWidget *OptionsDialog::createMapPage()
+ projections.at(i).value();
_projection->addItem(text, QVariant(projections.at(i).key()));
}
_projection->setCurrentIndex(_projection->findData(_options->projection));
_projection->setCurrentIndex(_projection->findData(_options.projection));
#ifdef ENABLE_HIDPI
_hidpi = new QRadioButton(tr("High-resolution"));
_lodpi = new QRadioButton(tr("Standard"));
if (_options->hidpiMap)
if (_options.hidpiMap)
_hidpi->setChecked(true);
else
_lodpi->setChecked(true);
@ -111,10 +112,10 @@ QWidget *OptionsDialog::createAppearancePage()
{
// Tracks
_trackWidth = new QSpinBox();
_trackWidth->setValue(_options->trackWidth);
_trackWidth->setValue(_options.trackWidth);
_trackWidth->setMinimum(1);
_trackStyle = new StyleComboBox();
_trackStyle->setValue(_options->trackStyle);
_trackStyle->setValue(_options.trackStyle);
QFormLayout *trackLayout = new QFormLayout();
#ifdef Q_OS_MAC
trackLayout->addRow(tr("Track width:"), _trackWidth);
@ -128,10 +129,10 @@ QWidget *OptionsDialog::createAppearancePage()
// Routes
_routeWidth = new QSpinBox();
_routeWidth->setValue(_options->routeWidth);
_routeWidth->setValue(_options.routeWidth);
_routeWidth->setMinimum(1);
_routeStyle = new StyleComboBox();
_routeStyle->setValue(_options->routeStyle);
_routeStyle->setValue(_options.routeStyle);
QFormLayout *routeLayout = new QFormLayout();
#ifdef Q_OS_MAC
routeLayout->addRow(tr("Route width:"), _routeWidth);
@ -145,11 +146,11 @@ QWidget *OptionsDialog::createAppearancePage()
// Areas
_areaWidth = new QSpinBox();
_areaWidth->setValue(_options->areaWidth);
_areaWidth->setValue(_options.areaWidth);
_areaStyle = new StyleComboBox();
_areaStyle->setValue(_options->areaStyle);
_areaStyle->setValue(_options.areaStyle);
_areaOpacity = new PercentSlider();
_areaOpacity->setValue(_options->areaOpacity);
_areaOpacity->setValue(_options.areaOpacity);
QFormLayout *areaLayout = new QFormLayout();
#ifdef Q_OS_MAC
areaLayout->addRow(tr("Area border width:"), _areaWidth);
@ -165,18 +166,15 @@ QWidget *OptionsDialog::createAppearancePage()
// Palette & antialiasing
_baseColor = new ColorBox();
_baseColor->setColor(_options->palette.color());
_colorOffset = new QDoubleSpinBox();
_colorOffset->setMinimum(0);
_colorOffset->setMaximum(1.0);
_colorOffset->setSingleStep(0.01);
_colorOffset->setValue(_options->palette.shift());
_baseColor->setColor(_options.palette.color());
_colorOffset = new PercentSlider();
_colorOffset->setValue(_options.palette.shift() * 100);
QFormLayout *paletteLayout = new QFormLayout();
paletteLayout->addRow(tr("Base color:"), _baseColor);
paletteLayout->addRow(tr("Palette shift:"), _colorOffset);
_pathAA = new QCheckBox(tr("Use anti-aliasing"));
_pathAA->setChecked(_options->pathAntiAliasing);
_pathAA->setChecked(_options.pathAntiAliasing);
QFormLayout *pathAALayout = new QFormLayout();
pathAALayout->addWidget(_pathAA);
@ -203,9 +201,9 @@ QWidget *OptionsDialog::createAppearancePage()
// Waypoints
_waypointSize = new QSpinBox();
_waypointSize->setMinimum(1);
_waypointSize->setValue(_options->waypointSize);
_waypointSize->setValue(_options.waypointSize);
_waypointColor = new ColorBox();
_waypointColor->setColor(_options->waypointColor);
_waypointColor->setColor(_options.waypointColor);
QFormLayout *waypointLayout = new QFormLayout();
#ifdef Q_OS_MAC
waypointLayout->addRow(tr("Waypoint color:"), _waypointColor);
@ -219,9 +217,9 @@ QWidget *OptionsDialog::createAppearancePage()
_poiSize = new QSpinBox();
_poiSize->setMinimum(1);
_poiSize->setValue(_options->poiSize);
_poiSize->setValue(_options.poiSize);
_poiColor = new ColorBox();
_poiColor->setColor(_options->poiColor);
_poiColor->setColor(_options.poiColor);
QFormLayout *poiLayout = new QFormLayout();
#ifdef Q_OS_MAC
poiLayout->addRow(tr("POI color:"), _poiColor);
@ -249,9 +247,9 @@ QWidget *OptionsDialog::createAppearancePage()
// Graphs
_sliderColor = new ColorBox();
_sliderColor->setColor(_options->sliderColor);
_sliderColor->setColor(_options.sliderColor);
_graphWidth = new QSpinBox();
_graphWidth->setValue(_options->graphWidth);
_graphWidth->setValue(_options.graphWidth);
_graphWidth->setMinimum(1);
QFormLayout *graphLayout = new QFormLayout();
@ -259,7 +257,7 @@ QWidget *OptionsDialog::createAppearancePage()
graphLayout->addRow(tr("Slider color:"), _sliderColor);
_graphAA = new QCheckBox(tr("Use anti-aliasing"));
_graphAA->setChecked(_options->graphAntiAliasing);
_graphAA->setChecked(_options.graphAntiAliasing);
QFormLayout *graphAALayout = new QFormLayout();
graphAALayout->addWidget(_graphAA);
@ -273,9 +271,9 @@ QWidget *OptionsDialog::createAppearancePage()
// Map
_mapOpacity = new PercentSlider();
_mapOpacity->setValue(_options->mapOpacity);
_mapOpacity->setValue(_options.mapOpacity);
_backgroundColor = new ColorBox();
_backgroundColor->setColor(_options->backgroundColor);
_backgroundColor->setColor(_options.backgroundColor);
_backgroundColor->enableAlphaChannel(false);
QFormLayout *mapLayout = new QFormLayout();
@ -303,19 +301,19 @@ QWidget *OptionsDialog::createDataPage()
QString filterToolTip = tr("Moving average window size");
_elevationFilter = new OddSpinBox();
_elevationFilter->setValue(_options->elevationFilter);
_elevationFilter->setValue(_options.elevationFilter);
_elevationFilter->setToolTip(filterToolTip);
_speedFilter = new OddSpinBox();
_speedFilter->setValue(_options->speedFilter);
_speedFilter->setValue(_options.speedFilter);
_speedFilter->setToolTip(filterToolTip);
_heartRateFilter = new OddSpinBox();
_heartRateFilter->setValue(_options->heartRateFilter);
_heartRateFilter->setValue(_options.heartRateFilter);
_heartRateFilter->setToolTip(filterToolTip);
_cadenceFilter = new OddSpinBox();
_cadenceFilter->setValue(_options->cadenceFilter);
_cadenceFilter->setValue(_options.cadenceFilter);
_cadenceFilter->setToolTip(filterToolTip);
_powerFilter = new OddSpinBox();
_powerFilter->setValue(_options->powerFilter);
_powerFilter->setValue(_options.powerFilter);
_powerFilter->setToolTip(filterToolTip);
QFormLayout *smoothLayout = new QFormLayout();
@ -330,7 +328,7 @@ QWidget *OptionsDialog::createDataPage()
#endif // Q_OS_MAC
_outlierEliminate = new QCheckBox(tr("Eliminate GPS outliers"));
_outlierEliminate->setChecked(_options->outlierEliminate);
_outlierEliminate->setChecked(_options.outlierEliminate);
QFormLayout *outlierLayout = new QFormLayout();
outlierLayout->addWidget(_outlierEliminate);
@ -351,7 +349,7 @@ QWidget *OptionsDialog::createDataPage()
_automaticPause = new QRadioButton(tr("Automatic"));
_manualPause = new QRadioButton(tr("Custom"));
if (_options->automaticPause)
if (_options.automaticPause)
_automaticPause->setChecked(true);
else
_manualPause->setChecked(true);
@ -361,20 +359,20 @@ QWidget *OptionsDialog::createDataPage()
_pauseSpeed->setSingleStep(0.1);
_pauseSpeed->setMinimum(0.1);
_pauseSpeed->setEnabled(_manualPause->isChecked());
if (_options->units == Imperial) {
_pauseSpeed->setValue(_options->pauseSpeed * MS2MIH);
if (_units == Imperial) {
_pauseSpeed->setValue(_options.pauseSpeed * MS2MIH);
_pauseSpeed->setSuffix(UNIT_SPACE + tr("mi/h"));
} else if (_options->units == Nautical) {
_pauseSpeed->setValue(_options->pauseSpeed * MS2KN);
} else if (_units == Nautical) {
_pauseSpeed->setValue(_options.pauseSpeed * MS2KN);
_pauseSpeed->setSuffix(UNIT_SPACE + tr("kn"));
} else {
_pauseSpeed->setValue(_options->pauseSpeed * MS2KMH);
_pauseSpeed->setValue(_options.pauseSpeed * MS2KMH);
_pauseSpeed->setSuffix(UNIT_SPACE + tr("km/h"));
}
_pauseInterval = new QSpinBox();
_pauseInterval->setMinimum(1);
_pauseInterval->setSuffix(UNIT_SPACE + tr("s"));
_pauseInterval->setValue(_options->pauseInterval);
_pauseInterval->setValue(_options.pauseInterval);
_pauseInterval->setEnabled(_manualPause->isChecked());
connect(_automaticPause, SIGNAL(toggled(bool)), this,
@ -402,54 +400,135 @@ QWidget *OptionsDialog::createDataPage()
_computedSpeed = new QRadioButton(tr("Computed from distance/time"));
_reportedSpeed = new QRadioButton(tr("Recorded by device"));
if (_options->useReportedSpeed)
if (_options.useReportedSpeed)
_reportedSpeed->setChecked(true);
else
_computedSpeed->setChecked(true);
_showSecondarySpeed = new QCheckBox(tr("Show secondary speed"));
_showSecondarySpeed->setChecked(_options.showSecondarySpeed);
_dataGPSElevation = new QRadioButton(tr("GPS data"));
_dataDEMElevation = new QRadioButton(tr("DEM data"));
if (_options->dataUseDEM)
if (_options.dataUseDEM)
_dataDEMElevation->setChecked(true);
else
_dataGPSElevation->setChecked(true);
_showSecondaryElevation = new QCheckBox(tr("Show secondary elevation"));
_showSecondaryElevation->setChecked(_options.showSecondaryElevation);
#ifdef ENABLE_TIMEZONES
_utcZone = new QRadioButton(tr("UTC"));
_systemZone = new QRadioButton(tr("System"));
_customZone = new QRadioButton(tr("Custom"));
if (_options.timeZone.type() == TimeZoneInfo::UTC)
_utcZone->setChecked(true);
else if (_options.timeZone.type() == TimeZoneInfo::System)
_systemZone->setChecked(true);
else
_customZone->setChecked(true);
_timeZone = new QComboBox();
_timeZone->setEnabled(_customZone->isChecked());
QList<QByteArray> zones = QTimeZone::availableTimeZoneIds();
for (int i = 0; i < zones.size(); i++)
_timeZone->addItem(zones.at(i));
_timeZone->setCurrentText(_options.timeZone.customZone().id());
connect(_customZone, SIGNAL(toggled(bool)), _timeZone,
SLOT(setEnabled(bool)));
QHBoxLayout *customZoneLayout = new QHBoxLayout();
customZoneLayout->addSpacing(20);
customZoneLayout->addWidget(_timeZone);
#endif // ENABLE_TIMEZONES
_useSegments = new QCheckBox(tr("Use segments"));
_useSegments->setChecked(_options.useSegments);
QWidget *sourceTab = new QWidget();
QVBoxLayout *sourceTabLayout = new QVBoxLayout();
#ifdef Q_OS_MAC
QButtonGroup *speedGroup = new QButtonGroup(this);
speedGroup->addButton(_computedSpeed);
speedGroup->addButton(_reportedSpeed);
QVBoxLayout *speedOptions = new QVBoxLayout();
speedOptions->addWidget(_computedSpeed);
speedOptions->addWidget(_reportedSpeed);
speedOptions->addWidget(_showSecondarySpeed);
QButtonGroup *elevationGroup = new QButtonGroup(this);
elevationGroup->addButton(_dataGPSElevation);
elevationGroup->addButton(_dataDEMElevation);
QVBoxLayout *elevationOptions = new QVBoxLayout();
elevationOptions->addWidget(_dataGPSElevation);
elevationOptions->addWidget(_dataDEMElevation);
elevationOptions->addWidget(_showSecondaryElevation);
#ifdef ENABLE_TIMEZONES
QButtonGroup *timeZoneGroup = new QButtonGroup(this);
timeZoneGroup->addButton(_utcZone);
timeZoneGroup->addButton(_systemZone);
timeZoneGroup->addButton(_customZone);
QVBoxLayout *zoneOptions = new QVBoxLayout();
zoneOptions->addWidget(_utcZone);
zoneOptions->addWidget(_systemZone);
zoneOptions->addWidget(_customZone);
zoneOptions->addItem(customZoneLayout);
#endif // ENABLE_TIMEZONES
QFormLayout *formLayout = new QFormLayout();
formLayout->addRow(tr("Speed:"), speedOptions);
formLayout->addRow(tr("Elevation:"), elevationOptions);
#ifdef ENABLE_TIMEZONES
formLayout->addRow(tr("Time zone:"), zoneOptions);
#endif // ENABLE_TIMEZONES
QFormLayout *segmentsLayout = new QFormLayout();
segmentsLayout->addWidget(_useSegments);
sourceTabLayout->addLayout(formLayout);
sourceTabLayout->addWidget(line());
sourceTabLayout->addLayout(segmentsLayout);
#else // Q_OS_MAC
QFormLayout *speedLayout = new QFormLayout();
QFormLayout *elevationLayout = new QFormLayout();
#ifdef ENABLE_TIMEZONES
QFormLayout *timeZoneLayout = new QFormLayout();
#endif // ENABLE_TIMEZONES
QFormLayout *segmentsLayout = new QFormLayout();
speedLayout->addWidget(_computedSpeed);
speedLayout->addWidget(_reportedSpeed);
speedLayout->addWidget(_showSecondarySpeed);
QGroupBox *speedBox = new QGroupBox(tr("Speed"));
speedBox->setLayout(speedLayout);
elevationLayout->addWidget(_dataGPSElevation);
elevationLayout->addWidget(_dataDEMElevation);
elevationLayout->addWidget(_showSecondaryElevation);
QGroupBox *elevationBox = new QGroupBox(tr("Elevation"));
elevationBox->setLayout(elevationLayout);
#ifdef ENABLE_TIMEZONES
timeZoneLayout->addWidget(_utcZone);
timeZoneLayout->addWidget(_systemZone);
timeZoneLayout->addWidget(_customZone);
timeZoneLayout->addItem(customZoneLayout);
QGroupBox *timeZoneBox = new QGroupBox(tr("Time zone"));
timeZoneBox->setLayout(timeZoneLayout);
#endif // ENABLE_TIMEZONES
segmentsLayout->addWidget(_useSegments);
sourceTabLayout->addWidget(speedBox);
sourceTabLayout->addWidget(elevationBox);
#ifdef ENABLE_TIMEZONES
sourceTabLayout->addWidget(timeZoneBox);
#endif // ENABLE_TIMEZONES
sourceTabLayout->addLayout(segmentsLayout);
#endif // Q_OS_MAC
sourceTabLayout->addStretch();
sourceTab->setLayout(sourceTabLayout);
@ -465,34 +544,22 @@ QWidget *OptionsDialog::createDataPage()
QWidget *OptionsDialog::createPOIPage()
{
_poiGPSElevation = new QRadioButton(tr("GPS data"));
_poiDEMElevation = new QRadioButton(tr("DEM data"));
if (_options->poiUseDEM)
_poiDEMElevation->setChecked(true);
else
_poiGPSElevation->setChecked(true);
_poiRadius = new QDoubleSpinBox();
_poiRadius->setSingleStep(1);
_poiRadius->setDecimals(1);
if (_options->units == Imperial) {
_poiRadius->setValue(_options->poiRadius / MIINM);
if (_units == Imperial) {
_poiRadius->setValue(_options.poiRadius / MIINM);
_poiRadius->setSuffix(UNIT_SPACE + tr("mi"));
} else if (_options->units == Nautical) {
_poiRadius->setValue(_options->poiRadius / NMIINM);
} else if (_units == Nautical) {
_poiRadius->setValue(_options.poiRadius / NMIINM);
_poiRadius->setSuffix(UNIT_SPACE + tr("nmi"));
} else {
_poiRadius->setValue(_options->poiRadius / KMINM);
_poiRadius->setValue(_options.poiRadius / KMINM);
_poiRadius->setSuffix(UNIT_SPACE + tr("km"));
}
QVBoxLayout *elevationLayout = new QVBoxLayout();
elevationLayout->addWidget(_poiGPSElevation);
elevationLayout->addWidget(_poiDEMElevation);
QFormLayout *poiLayout = new QFormLayout();
poiLayout->addRow(tr("Radius:"), _poiRadius);
poiLayout->addRow(tr("Elevation:"), elevationLayout);
QWidget *poiTab = new QWidget();
poiTab->setLayout(poiLayout);
@ -507,7 +574,7 @@ QWidget *OptionsDialog::createExportPage()
{
_wysiwyg = new QRadioButton(tr("WYSIWYG"));
_hires = new QRadioButton(tr("High-Resolution"));
if (_options->hiresPrint)
if (_options.hiresPrint)
_hires->setChecked(true);
else
_wysiwyg->setChecked(true);
@ -536,17 +603,17 @@ QWidget *OptionsDialog::createExportPage()
_name = new QCheckBox(tr("Name"));
_name->setChecked(_options->printName);
_name->setChecked(_options.printName);
_date = new QCheckBox(tr("Date"));
_date->setChecked(_options->printDate);
_date->setChecked(_options.printDate);
_distance = new QCheckBox(tr("Distance"));
_distance->setChecked(_options->printDistance);
_distance->setChecked(_options.printDistance);
_time = new QCheckBox(tr("Time"));
_time->setChecked(_options->printTime);
_time->setChecked(_options.printTime);
_movingTime = new QCheckBox(tr("Moving time"));
_movingTime->setChecked(_options->printMovingTime);
_movingTime->setChecked(_options.printMovingTime);
_itemCount = new QCheckBox(tr("Item count (>1)"));
_itemCount->setChecked(_options->printItemCount);
_itemCount->setChecked(_options.printItemCount);
QFormLayout *headerTabLayout = new QFormLayout();
headerTabLayout->addWidget(_name);
@ -561,7 +628,7 @@ QWidget *OptionsDialog::createExportPage()
_separateGraphPage = new QCheckBox(tr("Separate graph page"));
_separateGraphPage->setChecked(_options->separateGraphPage);
_separateGraphPage->setChecked(_options.separateGraphPage);
QFormLayout *graphTabLayout = new QFormLayout();
graphTabLayout->addWidget(_separateGraphPage);
@ -580,23 +647,23 @@ QWidget *OptionsDialog::createExportPage()
QWidget *OptionsDialog::createSystemPage()
{
_useOpenGL = new QCheckBox(tr("Use OpenGL"));
_useOpenGL->setChecked(_options->useOpenGL);
_useOpenGL->setChecked(_options.useOpenGL);
#ifdef ENABLE_HTTP2
_enableHTTP2 = new QCheckBox(tr("Enable HTTP/2"));
_enableHTTP2->setChecked(_options->enableHTTP2);
_enableHTTP2->setChecked(_options.enableHTTP2);
#endif // ENABLE_HTTP2
_pixmapCache = new QSpinBox();
_pixmapCache->setMinimum(16);
_pixmapCache->setMaximum(1024);
_pixmapCache->setSuffix(UNIT_SPACE + tr("MB"));
_pixmapCache->setValue(_options->pixmapCache);
_pixmapCache->setValue(_options.pixmapCache);
_connectionTimeout = new QSpinBox();
_connectionTimeout->setMinimum(30);
_connectionTimeout->setMaximum(120);
_connectionTimeout->setSuffix(UNIT_SPACE + tr("s"));
_connectionTimeout->setValue(_options->connectionTimeout);
_connectionTimeout->setValue(_options.connectionTimeout);
QFormLayout *formLayout = new QFormLayout();
formLayout->addRow(tr("Image cache size:"), _pixmapCache);
@ -621,8 +688,8 @@ QWidget *OptionsDialog::createSystemPage()
return systemPage;
}
OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
: QDialog(parent), _options(options)
OptionsDialog::OptionsDialog(Options &options, Units units, QWidget *parent)
: QDialog(parent), _options(options), _units(units)
{
QStackedWidget *pages = new QStackedWidget();
pages->addWidget(createAppearancePage());
@ -674,73 +741,82 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
void OptionsDialog::accept()
{
_options->palette.setColor(_baseColor->color());
_options->palette.setShift(_colorOffset->value());
_options->mapOpacity = _mapOpacity->value();
_options->backgroundColor = _backgroundColor->color();
_options->trackWidth = _trackWidth->value();
_options->trackStyle = (Qt::PenStyle) _trackStyle->itemData(
_options.palette.setColor(_baseColor->color());
_options.palette.setShift(_colorOffset->value() / 100.0);
_options.mapOpacity = _mapOpacity->value();
_options.backgroundColor = _backgroundColor->color();
_options.trackWidth = _trackWidth->value();
_options.trackStyle = (Qt::PenStyle) _trackStyle->itemData(
_trackStyle->currentIndex()).toInt();
_options->routeWidth = _routeWidth->value();
_options->routeStyle = (Qt::PenStyle) _routeStyle->itemData(
_options.routeWidth = _routeWidth->value();
_options.routeStyle = (Qt::PenStyle) _routeStyle->itemData(
_routeStyle->currentIndex()).toInt();
_options->pathAntiAliasing = _pathAA->isChecked();
_options->areaWidth = _areaWidth->value();
_options->areaStyle = (Qt::PenStyle) _areaStyle->itemData(
_options.pathAntiAliasing = _pathAA->isChecked();
_options.areaWidth = _areaWidth->value();
_options.areaStyle = (Qt::PenStyle) _areaStyle->itemData(
_areaStyle->currentIndex()).toInt();
_options->areaOpacity = _areaOpacity->value();
_options->waypointSize = _waypointSize->value();
_options->waypointColor = _waypointColor->color();
_options->poiSize = _poiSize->value();
_options->poiColor = _poiColor->color();
_options->graphWidth = _graphWidth->value();
_options->sliderColor = _sliderColor->color();
_options->graphAntiAliasing = _graphAA->isChecked();
_options.areaOpacity = _areaOpacity->value();
_options.waypointSize = _waypointSize->value();
_options.waypointColor = _waypointColor->color();
_options.poiSize = _poiSize->value();
_options.poiColor = _poiColor->color();
_options.graphWidth = _graphWidth->value();
_options.sliderColor = _sliderColor->color();
_options.graphAntiAliasing = _graphAA->isChecked();
_options->projection = _projection->itemData(_projection->currentIndex())
_options.projection = _projection->itemData(_projection->currentIndex())
.toInt();
#ifdef ENABLE_HIDPI
_options->hidpiMap = _hidpi->isChecked();
_options.hidpiMap = _hidpi->isChecked();
#endif // ENABLE_HIDPI
_options->elevationFilter = _elevationFilter->value();
_options->speedFilter = _speedFilter->value();
_options->heartRateFilter = _heartRateFilter->value();
_options->cadenceFilter = _cadenceFilter->value();
_options->powerFilter = _powerFilter->value();
_options->outlierEliminate = _outlierEliminate->isChecked();
_options->automaticPause = _automaticPause->isChecked();
qreal pauseSpeed = (_options->units == Imperial)
? _pauseSpeed->value() / MS2MIH : (_options->units == Nautical)
_options.elevationFilter = _elevationFilter->value();
_options.speedFilter = _speedFilter->value();
_options.heartRateFilter = _heartRateFilter->value();
_options.cadenceFilter = _cadenceFilter->value();
_options.powerFilter = _powerFilter->value();
_options.outlierEliminate = _outlierEliminate->isChecked();
_options.automaticPause = _automaticPause->isChecked();
qreal pauseSpeed = (_units == Imperial)
? _pauseSpeed->value() / MS2MIH : (_units == Nautical)
? _pauseSpeed->value() / MS2KN : _pauseSpeed->value() / MS2KMH;
if (qAbs(pauseSpeed - _options->pauseSpeed) > 0.01)
_options->pauseSpeed = pauseSpeed;
_options->pauseInterval = _pauseInterval->value();
_options->useReportedSpeed = _reportedSpeed->isChecked();
_options->dataUseDEM = _dataDEMElevation->isChecked();
if (qAbs(pauseSpeed - _options.pauseSpeed) > 0.01)
_options.pauseSpeed = pauseSpeed;
_options.pauseInterval = _pauseInterval->value();
_options.useReportedSpeed = _reportedSpeed->isChecked();
_options.dataUseDEM = _dataDEMElevation->isChecked();
_options.showSecondaryElevation = _showSecondaryElevation->isChecked();
_options.showSecondarySpeed = _showSecondarySpeed->isChecked();
#ifdef ENABLE_TIMEZONES
_options.timeZone.setType(_utcZone->isChecked()
? TimeZoneInfo::UTC : _systemZone->isChecked()
? TimeZoneInfo::System : TimeZoneInfo::Custom);
_options.timeZone.setCustomZone(QTimeZone(_timeZone->currentText()
.toLatin1()));
#endif // ENABLE_TIMEZONES
_options.useSegments = _useSegments->isChecked();
qreal poiRadius = (_options->units == Imperial)
? _poiRadius->value() * MIINM : (_options->units == Nautical)
qreal poiRadius = (_units == Imperial)
? _poiRadius->value() * MIINM : (_units == Nautical)
? _poiRadius->value() * NMIINM : _poiRadius->value() * KMINM;
if (qAbs(poiRadius - _options->poiRadius) > 0.01)
_options->poiRadius = poiRadius;
_options->poiUseDEM = _poiDEMElevation->isChecked();
if (qAbs(poiRadius - _options.poiRadius) > 0.01)
_options.poiRadius = poiRadius;
_options->useOpenGL = _useOpenGL->isChecked();
_options.useOpenGL = _useOpenGL->isChecked();
#ifdef ENABLE_HTTP2
_options->enableHTTP2 = _enableHTTP2->isChecked();
_options.enableHTTP2 = _enableHTTP2->isChecked();
#endif // ENABLE_HTTP2
_options->pixmapCache = _pixmapCache->value();
_options->connectionTimeout = _connectionTimeout->value();
_options.pixmapCache = _pixmapCache->value();
_options.connectionTimeout = _connectionTimeout->value();
_options->hiresPrint = _hires->isChecked();
_options->printName = _name->isChecked();
_options->printDate = _date->isChecked();
_options->printDistance = _distance->isChecked();
_options->printTime = _time->isChecked();
_options->printMovingTime = _movingTime->isChecked();
_options->printItemCount = _itemCount->isChecked();
_options->separateGraphPage = _separateGraphPage->isChecked();
_options.hiresPrint = _hires->isChecked();
_options.printName = _name->isChecked();
_options.printDate = _date->isChecked();
_options.printDistance = _distance->isChecked();
_options.printTime = _time->isChecked();
_options.printMovingTime = _movingTime->isChecked();
_options.printItemCount = _itemCount->isChecked();
_options.separateGraphPage = _separateGraphPage->isChecked();
QDialog::accept();
}

View File

@ -5,6 +5,9 @@
#include "common/config.h"
#include "palette.h"
#include "units.h"
#ifdef ENABLE_TIMEZONES
#include "timezoneinfo.h"
#endif // ENABLE_TIMEZONES
class ColorBox;
class StyleComboBox;
@ -17,6 +20,7 @@ class QRadioButton;
class PercentSlider;
class LimitedComboBox;
struct Options {
// Appearance
Palette palette;
@ -54,9 +58,14 @@ struct Options {
int pauseInterval;
bool useReportedSpeed;
bool dataUseDEM;
bool showSecondaryElevation;
bool showSecondarySpeed;
#ifdef ENABLE_TIMEZONES
TimeZoneInfo timeZone;
#endif // ENABLE_TIMEZONES
bool useSegments;
// POI
int poiRadius;
bool poiUseDEM;
// System
bool useOpenGL;
#ifdef ENABLE_HTTP2
@ -73,8 +82,6 @@ struct Options {
bool printMovingTime;
bool printItemCount;
bool separateGraphPage;
Units units;
};
class OptionsDialog : public QDialog
@ -85,7 +92,7 @@ public slots:
void accept();
public:
OptionsDialog(Options *options, QWidget *parent = 0);
OptionsDialog(Options &options, Units units, QWidget *parent = 0);
private slots:
void automaticPauseDetectionSet(bool set);
@ -98,11 +105,12 @@ private:
QWidget *createSystemPage();
QWidget *createExportPage();
Options *_options;
Options &_options;
Units _units;
// Appearance
ColorBox *_baseColor;
QDoubleSpinBox *_colorOffset;
PercentSlider *_colorOffset;
PercentSlider *_mapOpacity;
ColorBox *_backgroundColor;
QSpinBox *_trackWidth;
@ -133,7 +141,6 @@ private:
OddSpinBox *_cadenceFilter;
OddSpinBox *_powerFilter;
QCheckBox *_outlierEliminate;
QRadioButton *_automaticPause;
QRadioButton *_manualPause;
QDoubleSpinBox *_pauseSpeed;
@ -142,10 +149,17 @@ private:
QRadioButton *_reportedSpeed;
QRadioButton *_dataGPSElevation;
QRadioButton *_dataDEMElevation;
QCheckBox *_showSecondaryElevation;
QCheckBox *_showSecondarySpeed;
#ifdef ENABLE_TIMEZONES
QRadioButton *_utcZone;
QRadioButton *_systemZone;
QRadioButton *_customZone;
QComboBox *_timeZone;
#endif // ENABLE_TIMEZONES
QCheckBox *_useSegments;
// POI
QDoubleSpinBox *_poiRadius;
QRadioButton *_poiGPSElevation;
QRadioButton *_poiDEMElevation;
// System
QSpinBox *_pixmapCache;
QSpinBox *_connectionTimeout;

View File

@ -21,12 +21,16 @@ static inline unsigned segments(qreal distance)
return ceil(distance / GEOGRAPHICAL_MILE);
}
Units PathItem::_units = Metric;
#ifdef ENABLE_TIMEZONES
QTimeZone PathItem::_timeZone = QTimeZone::utc();
#endif // ENABLE_TIMEZONES
PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent)
: GraphicsItem(parent), _path(path), _map(map)
{
Q_ASSERT(_path.isValid());
_units = Metric;
_digitalZoom = 0;
_width = 3;
QBrush brush(Qt::SolidPattern);
@ -352,16 +356,6 @@ void PathItem::showTicks(bool show)
updateTicks();
}
void PathItem::setUnits(Units units)
{
if (_units == units)
return;
prepareGeometryChange();
_units = units;
updateTicks();
}
void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);

View File

@ -1,8 +1,12 @@
#ifndef PATHITEM_H
#define PATHITEM_H
#include "common/config.h"
#include <QGraphicsObject>
#include <QPen>
#ifdef ENABLE_TIMEZONES
#include <QTimeZone>
#endif // ENABLE_TIMEZONES
#include "data/path.h"
#include "markeritem.h"
#include "units.h"
@ -28,7 +32,6 @@ public:
void setMap(Map *map);
void setUnits(Units units);
void setColor(const QColor &color);
void setWidth(qreal width);
void setStyle(Qt::PenStyle style);
@ -37,6 +40,13 @@ public:
void showMarker(bool show);
void showTicks(bool show);
void updateTicks();
static void setUnits(Units units) {_units = units;}
#ifdef ENABLE_TIMEZONES
static void setTimeZone(const QTimeZone &zone) {_timeZone = zone;}
#endif // ENABLE_TIMEZONES
public slots:
void moveMarker(qreal distance);
void hover(bool hover);
@ -49,7 +59,10 @@ protected:
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
Units _units;
static Units _units;
#ifdef ENABLE_TIMEZONES
static QTimeZone _timeZone;
#endif // ENABLE_TIMEZONES
private:
const PathSegment *segment(qreal x) const;
@ -60,7 +73,6 @@ private:
qreal xInM() const;
unsigned tickSize() const;
void updateTicks();
Path _path;
Map *_map;

View File

@ -1,30 +1,27 @@
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QGridLayout>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QComboBox>
#include <QRadioButton>
#include <QPushButton>
#include <QFileInfo>
#include <QMessageBox>
#include <QTabWidget>
#include <QDoubleSpinBox>
#include "marginswidget.h"
#include "fileselectwidget.h"
#include "units.h"
#include "exportdialog.h"
#include "pdfexportdialog.h"
ExportDialog::ExportDialog(Export *exp, QWidget *parent)
: QDialog(parent), _export(exp)
PDFExportDialog::PDFExportDialog(PDFExport &exp, Units units, QWidget *parent)
: QDialog(parent), _export(exp), _units(units)
{
int index;
_fileSelect = new FileSelectWidget();
_fileSelect->setFilter(tr("PDF files") + " (*.pdf);;" + tr("All files")
+ " (*)");
_fileSelect->setFile(_export->fileName);
_fileSelect->setFile(_export.fileName);
_paperSize = new QComboBox();
_paperSize->addItem("A2", QPrinter::A2);
@ -39,14 +36,14 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
_paperSize->addItem("Tabloid", QPrinter::Tabloid);
_paperSize->addItem("Legal", QPrinter::Legal);
_paperSize->addItem("Letter", QPrinter::Letter);
if ((index = _paperSize->findData(_export->paperSize)) >= 0)
if ((index = _paperSize->findData(_export.paperSize)) >= 0)
_paperSize->setCurrentIndex(index);
_resolution = new QComboBox();
_resolution->addItem("150 DPI", 150);
_resolution->addItem("300 DPI", 300);
_resolution->addItem("600 DPI", 600);
if ((index = _resolution->findData(_export->resolution)) >= 0)
if ((index = _resolution->findData(_export.resolution)) >= 0)
_resolution->setCurrentIndex(index);
_portrait = new QRadioButton(tr("Portrait"));
@ -54,41 +51,16 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
QHBoxLayout *orientationLayout = new QHBoxLayout();
orientationLayout->addWidget(_portrait);
orientationLayout->addWidget(_landscape);
if (_export->orientation == QPrinter::Portrait)
if (_export.orientation == QPrinter::Portrait)
_portrait->setChecked(true);
else
_landscape->setChecked(true);
_topMargin = new QDoubleSpinBox();
_bottomMargin = new QDoubleSpinBox();
_leftMargin = new QDoubleSpinBox();
_rightMargin = new QDoubleSpinBox();
QString us = (_export->units == Metric) ? tr("mm") : tr("in");
_topMargin->setSuffix(UNIT_SPACE + us);
_bottomMargin->setSuffix(UNIT_SPACE + us);
_leftMargin->setSuffix(UNIT_SPACE + us);
_rightMargin->setSuffix(UNIT_SPACE + us);
if (_export->units == Metric) {
_topMargin->setValue(_export->margins.top());
_bottomMargin->setValue(_export->margins.bottom());
_leftMargin->setValue(_export->margins.left());
_rightMargin->setValue(_export->margins.right());
} else {
_topMargin->setValue(_export->margins.top() * MM2IN);
_bottomMargin->setValue(_export->margins.bottom() * MM2IN);
_leftMargin->setValue(_export->margins.left() * MM2IN);
_rightMargin->setValue(_export->margins.right() * MM2IN);
_topMargin->setSingleStep(0.1);
_bottomMargin->setSingleStep(0.1);
_leftMargin->setSingleStep(0.1);
_rightMargin->setSingleStep(0.1);
}
QGridLayout *marginsLayout = new QGridLayout();
marginsLayout->addWidget(_topMargin, 0, 0, 1, 2, Qt::AlignCenter);
marginsLayout->addWidget(_leftMargin, 1, 0, 1, 1, Qt::AlignRight);
marginsLayout->addWidget(_rightMargin, 1, 1, 1, 1, Qt::AlignLeft);
marginsLayout->addWidget(_bottomMargin, 2, 0, 1, 2, Qt::AlignCenter);
_margins = new MarginsFWidget();
_margins->setUnits((units == Metric) ? tr("cm") : tr("in"));
_margins->setSingleStep(0.1);
_margins->setValue((units == Metric)
? _export.margins * MM2CM : _export.margins * MM2IN);
#ifndef Q_OS_MAC
QGroupBox *pageSetupBox = new QGroupBox(tr("Page Setup"));
@ -97,7 +69,7 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
pageSetupLayout->addRow(tr("Page size:"), _paperSize);
pageSetupLayout->addRow(tr("Resolution:"), _resolution);
pageSetupLayout->addRow(tr("Orientation:"), orientationLayout);
pageSetupLayout->addRow(tr("Margins:"), marginsLayout);
pageSetupLayout->addRow(tr("Margins:"), _margins);
#ifdef Q_OS_MAC
QFrame *line = new QFrame();
line->setFrameShape(QFrame::HLine);
@ -111,7 +83,7 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
#ifndef Q_OS_MAC
QGroupBox *outputFileBox = new QGroupBox(tr("Output file"));
QHBoxLayout *outputFileLayout = new QHBoxLayout();
QVBoxLayout *outputFileLayout = new QVBoxLayout();
outputFileLayout->addWidget(_fileSelect);
outputFileBox->setLayout(outputFileLayout);
#endif // Q_OS_MAC
@ -136,41 +108,13 @@ ExportDialog::ExportDialog(Export *exp, QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
}
bool ExportDialog::checkFile()
void PDFExportDialog::accept()
{
if (_fileSelect->file().isEmpty()) {
QMessageBox::warning(this, tr("Error"), tr("No output file selected."));
return false;
}
QFile file(_fileSelect->file());
QFileInfo fi(file);
bool exists = fi.exists();
bool opened = false;
if (exists && fi.isDir()) {
QMessageBox::warning(this, tr("Error"), tr("%1 is a directory.")
.arg(file.fileName()));
return false;
} else if ((exists && !fi.isWritable())
|| !(opened = file.open(QFile::Append))) {
QMessageBox::warning(this, tr("Error"), tr("%1 is not writable.")
.arg(file.fileName()));
return false;
}
if (opened) {
file.close();
if (!exists)
file.remove();
}
return true;
}
void ExportDialog::accept()
{
if (!checkFile())
QString error;
if (!_fileSelect->checkFile(error)) {
QMessageBox::warning(this, tr("Error"), error);
return;
}
QPrinter::Orientation orientation = _portrait->isChecked()
? QPrinter::Portrait : QPrinter::Landscape;
@ -178,17 +122,12 @@ void ExportDialog::accept()
(_paperSize->itemData(_paperSize->currentIndex()).toInt());
int resolution = _resolution->itemData(_resolution->currentIndex()).toInt();
_export->fileName = _fileSelect->file();
_export->paperSize = paperSize;
_export->resolution = resolution;
_export->orientation = orientation;
if (_export->units == Imperial)
_export->margins = MarginsF(_leftMargin->value() / MM2IN,
_topMargin->value() / MM2IN, _rightMargin->value() / MM2IN,
_bottomMargin->value() / MM2IN);
else
_export->margins = MarginsF(_leftMargin->value(), _topMargin->value(),
_rightMargin->value(), _bottomMargin->value());
_export.fileName = _fileSelect->file();
_export.paperSize = paperSize;
_export.resolution = resolution;
_export.orientation = orientation;
_export.margins = (_units == Imperial)
? _margins->value() / MM2IN : _margins->value() / MM2CM;
QDialog::accept();
}

View File

@ -1,5 +1,5 @@
#ifndef EXPORTDIALOG_H
#define EXPORTDIALOG_H
#ifndef PDFEXPORTDIALOG_H
#define PDFEXPORTDIALOG_H
#include <QDialog>
#include <QPrinter>
@ -9,42 +9,37 @@
class QComboBox;
class QRadioButton;
class FileSelectWidget;
class QDoubleSpinBox;
class MarginsFWidget;
struct Export {
struct PDFExport
{
QString fileName;
QPrinter::PaperSize paperSize;
QPrinter::Orientation orientation;
MarginsF margins;
int resolution;
Units units;
};
class ExportDialog : public QDialog
class PDFExportDialog : public QDialog
{
Q_OBJECT
public:
ExportDialog(Export *exp, QWidget *parent = 0);
PDFExportDialog(PDFExport &exp, Units units, QWidget *parent = 0);
public slots:
void accept();
private:
bool checkFile();
Export *_export;
PDFExport &_export;
Units _units;
FileSelectWidget *_fileSelect;
QComboBox *_paperSize;
QComboBox *_resolution;
QRadioButton *_portrait;
QRadioButton *_landscape;
QDoubleSpinBox *_topMargin;
QDoubleSpinBox *_bottomMargin;
QDoubleSpinBox *_leftMargin;
QDoubleSpinBox *_rightMargin;
MarginsFWidget *_margins;
};
#endif // EXPORTDIALOG_H
#endif // PDFEXPORTDIALOG_H

101
src/GUI/pngexportdialog.cpp Normal file
View File

@ -0,0 +1,101 @@
#include <QVBoxLayout>
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QMessageBox>
#include <QTabWidget>
#include <QCheckBox>
#include "units.h"
#include "fileselectwidget.h"
#include "marginswidget.h"
#include "pngexportdialog.h"
PNGExportDialog::PNGExportDialog(PNGExport &exp, QWidget *parent)
: QDialog(parent), _export(exp)
{
_fileSelect = new FileSelectWidget();
_fileSelect->setFilter(tr("PNG files") + " (*.png);;" + tr("All files")
+ " (*)");
_fileSelect->setFile(_export.fileName);
_width = new QSpinBox();
_width->setMinimum(256);
_width->setMaximum(4096);
_width->setValue(_export.size.width());
_width->setSuffix(UNIT_SPACE + tr("px"));
_height = new QSpinBox();
_height->setMinimum(256);
_height->setMaximum(4096);
_height->setValue(_export.size.height());
_height->setSuffix(UNIT_SPACE + tr("px"));
_margins = new MarginsWidget();
_margins->setValue(_export.margins);
_margins->setUnits(tr("px"));
_antialiasing = new QCheckBox(tr("Use anti-aliasing"));
_antialiasing->setChecked(_export.antialiasing);
#ifndef Q_OS_MAC
QGroupBox *pageSetupBox = new QGroupBox(tr("Image Setup"));
#endif // Q_OS_MAC
QFormLayout *pageSetupLayout = new QFormLayout;
pageSetupLayout->addRow(tr("Image width:"), _width);
pageSetupLayout->addRow(tr("Image height:"), _height);
pageSetupLayout->addRow(tr("Margins:"), _margins);
pageSetupLayout->addWidget(_antialiasing);
#ifdef Q_OS_MAC
QFrame *line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
pageSetupLayout->addRow(line);
pageSetupLayout->addRow(tr("File:"), _fileSelect);
pageSetupLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
#else // Q_OS_MAC
pageSetupBox->setLayout(pageSetupLayout);
#endif // Q_OS_MAC
#ifndef Q_OS_MAC
QGroupBox *outputFileBox = new QGroupBox(tr("Output file"));
QVBoxLayout *outputFileLayout = new QVBoxLayout();
outputFileLayout->addWidget(_fileSelect);
outputFileBox->setLayout(outputFileLayout);
#endif // Q_OS_MAC
QDialogButtonBox *buttonBox = new QDialogButtonBox();
buttonBox->addButton(tr("Export"), QDialogButtonBox::AcceptRole);
buttonBox->addButton(QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
QVBoxLayout *layout = new QVBoxLayout;
#ifdef Q_OS_MAC
layout->addLayout(pageSetupLayout);
#else // Q_OS_MAC
layout->addWidget(pageSetupBox);
layout->addWidget(outputFileBox);
#endif // Q_OS_MAC
layout->addWidget(buttonBox);
setLayout(layout);
setWindowTitle(tr("Export to PNG"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
}
void PNGExportDialog::accept()
{
QString error;
if (!_fileSelect->checkFile(error)) {
QMessageBox::warning(this, tr("Error"), error);
return;
}
_export.fileName = _fileSelect->file();
_export.size = QSize(_width->value(), _height->value());
_export.margins = _margins->value();
_export.antialiasing = _antialiasing->isChecked();
QDialog::accept();
}

41
src/GUI/pngexportdialog.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef PNGEXPORTDIALOG_H
#define PNGEXPORTDIALOG_H
#include <QDialog>
#include <QMargins>
#include "margins.h"
class FileSelectWidget;
class MarginsWidget;
class QSpinBox;
class QCheckBox;
struct PNGExport
{
QString fileName;
QSize size;
QMargins margins;
bool antialiasing;
};
class PNGExportDialog : public QDialog
{
Q_OBJECT
public:
PNGExportDialog(PNGExport &exp, QWidget *parent = 0);
public slots:
void accept();
private:
PNGExport &_export;
FileSelectWidget *_fileSelect;
QSpinBox *_width;
QSpinBox *_height;
MarginsWidget *_margins;
QCheckBox *_antialiasing;
};
#endif // PNGEXPORTDIALOG_H

View File

@ -5,7 +5,7 @@
PowerGraphItem::PowerGraphItem(const Graph &graph, GraphType type, int width,
const QColor &color, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
: GraphItem(graph, type, width, color, Qt::SolidLine, parent)
{
}

View File

@ -15,6 +15,8 @@ QString RouteItem::info() const
tt.insert(tr("Name"), _name);
if (!_desc.isEmpty())
tt.insert(tr("Description"), _desc);
if (!_comment.isEmpty() && _comment != _desc)
tt.insert(tr("Comment"), _comment);
tt.insert(tr("Distance"), Format::distance(path().last().last().distance(),
_units));
if (!_links.isEmpty()) {
@ -43,8 +45,8 @@ RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
_name = route.name();
_desc = route.description();
_comment = route.comment();
_links = route.links();
_coordinatesFormat = DecimalDegrees;
}
void RouteItem::setMap(Map *map)
@ -55,28 +57,6 @@ void RouteItem::setMap(Map *map)
PathItem::setMap(map);
}
void RouteItem::setUnits(Units u)
{
if (_units == u)
return;
for (int i = 0; i < _waypoints.count(); i++)
_waypoints[i]->setToolTipFormat(u, _coordinatesFormat);
PathItem::setUnits(u);
}
void RouteItem::setCoordinatesFormat(CoordinatesFormat format)
{
if (_coordinatesFormat == format)
return;
_coordinatesFormat = format;
for (int i = 0; i < _waypoints.count(); i++)
_waypoints[i]->setToolTipFormat(_units, _coordinatesFormat);
}
void RouteItem::showWaypoints(bool show)
{
for (int i = 0; i < _waypoints.count(); i++)

View File

@ -19,8 +19,6 @@ public:
void setMap(Map *map);
void setUnits(Units u);
void setCoordinatesFormat(CoordinatesFormat format);
void showWaypoints(bool show);
void showWaypointLabels(bool show);
@ -29,8 +27,8 @@ public:
private:
QString _name;
QString _desc;
QString _comment;
QVector<Link> _links;
CoordinatesFormat _coordinatesFormat;
QVector<WaypointItem*> _waypoints;
};

View File

@ -66,26 +66,45 @@
#define SHOW_WAYPOINT_LABELS_SETTING "waypointLabels"
#define SHOW_WAYPOINT_LABELS_DEFAULT true
#define EXPORT_SETTINGS_GROUP "Export"
#define PDF_EXPORT_SETTINGS_GROUP "Export"
#define PAPER_ORIENTATION_SETTING "orientation"
#define PAPER_ORIENTATION_DEFAULT QPrinter::Portrait
#define PAPER_SIZE_SETTING "size"
#define PAPER_SIZE_DEFAULT (IMPERIAL_UNITS() ? QPrinter::Letter \
: QPrinter::A4)
#define MARGIN_LEFT_SETTING "marginLeft"
#define MARGIN_LEFT_DEFAULT 5 /* mm */
#define MARGIN_TOP_SETTING "marginTop"
#define MARGIN_TOP_DEFAULT 5 /* mm */
#define MARGIN_RIGHT_SETTING "marginRight"
#define MARGIN_RIGHT_DEFAULT 5 /* mm */
#define MARGIN_BOTTOM_SETTING "marginBottom"
#define MARGIN_BOTTOM_DEFAULT 5 /* mm */
#define EXPORT_FILENAME_SETTING "fileName"
#define EXPORT_FILENAME_DEFAULT QString("%1/export.pdf"). \
#define PDF_MARGIN_LEFT_SETTING "marginLeft"
#define PDF_MARGIN_LEFT_DEFAULT 5 /* mm */
#define PDF_MARGIN_TOP_SETTING "marginTop"
#define PDF_MARGIN_TOP_DEFAULT 5 /* mm */
#define PDF_MARGIN_RIGHT_SETTING "marginRight"
#define PDF_MARGIN_RIGHT_DEFAULT 5 /* mm */
#define PDF_MARGIN_BOTTOM_SETTING "marginBottom"
#define PDF_MARGIN_BOTTOM_DEFAULT 5 /* mm */
#define PDF_FILENAME_SETTING "fileName"
#define PDF_FILENAME_DEFAULT QString("%1/export.pdf"). \
arg(QDir::currentPath())
#define RESOLUTION_SETTING "resolution"
#define RESOLUTION_DEFAULT 600
#define PNG_EXPORT_SETTINGS_GROUP "PNGExport"
#define PNG_WIDTH_SETTING "width"
#define PNG_WIDTH_DEFAULT 600
#define PNG_HEIGHT_SETTING "height"
#define PNG_HEIGHT_DEFAULT 800
#define PNG_MARGIN_LEFT_SETTING "marginLeft"
#define PNG_MARGIN_LEFT_DEFAULT 5 /* px */
#define PNG_MARGIN_TOP_SETTING "marginTop"
#define PNG_MARGIN_TOP_DEFAULT 5 /* px */
#define PNG_MARGIN_RIGHT_SETTING "marginRight"
#define PNG_MARGIN_RIGHT_DEFAULT 5 /* px */
#define PNG_MARGIN_BOTTOM_SETTING "marginBottom"
#define PNG_MARGIN_BOTTOM_DEFAULT 5 /* px */
#define PNG_ANTIALIASING_SETTING "antialiasing"
#define PNG_ANTIALIASING_DEFAULT true
#define PNG_FILENAME_SETTING "fileName"
#define PNG_FILENAME_DEFAULT QString("%1/export.png"). \
arg(QDir::currentPath())
#define OPTIONS_SETTINGS_GROUP "Options"
#define PALETTE_COLOR_SETTING "paletteColor"
#define PALETTE_COLOR_DEFAULT QColor(Qt::blue)
@ -122,7 +141,7 @@
#define PATH_AA_SETTING "pathAntiAliasing"
#define PATH_AA_DEFAULT true
#define GRAPH_AA_SETTING "graphAntiAliasing"
#define GRAPH_AA_DEFAULT false
#define GRAPH_AA_DEFAULT true
#define ELEVATION_FILTER_SETTING "elevationFilter"
#define ELEVATION_FILTER_DEFAULT 3
#define SPEED_FILTER_SETTING "speedFilter"
@ -145,10 +164,15 @@
#define USE_REPORTED_SPEED_DEFAULT false
#define DATA_USE_DEM_SETTING "dataUseDEM"
#define DATA_USE_DEM_DEFAULT false
#define SHOW_SECONDARY_ELEVATION_SETTING "showSecondaryElevation"
#define SHOW_SECONDARY_ELEVATION_DEFAULT false
#define SHOW_SECONDARY_SPEED_SETTING "showSecondarySpeed"
#define SHOW_SECONDARY_SPEED_DEFAULT false
#define TIME_ZONE_SETTING "timeZone"
#define USE_SEGMENTS_SETTING "useSegments"
#define USE_SEGMENTS_DEFAULT true
#define POI_RADIUS_SETTING "poiRadius"
#define POI_RADIUS_DEFAULT (int)(IMPERIAL_UNITS() ? MIINM : KMINM)
#define POI_USE_DEM_SETTING "poiUseDEM"
#define POI_USE_DEM_DEFAULT false
#define USE_OPENGL_SETTING "useOpenGL"
#define USE_OPENGL_DEFAULT false
#define ENABLE_HTTP2_SETTING "enableHTTP2"

View File

@ -40,31 +40,46 @@ void SpeedGraph::setInfo()
clearInfo();
}
GraphItem *SpeedGraph::loadGraph(const Graph &graph, const Track &track,
const QColor &color, bool primary)
{
if (!graph.isValid())
return 0;
SpeedGraphItem *gi = new SpeedGraphItem(graph, _graphType, _width,
color, primary ? Qt::SolidLine : Qt::DashLine, track.movingTime());
gi->setTimeType(_timeType);
gi->setUnits(_units);
_tracks.append(gi);
if (_showTracks)
addGraph(gi);
if (primary) {
_avg.append(QPointF(track.distance(), gi->avg()));
_mavg.append(QPointF(track.distance(), gi->mavg()));
}
return gi;
}
QList<GraphItem*> SpeedGraph::loadData(const Data &data)
{
QList<GraphItem*> graphs;
for (int i = 0; i < data.tracks().count(); i++) {
GraphItem *primary, *secondary;
QColor color(_palette.nextColor());
const Track &track = data.tracks().at(i);
const Graph &graph = track.speed();
const GraphPair &gp = track.speed();
if (!graph.isValid()) {
_palette.nextColor();
graphs.append(0);
} else {
SpeedGraphItem *gi = new SpeedGraphItem(graph, _graphType, _width,
_palette.nextColor(), track.movingTime());
gi->setTimeType(_timeType);
gi->setUnits(_units);
primary = loadGraph(gp.primary(), track, color, true);
secondary = primary
? loadGraph(gp.secondary(), track, color, false) : 0;
if (primary && secondary)
primary->setSecondaryGraph(secondary);
_tracks.append(gi);
if (_showTracks)
addGraph(gi);
_avg.append(QPointF(track.distance(), gi->avg()));
_mavg.append(QPointF(track.distance(), gi->mavg()));
graphs.append(gi);
}
graphs.append(primary);
}
for (int i = 0; i < data.routes().count(); i++) {

View File

@ -5,6 +5,7 @@
#include "graphtab.h"
class SpeedGraphItem;
class Track;
class SpeedGraph : public GraphTab
{
@ -22,6 +23,8 @@ public:
void showTracks(bool show);
private:
GraphItem *loadGraph(const Graph &graph, const Track &track,
const QColor &color, bool primary);
qreal avg() const;
qreal max() const {return bounds().bottom();}
void setYUnits();

View File

@ -5,8 +5,8 @@
SpeedGraphItem::SpeedGraphItem(const Graph &graph, GraphType type, int width,
const QColor &color, qreal movingTime, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
const QColor &color, Qt::PenStyle style, qreal movingTime,
QGraphicsItem *parent) : GraphItem(graph, type, width, color, style, parent)
{
_timeType = Total;

View File

@ -10,7 +10,8 @@ class SpeedGraphItem : public GraphItem
public:
SpeedGraphItem(const Graph &graph, GraphType type, int width,
const QColor &color, qreal movingTime, QGraphicsItem *parent = 0);
const QColor &color, Qt::PenStyle style, qreal movingTime,
QGraphicsItem *parent = 0);
qreal avg() const {return _avg;}
qreal mavg() const {return _mavg;}

View File

@ -5,7 +5,7 @@
TemperatureGraphItem::TemperatureGraphItem(const Graph &graph, GraphType type,
int width, const QColor &color, QGraphicsItem *parent)
: GraphItem(graph, type, width, color, parent)
: GraphItem(graph, type, width, color, Qt::SolidLine, parent)
{
_min = GraphItem::min();
_max = GraphItem::max();

69
src/GUI/timezoneinfo.h Normal file
View File

@ -0,0 +1,69 @@
#ifndef TIMEZONEINFO_H
#define TIMEZONEINFO_H
#include <QTimeZone>
#include <QDataStream>
class TimeZoneInfo
{
public:
enum Type {
UTC,
System,
Custom
};
TimeZoneInfo() : _type(UTC), _customZone(QTimeZone::systemTimeZone()) {}
Type type() const {return _type;}
const QTimeZone &customZone() const {return _customZone;}
QTimeZone zone() const
{
if (_type == UTC)
return QTimeZone::utc();
else if (_type == System)
return QTimeZone::systemTimeZone();
else
return _customZone;
}
void setType(Type type) {_type = type;}
void setCustomZone(const QTimeZone &zone) {_customZone = zone;}
bool operator==(const TimeZoneInfo &other) const
{
if (_type == UTC || _type == System)
return _type == other._type;
else
return (other._type == Custom && _customZone == other._customZone);
}
bool operator!=(const TimeZoneInfo &other) {return !(*this == other);}
private:
friend QDataStream& operator<<(QDataStream &out, const TimeZoneInfo &info);
friend QDataStream& operator>>(QDataStream &in, TimeZoneInfo &info);
Type _type;
QTimeZone _customZone;
};
Q_DECLARE_METATYPE(TimeZoneInfo)
inline QDataStream &operator<<(QDataStream &out, const TimeZoneInfo &info)
{
out << static_cast<int>(info._type) << info._customZone;
return out;
}
inline QDataStream &operator>>(QDataStream &in, TimeZoneInfo &info)
{
int t;
in >> t;
info._type = static_cast<TimeZoneInfo::Type>(t);
in >> info._customZone;
return in;
}
#endif // TIMEZONEINFO_H

View File

@ -13,6 +13,8 @@ QString TrackItem::info() const
tt.insert(tr("Name"), _name);
if (!_desc.isEmpty())
tt.insert(tr("Description"), _desc);
if (!_comment.isEmpty() && _comment != _desc)
tt.insert(tr("Comment"), _comment);
tt.insert(tr("Distance"), Format::distance(path().last().last().distance(),
_units));
if (_time > 0)
@ -20,7 +22,13 @@ QString TrackItem::info() const
if (_movingTime > 0)
tt.insert(tr("Moving time"), Format::timeSpan(_movingTime));
if (!_date.isNull())
tt.insert(tr("Date"), _date.toString(Qt::SystemLocaleShortDate));
tt.insert(tr("Date"),
#ifdef ENABLE_TIMEZONES
_date.toTimeZone(_timeZone)
#else // ENABLE_TIMEZONES
_date
#endif // ENABLE_TIMEZONES
.toString(Qt::SystemLocaleShortDate));
if (!_links.isEmpty()) {
QString links;
for (int i = 0; i < _links.size(); i++) {
@ -41,6 +49,7 @@ TrackItem::TrackItem(const Track &track, Map *map, QGraphicsItem *parent)
{
_name = track.name();
_desc = track.description();
_comment = track.comment();
_links = track.links();
_date = track.date();
_time = track.time();

View File

@ -22,6 +22,7 @@ public:
private:
QString _name;
QString _desc;
QString _comment;
QVector<Link> _links;
QDateTime _date;
qreal _time;

View File

@ -16,6 +16,7 @@ enum Units {
#define MS2KN 1.943844490000 // m/s -> kn
#define FT2MI 0.000189393939 // ft -> mi
#define MM2IN 0.039370100000 // mm -> in
#define MM2CM 0.100000000000 // mm -> cm
#define H2S 0.000277777778 // h -> s
#define MIN2S 0.016666666667 // min -> s

View File

@ -13,6 +13,13 @@
#define FS(size) \
((int)((qreal)size * 1.41))
Units WaypointItem::_units = Metric;
CoordinatesFormat WaypointItem::_format = DecimalDegrees;
#ifdef ENABLE_TIMEZONES
QTimeZone WaypointItem::_timeZone = QTimeZone::utc();
#endif // ENABLE_TIMEZONES
QString WaypointItem::info() const
{
ToolTip tt;
@ -21,15 +28,28 @@ QString WaypointItem::info() const
tt.insert(qApp->translate("WaypointItem", "Name"), _waypoint.name());
tt.insert(qApp->translate("WaypointItem", "Coordinates"),
Format::coordinates(_waypoint.coordinates(), _format));
if (_waypoint.hasElevation())
tt.insert(qApp->translate("WaypointItem", "Elevation"),
Format::elevation(_waypoint.elevation(), _units));
if (!std::isnan(_waypoint.elevations().first)) {
QString val = Format::elevation(_waypoint.elevations().first, _units);
if (!std::isnan(_waypoint.elevations().second))
val += " (" + Format::elevation(_waypoint.elevations().second,
_units) + ")";
tt.insert(qApp->translate("WaypointItem", "Elevation"), val);
}
if (_waypoint.timestamp().isValid())
tt.insert(qApp->translate("WaypointItem", "Date"),
_waypoint.timestamp().toString(Qt::SystemLocaleShortDate));
#ifdef ENABLE_TIMEZONES
_waypoint.timestamp().toTimeZone(_timeZone)
#else // ENABLE_TIMEZONES
_waypoint.timestamp()
#endif // ENABLE_TIMEZONES
.toString(Qt::SystemLocaleShortDate));
if (!_waypoint.description().isEmpty())
tt.insert(qApp->translate("WaypointItem", "Description"),
_waypoint.description());
if (!_waypoint.comment().isEmpty()
&& _waypoint.comment() != _waypoint.description())
tt.insert(qApp->translate("WaypointItem", "Comment"),
_waypoint.comment());
if (_waypoint.address().isValid()) {
QString addr("<address>");
addr += _waypoint.address().street();
@ -70,9 +90,6 @@ WaypointItem::WaypointItem(const Waypoint &waypoint, Map *map,
_font.setPixelSize(FS(_size));
_font.setFamily(FONT_FAMILY);
_units = Metric;
_format = DecimalDegrees;
updateCache();
setPos(map->ll2xy(waypoint.coordinates()));
@ -143,12 +160,6 @@ void WaypointItem::setColor(const QColor &color)
update();
}
void WaypointItem::setToolTipFormat(Units units, CoordinatesFormat format)
{
_units = units;
_format = format;
}
void WaypointItem::showLabel(bool show)
{
if (_showLabel == show)

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