1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-16 11:54:23 +02:00

Compare commits

...

219 Commits
7.32 ... 7.38

Author SHA1 Message Date
84d5673e17 Merge branch 'origin/master' into Weblate. 2020-12-15 21:51:38 +01:00
e40836e6bb Added missing file associations + icons 2020-12-15 21:51:08 +01:00
88aef38f9d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-12-15 02:29:30 +01:00
7d8dcec88b Try to break even less bounding box transformations 2020-12-14 22:06:59 +01:00
561d8362a9 Fixed projection comparison 2020-12-14 22:04:50 +01:00
7f9fde76e9 Merge branch 'origin/master' into Weblate. 2020-12-13 19:41:17 +01:00
239e571358 Provide propper map bounds for overviews 2020-12-13 19:40:09 +01:00
44b28e3d4d Merge branch 'origin/master' into Weblate. 2020-12-12 10:20:19 +01:00
4cef089c81 A more robust RectC to RectD algorithm 2020-12-12 10:19:48 +01:00
05ac5ccedb Merge branch 'origin/master' into Weblate. 2020-12-10 22:02:22 +01:00
22fb6071f7 Refactoring 2020-12-10 22:02:09 +01:00
2c78772a67 Merge branch 'origin/master' into Weblate. 2020-12-10 01:09:42 +01:00
0f03ef4af7 Yet another map load crash fix 2020-12-10 01:09:23 +01:00
351cc49ec9 Merge branch 'origin/master' into Weblate. 2020-12-09 23:08:07 +01:00
743a937f41 Fixed crashing async map loading
fixes #331
2020-12-09 23:07:05 +01:00
033225502f Merge branch 'origin/master' into Weblate. 2020-12-08 21:30:37 +01:00
75b8b9eab0 Upadte linux file associations 2020-12-08 21:30:17 +01:00
e76e7b71ed Check for duplicit map loads 2020-12-08 21:29:20 +01:00
41ea07d020 Merge branch 'origin/master' into Weblate. 2020-12-08 01:13:05 +01:00
4bad086152 Enable maps drag&drop 2020-12-08 01:12:39 +01:00
8be088be0a Merge branch 'origin/master' into Weblate. 2020-12-08 01:01:57 +01:00
73021bec01 Added "Open with GPXSee" associations 2020-12-08 01:01:26 +01:00
7584116168 Removed cut&paste remains 2020-12-08 00:59:18 +01:00
59b734c402 Cosmetics 2020-12-08 00:58:01 +01:00
8168d52f09 Merge branch 'origin/master' into Weblate. 2020-12-06 23:32:07 +01:00
74796e3e41 Only trigger the last maploaded 2020-12-06 23:31:45 +01:00
676024854a Merge branch 'origin/master' into Weblate. 2020-12-06 19:18:14 +01:00
10e1b5c4fb Open map files passed as program arguments
closes #327
2020-12-06 19:17:09 +01:00
54570ed97e Merge branch 'origin/master' into Weblate. 2020-12-06 13:05:35 +01:00
07fa377e38 Remove the weired file lists copies
It used to be written in the Qt4 documentation to iterate over a copy, but
there is aparently no real reason doing that...
2020-12-06 13:03:32 +01:00
2b8c3f64ac Only trigger the last loaded map 2020-12-06 12:53:39 +01:00
a60cccb57e Merge branch 'origin/master' into Weblate. 2020-12-06 00:12:05 +01:00
c2e50e5213 Use a smooth digital zoom 2020-12-06 00:11:47 +01:00
0ea8e008c2 Merge branch 'origin/master' into Weblate. 2020-12-05 12:26:33 +01:00
082435c83d Translated using Weblate (Hungarian)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-12-05 12:26:33 +01:00
e63ad7a244 Make the maps submenus work with large amount of items 2020-12-05 12:25:59 +01:00
32a4365543 Merge branch 'origin/master' into Weblate. 2020-12-04 00:26:20 +01:00
abd1dc2450 Added support for polyconic projections 2020-12-04 00:25:57 +01:00
5674534efd Merge branch 'origin/master' into Weblate. 2020-12-03 21:15:19 +01:00
33287f9d76 Translated using Weblate (Hungarian)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2020-12-03 21:15:18 +01:00
1dfe84c4af Translated using Weblate (Ukrainian)
Currently translated at 98.4% (377 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-12-03 21:15:18 +01:00
7fe8d204bc Translated using Weblate (Turkish)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2020-12-03 21:15:18 +01:00
5080247e10 Translated using Weblate (Russian)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-12-03 21:15:18 +01:00
13d6c7c643 Translated using Weblate (Finnish)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-12-03 21:15:17 +01:00
547d7a5f23 Fix the POI search algorithm
(At least so, that it does not trigger the rtree assert. The whole RectC logic
has to be fixed to properly handle poles/dateline "overflows")
2020-12-03 21:12:41 +01:00
9e03d85b7a Fixed actions logic 2020-12-03 20:58:22 +01:00
b811132394 Translated using Weblate (Swedish)
Currently translated at 100.0% (383 of 383 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2020-12-03 06:51:47 +01:00
ca33328d99 Merge branch 'origin/master' into Weblate. 2020-12-03 00:11:58 +01:00
41c8a4d935 Version++ 2020-12-03 00:11:49 +01:00
acd09400be Localization update 2020-12-03 00:10:24 +01:00
16bfd593c7 Merge branch 'origin/master' into Weblate. 2020-12-02 23:58:59 +01:00
9e70a1ffbb Added the "Load map dir" feature 2020-12-02 23:58:11 +01:00
1b590fbf76 Merge branch 'origin/master' into Weblate. 2020-12-02 20:51:37 +01:00
8d52dbf59f Fixed issue with Mercator projections 2020-12-02 20:51:19 +01:00
c6fd32fc61 Merge branch 'origin/master' into Weblate. 2020-12-01 20:17:58 +01:00
af6082425e Propper map size must be known from the start 2020-12-01 20:17:19 +01:00
785123f005 Merge branch 'origin/master' into Weblate. 2020-12-01 19:04:34 +01:00
df3ee11f42 Properly handle skewed charts 2020-12-01 19:03:58 +01:00
6af1ff35ab Merge branch 'origin/master' into Weblate. 2020-11-28 20:34:53 +01:00
8423fc1230 Remove the untested and broken NOS stuff 2020-11-28 20:34:25 +01:00
a62d84da67 Merge branch 'origin/master' into Weblate. 2020-11-28 14:50:31 +01:00
2431f432d4 Use the right Mercator 2020-11-28 14:50:10 +01:00
6c4ebc40ca Merge branch 'origin/master' into Weblate. 2020-11-28 14:48:55 +01:00
0cc6908b30 Fixed broken projection comparsion
+ refactoring/code cleanup
2020-11-28 14:48:20 +01:00
becf57e4eb Merge branch 'origin/master' into Weblate. 2020-11-27 01:12:51 +01:00
96733883cb Added support for BSB charts maps 2020-11-27 01:11:50 +01:00
973c086029 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (376 of 376 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-11-25 17:29:14 +01:00
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
176 changed files with 11123 additions and 5872 deletions

View File

@ -1,4 +1,4 @@
version: 7.32.{build}
version: 7.38.{build}
configuration:
- Release

View File

@ -9,7 +9,7 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common G
* 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.32
VERSION = 7.38
QT += core \
gui \
@ -19,8 +19,12 @@ 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/mapitem.h \
src/GUI/marginswidget.h \
src/GUI/planeitem.h \
src/GUI/popup.h \
src/common/garmin.h \
src/common/staticassert.h \
@ -53,7 +57,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 \
@ -93,13 +96,18 @@ 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/bsbmap.h \
src/map/invalidmap.h \
src/map/polyconic.h \
src/map/projection.h \
src/map/ellipsoid.h \
src/map/datum.h \
@ -198,8 +206,13 @@ 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/mapitem.cpp \
src/GUI/marginswidget.cpp \
src/GUI/popup.cpp \
src/common/coordinates.cpp \
src/common/rectc.cpp \
@ -224,7 +237,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 \
@ -256,18 +268,22 @@ SOURCES += src/main.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/bsbmap.cpp \
src/map/maplist.cpp \
src/map/onlinemap.cpp \
src/map/downloader.cpp \
src/map/emptymap.cpp \
src/map/ozimap.cpp \
src/map/polyconic.cpp \
src/map/tar.cpp \
src/map/atlas.cpp \
src/map/ozf.cpp \
@ -344,7 +360,9 @@ 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
@ -415,7 +433,13 @@ macx {
icons/formats/json.icns \
icons/formats/cup.icns \
icons/formats/gpi.icns \
icons/formats/sml.icns
icons/formats/sml.icns \
icons/formats/img.icns \
icons/formats/jnx.icns \
icons/formats/kap.icns \
icons/formats/mbts.icns \
icons/formats/rmap.icns \
icons/formats/tba.icns
QMAKE_BUNDLE_DATA += locale maps icons csv
}
@ -435,7 +459,14 @@ win32 {
icons/formats/json.ico \
icons/formats/cup.ico \
icons/formats/gpi.ico \
icons/formats/sml.ico
icons/formats/sml.ico \
icons/formats/img.ico \
icons/formats/jnx.ico \
icons/formats/kap.ico \
icons/formats/map.ico \
icons/formats/mbts.ico \
icons/formats/rmap.ico \
icons/formats/tba.ico
DEFINES += _USE_MATH_DEFINES \
NOGDI
}

View 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

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 571 B

After

Width:  |  Height:  |  Size: 571 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
icons/formats/img.icns Normal file

Binary file not shown.

BIN
icons/formats/img.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
icons/formats/jnx.icns Normal file

Binary file not shown.

BIN
icons/formats/jnx.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
icons/formats/kap.icns Normal file

Binary file not shown.

BIN
icons/formats/kap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
icons/formats/map.icns Normal file

Binary file not shown.

BIN
icons/formats/map.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

BIN
icons/formats/mbts.icns Normal file

Binary file not shown.

BIN
icons/formats/mbts.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
icons/formats/rmap.icns Normal file

Binary file not shown.

BIN
icons/formats/rmap.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View File

@ -13,3 +13,10 @@ slf:#881199
cup:#20a810
gpi:#fca314
sml:#6434eb
img:#cf0a0a
jnx:#aeff00
kap:#080045
map:#f6ff00
mbts:#ff0062
rmap:#145cba
tba:#367050

BIN
icons/formats/tba.icns Normal file

Binary file not shown.

BIN
icons/formats/tba.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

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

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

@ -42,7 +42,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/tcx+xml</string>
<string>application/vnd.garmin.tcx+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/tcx.icns</string>
@ -74,7 +74,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/loc+xml</string>
<string>application/vnd.groundspeak.loc+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/loc.icns</string>
@ -90,7 +90,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/slf+xml</string>
<string>application/vnd.sigma.slf+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/slf.icns</string>
@ -250,7 +250,7 @@
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/sml+xml</string>
<string>application/vnd.suunto.sml+xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/sml.icns</string>
@ -259,6 +259,193 @@
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>jpeg</string>
<string>jpg</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/jpeg</string>
</array>
<key>CFBundleTypeName</key>
<string>JPEG Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>csv</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>text/csv</string>
</array>
<key>CFBundleTypeName</key>
<string>Comma-Separated Values (CSV) Files</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>img</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.garmin.img</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/img.icns</string>
<key>CFBundleTypeName</key>
<string>Garmin IMG Map</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>gmap</string>
<string>gmapi</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.garmin.gmap</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/img.icns</string>
<key>CFBundleTypeName</key>
<string>Garmin Map Product File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>jnx</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.garmin.jnx</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/jnx.icns</string>
<key>CFBundleTypeName</key>
<string>Garmin JNX Map</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>kap</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.maptech.kap</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/kap.icns</string>
<key>CFBundleTypeName</key>
<string>BSB Nautical Charts</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>map</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.oziexplorer.map</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/map.icns</string>
<key>CFBundleTypeName</key>
<string>OziExplorer Map File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>rmap</string>
<string>rtmap</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.twonav.rmap</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/rmap.icns</string>
<key>CFBundleTypeName</key>
<string>TwoNav Raster Map File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tba</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.trekbuddy.tba</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/tba.icns</string>
<key>CFBundleTypeName</key>
<string>TrekBuddy Atlas</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>mbtiles</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.mapbox.mbtiles</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/mbts.icns</string>
<key>CFBundleTypeName</key>
<string>MBTiles Map File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tiff</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/tiff</string>
</array>
<key>CFBundleTypeName</key>
<string>GeoTIFF Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>xml</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.gpxsee.map+xml</string>
</array>
<key>CFBundleTypeName</key>
<string>GPXSee Map Definition File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
@ -302,7 +489,7 @@
<string>tcx</string>
</array>
<key>public.mime-type</key>
<string>application/tcx+xml</string>
<string>application/vnd.garmin.tcx+xml</string>
</dict>
</dict>
<dict>
@ -344,7 +531,7 @@
<string>loc</string>
</array>
<key>public.mime-type</key>
<string>application/loc+xml</string>
<string>application/vnd.groundspeak.loc+xml</string>
</dict>
</dict>
<dict>
@ -365,7 +552,7 @@
<string>slf</string>
</array>
<key>public.mime-type</key>
<string>application/slf+xml</string>
<string>application/vnd.sigma.slf+xml</string>
</dict>
</dict>
<dict>
@ -575,7 +762,269 @@
<string>sml</string>
</array>
<key>public.mime-type</key>
<string>application/sml+xml</string>
<string>application/vnd.suunto.sml+xml</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>public.jpeg</string>
<key>UTTypeReferenceURL</key>
<string>http://www.w3.org/Graphics/JPEG/</string>
<key>UTTypeDescription</key>
<string>JPEG Image</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>jpeg</string>
<string>jpg</string>
</array>
<key>public.mime-type</key>
<string>image/jpeg</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>public.csv</string>
<key>UTTypeReferenceURL</key>
<string>https://tools.ietf.org/html/rfc4180</string>
<key>UTTypeDescription</key>
<string>Comma-Separated Values (CSV) Files</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>csv</string>
</array>
<key>public.mime-type</key>
<string>text/csv</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.garmin.img</string>
<key>UTTypeReferenceURL</key>
<string>https://sourceforge.net/projects/garmin-img/</string>
<key>UTTypeDescription</key>
<string>Garmin IMG map</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>img</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.garmin.img</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.garmin.jnx</string>
<key>UTTypeReferenceURL</key>
<string>http://whiter.brinkster.net/en/JNX.shtml</string>
<key>UTTypeDescription</key>
<string>Garmin JNX Map</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>jnx</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.garmin.jnx</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.garmin.gmap</string>
<key>UTTypeReferenceURL</key>
<string>https://sourceforge.net/projects/garmin-img/</string>
<key>UTTypeDescription</key>
<string>Garmin Map Product File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>xml</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.garmin.gmap</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.maptech.kap</string>
<key>UTTypeReferenceURL</key>
<string>http://libbsb.sourceforge.net/bsb_file_format.html</string>
<key>UTTypeDescription</key>
<string>BSB Nautical Charts</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>kap</string>
</array>
<key>public.mime-type</key>
<string>image/vnd.maptech.kap</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.oziexplorer3.map</string>
<key>UTTypeReferenceURL</key>
<string>https://www.oziexplorer3.com/eng/help/map_file_format.html</string>
<key>UTTypeDescription</key>
<string>OziExplorer Map File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>map</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.oziexplorer.map</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.mapbox.mbtiles</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/mapbox/mbtiles-spec</string>
<key>UTTypeDescription</key>
<string>MBTiles Map File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mbtiles</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.mapbox.mbtiles</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.twonav.rmap</string>
<key>UTTypeReferenceURL</key>
<string>https://wiki.openstreetmap.org/wiki/TwoNav_RMAP</string>
<key>UTTypeDescription</key>
<string>TwoNav Raster Map File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>rmap</string>
<string>rtmap</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.twonav.rmap</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>net.trekbuddy.tba</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/kruhc/trekbuddy</string>
<key>UTTypeDescription</key>
<string>TrekBuddy Atlas</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>tba</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.trekbuddy.tba</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>public.tiff</string>
<key>UTTypeReferenceURL</key>
<string>https://www.adobe.io/open/standards/TIFF.html</string>
<key>UTTypeDescription</key>
<string>TIFF Image</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>tiff</string>
<string>tif</string>
</array>
<key>public.mime-type</key>
<string>image/tiff</string>
</dict>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>org.gpxsee.map</string>
<key>UTTypeReferenceURL</key>
<string>http://www.gpxsee.org/map/1.4/</string>
<key>UTTypeDescription</key>
<string>GPXSee Map Definition File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>xml</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.gpxsee.map+xml</string>
</dict>
</dict>
</array>

View File

@ -18,13 +18,14 @@
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
WMS, TMS, QuadTiles).</li>
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
TwoNav RMaps, Garmin IMG &amp; JNX, GeoTIFF images).</li>
TwoNav RMaps, Garmin IMG &amp; JNX maps, GeoTIFF images,
BSB nautical charts).</li>
<li>Elevation, speed, heart rate, cadence, power, temperature and
gear ratio graphs.</li>
<li>Support for multiple tracks in one view.</li>
<li>Support for POI files.</li>
<li>Support for DEM files (SRTM HGT).</li>
<li>Print/export to PDF.</li>
<li>Print/export to PDF &amp; PNG.</li>
<li>Full-screen mode.</li>
<li>HiDPI/Retina displays &amp; maps support.</li>
</ul>
@ -58,7 +59,7 @@
<mimetypes>
<mimetype>application/gpx+xml</mimetype>
<mimetype>application/tcx+xml</mimetype>
<mimetype>application/vnd.garmin.tcx+xml</mimetype>
<mimetype>application/vnd.ant.fit</mimetype>
<mimetype>application/vnd.google-earth.kml+xml</mimetype>
<mimetype>application/vnd.fai.igc</mimetype>
@ -66,11 +67,24 @@
<mimetype>application/vnd.oziexplorer.plt</mimetype>
<mimetype>application/vnd.oziexplorer.rte</mimetype>
<mimetype>application/vnd.oziexplorer.wpt</mimetype>
<mimetype>application/loc+xml</mimetype>
<mimetype>application/slf+xml</mimetype>
<mimetype>application/vnd.groundspeak.loc+xml</mimetype>
<mimetype>application/vnd.sigma.slf+xml</mimetype>
<mimetype>application/geo+json</mimetype>
<mimetype>application/vnd.naviter.seeyou.cup</mimetype>
<mimetype>application/vnd.garmin.gpi</mimetype>
<mimetype>application/sml+xml</mimetype>
<mimetype>application/vnd.suunto.sml+xml</mimetype>
<mimetype>image/jpeg</mimetype>
<mimetype>text/csv</mimetype>
<mimetype>application/vnd.garmin.img</mimetype>
<mimetype>application/vnd.garmin.jnx</mimetype>
<mimetype>application/vnd.garmin.gmap+xml</mimetype>
<mimetype>image/vnd.maptech.kap</mimetype>
<mimetype>application/vnd.oziexplorer.map</mimetype>
<mimetype>application/vnd.mapbox.mbtiles</mimetype>
<mimetype>application/vnd.twonav.rmap</mimetype>
<mimetype>application/vnd.trekbuddy.tba</mimetype>
<mimetype>application/vnd.gpxsee.map+xml</mimetype>
<mimetype>application/x-tar</mimetype>
<mimetype>image/tiff</mimetype>
</mimetypes>
</component>

View File

@ -1887,6 +1887,7 @@ CI1971 / Chatham Islands Map Grid,5518,4672,5517,9001,9807,4500,8801,-44,9110,88
CI1979 / Chatham Islands Map Grid,5519,4673,5517,9001,9807,4500,8801,-44,9110,8802,-176.3,9110,8805,1,9201,8806,350000,9001,8807,650000,9001,,,,,,
DHDN / 3-degree Gauss-Kruger zone 1,5520,4314,16261,9001,9807,4530,8801,0,9102,8802,3,9102,8805,1,9201,8806,1500000,9001,8807,0,9001,,,,,,
WGS 84 / Gabon TM 2011,5523,4326,5522,9001,9807,4499,8801,0,9102,8802,11.3,9110,8805,0.9996,9201,8806,1500000,9001,8807,5500000,9001,,,,,,
SAD69(96) / Brazil Polyconic,5530,5527,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
SAD69(96) / UTM zone 21S,5531,5527,16121,9001,9807,4400,8801,0,9102,8802,-57,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SAD69(96) / UTM zone 22S,5532,4618,16122,9001,9807,4400,8801,0,9102,8802,-51,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SAD69(96) / UTM zone 23S,5533,5527,16123,9001,9807,4400,8801,0,9102,8802,-45,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
@ -1970,6 +1971,7 @@ SAD69(96) / UTM zone 18S,5875,5527,16118,9001,9807,4400,8801,0,9102,8802,-75,910
SAD69(96) / UTM zone 19S,5876,5527,16119,9001,9807,4400,8801,0,9102,8802,-69,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SAD69(96) / UTM zone 20S,5877,5527,16120,9001,9807,4400,8801,0,9102,8802,-63,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
Cadastre 1997 / UTM zone 38S,5879,4475,16138,9001,9807,4400,8801,0,9102,8802,45,9102,8805,0.9996,9201,8806,500000,9001,8807,10000000,9001,,,,,,
SIRGAS 2000 / Brazil Polyconic,5880,4674,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
WGS 84 / EPSG Arctic Regional zone A1,5921,4326,5906,9001,9802,4400,8821,81.19020136,9110,8822,-111,9102,8823,85,9102,8824,77,9102,8826,0,9001,8827,0,9001,,,
WGS 84 / EPSG Arctic Regional zone A2,5922,4326,5907,9001,9802,4400,8821,81.19020136,9110,8822,-39,9102,8823,85,9102,8824,77,9102,8826,0,9001,8827,0,9001,,,
WGS 84 / EPSG Arctic Regional zone A3,5923,4326,5908,9001,9802,4400,8821,81.19020136,9110,8822,33,9102,8823,85,9102,8824,77,9102,8826,0,9001,8827,0,9001,,,
@ -3046,6 +3048,8 @@ Pulkovo 1942 / Gauss-Kruger 32N,28492,4284,16332,9001,9807,4530,8801,0,9102,8802
Qatar 1974 / Qatar National Grid,28600,4285,19919,9001,9807,4400,8801,24.27,9110,8802,51.13,9110,8805,0.99999,9201,8806,200000,9001,8807,300000,9001,,,,,,
Amersfoort / RD Old,28991,4289,19913,9001,9809,4499,8801,52.0922178,9110,8802,5.23155,9110,8805,0.9999079,9201,8806,0,9001,8807,0,9001,,,,,,
Amersfoort / RD New,28992,4289,19914,9001,9809,4499,8801,52.0922178,9110,8802,5.23155,9110,8805,0.9999079,9201,8806,155000,9001,8807,463000,9001,,,,,,
SAD69 / Brazil Polyconic,29100,4291,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
SAD69 / Brazil Polyconic,29101,4618,19941,9001,9818,4499,8801,0,9102,8802,-54,9102,8806,5000000,9001,8807,10000000,9001,,,,,,,,,
SAD69 / UTM zone 18N,29118,4291,16018,9001,9807,4400,8801,0,9102,8802,-75,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,,,,
SAD69 / UTM zone 19N,29119,4291,16019,9001,9807,4400,8801,0,9102,8802,-69,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,,,,
SAD69 / UTM zone 20N,29120,4291,16020,9001,9807,4400,8801,0,9102,8802,-63,9102,8805,0.9996,9201,8806,500000,9001,8807,0,9001,,,,,,

Can't render this file because it is too large.

View File

@ -15,4 +15,4 @@ Icon=gpxsee
Terminal=false
Type=Application
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt;
MimeType=application/gpx+xml;application/tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/loc+xml;application/slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/sml+xml;
MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.32"
!define VERSION "7.38"
; 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"
@ -106,14 +109,14 @@ Section "GPXSee" SEC_APP
; Associate file formats
DetailPrint "Associating file types..."
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 8
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 9
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 10
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 11
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 12
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 13
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 14
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 15
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 11
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 16
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 17
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 18
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 19
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 20
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 21
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 22
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
@ -121,6 +124,47 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP File" 5
!insertmacro FILE_ASSOCIATION_ADD "gpi" "Garmin POI File" 6
!insertmacro FILE_ASSOCIATION_ADD "sml" "Suunto Markup Language" 7
!insertmacro FILE_ASSOCIATION_ADD "img" "Garmin IMG Map" 8
!insertmacro FILE_ASSOCIATION_ADD "jnx" "Garmin JNX Map" 9
!insertmacro FILE_ASSOCIATION_ADD "kap" "BSB Nautical Chart" 10
!insertmacro FILE_ASSOCIATION_ADD "map" "OziExplorer Map File" 12
!insertmacro FILE_ASSOCIATION_ADD "mbtiles" "MBTiles Map File" 13
!insertmacro FILE_ASSOCIATION_ADD "rmap" "TwoNav Raster Map File" 14
!insertmacro FILE_ASSOCIATION_ADD "tba" "TrekBuddy Atlas" 15
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tcx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".fit\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".igc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".nmea\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".plt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rte\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".wpt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".loc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".slf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".geojson\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".cup\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".gpi\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".sml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".csv\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".json\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpeg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".img\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jnx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".map\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".mbtiles\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rtmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tar\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tba\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tif\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tiff\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".xml\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -207,7 +251,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$StartMenuFolder\*.*"
RMDir "$SMPROGRAMS\$StartMenuFolder"
; Remove GPX file association
; Remove file associations
!insertmacro FILE_ASSOCIATION_REMOVE "gpx"
!insertmacro FILE_ASSOCIATION_REMOVE "tcx"
!insertmacro FILE_ASSOCIATION_REMOVE "kml"
@ -223,6 +267,47 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
!insertmacro FILE_ASSOCIATION_REMOVE "gpi"
!insertmacro FILE_ASSOCIATION_REMOVE "sml"
!insertmacro FILE_ASSOCIATION_REMOVE "img"
!insertmacro FILE_ASSOCIATION_REMOVE "jnx"
!insertmacro FILE_ASSOCIATION_REMOVE "kap"
!insertmacro FILE_ASSOCIATION_REMOVE "map"
!insertmacro FILE_ASSOCIATION_REMOVE "mbtiles"
!insertmacro FILE_ASSOCIATION_REMOVE "rmap"
!insertmacro FILE_ASSOCIATION_REMOVE "tba"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".fit\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".igc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".nmea\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".plt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rte\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".wpt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".loc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".slf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".geojson\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".cup\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".gpi\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".sml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".csv\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".json\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpeg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".img\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jnx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".map\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".mbtiles\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rtmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tar\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tba\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tif\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tiff\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".xml\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -253,4 +338,4 @@ LangString DESC_LOCALIZATION ${LANG_ENGLISH} \
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_MSVC} $(DESC_MSVC)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_APP} $(DESC_APP)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LOCALIZATION} $(DESC_LOCALIZATION)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
!insertmacro MUI_FUNCTION_DESCRIPTION_END

View File

@ -1,35 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<!-- Data files -->
<mime-type type="application/gpx+xml">
<comment>GPS Exchange Format</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.topografix.com/GPX/1/0" localName="gpx"/>
<root-XML namespaceURI="http://www.topografix.com/GPX/1/1" localName="gpx"/>
<glob pattern="*.gpx"/>
</mime-type>
<mime-type type="application/tcx+xml">
<mime-type type="application/vnd.garmin.tcx+xml">
<comment>Training Center XML</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" localName="TrainingCenterDatabase"/>
<glob pattern="*.tcx"/>
</mime-type>
<mime-type type="application/kml+xml">
<mime-type type="application/vnd.google-earth.kml+xml">
<comment>Keyhole Markup Language</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.opengis.net/kml/2.2" localName="kml"/>
<glob pattern="*.kml"/>
</mime-type>
<mime-type type="application/loc+xml">
<mime-type type="application/vnd.groundspeak.loc+xml">
<comment>Geocaching.com Waypoint File</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<glob pattern="*.loc"/>
</mime-type>
<mime-type type="application/slf+xml">
<mime-type type="application/vnd.sigma.slf+xml">
<comment>Sigma Log Format</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
@ -40,6 +46,9 @@
<comment>Flexible and Interoperable Data Transfer</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application-octet-stream"/>
<magic>
<match type="string" offset="8" value=".FIT"/>
</magic>
<glob pattern="*.fit"/>
</mime-type>
@ -61,6 +70,9 @@
<comment>OziExplorer Track Point File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Track Point File"/>
</magic>
<glob pattern="*.plt"/>
</mime-type>
@ -68,6 +80,9 @@
<comment>OziExplorer Route File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Route File"/>
</magic>
<glob pattern="*.rte"/>
</mime-type>
@ -75,6 +90,9 @@
<comment>OziExplorer Waypoint File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Waypoint File"/>
</magic>
<glob pattern="*.wpt"/>
</mime-type>
@ -96,13 +114,103 @@
<comment>Garmin POI File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<magic>
<match type="string" offset="8" value="GRMREC"/>
</magic>
<glob pattern="*.gpi"/>
</mime-type>
<mime-type type="application/sml+xml">
<mime-type type="application/vnd.suunto.sml+xml">
<comment>Suunto Markup Language</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.suunto.com/schemas/sml" localName="sml"/>
<glob pattern="*.sml"/>
</mime-type>
<!-- Maps -->
<mime-type type="application/vnd.garmin.img">
<comment>Garmin IMG Map</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application-octet-stream"/>
<magic>
<match type="string" offset="16" value="DSKIMG"/>
</magic>
<glob pattern="*.img"/>
</mime-type>
<mime-type type="application/vnd.garmin.jnx">
<comment>Garmin JNX Map</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application-octet-stream"/>
<glob pattern="*.jnx"/>
</mime-type>
<mime-type type="application/vnd.garmin.gmap+xml">
<comment>Garmin Map Product File</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.garmin.com/xmlschemas/MapProduct/v1" localName="MapProduct"/>
<root-XML namespaceURI="http://www.garmin.com/xmlschemas/MapProduct/v2" localName="MapProduct"/>
<glob pattern="*.xml"/>
</mime-type>
<mime-type type="image/vnd.maptech.kap">
<comment>BSB Nautical Chart</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.kap"/>
</mime-type>
<mime-type type="application/vnd.oziexplorer.map">
<comment>OziExplorer Map File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="OziExplorer Map Data File"/>
</magic>
<glob pattern="*.map"/>
</mime-type>
<mime-type type="application/vnd.mapbox.mbtiles">
<comment>MBTiles Map File</comment>
<sub-class-of type="application/vnd.sqlite3"/>
<generic-icon name="application/octet-stream"/>
<glob pattern="*.mbtiles"/>
</mime-type>
<mime-type type="application/vnd.twonav.rmap">
<comment>TwoNav Raster Map File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<magic>
<match type="string" offset="0" value="CompeGPSRasterImage"/>
</magic>
<glob pattern="*.rmap"/>
<glob pattern="*.rtmap"/>
</mime-type>
<mime-type type="application/vnd.trekbuddy.tba">
<comment>TrekBuddy Atlas</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-plain"/>
<magic>
<match type="string" offset="0" value="Atlas 1.0"/>
</magic>
<glob pattern="*.tba"/>
</mime-type>
<mime-type type="application/vnd.gpxsee.map+xml">
<comment>GPXSee Map Definition File</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="application-xml"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.0" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.1" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.2" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.3" localName="map"/>
<root-XML namespaceURI="http://www.gpxsee.org/map/1.4" localName="map"/>
<glob pattern="*.xml"/>
</mime-type>
</mime-info>

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.32"
!define VERSION "7.38"
; 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"
@ -113,14 +116,14 @@ Section "GPXSee" SEC_APP
; Associate file formats
DetailPrint "Associating file types..."
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 8
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 9
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 10
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 11
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 12
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 13
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 14
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 15
!insertmacro FILE_ASSOCIATION_ADD "gpx" "GPS Exchange Format" 11
!insertmacro FILE_ASSOCIATION_ADD "tcx" "Training Center XML" 16
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 17
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 18
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 19
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 20
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track Point File" 21
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 22
!insertmacro FILE_ASSOCIATION_ADD "wpt" "OziExplorer Waypoint File" 1
!insertmacro FILE_ASSOCIATION_ADD "loc" "Geocaching.com Waypoint File" 2
!insertmacro FILE_ASSOCIATION_ADD "slf" "Sigma Log File" 3
@ -128,6 +131,47 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "cup" "SeeYou CUP File" 5
!insertmacro FILE_ASSOCIATION_ADD "gpi" "Garmin POI File" 6
!insertmacro FILE_ASSOCIATION_ADD "sml" "Suunto Markup Language" 7
!insertmacro FILE_ASSOCIATION_ADD "img" "Garmin IMG Map" 8
!insertmacro FILE_ASSOCIATION_ADD "jnx" "Garmin JNX Map" 9
!insertmacro FILE_ASSOCIATION_ADD "kap" "BSB Nautical Chart" 10
!insertmacro FILE_ASSOCIATION_ADD "map" "OziExplorer Map File" 12
!insertmacro FILE_ASSOCIATION_ADD "mbtiles" "MBTiles Map File" 13
!insertmacro FILE_ASSOCIATION_ADD "rmap" "TwoNav Raster Map File" 14
!insertmacro FILE_ASSOCIATION_ADD "tba" "TrekBuddy Atlas" 15
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tcx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".fit\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".igc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".nmea\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".plt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rte\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".wpt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".loc\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".slf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".geojson\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".cup\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".gpi\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".sml\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".csv\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".json\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jpeg\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".img\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".jnx\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".kap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".map\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".mbtiles\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".rtmap\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tar\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tba\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tif\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".tiff\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".xml\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd
@ -215,7 +259,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$StartMenuFolder\*.*"
RMDir "$SMPROGRAMS\$StartMenuFolder"
; Remove File associations
; Remove file associations
!insertmacro FILE_ASSOCIATION_REMOVE "gpx"
!insertmacro FILE_ASSOCIATION_REMOVE "tcx"
!insertmacro FILE_ASSOCIATION_REMOVE "kml"
@ -231,6 +275,47 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "cup"
!insertmacro FILE_ASSOCIATION_REMOVE "gpi"
!insertmacro FILE_ASSOCIATION_REMOVE "sml"
!insertmacro FILE_ASSOCIATION_REMOVE "img"
!insertmacro FILE_ASSOCIATION_REMOVE "jnx"
!insertmacro FILE_ASSOCIATION_REMOVE "kap"
!insertmacro FILE_ASSOCIATION_REMOVE "map"
!insertmacro FILE_ASSOCIATION_REMOVE "mbtiles"
!insertmacro FILE_ASSOCIATION_REMOVE "rmap"
!insertmacro FILE_ASSOCIATION_REMOVE "tba"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".fit\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".igc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".nmea\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".plt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rte\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".wpt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".loc\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".slf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".geojson\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".cup\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".gpi\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".sml\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".csv\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".json\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jpeg\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".img\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".jnx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".kap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".map\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".mbtiles\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".rtmap\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tar\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tba\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tif\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tiff\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".xml\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
SectionEnd

View File

@ -16,6 +16,7 @@
#include "opengl.h"
#include "gui.h"
#include "settings.h"
#include "mapaction.h"
#include "app.h"
@ -76,11 +77,25 @@ App::~App()
int App::run()
{
MapAction *lastReady = 0;
QStringList args(arguments());
_gui->show();
QStringList args(arguments());
for (int i = 1; i < args.count(); i++)
_gui->openFile(args.at(i));
for (int i = 1; i < args.count(); i++) {
if (!_gui->openFile(args.at(i), true)) {
MapAction *a;
if (!_gui->loadMap(args.at(i), a, true))
_gui->openFile(args.at(i), false);
else {
if (a)
lastReady = a;
}
}
}
if (lastReady)
lastReady->trigger();
return exec();
}
@ -89,7 +104,18 @@ bool App::event(QEvent *event)
{
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *e = static_cast<QFileOpenEvent *>(event);
return _gui->openFile(e->file());
if (!_gui->openFile(e->file(), true)) {
MapAction *a;
if (!_gui->loadMap(e->file(), a, true))
return _gui->openFile(e->file(), false);
else {
if (a)
a->trigger();
return true;
}
} else
return true;
}
return QApplication::event(event);

View File

@ -5,6 +5,7 @@
#include <QGraphicsSceneMouseEvent>
#include "map/map.h"
#include "popup.h"
#include "tooltip.h"
#include "areaitem.h"
@ -22,7 +23,7 @@ QString AreaItem::info() const
}
AreaItem::AreaItem(const Area &area, Map *map, GraphicsItem *parent)
: GraphicsItem(parent), _area(area)
: PlaneItem(parent), _area(area)
{
_map = map;
_digitalZoom = 0;
@ -158,7 +159,6 @@ void AreaItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Q_UNUSED(event);
_pen.setWidthF((_width + 1) * pow(2, -_digitalZoom));
setZValue(zValue() + 1.0);
update();
}
@ -167,12 +167,5 @@ void AreaItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Q_UNUSED(event);
_pen.setWidthF(_width * pow(2, -_digitalZoom));
setZValue(zValue() - 1.0);
update();
}
void AreaItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Popup::show(event->screenPos(), info(), event->widget());
QGraphicsItem::mousePressEvent(event);
}

View File

@ -2,12 +2,9 @@
#define AREAITEM_H
#include "data/area.h"
#include "graphicsscene.h"
#include "tooltip.h"
#include "planeitem.h"
class Map;
class AreaItem : public GraphicsItem
class AreaItem : public PlaneItem
{
public:
AreaItem(const Area &area, Map *map, GraphicsItem *parent = 0);
@ -19,6 +16,7 @@ public:
const Area &area() const {return _area;}
RectC bounds() const {return _area.boundingRect();}
void setMap(Map *map);
void setColor(const QColor &color);
@ -27,17 +25,15 @@ public:
void setStyle(Qt::PenStyle style);
void setDigitalZoom(int zoom);
virtual QString info() const;
QString info() const;
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
private:
QPainterPath painterPath(const Polygon &polygon);
void updatePainterPath();
ToolTip toolTip() const;
Area _area;
Map *_map;

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

@ -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

@ -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

@ -11,7 +11,7 @@ GraphItem::GraphItem(const Graph &graph, GraphType type, int width,
Q_ASSERT(_graph.isValid());
_units = Metric;
_pen = QPen(color, width, style);
_pen = QPen(color, width, style, Qt::FlatCap);
_sx = 0; _sy = 0;
_time = _graph.hasTime();
setZValue(2.0);

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

@ -9,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"
@ -22,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)
{
@ -38,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);
@ -73,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()
@ -144,7 +142,7 @@ void GraphView::setXUnits()
}
}
createXLabel();
_xAxisLabel->setLabel(_xLabel, _xUnits);
}
void GraphView::setUnits(Units units)
@ -163,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);
@ -257,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);
@ -268,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);
@ -278,7 +281,9 @@ void GraphView::redraw(const QSizeF &size)
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();
@ -288,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++)
@ -316,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());
}
@ -367,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);
}

View File

@ -10,6 +10,7 @@
class AxisItem;
class AxisLabelItem;
class SliderItem;
class SliderInfoItem;
class GraphItem;
@ -86,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);
@ -96,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 "mapitem.h"
#include "mapaction.h"
#include "gui.h"
@ -130,20 +131,25 @@ void GUI::createMapActions()
if (mapDir.isNull())
return;
QString unused;
QList<Map*> maps(MapList::loadMaps(mapDir, unused));
QList<Map*> maps(MapList::loadMaps(mapDir));
for (int i = 0; i < maps.count(); i++) {
MapAction *a = createMapAction(maps.at(i));
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
Map *map = maps.at(i);
if (map->isValid()) {
MapAction *a = createMapAction(map);
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
} else {
qWarning("%s: %s", qPrintable(map->path()),
qPrintable(map->errorString()));
delete map;
}
}
}
MapAction *GUI::createMapAction(Map *map)
{
MapAction *a = new MapAction(map);
MapAction *a = new MapAction(map, _mapsActionGroup);
a->setMenuRole(QAction::NoRole);
a->setCheckable(true);
a->setActionGroup(_mapsActionGroup);
connect(a, SIGNAL(triggered()), this, SLOT(mapChanged()));
return a;
@ -160,7 +166,7 @@ void GUI::mapInitialized()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
qWarning("%s: %s", qPrintable(map->name()), qPrintable(map->errorString()));
qWarning("%s: %s", qPrintable(map->path()), qPrintable(map->errorString()));
action->deleteLater();
}
}
@ -230,13 +236,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);
@ -300,10 +313,14 @@ void GUI::createActions()
this);
_loadMapAction->setMenuRole(QAction::NoRole);
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
_loadMapDirAction = new QAction(QIcon(OPEN_FILE_ICON),
tr("Load map directory..."), this);
_loadMapDirAction->setMenuRole(QAction::NoRole);
connect(_loadMapDirAction, SIGNAL(triggered()), this, SLOT(loadMapDir()));
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
_clearMapCacheAction->setEnabled(false);
_clearMapCacheAction->setMenuRole(QAction::NoRole);
connect(_clearMapCacheAction, SIGNAL(triggered()), _mapView,
connect(_clearMapCacheAction, SIGNAL(triggered()), this,
SLOT(clearMapCache()));
_nextMapAction = new QAction(tr("Next map"), this);
_nextMapAction->setMenuRole(QAction::NoRole);
@ -497,7 +514,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();
@ -512,6 +530,7 @@ void GUI::createMenus()
_mapMenu->addActions(_mapsActionGroup->actions());
_mapsEnd = _mapMenu->addSeparator();
_mapMenu->addAction(_loadMapAction);
_mapMenu->addAction(_loadMapDirAction);
_mapMenu->addAction(_clearMapCacheAction);
_mapMenu->addSeparator();
_mapMenu->addAction(_showCoordinatesAction);
@ -624,15 +643,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));
@ -642,9 +661,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()
@ -713,7 +736,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();
}
@ -745,101 +771,45 @@ void GUI::paths()
void GUI::openFile()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats()));
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
openFile(*it);
if (!list.isEmpty())
_dataDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++)
openFile(files.at(i));
if (!files.isEmpty())
_dataDir = QFileInfo(files.last()).path();
}
bool GUI::openFile(const QString &fileName)
bool GUI::openFile(const QString &fileName, bool silent)
{
if (fileName.isEmpty() || _files.contains(fileName))
return false;
if (loadFile(fileName)) {
_files.append(fileName);
_browser->setCurrent(fileName);
_fileActionGroup->setEnabled(true);
_navigationActionGroup->setEnabled(true);
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
if (_files.contains(fileName))
return true;
} else {
if (_files.isEmpty())
_fileActionGroup->setEnabled(false);
if (!loadFile(fileName, silent))
return false;
}
_files.append(fileName);
_browser->setCurrent(fileName);
_fileActionGroup->setEnabled(true);
// Explicitly enable the reload action as it may be disabled by loadMapDir()
_reloadFileAction->setEnabled(true);
_navigationActionGroup->setEnabled(true);
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
return true;
}
bool GUI::loadFile(const QString &fileName)
bool GUI::loadFile(const QString &fileName, bool silent)
{
Data data(fileName);
QList<QList<GraphItem*> > graphs;
QList<PathItem*> paths;
Data data(fileName, !silent);
if (data.isValid()) {
for (int i = 0; i < data.tracks().count(); i++) {
const Track &track = data.tracks().at(i);
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
#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)
_dateRange.second = date;
}
_trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++)
_routeDistance += data.routes().at(i).distance();
_routeCount += data.routes().count();
_waypointCount += data.waypoints().count();
_areaCount += data.areas().count();
if (_pathName.isNull()) {
if (data.tracks().count() == 1 && !data.routes().count())
_pathName = data.tracks().first().name();
else if (data.routes().count() == 1 && !data.tracks().count())
_pathName = data.routes().first().name();
} else
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
graphs.append(_tabs.at(i)->loadData(data));
if (updateGraphTabs())
_splitter->refresh();
paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i);
for (int j = 0; j < graphs.count(); j++) {
const GraphItem *gi = graphs.at(j).at(i);
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
}
loadData(data);
return true;
} else {
} else if (!silent) {
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
@ -851,25 +821,83 @@ bool GUI::loadFile(const QString &fileName)
error.append("\n" + tr("Line: %1").arg(data.errorLine()));
QMessageBox::critical(this, APP_NAME, error);
return false;
} else
return false;
}
void GUI::loadData(const Data &data)
{
QList<QList<GraphItem*> > graphs;
QList<PathItem*> paths;
for (int i = 0; i < data.tracks().count(); i++) {
const Track &track = data.tracks().at(i);
_trackDistance += track.distance();
_time += track.time();
_movingTime += track.movingTime();
#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)
_dateRange.second = date;
}
_trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++)
_routeDistance += data.routes().at(i).distance();
_routeCount += data.routes().count();
_waypointCount += data.waypoints().count();
_areaCount += data.areas().count();
if (_pathName.isNull()) {
if (data.tracks().count() == 1 && !data.routes().count())
_pathName = data.tracks().first().name();
else if (data.routes().count() == 1 && !data.tracks().count())
_pathName = data.routes().first().name();
} else
_pathName = QString();
for (int i = 0; i < _tabs.count(); i++)
graphs.append(_tabs.at(i)->loadData(data));
if (updateGraphTabs())
_splitter->refresh();
paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i);
for (int j = 0; j < graphs.count(); j++) {
const GraphItem *gi = graphs.at(j).at(i);
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
}
}
void GUI::openPOIFile()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open POI file"),
_poiDir, Data::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open POI file"),
_poiDir, Data::formats()));
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
openPOIFile(*it);
if (!list.isEmpty())
_poiDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++)
openPOIFile(files.at(i));
if (!files.isEmpty())
_poiDir = QFileInfo(files.last()).path();
}
bool GUI::openPOIFile(const QString &fileName)
{
if (fileName.isEmpty() || _poi->files().contains(fileName))
return false;
if (_poi->files().contains(fileName))
return true;
if (_poi->loadFile(fileName)) {
_mapView->showPOI(true);
@ -928,7 +956,7 @@ void GUI::openOptions()
Options options(_options);
bool reload = false;
OptionsDialog dialog(&options, this);
OptionsDialog dialog(options, _units, this);
if (dialog.exec() != QDialog::Accepted)
return;
@ -1019,9 +1047,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;
@ -1029,16 +1057,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());
@ -1110,12 +1175,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)
@ -1151,53 +1217,91 @@ 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;
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;
}
}
}
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;
@ -1337,45 +1441,73 @@ void GUI::showGraphSliderInfo(bool show)
void GUI::loadMap()
{
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open map file"),
_mapDir, MapList::formats());
QStringList list = files;
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open map file"),
_mapDir, MapList::formats()));
MapAction *a, *lastReady = 0;
for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
loadMap(*it);
if (!list.isEmpty())
_mapDir = QFileInfo(list.first()).path();
for (int i = 0; i < files.size(); i++) {
if (loadMap(files.at(i), a) && a)
lastReady = a;
}
if (!files.isEmpty())
_mapDir = QFileInfo(files.last()).path();
if (lastReady)
lastReady->trigger();
}
bool GUI::loadMap(const QString &fileName)
static MapAction *findMapAction(const QList<QAction*> &mapActions,
const Map *map)
{
// On OS X fileName may be a directory!
if (fileName.isEmpty())
return false;
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 < mapActions.count(); i++) {
const Map *m = mapActions.at(i)->data().value<Map*>();
if (map->path() == m->path())
return static_cast<MapAction*>(mapActions.at(i));
}
return 0;
}
bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent)
{
QList<Map*> maps(MapList::loadMaps(fileName));
QList<QAction*> existingActions(_mapsActionGroup->actions());
MapAction *lastReady = 0;
bool valid = 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()));
MapAction *a;
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
if (!silent)
QMessageBox::critical(this, APP_NAME,
tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString());
delete map;
} else {
valid = true;
a = createMapAction(map);
_mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) {
lastReady = a;
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoaded()));
}
} else {
valid = true;
map = a->data().value<Map*>();
if (map->isReady())
lastReady = a;
}
}
return true;
action = lastReady;
return valid;
}
void GUI::mapLoaded()
@ -1388,13 +1520,94 @@ void GUI::mapLoaded()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
QString error = tr("Error loading map:") + "\n\n"
+ map->name() + "\n\n" + map->errorString();
QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
}
void GUI::mapLoadedDir()
{
MapAction *action = static_cast<MapAction*>(QObject::sender());
Map *map = action->data().value<Map*>();
if (map->isValid()) {
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
QList<MapAction*> actions;
actions.append(action);
_mapView->loadMaps(actions);
} else {
QString error = tr("Error loading map:") + "\n\n" + map->path() + "\n\n"
+ map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
}
void GUI::loadMapDir()
{
QString dir(QFileDialog::getExistingDirectory(this,
tr("Select map directory"), _mapDir, QFileDialog::ShowDirsOnly));
if (dir.isEmpty())
return;
QList<Map*> maps(MapList::loadMaps(dir));
QList<MapAction*> actions;
QList<QAction*> existingActions(_mapsActionGroup->actions());
QFileInfo fi(dir);
QMenu *menu = new QMenu(fi.fileName());
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a;
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
QMessageBox::critical(this, APP_NAME, tr("Error loading map:")
+ "\n\n" + map->path() + "\n\n" + map->errorString());
delete map;
} else {
a = createMapAction(map);
menu->addAction(a);
if (map->isReady()) {
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
actions.append(a);
} else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoadedDir()));
}
} else {
map = a->data().value<Map*>();
if (map->isReady())
actions.append(a);
}
}
_mapView->loadMaps(actions);
if (menu->isEmpty())
delete menu;
else {
menu->setStyleSheet("QMenu { menu-scrollable: 1; }");
_mapMenu->insertMenu(_mapsEnd, menu);
}
_mapDir = fi.absolutePath();
_areaCount += maps.size();
_fileActionGroup->setEnabled(true);
_reloadFileAction->setEnabled(false);
}
void GUI::clearMapCache()
{
if (QMessageBox::question(this, APP_NAME,
tr("Clear the map tile cache?")) == QMessageBox::Yes)
_mapView->clearMapCache();
}
void GUI::updateStatusBarInfo()
{
if (_files.count() == 0)
@ -1445,7 +1658,7 @@ void GUI::nextMap()
if (!checked)
return;
QList<QAction*> maps = _mapsActionGroup->actions();
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()) {
@ -1461,7 +1674,7 @@ void GUI::prevMap()
if (!checked)
return;
QList<QAction*> maps = _mapsActionGroup->actions();
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()) {
@ -1552,8 +1765,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++)
@ -1688,9 +1900,25 @@ void GUI::dragEnterEvent(QDragEnterEvent *event)
void GUI::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
for (int i = 0; i < urls.size(); i++)
openFile(urls.at(i).toLocalFile());
MapAction *lastReady = 0;
QList<QUrl> urls(event->mimeData()->urls());
for (int i = 0; i < urls.size(); i++) {
QString file(urls.at(i).toLocalFile());
if (!openFile(file, true)) {
MapAction *a;
if (!loadMap(file, a, true))
openFile(file, false);
else {
if (a)
lastReady = a;
}
}
}
if (lastReady)
lastReady->trigger();
event->acceptProposedAction();
}
@ -1796,23 +2024,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);
@ -2078,23 +2325,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);
@ -2270,7 +2536,7 @@ void GUI::readSettings()
QAction *GUI::mapAction(const QString &name)
{
QList<QAction *> maps = _mapsActionGroup->actions();
QList<QAction *> maps(_mapsActionGroup->actions());
// Last map
for (int i = 0; i < maps.count(); i++) {

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;
@ -29,6 +30,7 @@ class Map;
class POI;
class QScreen;
class MapAction;
class Data;
class GUI : public QMainWindow
{
@ -37,7 +39,9 @@ class GUI : public QMainWindow
public:
GUI();
bool openFile(const QString &fileName);
bool openFile(const QString &fileName, bool silent = false);
bool loadMap(const QString &fileName, MapAction *&action,
bool silent = false);
void show();
private slots:
@ -45,7 +49,8 @@ private slots:
void keys();
void paths();
void printFile();
void exportFile();
void exportPDFFile();
void exportPNGFile();
void openFile();
void closeAll();
void reloadFiles();
@ -60,9 +65,11 @@ private slots:
void showTracks(bool show);
void showRoutes(bool show);
void loadMap();
void loadMapDir();
void nextMap();
void prevMap();
void openOptions();
void clearMapCache();
void mapChanged();
void graphChanged(int);
@ -89,6 +96,7 @@ private slots:
void logicalDotsPerInchChanged(qreal dpi);
void mapLoaded();
void mapLoadedDir();
void mapInitialized();
private:
@ -97,6 +105,10 @@ private:
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);
MapAction *createMapAction(Map *map);
@ -111,9 +123,8 @@ private:
void createBrowser();
bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName);
bool loadMap(const QString &fileName);
void exportFile(const QString &fileName);
bool loadFile(const QString &fileName, bool silent = false);
void loadData(const Data &data);
void updateStatusBarInfo();
void updateWindowTitle();
void updateNavigationActions();
@ -153,7 +164,8 @@ private:
QAction *_aboutAction;
QAction *_aboutQtAction;
QAction *_printFileAction;
QAction *_exportFileAction;
QAction *_exportPDFFileAction;
QAction *_exportPNGFileAction;
QAction *_openFileAction;
QAction *_closeFileAction;
QAction *_reloadFileAction;
@ -166,6 +178,7 @@ private:
QAction *_showMapAction;
QAction *_fullscreenAction;
QAction *_loadMapAction;
QAction *_loadMapDirAction;
QAction *_clearMapCacheAction;
QAction *_showGraphsAction;
QAction *_showGraphGridAction;
@ -228,10 +241,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

@ -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)

230
src/GUI/mapitem.cpp Normal file
View File

@ -0,0 +1,230 @@
#include <cmath>
#include <QCursor>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include "map/map.h"
#include "mapaction.h"
#include "popup.h"
#include "tooltip.h"
#include "mapitem.h"
static void growLeft(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.x() < rect.left())
rect.setLeft(p.x());
}
static void growRight(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.x() > rect.right())
rect.setRight(p.x());
}
static void growTop(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.y() > rect.top())
rect.setTop(p.y());
}
static void growBottom(Map *map, const Coordinates &c, QRectF &rect)
{
QPointF p(map->ll2xy(c));
if (p.y() < rect.bottom())
rect.setBottom(p.y());
}
static QRectF bbox(const RectC &rect, Map *map, int samples = 100)
{
if (!rect.isValid())
return QRectF();
double dx = rect.width() / samples;
double dy = rect.height() / samples;
QPointF tl(map->ll2xy(rect.topLeft()));
QPointF br(map->ll2xy(rect.bottomRight()));
QRectF prect(tl, br);
for (int i = 0; i <= samples; i++) {
double x = remainder(rect.left() + i * dx, 360.0);
growTop(map, Coordinates(x, rect.bottom()), prect);
growBottom(map, Coordinates(x, rect.top()), prect);
}
for (int i = 0; i <= samples; i++) {
double y = rect.bottom() + i * dy;
growLeft(map, Coordinates(rect.left(), y), prect);
growRight(map, Coordinates(rect.right(), y), prect);
}
return prect;
}
QString MapItem::info() const
{
ToolTip tt;
if (!_name.isEmpty())
tt.insert(tr("Name"), _name);
if (!_fileName.isEmpty())
tt.insert(tr("File"), _fileName);
return tt.toString();
}
MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent)
: PlaneItem(parent)
{
Map *src = action->data().value<Map*>();
Q_ASSERT(map->isReady());
_name = src->name();
_fileName = src->path();
_bounds = src->llBounds();
connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
_map = map;
_digitalZoom = 0;
_width = 2;
_opacity = 0.5;
QBrush brush(Qt::SolidPattern);
_pen = QPen(brush, _width);
updatePainterPath();
setCursor(Qt::ArrowCursor);
setAcceptHoverEvents(true);
}
void MapItem::updatePainterPath()
{
_painterPath = QPainterPath();
QRectF r(bbox(_bounds, _map));
if (r.left() > r.right()) {
QRectF r1(bbox(RectC(_bounds.topLeft(),
Coordinates(180, _bounds.bottomRight().lat())), _map));
QRectF r2(bbox(RectC(Coordinates(-180, _bounds.topLeft().lat()),
_bounds.bottomRight()), _map));
_painterPath.addRect(r1);
_painterPath.addRect(r2);
} else
_painterPath.addRect(r);
}
void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setPen(_width ? _pen : QPen(Qt::NoPen));
painter->drawPath(_painterPath);
painter->fillPath(_painterPath, _brush);
//QPen p = QPen(QBrush(Qt::red), 0);
//painter->setPen(p);
//painter->drawRect(boundingRect());
}
void MapItem::setMap(Map *map)
{
prepareGeometryChange();
_map = map;
updatePainterPath();
}
void MapItem::setColor(const QColor &color)
{
if (_pen.color() == color)
return;
QColor bc(color);
bc.setAlphaF(_opacity * color.alphaF());
_pen.setColor(color);
_brush = QBrush(bc);
update();
}
void MapItem::setOpacity(qreal opacity)
{
if (_opacity == opacity)
return;
_opacity = opacity;
QColor bc(_pen.color());
bc.setAlphaF(_opacity * _pen.color().alphaF());
_brush = QBrush(bc);
update();
}
void MapItem::setWidth(qreal width)
{
if (_width == width)
return;
prepareGeometryChange();
_width = width;
_pen.setWidthF(_width * pow(2, -_digitalZoom));
}
void MapItem::setStyle(Qt::PenStyle style)
{
if (_pen.style() == style)
return;
_pen.setStyle(style);
update();
}
void MapItem::setDigitalZoom(int zoom)
{
if (_digitalZoom == zoom)
return;
prepareGeometryChange();
_digitalZoom = zoom;
_pen.setWidthF(_width * pow(2, -_digitalZoom));
}
void MapItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
_pen.setWidthF((_width + 1) * pow(2, -_digitalZoom));
update();
}
void MapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
Q_UNUSED(event);
_pen.setWidthF(_width * pow(2, -_digitalZoom));
update();
}
void MapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event);
emit triggered();
}

57
src/GUI/mapitem.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef MAPITEM_H
#define MAPITEM_H
#include "planeitem.h"
class MapAction;
class MapItem : public QObject, public PlaneItem
{
Q_OBJECT
public:
MapItem(MapAction *action, Map *map, GraphicsItem *parent = 0);
QPainterPath shape() const {return _painterPath;}
QRectF boundingRect() const {return _painterPath.boundingRect();}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
RectC bounds() const {return _bounds;}
void setMap(Map *map);
void setColor(const QColor &color);
void setOpacity(qreal opacity);
void setWidth(qreal width);
void setStyle(Qt::PenStyle style);
void setDigitalZoom(int zoom);
QString info() const;
signals:
void triggered();
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
private:
void updatePainterPath();
RectC _bounds;
QString _name;
QString _fileName;
Map *_map;
int _digitalZoom;
qreal _width;
QPen _pen;
QBrush _brush;
qreal _opacity;
QPainterPath _painterPath;
};
#endif // MAPITEM_H

View File

@ -3,6 +3,7 @@
#include <QWheelEvent>
#include <QApplication>
#include <QScrollBar>
#include <QClipboard>
#include "data/poi.h"
#include "data/data.h"
#include "map/map.h"
@ -14,8 +15,10 @@
#include "areaitem.h"
#include "scaleitem.h"
#include "coordinatesitem.h"
#include "mapitem.h"
#include "keys.h"
#include "graphicsscene.h"
#include "mapaction.h"
#include "mapview.h"
@ -26,6 +29,20 @@
#define COORDINATES_OFFSET SCALE_OFFSET
template<typename T>
static void updateZValues(T &items)
{
for (int i = 0; i < items.size(); i++) {
const QGraphicsItem *ai = items.at(i);
for (int j = 0; j < items.size(); j++) {
QGraphicsItem *aj = items[j];
if (aj->boundingRect().contains(ai->boundingRect()))
aj->setZValue(qMin(ai->zValue() - 1, aj->zValue()));
}
}
}
MapView::MapView(Map *map, POI *poi, QWidget *parent)
: QGraphicsView(parent)
{
@ -38,7 +55,7 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHint(QPainter::Antialiasing, true);
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
setResizeAnchor(QGraphicsView::AnchorViewCenter);
setAcceptDrops(false);
@ -169,18 +186,19 @@ void MapView::addArea(const Area &area)
}
AreaItem *ai = new AreaItem(area, _map);
_areas.append(ai);
_ar |= ai->area().boundingRect();
ai->setColor(_palette.nextColor());
ai->setWidth(_areaWidth);
ai->setStyle(_areaStyle);
ai->setOpacity(_areaOpacity);
ai->setDigitalZoom(_digitalZoom);
ai->setVisible(_showAreas);
_scene->addItem(ai);
_ar |= ai->bounds();
_areas.append(ai);
if (_showAreas)
addPOI(_poi->points(ai->area()));
addPOI(_poi->points(ai->bounds()));
}
void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
@ -204,6 +222,26 @@ void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
}
}
MapItem *MapView::addMap(MapAction *map)
{
MapItem *mi = new MapItem(map, _map);
mi->setColor(_palette.nextColor());
mi->setWidth(_areaWidth);
mi->setStyle(_areaStyle);
mi->setOpacity(_areaOpacity);
mi->setDigitalZoom(_digitalZoom);
mi->setVisible(_showAreas);
_scene->addItem(mi);
_ar |= mi->bounds();
_areas.append(mi);
if (_showAreas)
addPOI(_poi->points(mi->bounds()));
return mi;
}
QList<PathItem *> MapView::loadData(const Data &data)
{
QList<PathItem *> paths;
@ -226,18 +264,37 @@ QList<PathItem *> MapView::loadData(const Data &data)
else
updatePOIVisibility();
if (!data.areas().isEmpty())
updateZValues(_areas);
centerOn(contentCenter());
return paths;
}
void MapView::loadMaps(const QList<MapAction *> &maps)
{
int zoom = _map->zoom();
for (int i = 0; i < maps.size(); i++)
addMap(maps.at(i));
if (fitMapZoom() != zoom)
rescale();
else
updatePOIVisibility();
updateZValues(_areas);
centerOn(contentCenter());
}
int MapView::fitMapZoom() const
{
RectC br = _tr | _rr | _wr | _ar;
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
br.isNull() ? RectC(_map->xy2ll(_map->bounds().topLeft()),
_map->xy2ll(_map->bounds().bottomRight())) : br);
br.isNull() ? _map->llBounds() : br);
}
QPointF MapView::contentCenter() const
@ -372,7 +429,7 @@ void MapView::updatePOI()
addPOI(_poi->points(_routes.at(i)->path()));
if (_showAreas)
for (int i = 0; i < _areas.size(); i++)
addPOI(_poi->points(_areas.at(i)->area()));
addPOI(_poi->points(_areas.at(i)->bounds()));
if (_showWaypoints)
for (int i = 0; i< _waypoints.size(); i++)
addPOI(_poi->points(_waypoints.at(i)->waypoint()));
@ -503,6 +560,10 @@ void MapView::wheelEvent(QWheelEvent *event)
void MapView::mouseDoubleClickEvent(QMouseEvent *event)
{
QGraphicsView::mouseDoubleClickEvent(event);
if (event->isAccepted())
return;
if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton)
return;
@ -522,7 +583,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;
}
@ -530,8 +596,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;
@ -559,10 +643,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();
@ -594,7 +686,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);

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"
@ -28,25 +29,36 @@ class ScaleItem;
class CoordinatesItem;
class PathItem;
class GraphItem;
class AreaItem;
class PlaneItem;
class MapItem;
class Area;
class GraphicsScene;
class QTimeZone;
class MapAction;
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);
void loadMaps(const QList<MapAction*> &maps);
void setPalette(const Palette &palette);
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();
@ -99,6 +111,7 @@ private:
PathItem *addTrack(const Track &track);
PathItem *addRoute(const Route &route);
MapItem *addMap(MapAction *map);
void addArea(const Area &area);
void addWaypoints(const QVector<Waypoint> &waypoints);
void addPOI(const QList<Waypoint> &waypoints);
@ -114,13 +127,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;
@ -129,7 +144,7 @@ private:
QList<TrackItem*> _tracks;
QList<RouteItem*> _routes;
QList<WaypointItem*> _waypoints;
QList<AreaItem*> _areas;
QList<PlaneItem*> _areas;
POIHash _pois;
RectC _tr, _rr, _wr, _ar;
@ -154,6 +169,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

@ -56,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);
@ -112,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);
@ -129,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);
@ -146,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);
@ -166,15 +166,15 @@ QWidget *OptionsDialog::createAppearancePage()
// Palette & antialiasing
_baseColor = new ColorBox();
_baseColor->setColor(_options->palette.color());
_baseColor->setColor(_options.palette.color());
_colorOffset = new PercentSlider();
_colorOffset->setValue(_options->palette.shift() * 100);
_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);
@ -201,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);
@ -217,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);
@ -247,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();
@ -257,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);
@ -271,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();
@ -301,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();
@ -328,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);
@ -349,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);
@ -359,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,
@ -400,29 +400,29 @@ 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);
_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);
_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)
if (_options.timeZone.type() == TimeZoneInfo::UTC)
_utcZone->setChecked(true);
else if (_options->timeZone.type() == TimeZoneInfo::System)
else if (_options.timeZone.type() == TimeZoneInfo::System)
_systemZone->setChecked(true);
else
_customZone->setChecked(true);
@ -431,7 +431,7 @@ QWidget *OptionsDialog::createDataPage()
QList<QByteArray> zones = QTimeZone::availableTimeZoneIds();
for (int i = 0; i < zones.size(); i++)
_timeZone->addItem(zones.at(i));
_timeZone->setCurrentText(_options->timeZone.customZone().id());
_timeZone->setCurrentText(_options.timeZone.customZone().id());
connect(_customZone, SIGNAL(toggled(bool)), _timeZone,
SLOT(setEnabled(bool)));
QHBoxLayout *customZoneLayout = new QHBoxLayout();
@ -440,7 +440,7 @@ QWidget *OptionsDialog::createDataPage()
#endif // ENABLE_TIMEZONES
_useSegments = new QCheckBox(tr("Use segments"));
_useSegments->setChecked(_options->useSegments);
_useSegments->setChecked(_options.useSegments);
QWidget *sourceTab = new QWidget();
QVBoxLayout *sourceTabLayout = new QVBoxLayout();
@ -477,12 +477,18 @@ QWidget *OptionsDialog::createDataPage()
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
formLayout->addRow(_useSegments);
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();
@ -541,14 +547,14 @@ QWidget *OptionsDialog::createPOIPage()
_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"));
}
@ -568,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);
@ -597,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);
@ -622,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);
@ -641,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);
@ -682,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());
@ -735,82 +741,82 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
void OptionsDialog::accept()
{
_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(
_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();
_options->showSecondaryElevation = _showSecondaryElevation->isChecked();
_options->showSecondarySpeed = _showSecondarySpeed->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()
_options.timeZone.setType(_utcZone->isChecked()
? TimeZoneInfo::UTC : _systemZone->isChecked()
? TimeZoneInfo::System : TimeZoneInfo::Custom);
_options->timeZone.setCustomZone(QTimeZone(_timeZone->currentText()
_options.timeZone.setCustomZone(QTimeZone(_timeZone->currentText()
.toLatin1()));
#endif // ENABLE_TIMEZONES
_options->useSegments = _useSegments->isChecked();
_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;
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

@ -82,8 +82,6 @@ struct Options {
bool printMovingTime;
bool printItemCount;
bool separateGraphPage;
Units units;
};
class OptionsDialog : public QDialog
@ -94,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);
@ -107,8 +105,9 @@ private:
QWidget *createSystemPage();
QWidget *createExportPage();
Options *_options;
Options &_options;
Units _units;
// Appearance
ColorBox *_baseColor;
PercentSlider *_colorOffset;

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

24
src/GUI/planeitem.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef PLANEITEM_H
#define PLANEITEM_H
#include "common/rectc.h"
#include "graphicsscene.h"
class Map;
class PlaneItem : public GraphicsItem
{
public:
PlaneItem(GraphicsItem *parent = 0) : GraphicsItem(parent) {}
virtual RectC bounds() const = 0;
virtual void setMap(Map *map) = 0;
virtual void setColor(const QColor &color) = 0;
virtual void setOpacity(qreal opacity) = 0;
virtual void setWidth(qreal width) = 0;
virtual void setStyle(Qt::PenStyle style) = 0;
virtual void setDigitalZoom(int zoom) = 0;
};
#endif // PLANEITEM_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

@ -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"

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

@ -15,4 +15,15 @@ inline double toWGS24(qint32 v)
return toWGS32(LS(v, 8));
}
inline quint8 vs(const quint8 b0)
{
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
return sizes[b0 & 0x07];
}
inline quint8 bs(const quint8 val)
{
return (val + 7) >> 3;
}
#endif // GARMIN_H

View File

@ -1,3 +1,4 @@
#include <cmath>
#include "wgs84.h"
#include "rectc.h"
@ -6,6 +7,16 @@
#define MIN_LON deg2rad(-180.0)
#define MAX_LON deg2rad(180.0)
static inline double WLON(double lon)
{
return remainder(lon, 360.0);
}
static inline double LLAT(double lat)
{
return (lat < 0.0) ? qMax(lat, -90.0) : qMin(lat, 90.0);
}
RectC::RectC(const Coordinates &center, double radius)
{
double radDist = radius / WGS84_RADIUS;
@ -151,6 +162,12 @@ RectC RectC::united(const Coordinates &c) const
return RectC(Coordinates(l, t), Coordinates(r, b));
}
RectC RectC::adjusted(double lon1, double lat1, double lon2, double lat2) const
{
return RectC(Coordinates(WLON(_tl.lon() + lon1), LLAT(_tl.lat() + lat1)),
Coordinates(WLON(_br.lon() + lon2), LLAT(_br.lat() + lat2)));
}
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const RectC &rect)
{

View File

@ -15,7 +15,8 @@ public:
bool isNull() const
{return _tl.isNull() && _br.isNull();}
bool isValid() const
{return (_tl.isValid() && _br.isValid() && _tl != _br);}
{return (_tl.isValid() && _br.isValid()
&& _tl.lat() != _br.lat() && _tl.lon() != _br.lon());}
Coordinates topLeft() const {return _tl;}
Coordinates bottomRight() const {return _br;}
@ -23,14 +24,18 @@ public:
{return Coordinates((_tl.lon() + _br.lon()) / 2.0,
(_tl.lat() + _br.lat()) / 2.0);}
double width() const
{
double res = right() - left();
return (left() > right()) ? 360.0 - res : res;
}
double height() const {return (top() - bottom());}
double top() const {return _tl.lat();}
double bottom() const {return _br.lat();}
double left() const {return _tl.lon();}
double right() const {return _br.lon();}
double width() const {return (right() - left());}
double height() const {return (top() - bottom());}
void setLeft(double val) {_tl.rlon() = val;}
void setRight(double val) {_br.rlon() = val;}
void setTop(double val) {_tl.rlat() = val;}
@ -42,6 +47,7 @@ public:
RectC &operator&=(const RectC &r) {*this = *this & r; return *this;}
RectC united(const Coordinates &c) const;
RectC adjusted(double lon1, double lat1, double lon2, double lat2) const;
bool intersects(const RectC &r) const
{return (right() >= r.left() && bottom() <= r.top() && left() <= r.right()

View File

@ -1,7 +1,29 @@
// TITLE
//
// R-TREES: A DYNAMIC INDEX STRUCTURE FOR SPATIAL SEARCHING
//
// DESCRIPTION
//
// A C++ templated version of the RTree algorithm.
// For more information please read the comments in RTree.h
//
// AUTHORS
//
// * 1983 Original algorithm and test code by Antonin Guttman
// and Michael Stonebraker, UC Berkely
// * 1994 ANSI C ported from original test code by Melinda Green
// (melinda@superliminal.com)
// * 1995 Sphere volume fix for degeneracy problem submitted by Paul Brook
// * 2004 Templated C++ port by Greg Douglas
// * 2018 Iterator fix and Qt macros by Martin Tuma
//
// LICENSE:
//
// Entirely free for all uses. Enjoy!
#ifndef RTREE_H
#define RTREE_H
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <QtGlobal>
@ -387,10 +409,10 @@ RTREE_TEMPLATE
void RTREE_QUAL::Insert(const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
{
#ifdef _DEBUG
#ifndef QT_NO_DEBUG
for (int index=0; index<NUMDIMS; ++index)
Q_ASSERT(a_min[index] <= a_max[index]);
#endif //_DEBUG
#endif // QT_NO_DEBUG
Rect rect;
@ -407,10 +429,10 @@ RTREE_TEMPLATE
void RTREE_QUAL::Remove(const ELEMTYPE a_min[NUMDIMS],
const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
{
#ifdef _DEBUG
#ifndef QT_NO_DEBUG
for (int index=0; index<NUMDIMS; ++index)
Q_ASSERT(a_min[index] <= a_max[index]);
#endif //_DEBUG
#endif // QT_NO_DEBUG
Rect rect;
@ -427,10 +449,10 @@ RTREE_TEMPLATE
int RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS],
bool a_resultCallback(DATATYPE a_data, void* a_context), void* a_context) const
{
#ifdef _DEBUG
#ifndef QT_NO_DEBUG
for (int index=0; index<NUMDIMS; ++index)
Q_ASSERT(a_min[index] <= a_max[index]);
#endif //_DEBUG
#endif // QT_NO_DEBUG
Rect rect;
@ -636,10 +658,10 @@ bool RTREE_QUAL::InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root,
{
Q_ASSERT(a_rect && a_root);
Q_ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level);
#ifdef _DEBUG
#ifndef QT_NO_DEBUG
for (int index=0; index < NUMDIMS; ++index)
Q_ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]);
#endif //_DEBUG
#endif // QT_NO_DEBUG
Node* newRoot;
Node* newNode;

View File

@ -33,18 +33,18 @@ public:
return false;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
if (_be)
val = data;
else {
for (size_t i = 0; i < sizeof(T); i++)
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
}
if (_be)
val = data;
else {
for (size_t i = 0; i < sizeof(T); i++)
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
}
#else
if (_be) {
for (size_t i = 0; i < sizeof(T); i++)
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
} else
val = data;
if (_be) {
for (size_t i = 0; i < sizeof(T); i++)
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
} else
val = data;
#endif
return true;

View File

@ -8,6 +8,19 @@
class Area : public QList<Polygon>
{
public:
Area() {}
Area(const RectC &rect)
{
Polygon polygon;
QVector<Coordinates> v(4);
v[0] = Coordinates(rect.left(), rect.top());
v[1] = Coordinates(rect.right(), rect.top());
v[2] = Coordinates(rect.right(), rect.bottom());
v[3] = Coordinates(rect.left(), rect.bottom());
polygon.append(v);
append(polygon);
}
const QString& name() const {return _name;}
const QString& description() const {return _desc;}
void setName(const QString &name) {_name = name;}

View File

@ -20,6 +20,7 @@
#include "cupparser.h"
#include "gpiparser.h"
#include "smlparser.h"
#include "map/map.h"
#include "data.h"
@ -82,7 +83,7 @@ void Data::processData(QList<TrackData> &trackData, QList<RouteData> &routeData)
_routes.append(Route(routeData.at(i)));
}
Data::Data(const QString &fileName)
Data::Data(const QString &fileName, bool tryUnknown)
{
QFile file(fileName);
QFileInfo fi(fileName);
@ -108,7 +109,7 @@ Data::Data(const QString &fileName)
_errorLine = it.value()->errorLine();
_errorString = it.value()->errorString();
}
} else {
} else if (tryUnknown) {
for (it = _parsers.begin(); it != _parsers.end(); it++) {
if (it.value()->parse(&file, trackData, routeData, _polygons,
_waypoints)) {

View File

@ -10,11 +10,10 @@
#include "route.h"
#include "parser.h"
class Data
{
public:
Data(const QString &fileName);
Data(const QString &fileName, bool full = true);
bool isValid() const {return _valid;}
const QString &errorString() const {return _errorString;}

View File

@ -51,13 +51,13 @@ class FITParser::CTX {
public:
CTX(QFile *file, QVector<Waypoint> &waypoints)
: file(file), waypoints(waypoints), len(0), endian(0), timestamp(0),
lastWrite(0), ratio(NAN) {}
ratio(NAN) {}
QFile *file;
QVector<Waypoint> &waypoints;
quint32 len;
quint8 endian;
quint32 timestamp, lastWrite;
quint32 timestamp;
MessageDefinition defs[16];
qreal ratio;
Trackpoint trackpoint;
@ -361,14 +361,12 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
ctx.ratio = ((qreal)front / (qreal)rear);
}
} else if (def->globalId == RECORD_MESSAGE) {
if (ctx.timestamp > ctx.lastWrite
&& ctx.trackpoint.coordinates().isValid()) {
if (ctx.trackpoint.coordinates().isValid()) {
ctx.trackpoint.setTimestamp(QDateTime::fromTime_t(ctx.timestamp
+ 631065600));
ctx.trackpoint.setRatio(ctx.ratio);
ctx.segment.append(ctx.trackpoint);
ctx.trackpoint = Trackpoint();
ctx.lastWrite = ctx.timestamp;
}
} else if (def->globalId == COURSE_POINT)
if (waypoint.coordinates().isValid())

View File

@ -485,15 +485,8 @@ static quint32 readCamera(QDataStream &stream, QVector<Waypoint> &waypoints,
waypoints.append(Coordinates(toWGS24(lon), toWGS24(lat)));
Area area;
Polygon polygon;
QVector<Coordinates> v(4);
v[0] = Coordinates(toWGS24(left), toWGS24(top));
v[1] = Coordinates(toWGS24(right), toWGS24(top));
v[2] = Coordinates(toWGS24(right), toWGS24(bottom));
v[3] = Coordinates(toWGS24(left), toWGS24(bottom));
polygon.append(v);
area.append(polygon);
Area area(RectC(Coordinates(toWGS24(left), toWGS24(top)),
Coordinates(toWGS24(right), toWGS24(bottom))));
switch (type) {
case 8:

View File

@ -80,12 +80,25 @@ void POI::search(const RectC &rect, QSet<int> &set) const
{
qreal min[2], max[2];
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
if (rect.left() > rect.right()) {
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = 180.0;
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
_tree.Search(min, max, cb, &set);
min[0] = -180.0;
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
} else {
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
}
}
QList<Waypoint> POI::points(const Path &path) const
@ -130,16 +143,10 @@ QList<Waypoint> POI::points(const Waypoint &point) const
{
QList<Waypoint> ret;
QSet<int> set;
qreal min[2], max[2];
QSet<int>::const_iterator it;
RectC br(point.coordinates(), _radius);
min[0] = br.topLeft().lon();
min[1] = br.bottomRight().lat();
max[0] = br.bottomRight().lon();
max[1] = br.topLeft().lat();
_tree.Search(min, max, cb, &set);
search(br, set);
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));
@ -147,22 +154,15 @@ QList<Waypoint> POI::points(const Waypoint &point) const
return ret;
}
QList<Waypoint> POI::points(const Area &area) const
QList<Waypoint> POI::points(const RectC &rect) const
{
QList<Waypoint> ret;
qreal min[2], max[2];
QSet<int> set;
QSet<int>::const_iterator it;
RectC br(area.boundingRect());
double offset = rad2deg(_radius / WGS84_RADIUS);
min[0] = br.topLeft().lon() - offset;
min[1] = br.bottomRight().lat() - offset;
max[0] = br.bottomRight().lon() + offset;
max[1] = br.topLeft().lat() + offset;
_tree.Search(min, max, cb, &set);
RectC br(rect.adjusted(-offset, offset, offset, -offset));
search(br, set);
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));

View File

@ -9,7 +9,6 @@
#include "waypoint.h"
class Path;
class Area;
class RectC;
class POI : public QObject
@ -29,7 +28,7 @@ public:
QList<Waypoint> points(const Path &path) const;
QList<Waypoint> points(const Waypoint &point) const;
QList<Waypoint> points(const Area &area) const;
QList<Waypoint> points(const RectC &rect) const;
const QStringList &files() const {return _files;}
void enableFile(const QString &fileName, bool enable);

View File

@ -95,9 +95,11 @@ Track::Track(const TrackData &data) : _pause(0)
if (_useSegments)
_data = data;
else {
_data.append(SegmentData());
for (int i = 0; i < data.size(); i++)
_data[0] << data.at(i);
if (!data.isEmpty()) {
_data.append(data.first());
for (int i = 1; i < data.size(); i++)
_data.first() << data.at(i);
}
}
for (int i = 0; i < _data.size(); i++) {

View File

@ -12,6 +12,22 @@ bool BitStream1::flush()
return true;
}
bool BitStream1::readUInt24(quint32 &val)
{
quint8 b;
val = 0;
for (int i = 0; i < 3; i++) {
if (!read(8, b))
return false;
val |= (b << (i * 8));
}
return true;
}
bool BitStream4F::flush()
{
if (_length && !_file.seek(_hdl, _file.pos(_hdl) + _length))

View File

@ -12,6 +12,8 @@ public:
bool flush();
quint64 bitsAvailable() const {return (quint64)_length * 8 + _remaining;}
bool readUInt24(quint32 &val);
private:
const SubFile &_file;
SubFile::Handle &_hdl;

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