Compare commits

...

137 Commits

Author SHA1 Message Date
x7z4w
98f537bc86 [ci] Fix appstream
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-20 09:00:45 +00:00
Filip Czaplicki
9c0e1abd15 [styles] Deduplicate mapcss rules
Change done automatically using
``` zsh
for x in **/*.mapcss; do
    rg --passthru -UN --pcre2 '^node\|([^,]+),?\narea\|\1,?' --replace 'node|$1,' $x | sponge $x;
    rg --passthru -UN --pcre2 '^area\|([^,]+),?\nnode\|\1,?' --replace 'node|$1,' $x | sponge $x;
done
```

Follow up to #999

Signed-off-by: Filip Czaplicki <git@starsep.com>
2025-08-20 07:53:37 +02:00
Jean-Baptiste
ca9b3535a8 [android] Use Material 3 theme on linear progress bar
Signed-off-by: jeanbaptisteC <jeanbaptiste.charron@outlook.fr>
2025-08-20 06:51:55 +02:00
Jean-Baptiste
dddbfa315d [android] Drop OSM OAuth1 login
Signed-off-by: jeanbaptisteC <jeanbaptiste.charron@outlook.fr>
2025-08-20 06:35:21 +02:00
Jean-Baptiste
c30990ecda [android] Fix deprecation in HoursMinutesPickerFragment
Signed-off-by: jeanbaptisteC <jeanbaptiste.charron@outlook.fr>
2025-08-20 06:20:08 +02:00
x7z4w
fdb72c9d31 [android] Remove BOM
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-20 06:19:10 +02:00
Jean-Baptiste
139facfb00 [iOS] Remove old translations about osm re-auth
Signed-off-by: jeanbaptisteC <jeanbaptiste.charron@outlook.fr>
2025-08-19 19:39:11 +02:00
Konstantin Pastbin
7536591ca4 [routing] Make ladder and steps speed slower
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-19 23:34:00 +07:00
Viktor Govako
c7592276f7 [classifier] Added highway=ladder to the routing and other checkers.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-19 23:34:00 +07:00
Viktor Govako
8ef68a5559 [style] Set line rules for highway=ladder.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-19 23:34:00 +07:00
vikiawv
e46d3d9b65 [styles] Added Roadshieldcolors in Europe (Belgium-Portugal)
[styles] Added roadshield-color Romania

also some other, even though only highways there, as there are no letter markers inside the ref code
Spain and Turkey need to be checked by person with local knowledge.

[styles] corrected Ireland Motorway and Romania DS/DJ-Streets

Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-08-19 18:48:10 +07:00
Jean-Baptiste
62de63eda0 [android]Use ContextCompat API instead Resources API
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-19 07:45:03 +02:00
Codeberg Translate
e786dbe5f5 [strings] Update from Codeberg Translate
Co-authored-by: AnanasSux <ananassux@noreply.codeberg.org>
Co-authored-by: B o d o <timtrek@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Laurent FAVOLE <lfavole@noreply.codeberg.org>
Co-authored-by: Lenny Angst <lenny@familie-angst.ch>
Co-authored-by: Mickael81 <mickael81@noreply.codeberg.org>
Co-authored-by: N4ta <codeberg@n4ta.anonaddy.me>
Co-authored-by: Outbreak2096 <outbreak2096@noreply.codeberg.org>
Co-authored-by: Prefill add-on <noreply-addon-prefill@weblate.org>
Co-authored-by: Priit Jõerüüt <jrtcdbrg@noreply.codeberg.org>
Co-authored-by: Stephan-P <stephan-p@noreply.codeberg.org>
Co-authored-by: alexgabi <alexgabi@noreply.codeberg.org>
Co-authored-by: and4po <and4po@noreply.codeberg.org>
Co-authored-by: aoxa <aoxa@noreply.codeberg.org>
Co-authored-by: concede2913 <concede2913@noreply.codeberg.org>
Co-authored-by: ghose <ghose@noreply.codeberg.org>
Co-authored-by: gimse <gimse@noreply.codeberg.org>
Co-authored-by: lazlo <lazlo@noreply.codeberg.org>
Co-authored-by: ldmpub <ldmpub@noreply.codeberg.org>
Co-authored-by: matheusgomesms <matheusgomesms@noreply.codeberg.org>
Co-authored-by: metehan <metehan@noreply.codeberg.org>
Co-authored-by: patepelo <patepelo@noreply.codeberg.org>
Co-authored-by: phama <phama@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/comaps/android-typestrings/
Translate-URL: https://translate.codeberg.org/projects/comaps/ios-typestrings/
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Android UI Strings
Translation: CoMaps/Apple AppStore description
Translation: CoMaps/Countries and regions names
Translation: CoMaps/F-Droid app description
Translation: CoMaps/Voice announcements for navigation (TTS)
Translation: CoMaps/iOS - Map Feature Types
Translation: CoMaps/iOS Plist
Translation: CoMaps/iOS Plurals
Translation: CoMaps/iOS UI Strings
2025-08-19 04:38:04 +00:00
Harry Bond
d44f0ae7da [android] Display overlay layer state with icon
Fixes #1402

Signed-off-by: Harry Bond <me@hbond.xyz>
2025-08-19 06:37:50 +02:00
Jean-Baptiste
4232de04ac [android] Fix padding in bookmark category settings
Signed-off-by: JeanBaptisteC <jeanbaptiste.charron@outlook.fr>
2025-08-18 20:29:12 +02:00
map-per
bfacc2a98d Fix standalone notes not being saved when not logged in (#1433)
Signed-off-by: map-per <map-per@gmx.de>
2025-08-18 20:08:40 +02:00
Eivind Samseth
d04327082d [drape] Match iOS double tap to zoom behavior
Signed-off-by: eisa01 <eisa01@gmail.com>
2025-08-18 14:15:27 +02:00
Yannik Bloscheck
3097b54036 [ios] Import functional in MWMEditorHelper.mm
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-18 09:07:05 +02:00
Yannik Bloscheck
e2fa169832 [ios] Fix modulemap path in Xcode
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
3d6d08e2a1 [kml] Factor out ParseXXXColor functions.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Interactiondesigner
5e8eeb1f20 Update categories_cuisines.txt
Changed translation of cuisine=barbecue in German from "Grill" to "Barbecue" since cuisine=Grill als uses "Grill". So when adding a restaurant, it can be better distinguished between more traditional European/Middle Eastern grill and the more American Barbecue cuisine.

Signed-off-by: Interactiondesigner <mr.funky@gmx.de>
2025-08-18 09:07:05 +02:00
Viktor Govako
8d61c7447b [routing][tests] Added "agricultural" roads test.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Osyotr
4117cca562 CMake fixes for Windows
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Osyotr
416b8ab95a Fix quoting in curl cmdline
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Osyotr
d8f9323705 Add missing lib on Windows (#11004)
* Add missing lib on Windows

Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>

* Update libs/platform/CMakeLists.txt

Signed-off-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com>

---------

Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
Signed-off-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com>
Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Alexander Borsuk
e3d47775fc [TTS] Clearer pronouncement of route recalculation in ru
> При уходе с тропы если язык подсказок русский, говорит - «преращик маршрута».

Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-18 09:07:05 +02:00
Andrei Shkrob
a580c19dc0 [android-auto] Fix null pointer exception
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-18 09:07:05 +02:00
Andrei Shkrob
8e0d4776af [style] Some improvements
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-18 09:07:05 +02:00
Alexander Borsuk
674abcf02e [linux] Fix zero file creation (birth) time
Observed in Ubuntu 24 via Orb on arm-based Mac

Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-18 09:07:05 +02:00
hemanggs
fbaa59ce3b [android] Refactoring regression fix
Signed-off-by: hemanggs <hemangmanhas@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
72ff90defd [base] Added to_uint base for string_view.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
1d29e7816a [coding] Rename non-empty string serialization.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
7b4862b442 [base] Updated IsSortedAndUnique function.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
b7b87f5530 [tracks] Safe GpsTrackCollection requests during recording.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
fb62982000 [tracks] Set close distance threshold to 10m.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
64f50d4e49 [tracks] Fixed ending points.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
fda1da03c8 [tracks] Fixed starting points.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
David Martinez
8477fff988 [strings] Add more Spanish categories translations
Signed-off-by: David Martinez <47610359+dvdmrtnz@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Osyotr
5158ceb311 Add windows support to vulkan_wrapper
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Ferenc Géczi
7e5e6ec78e [libs][linux] Fix incorrect include of fcntl.h
The POSIX standard says, that `fcntl.h` is to be included as `#include <fcntl.h>`.

This change fixes the compiler warnings that happen with `musl` libc :
```
/usr/include/sys/fcntl.h:1:2: warning: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Wcpp]
    1 | #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
      |  ^~~~~~~
In file included from /home/ferenc/github.com/organicmaps/organicmaps/libs/coding/mmap_reader.cpp:18,
                 from /home/ferenc/github.com/organicmaps/organicmaps/build-alpine-3.21/build-alpine-3.21/libs/coding/CMakeFiles/coding.dir/Unity/unity_0_cxx.cxx:40:
/usr/include/sys/fcntl.h:1:2: warning: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Wcpp]
    1 | #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
      |  ^~~~~~~
````

This happens because of the explicit [warning in the proxy header](
https://git.musl-libc.org/cgit/musl/tree/include/sys/fcntl.h)

Signed-off-by: Ferenc Géczi <ferenc.gm@gmail.com>
2025-08-18 09:07:05 +02:00
Osyotr
0ea0f2e49a Make UniformRandom standard-conforming
std::uniform_int_distribution<T> requires sizeof(T) >= sizeof(short)

Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
b1c2b204a1 gcc13 fix
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Alexander Borsuk
52a0c45083 Glaze smoke test
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-18 09:07:05 +02:00
Alexander Borsuk
4de9de38ad [3party] Add glaze submodule
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-18 09:07:05 +02:00
Alexander Borsuk
215c19dcc7 Fix unity build error by removing using namespace std;
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-18 09:07:05 +02:00
Osyotr
b5b333c832 Fix TokenizeIterator on Windows
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Osyotr
dfd7af92fa Remove usage of boost/iostreams from 3party/succint
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Osyotr
e00d5d33b2 Add missing include
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Osyotr
5ae8156fa3 Fix std::atomic_flag initialization
Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
2025-08-18 09:07:05 +02:00
Viktor Govako
b107638b8b [routing] SaveRoute minor fixes and CHECK.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-18 09:07:05 +02:00
Alexander Borsuk
c4599f4889 C++23
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-18 09:07:05 +02:00
Yannik Bloscheck
580209f7ea [ios] Ending search when switching over to routing
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-18 08:13:35 +02:00
Harry Bond
abc755c058 [styles] Don't show postbox labels
Fixes #1399
Signed-off-by: Harry Bond <me@hbond.xyz>


Signed-off-by: Harry Bond <me@hbond.xyz>
2025-08-18 08:07:14 +02:00
Yannik Bloscheck
035a8edebb [ios] Adding CarPlay entitlement
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-17 22:07:30 +02:00
Henry Sternberg
c59b63d784 [routing] OSM tag based time and turn penalties
Signed-off-by: Henry Sternberg <dev@bluelightmaps.com>
Co-Authored-By: eisa01 <eisa01@gmail.com>
Co-Authored-By: x7z4w <x7z4w@noreply.codeberg.org>
Co-Authored-By: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-17 19:40:00 +02:00
Jean-Baptiste
daf2a7d8e7 [android] Fix color issues for AppCompat components
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-17 18:43:47 +02:00
Jean-Baptiste
f549108e72 [docs] Remove custom styles badges to fix render on Github
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-17 18:24:37 +02:00
Codeberg Translate
90667e9fa1 [strings] Update from Codeberg Translate
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Mickael81 <mickael81@noreply.codeberg.org>
Co-authored-by: N4ta <codeberg@n4ta.anonaddy.me>
Co-authored-by: Priit Jõerüüt <jrtcdbrg@noreply.codeberg.org>
Co-authored-by: Stephan-P <stephan-p@noreply.codeberg.org>
Co-authored-by: alexgabi <alexgabi@noreply.codeberg.org>
Co-authored-by: aoxa <aoxa@noreply.codeberg.org>
Co-authored-by: concede2913 <concede2913@noreply.codeberg.org>
Co-authored-by: metehan <metehan@noreply.codeberg.org>
Co-authored-by: patepelo <patepelo@noreply.codeberg.org>
Co-authored-by: phama <phama@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/comaps/ios-typestrings/
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Android UI Strings
Translation: CoMaps/Apple AppStore description
Translation: CoMaps/Countries and regions names
Translation: CoMaps/F-Droid app description
Translation: CoMaps/iOS - Map Feature Types
Translation: CoMaps/iOS Plist
Translation: CoMaps/iOS UI Strings
2025-08-17 17:38:15 +02:00
vikiawv
8bac8b7d37 [styles] Austria Reference Color
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
Co-authored-by: vikiawv <vikiawv@noreply.codeberg.org>
Co-committed-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-08-17 15:54:03 +02:00
Konstantin Pastbin
bfffa1fff4 Format all C++ and Java code via clang-format
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-17 14:32:37 +07:00
Konstantin Pastbin
9f0290c0ec [ios] Disable clang-format temporary
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-17 14:28:44 +07:00
Andrei Shkrob
8a8a3c5a08 [ci] remove clang-format workflow
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-17 14:28:44 +07:00
Andrei Shkrob
518747d503 [ci] add code style check workflow
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-17 14:28:44 +07:00
Alexander Borsuk
5063b511ae tools/unix/clang-format.sh to format all necessary files in the repo
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-17 14:28:44 +07:00
Alexander Borsuk
fbe3f72fb1 .clang-format-ignore
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-17 14:28:44 +07:00
Alexander Borsuk
872c0d3e15 .clang-format rules
Signed-off-by: Alexander Borsuk <me@alex.bio>

.clang-format remove unnecessary semicolons

Signed-off-by: Alexander Borsuk <me@alex.bio>

[clang-format] Removed "AlignArrayOfStructures".

Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-17 14:28:44 +07:00
Andrei Shkrob
9833918aac [android][sdk] Refactoring
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-17 09:26:56 +02:00
renderexpert
0000ec149c Fix wrong texture setting for RouteMarker
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
da3053f5fc Make check more strict in ApplyTextures
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
5a0ff536a7 Regenerate Vulkan shaders
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
36f123ef25 Fix crash in CreateDescriptorSetGroup
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
01c2f02c86 Remove OpenGL ES2 leftovers that caused crash in Vulkan
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
4d702ec541 Set OpenGLES 3.0 as minimal version in Android manifest
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
344cf6d709 Fix OpenGL glUniform mismatch
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
14b3e8fc8f Fix shader tests on Linux
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
6d0daf6fe7 Rewrite shaders to use OpenGL ES3 syntax
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
9b3507211f Remove Tegra support hacks
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
a406462549 Remove Adreno 200 support hacks
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
897d7a253d Refactor shaders to use GLES3 syntax
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
renderexpert
b23c2ba3e3 [Drape] Remove GLES2-related code
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-08-17 08:30:56 +02:00
hb0nd
705c715356 [docs] Make funding section sound less threatening
Currently, it sounds like a threat to make it paid etc unless people donate 😅

Signed-off-by: hb0nd <me@hbond.xyz>
2025-08-16 19:48:29 +02:00
Jean-Baptiste
826ddba26f [android] Use material properties in styles and themes
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-16 11:04:30 +02:00
hemanggs
2492e8bda4 [Android] Standalone Note UI in Category select screen
Signed-off-by: hemanggs <hemangmanhas@gmail.com>
2025-08-16 07:04:33 +02:00
hemanggs
9e494ed8a5 [core] Create Standalone Note core
Signed-off-by: hemanggs <hemangmanhas@gmail.com>
2025-08-16 07:04:33 +02:00
Andrei Shkrob
1c8ac1f32a [android] Show bookmark icon in color selector
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 07:04:33 +02:00
Andrei Shkrob
d0bb8c1c49 [android] Fix colors order
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 07:04:33 +02:00
Jean-Baptiste
6c4503b0db [android] Improve size of bookmark icons
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-16 07:04:33 +02:00
Viktor Govako
a39b3a9921 [android] Fixed getting drawable icons.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-16 07:04:33 +02:00
Andrei Shkrob
8493ed369a [android] Fix collor selector issue
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 07:04:33 +02:00
Andrei Shkrob
2ded7e5e2b [android] Load icon types from core
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 07:04:33 +02:00
Andrei Shkrob
d9335c0b6c [android] Load predefined colors from core
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 07:04:33 +02:00
Andrei Shkrob
ebc5370052 [android] Load TTS languages from core
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 07:04:33 +02:00
Konstantin Pastbin
0a96a23ca0 [desktop] Fix Mac icon file location
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-16 01:43:47 +07:00
Konstantin Pastbin
5b05a7ac71 [3party] Protobuf MSVC and C++23 fixes
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-16 01:15:07 +07:00
Kiryl Kaveryn
31104eed4d [ios] Remove fileCoordinator wrapping from downloading starting
And add check `isUbiquitousItem` before downloading start. This method returns false when the file doesn't exist.

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
2025-08-16 00:33:06 +07:00
Kiryl Kaveryn
0f2353aae6 [ios] Track the percentDownloaded for the downloaded from the cloud files
Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
2025-08-16 00:32:58 +07:00
Kiryl Kaveryn
d01b8aaab4 [map] Remove zooming back on track deselection
Closes https://github.com/organicmaps/organicmaps/issues/10941

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
2025-08-16 00:27:55 +07:00
Alexander Borsuk
33f8e20f1b [Linux] Vulkan build fixes
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-16 00:23:24 +07:00
Alexander Borsuk
76d8396cb1 [3party] Updated Vulkan headers to v1.4.322
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-16 00:19:01 +07:00
Andrei Shkrob
0f744e7cf2 [desktop] Organize desktop resources
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-08-16 00:12:24 +07:00
Konstantin Pastbin
5d990bdc19 [docs] Add ninja to MacOS deps
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-15 11:47:53 +07:00
Yannik Bloscheck
1f2d70c720 [xcode] Updated upgrade check version to latest value
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-14 18:22:40 +02:00
Alexander Borsuk
76ffc99abd New cpp folder structure
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-14 20:52:04 +07:00
x7z4w
c9cbb64f12 [search] Follow-up fix for synonyms
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-14 11:07:33 +02:00
x7z4w
c4722f7025 [ci] Fix Github CI
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-14 10:57:30 +02:00
Yannik Bloscheck
211e3fb4f0 [ios] Fixing ATM translation on place page
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-13 20:26:31 +02:00
Konstantin Pastbin
ab0c2e70d5 [planet] Update map data to 250804
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-13 20:25:04 +02:00
Konstantin Pastbin
3133b88346 Relnotes for 1st August release
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-13 20:18:00 +02:00
x7z4w
b1479127e7 [ci] Use self-hosted runner
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-13 20:05:43 +02:00
Yannik Bloscheck
18c3b8cda5 [styles] Made general area slightly less grey
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-13 20:03:44 +02:00
Codeberg Translate
38037c1174 [strings] Update from Codeberg Translate
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: jimkats <jimkats@noreply.codeberg.org>
Co-authored-by: patepelo <patepelo@noreply.codeberg.org>
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Countries and regions names
Translation: CoMaps/iOS - Map Feature Types
2025-08-13 17:36:51 +00:00
Konstantin Pastbin
593f2fd828 [tools] Change World maps download mirror
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-13 13:06:50 +07:00
Jean-Baptiste
066afe4aa8 [android] Improve alignment layout
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-12 17:57:50 +02:00
Jean-Baptiste
2df3e3557b [android] Migrate last themes to Material Components
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-12 17:57:50 +02:00
Codeberg Translate
f79e86dff6 [strings] Update from Codeberg Translate
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/comaps/countries/
Translation: CoMaps/Countries and regions names
2025-08-12 15:11:24 +00:00
Konstantin Pastbin
244af5ea34 [core] Make DefaultLanguage arg const ref
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-12 19:35:51 +07:00
Yannik Bloscheck
185ae66101 [core] Fix local language not being used in some cases
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-08-12 12:36:56 +02:00
Konstantin Pastbin
f09b372590 [drape] Comment dummy assert firing in debug builds
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-12 16:23:43 +07:00
Konstantin Pastbin
de4ec645b6 [styles] Disable unused designer drules
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-12 10:14:53 +02:00
Konstantin Pastbin
b1710c0fd6 Revert "[android] Migrate last themes to Material Components"
This reverts commit b41bad5ea4.
2025-08-12 13:01:16 +07:00
Eivind Samseth
be0784e4ad [docs] Improve maps generator documentation
Add instructions for uv package managment and how to test on iOS

Signed-off-by: eisa01 <eisa01@gmail.com>
2025-08-11 21:00:50 +02:00
Henry Sternberg
78baadfe95 [core][drape] Making arrows smooth again
Signed-off-by: Henry Sternberg <dev@bluelightmaps.com>
2025-08-11 16:58:28 +02:00
Codeberg Translate
2dade5039a [strings] Update from Codeberg Translate
Co-authored-by: Artiman <artiman@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: N4ta <codeberg@n4ta.anonaddy.me>
Co-authored-by: ikanakova <ikanakova@noreply.codeberg.org>
Co-authored-by: patepelo <patepelo@noreply.codeberg.org>
Co-authored-by: sunsand <sunsand@noreply.codeberg.org>
Co-authored-by: sziatomi <sziatomi@noreply.codeberg.org>
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Android UI Strings
Translation: CoMaps/Countries and regions names
Translation: CoMaps/F-Droid app description
Translation: CoMaps/Voice announcements for navigation (TTS)
Translation: CoMaps/iOS - Map Feature Types
Translation: CoMaps/iOS UI Strings
2025-08-11 13:58:51 +00:00
x7z4w
36ec212671 [strings] Remove internal types
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-11 15:58:12 +02:00
x7z4w
bdbbed6265 [strings] Consistent categories strings
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-11 15:25:35 +02:00
Jean-Baptiste
007aa818ff [android] Add support of Android 16 - First part
Signed-off-by: Jean-Baptiste Charron <jeanbaptiste.charron@outlook.fr>
2025-08-11 14:59:57 +02:00
Viktor Govako
001246fd10 [routing][tests] Updated integration tests.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-08-11 14:58:45 +02:00
Alexander Borsuk
76d7ef146c Removed SignedRound and replaced std::round with std::lround where needed
Also see https://clang.llvm.org/extra/clang-tidy/checks/bugprone/incorrect-roundings.html

Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-11 14:58:45 +02:00
Alexander Borsuk
ae349462c6 Smoke test for std::round and std::lround
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-11 14:58:45 +02:00
Alexander Borsuk
972cefb074 Open in another app generates geo: URI with a q= query compatible with Google Maps
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-11 14:58:45 +02:00
Alexander Borsuk
30718e106e ADL for AlmostEqual* and use math:: instead of base:: (#9634)
* ADL for AlmostEqual* and use math:: instead of base::

Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-11 14:58:45 +02:00
Alexander Borsuk
82133c5743 Fixed failing is_finite tests on the latest clang
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-11 14:58:45 +02:00
Alexander Borsuk
8fe788c98d Removed -Ofast to silence clang warning
Signed-off-by: Alexander Borsuk <me@alex.bio>
2025-08-11 14:58:45 +02:00
Konstantin Pastbin
684784c2b2 [drape] Increase colors texture size
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-08-11 14:56:51 +02:00
Eivind Samseth
492eab91fc [generator] Remove survey:date support
Indefinite behavior if both check_date and survey:date are set. Likely need its own metadata key

Signed-off-by: eisa01 <eisa01@gmail.com>
2025-08-11 12:24:46 +02:00
x7z4w
86ebbf6006 Remove us1
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-11 10:06:44 +02:00
Codeberg Translate
45e15e2edb [strings] Update from Codeberg Translate
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: ERYpTION <eryption@noreply.codeberg.org>
Co-authored-by: Mannivu <mannivu@noreply.codeberg.org>
Co-authored-by: patepelo <patepelo@noreply.codeberg.org>
Co-authored-by: sziatomi <sziatomi@noreply.codeberg.org>
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Android UI Strings
Translation: CoMaps/Apple AppStore description
Translation: CoMaps/Countries and regions names
Translation: CoMaps/F-Droid app description
Translation: CoMaps/Google Play and Huawei AppGallery descriptions
Translation: CoMaps/iOS - Map Feature Types
Translation: CoMaps/iOS Plurals
Translation: CoMaps/iOS UI Strings
2025-08-10 15:11:32 +00:00
3477 changed files with 74231 additions and 82908 deletions

View File

@@ -3,7 +3,6 @@ BasedOnStyle: Google
AccessModifierOffset: -2 AccessModifierOffset: -2
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignArrayOfStructures: Right
AlignConsecutiveMacros: AcrossEmptyLinesAndComments AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: LeftWithLastLine AlignEscapedNewlines: LeftWithLastLine
AlignOperands: AlignAfterOperator AlignOperands: AlignAfterOperator
@@ -40,8 +39,10 @@ ColumnLimit: 120
ConstructorInitializerIndentWidth: 2 ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4
DerivePointerAlignment: false DerivePointerAlignment: false
EmptyLineBeforeAccessModifier: Always
IncludeBlocks: Preserve IncludeBlocks: Preserve
IndentAccessModifiers: false IndentAccessModifiers: false
IndentCaseLabels: false
IndentExternBlock: NoIndent IndentExternBlock: NoIndent
InsertBraces: false InsertBraces: false
InsertNewlineAtEOF: true InsertNewlineAtEOF: true
@@ -49,6 +50,7 @@ LambdaBodyIndentation: OuterScope
PackConstructorInitializers: CurrentLine PackConstructorInitializers: CurrentLine
PointerAlignment: Middle PointerAlignment: Middle
RemoveBracesLLVM: true RemoveBracesLLVM: true
RemoveSemicolon: true
QualifierAlignment: Right QualifierAlignment: Right
SpacesInContainerLiterals: false SpacesInContainerLiterals: false
Standard: Latest Standard: Latest

8
.clang-format-ignore Normal file
View File

@@ -0,0 +1,8 @@
# Files that should not be formatted.
./3party
# A patched copy of the https://registry.khronos.org/OpenGL/api/GLES3/gl3.h
./android/sdk/src/main/cpp/app/organicmaps/sdk/opengl/gl3stub.h
# Formatting it leads to crashes in runtime. Newer protobuf may fix it.
./libs/indexer/drules_struct.pb.cc
# No need to format this 3party tool.
tools/osmctools/*.c

View File

@@ -36,8 +36,6 @@ jobs:
android-google-beta: android-google-beta:
name: Android Google Beta name: Android Google Beta
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
environment: beta environment: beta
steps: steps:
- name: Install build tools and dependencies - name: Install build tools and dependencies

View File

@@ -11,7 +11,7 @@ on:
jobs: jobs:
android-check-metadata: android-check-metadata:
name: Check app metadata name: Check app metadata
runs-on: codeberg-tiny runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -37,9 +37,7 @@ on:
jobs: jobs:
lint: lint:
name: Android Lint name: Android Lint
runs-on: codeberg-tiny runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -58,8 +56,6 @@ jobs:
android-check: android-check:
name: Build Android Debug name: Build Android Debug
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@@ -6,7 +6,7 @@ on:
jobs: jobs:
precondition: precondition:
runs-on: codeberg-tiny runs-on: ubuntu-latest
name: Check preconditions name: Check preconditions
steps: steps:
- name: Checkout sources - name: Checkout sources
@@ -31,8 +31,6 @@ jobs:
android-google-beta: android-google-beta:
name: Android Google Beta name: Android Google Beta
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
needs: precondition needs: precondition
if: ${{ needs.precondition.outputs.updated != '' }} if: ${{ needs.precondition.outputs.updated != '' }}
environment: beta environment: beta

View File

@@ -5,9 +5,7 @@ on:
jobs: jobs:
android-release-metadata: android-release-metadata:
name: Upload Google Play metadata name: Upload Google Play metadata
runs-on: codeberg-tiny runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
environment: production environment: production
steps: steps:
- name: Checkout sources - name: Checkout sources

View File

@@ -10,8 +10,6 @@ jobs:
tag: tag:
name: Tag name: Tag
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
environment: production environment: production
steps: steps:
- name: Checkout sources - name: Checkout sources

View File

@@ -9,7 +9,7 @@ on:
jobs: jobs:
validate-appstream: validate-appstream:
name: Validate appstream metadata xml name: Validate appstream metadata xml
runs-on: codeberg-tiny runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -21,11 +21,12 @@ jobs:
- name: Install appstream validator and flatpak Builder - name: Install appstream validator and flatpak Builder
shell: bash shell: bash
run: | run: |
sudo apt update -y apt-get update
sudo apt install -y \ apt-get install -y flatpak dbus --no-install-recommends
flatpak mkdir /run/dbus
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo dbus-daemon --system
sudo flatpak install -y org.flatpak.Builder flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install -y org.flatpak.Builder
- name: Lint appstream data with flatpak Builder - name: Lint appstream data with flatpak Builder
shell: bash shell: bash

View File

@@ -33,7 +33,7 @@ concurrency:
jobs: jobs:
should-run-check: should-run-check:
name: Should run coverage name: Should run coverage
runs-on: codeberg-tiny runs-on: ubuntu-latest
outputs: outputs:
run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }} run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }}
manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }} manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }}

View File

@@ -5,4 +5,4 @@ jobs:
check: check:
runs-on: codeberg-tiny runs-on: codeberg-tiny
steps: steps:
- uses: https://github.com/KineticCafe/actions-dco@v1 - uses: https://github.com/KineticCafe/actions-dco@v1

View File

@@ -3,20 +3,20 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
pull_request: pull_request:
paths: paths:
- qt/res/app.comaps.comaps.desktop - qt/res/linux/app.comaps.comaps.desktop
- .forgejo/workflows/desktop-file-check.yaml # Run check on self change - .forgejo/workflows/desktop-file-check.yaml # Run check on self change
jobs: jobs:
validate-desktop-file: validate-desktop-file:
name: Validate .desktop file name: Validate .desktop file
runs-on: codeberg-tiny runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |
qt/res/app.comaps.comaps.desktop qt/res/linux/app.comaps.comaps.desktop
- name: Install desktop-file-validate tool - name: Install desktop-file-validate tool
shell: bash shell: bash
@@ -27,4 +27,4 @@ jobs:
- name: Validate desktop file - name: Validate desktop file
shell: bash shell: bash
run: desktop-file-validate qt/res/app.comaps.comaps.desktop && echo "Successfully validated .desktop file" run: desktop-file-validate qt/res/linux/app.comaps.comaps.desktop && echo "Successfully validated .desktop file"

View File

@@ -10,7 +10,7 @@ on:
jobs: jobs:
ios-check-metadata: ios-check-metadata:
name: Check app metadata name: Check app metadata
runs-on: codeberg-tiny runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -23,6 +23,10 @@ jobs:
shell: bash shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Configure repository
shell: bash
run: SKIP_GENERATE_SYMBOLS=1 ./configure.sh
- name: Lint - name: Lint
shell: bash shell: bash
working-directory: android working-directory: android
@@ -62,6 +66,7 @@ jobs:
libxinerama-dev \ libxinerama-dev \
libxcursor-dev \ libxcursor-dev \
libxi-dev \ libxi-dev \
python3-protobuf \
zlib1g-dev zlib1g-dev
- name: Checkout sources - name: Checkout sources

View File

@@ -1,43 +0,0 @@
name: clang-format
on:
push:
branches: [ master ]
paths:
- 'android/app/src/**.java'
- '.clang-format'
- '.github/workflows/clang-format.yml'
pull_request:
branches: [ master ]
paths:
- 'android/app/src/**.java'
- '.clang-format'
- '.github/workflows/clang-format.yml'
jobs:
check-formatting:
runs-on: ubuntu-latest
continue-on-error: true # TODO(AB): Remove this line when ready to enforce formatting.
steps:
- uses: actions/checkout@v4
- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y clang-format-19
clang-format-19 --version
- name: Check Java formatting
run: |
JAVA_FILES=($(find android/app/src -name '*.java'))
FORMATTING_ISSUES=$(clang-format-19 --dry-run --Werror $JAVA_FILES 2>&1 || true)
if [ -n "$FORMATTING_ISSUES" ]; then
echo "$FORMATTING_ISSUES"
echo ""
echo "To fix formatting, please run:"
echo " clang-format -i <file>"
exit 1
fi

51
.github/workflows/code-style-check.yaml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: Code style check
on:
pull_request:
branches: [ master ]
paths: # Should stay in sync with tools/unix/clang-format.sh
- '.github/workflows/code-style-check.yaml'
- 'android/app/src/**.java'
- 'android/sdk/src/**.java'
- 'android/sdk/src/main/cpp/**.[ch]pp'
- 'dev_sandbox/**.[ch]pp'
- 'generator/**.[ch]pp'
- 'iphone/**.[ch]pp'
- 'iphone/**.[hm]'
- 'iphone/**.mm'
- 'libs/**.[ch]pp'
- 'libs/**.[hm]'
- '!libs/indexer/drules_struct.pb.h'
- 'libs/**.mm'
- 'qt/**.[ch]pp'
- 'qt/**.h'
- 'tools/**.[ch]pp'
- '.clang-format'
- '.clang-format-ignore'
jobs:
code-style-check:
runs-on: ubuntu-latest
steps:
- name: Install clang-format
run: |
sudo apt purge -y clang-format-18 # Remove default old version of clang-format
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
echo 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm-toolchain-noble-20.list
sudo apt-get update
sudo apt-get install -y clang-format-20
sudo update-alternatives --force --install /usr/bin/clang-format clang-format /usr/bin/clang-format-20 10
sudo update-alternatives --force --install /usr/bin/git-clang-format git-clang-format /usr/bin/git-clang-format-20 10
clang-format --version
- name: Checkout sources
uses: actions/checkout@v4
- name: Check code style
run: tools/unix/clang-format.sh
- name: Post clang-format comments
if: failure()
uses: reviewdog/action-suggester@v1.21.0
with:
tool_name: clang-format
fail_level: error

View File

@@ -30,6 +30,7 @@ jobs:
run: | run: |
brew install qt \ brew install qt \
optipng optipng
pip3 install "protobuf<3.21" --break-system-packages
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4

2
.gitignore vendored
View File

@@ -50,7 +50,7 @@ omim.sdf
*.suo *.suo
*.aps *.aps
*.rc *.rc
!qt/res/windows.rc !qt/res/windows/windows.rc
*.pdb *.pdb
out/ out/

4
.gitmodules vendored
View File

@@ -65,3 +65,7 @@
[submodule "3party/imgui/imgui"] [submodule "3party/imgui/imgui"]
path = 3party/imgui/imgui path = 3party/imgui/imgui
url = https://github.com/ocornut/imgui url = https://github.com/ocornut/imgui
[submodule "3party/glaze"]
path = 3party/glaze
url = https://github.com/stephenberry/glaze
branch = main

View File

@@ -57,6 +57,7 @@ endif()
add_subdirectory(agg) add_subdirectory(agg)
add_subdirectory(bsdiff-courgette) add_subdirectory(bsdiff-courgette)
add_subdirectory(glaze)
add_subdirectory(minizip) add_subdirectory(minizip)
add_subdirectory(open-location-code) add_subdirectory(open-location-code)
add_subdirectory(opening_hours) add_subdirectory(opening_hours)

View File

@@ -4,7 +4,9 @@ set(FT_DISABLE_HARFBUZZ ON)
add_subdirectory(freetype) add_subdirectory(freetype)
# Fix warning with ONE_PIXEL macro clash. # Fix warning with ONE_PIXEL macro clash.
target_compile_options(freetype PRIVATE -Wno-macro-redefined) if(NOT MSVC)
target_compile_options(freetype PRIVATE -Wno-macro-redefined)
endif()
# Use ft2build.h from the current directory instead of the default. # Use ft2build.h from the current directory instead of the default.
target_include_directories(freetype target_include_directories(freetype

1
3party/glaze Submodule

Submodule 3party/glaze added at 5a58d7936e

View File

@@ -11,14 +11,23 @@ target_include_directories(${PROJECT_NAME}
harfbuzz/src harfbuzz/src
) )
# Keep these settigns in sync with xcode/harfbuzz project. if (MSVC)
target_compile_options(${PROJECT_NAME} target_compile_options(${PROJECT_NAME}
PRIVATE PRIVATE
-fno-rtti /GR-
-fno-exceptions /EHsc-
-fno-threadsafe-statics /Zc:threadSafeInit-
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-format-pedantic> )
) else()
# Keep these settings in sync with xcode/harfbuzz project.
target_compile_options(${PROJECT_NAME}
PRIVATE
-fno-rtti
-fno-exceptions
-fno-threadsafe-statics
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-format-pedantic>
)
endif()
target_compile_definitions(${PROJECT_NAME} target_compile_definitions(${PROJECT_NAME}
PRIVATE PRIVATE
@@ -28,14 +37,20 @@ target_compile_definitions(${PROJECT_NAME}
#$<$<BOOL:${APPLE}>:HAVE_CORETEXT> #$<$<BOOL:${APPLE}>:HAVE_CORETEXT>
HAVE_ATEXIT HAVE_ATEXIT
HAVE_GETPAGESIZE HAVE_GETPAGESIZE
HAVE_MMAP
HAVE_MPROTECT HAVE_MPROTECT
HAVE_PTHREAD
HAVE_SYSCONF HAVE_SYSCONF
HAVE_SYS_MMAN_H
HAVE_UNISTD_H
) )
if (NOT MSVC)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
HAVE_MMAP
HAVE_PTHREAD
HAVE_SYS_MMAN_H
HAVE_UNISTD_H
)
endif()
target_link_libraries(${PROJECT_NAME} Freetype::Freetype) target_link_libraries(${PROJECT_NAME} Freetype::Freetype)
add_library(harfbuzz::harfbuzz ALIAS harfbuzz) add_library(harfbuzz::harfbuzz ALIAS harfbuzz)

View File

@@ -172,6 +172,7 @@ add_library(icuuc
icu/icu4c/source/common/uvector.cpp icu/icu4c/source/common/uvector.cpp
icu/icu4c/source/common/uvectr32.cpp icu/icu4c/source/common/uvectr32.cpp
icu/icu4c/source/common/uvectr64.h icu/icu4c/source/common/uvectr64.h
icu/icu4c/source/common/wintz.cpp
icu/icu4c/source/common/wintz.h icu/icu4c/source/common/wintz.h
) )

View File

@@ -11,6 +11,7 @@ set(SRC
protobuf/src/google/protobuf/message_lite.cc protobuf/src/google/protobuf/message_lite.cc
protobuf/src/google/protobuf/repeated_field.cc protobuf/src/google/protobuf/repeated_field.cc
protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
protobuf/src/google/protobuf/stubs/bytestream.cc protobuf/src/google/protobuf/stubs/bytestream.cc
protobuf/src/google/protobuf/stubs/common.cc protobuf/src/google/protobuf/stubs/common.cc
protobuf/src/google/protobuf/stubs/int128.cc protobuf/src/google/protobuf/stubs/int128.cc

View File

@@ -7,7 +7,6 @@
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/type_traits/is_pod.hpp> #include <boost/type_traits/is_pod.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include "mappable_vector.hpp" #include "mappable_vector.hpp"
@@ -283,12 +282,6 @@ namespace succinct { namespace mapper {
return mapper.bytes_read(); return mapper.bytes_read();
} }
template <typename T>
size_t map(T& val, boost::iostreams::mapped_file_source const& m, uint64_t flags = 0, const char* friendly_name = "<TOP>")
{
return map(val, m.data(), flags, friendly_name);
}
template <typename T> template <typename T>
uint64_t size_of(T& val) uint64_t size_of(T& val)
{ {

View File

@@ -8,7 +8,6 @@
#include <stdint.h> #include <stdint.h>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
namespace succinct { namespace util { namespace succinct { namespace util {
@@ -205,29 +204,6 @@ namespace succinct { namespace util {
std::string m_cur_value; std::string m_cur_value;
}; };
struct mmap_lines
{
typedef buffer_line_iterator iterator;
typedef buffer_line_iterator const_iterator;
mmap_lines(std::string filename)
: m_map(filename)
{}
const_iterator begin() const
{
return const_iterator(m_map.data(), m_map.size());
}
const_iterator end() const
{
return const_iterator();
}
private:
boost::iostreams::mapped_file_source m_map;
};
struct input_error : std::invalid_argument struct input_error : std::invalid_argument
{ {
input_error(std::string const& what) input_error(std::string const& what)

View File

@@ -19,7 +19,18 @@ extern "C" {
#endif #endif
#include "vulkan_wrapper.h" #include "vulkan_wrapper.h"
#if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#else
#include <dlfcn.h> #include <dlfcn.h>
#endif
int InitVulkan(void) { int InitVulkan(void) {
#if defined(__APPLE__) #if defined(__APPLE__)
@@ -30,6 +41,9 @@ int InitVulkan(void) {
if (!libvulkan) { if (!libvulkan) {
libvulkan = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL); libvulkan = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL);
} }
#elif defined( _WIN32 )
HMODULE libvulkan = LoadLibraryA("vulkan-1.dll");
auto dlsym = [](HMODULE h, char const * name) { return GetProcAddress(h, name); };
#else #else
void* libvulkan = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL); void* libvulkan = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
if (!libvulkan) { if (!libvulkan) {

View File

@@ -1,8 +1,9 @@
cmake_minimum_required(VERSION 3.22.1) cmake_minimum_required(VERSION 3.22.1)
project(omim C CXX) project(omim C CXX)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 23)
set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD 23)
# Our code does not rely on gnu extensions. # Our code does not rely on gnu extensions.
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_EXTENSIONS OFF)
@@ -38,12 +39,12 @@ if (APPLE AND NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android))
# https://gitlab.kitware.com/cmake/cmake/-/issues/21963 # https://gitlab.kitware.com/cmake/cmake/-/issues/21963
enable_language(OBJC) enable_language(OBJC)
set(CMAKE_OBJC_EXTENSIONS OFF) set(CMAKE_OBJC_EXTENSIONS OFF)
set(CMAKE_OBJC_STANDARD 11) set(CMAKE_OBJC_STANDARD 23)
set(CMAKE_OBJC_FLAGS -fobjc-arc) set(CMAKE_OBJC_FLAGS -fobjc-arc)
set(CMAKE_OBJC_VISIBILITY_PRESET hidden) set(CMAKE_OBJC_VISIBILITY_PRESET hidden)
enable_language(OBJCXX) enable_language(OBJCXX)
set(CMAKE_OBJCXX_EXTENSIONS OFF) set(CMAKE_OBJCXX_EXTENSIONS OFF)
set(CMAKE_OBJCXX_STANDARD 20) set(CMAKE_OBJCXX_STANDARD 23)
set(CMAKE_OBJCXX_FLAGS -fobjc-arc) set(CMAKE_OBJCXX_FLAGS -fobjc-arc)
set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden) set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)
endif() endif()
@@ -86,7 +87,7 @@ if (MSVC)
add_compile_options(/utf-8) add_compile_options(/utf-8)
add_link_options(/INCREMENTAL:NO) add_link_options(/INCREMENTAL:NO)
else() else()
add_compile_options(-ffast-math) add_compile_options(-ffast-math $<$<CXX_COMPILER_ID:GNU>:-Wno-psabi>)
endif() endif()
if (PLATFORM_WIN) if (PLATFORM_WIN)
@@ -105,7 +106,7 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel") elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel")
add_definitions(-DRELEASE) add_definitions(-DRELEASE)
if (NOT MSVC) if (NOT MSVC)
add_compile_options(-Ofast $<$<CXX_COMPILER_ID:GNU>:-flto=auto>) # Also enables -ffast-math add_compile_options(-O3 $<$<CXX_COMPILER_ID:GNU>:-flto=auto>)
endif() endif()
else() else()
message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE}) message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE})
@@ -184,7 +185,7 @@ if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
endif() endif()
# To allow #include "base/file_name.hpp" in all sources. # To allow #include "base/file_name.hpp" in all sources.
include_directories(${CMAKE_HOME_DIRECTORY}) include_directories("${CMAKE_HOME_DIRECTORY}" "${CMAKE_HOME_DIRECTORY}/libs" "${CMAKE_HOME_DIRECTORY}/tools")
if (USE_PCH) if (USE_PCH)
message(STATUS "Precompiled headers are ON") message(STATUS "Precompiled headers are ON")
@@ -196,7 +197,7 @@ if (USE_PCH)
endif() endif()
# Should be on the root level, not in 3party, so tests can get these dependencies. # Should be on the root level, not in 3party, so tests can get these dependencies.
if (PLATFORM_LINUX OR PLATFORM_WIN) if (PLATFORM_LINUX)
find_package(ICU COMPONENTS uc i18n data REQUIRED) find_package(ICU COMPONENTS uc i18n data REQUIRED)
find_package(Freetype REQUIRED) find_package(Freetype REQUIRED)
find_package(harfbuzz REQUIRED) find_package(harfbuzz REQUIRED)
@@ -226,49 +227,22 @@ endif()
# Used in qt/ and shaders/ # Used in qt/ and shaders/
find_package(Python3 REQUIRED COMPONENTS Interpreter) find_package(Python3 REQUIRED COMPONENTS Interpreter)
add_subdirectory(base) add_subdirectory(libs)
add_subdirectory(coding)
add_subdirectory(descriptions)
add_subdirectory(drape)
add_subdirectory(drape_frontend)
add_subdirectory(editor)
add_subdirectory(ge0)
add_subdirectory(generator/mwm_diff)
add_subdirectory(geometry)
add_subdirectory(indexer)
add_subdirectory(kml)
add_subdirectory(map)
add_subdirectory(cppjansson)
add_subdirectory(platform)
add_subdirectory(routing)
add_subdirectory(routing_common)
add_subdirectory(search)
add_subdirectory(shaders)
add_subdirectory(storage)
add_subdirectory(tracking)
add_subdirectory(traffic)
add_subdirectory(transit)
if (PLATFORM_DESKTOP) if (PLATFORM_DESKTOP)
omim_add_tool_subdirectory(feature_list) add_subdirectory(dev_sandbox)
add_subdirectory(generator) add_subdirectory(generator)
add_subdirectory(openlr) add_subdirectory(tools)
add_subdirectory(poly_borders)
omim_add_tool_subdirectory(topography_generator)
add_subdirectory(track_analyzing)
omim_add_tool_subdirectory(track_generator)
if (NOT SKIP_QT_GUI) if (NOT SKIP_QT_GUI)
add_subdirectory(qt) add_subdirectory(qt)
omim_add_tool_subdirectory(skin_generator)
endif() endif()
if (GENERATOR_TOOL) if (GENERATOR_TOOL)
add_compile_options(-march=native -mtune=native) add_compile_options(-march=native -mtune=native)
message(STATUS "target CPU optimizations enabled, produced binaries will NOT work on a different CPU") message(STATUS "target CPU optimizations enabled, produced binaries will NOT work on a different CPU")
endif() endif()
add_subdirectory(dev_sandbox)
endif() endif()
omim_add_test_subdirectory(qt_tstfrm) omim_add_test_subdirectory(libs/qt_tstfrm)
if (PLATFORM_ANDROID) if (PLATFORM_ANDROID)
add_subdirectory(android/sdk/src/main/cpp) add_subdirectory(android/sdk/src/main/cpp)

View File

@@ -20,19 +20,19 @@
<div align="center"> <div align="center">
<p align="center"> <p align="center">
<a href="https://codeberg.org/comaps/comaps/releases"> <a href="https://codeberg.org/comaps/comaps/releases">
<img src="https://img.shields.io/github/license/comaps/comaps?style=for-the-badge&logo=opensourceinitiative&logoColor=white&color=588157" alt="License" style="width: 90%; max-width: 150px;"/> <img src="https://img.shields.io/github/license/comaps/comaps?style=for-the-badge&logo=opensourceinitiative&logoColor=white&color=588157" alt="License"/>
</a> </a>
<a href="https://github.com/comaps/comaps/actions/workflows/android-check.yaml"> <a href="https://github.com/comaps/comaps/actions/workflows/android-check.yaml">
<img src="https://img.shields.io/github/actions/workflow/status/comaps/comaps/.github/workflows/android-check.yaml?label=Android%20Build&logo=android&logoColor=white&style=for-the-badge&color=588157" alt="Android Build Status" style="width: 90%; max-width: 170px;"/> <img src="https://img.shields.io/github/actions/workflow/status/comaps/comaps/.github/workflows/android-check.yaml?label=Android%20Build&logo=android&logoColor=white&style=for-the-badge&color=588157" alt="Android Build Status"/>
</a> </a>
<a href="https://github.com/comaps/comaps/actions/workflows/ios-check.yaml"> <a href="https://github.com/comaps/comaps/actions/workflows/ios-check.yaml">
<img src="https://img.shields.io/github/actions/workflow/status/comaps/comaps/.github/workflows/ios-check.yaml?label=iOS%20Build&logo=apple&logoColor=white&style=for-the-badge&color=588157" alt="iOS Build Status" style="width: 90%; max-width: 145px;"/> <img src="https://img.shields.io/github/actions/workflow/status/comaps/comaps/.github/workflows/ios-check.yaml?label=iOS%20Build&logo=apple&logoColor=white&style=for-the-badge&color=588157" alt="iOS Build Status"/>
</a> </a>
<a href="https://opencollective.com/comaps"> <a href="https://opencollective.com/comaps">
<img src="https://img.shields.io/opencollective/all/comaps?label=Open%20Collective%20Donors&logo=opencollective&logoColor=white&style=for-the-badge&color=588157" alt="Open Collective Donors" style="width: 90%; max-width: 191px;"/> <img src="https://img.shields.io/opencollective/all/comaps?label=Open%20Collective%20Donors&logo=opencollective&logoColor=white&style=for-the-badge&color=588157" alt="Open Collective Donors"/>
</a> </a>
<a href="https://liberapay.com/CoMaps"> <a href="https://liberapay.com/CoMaps">
<img src="https://img.shields.io/liberapay/patrons/CoMaps.svg?label=Liberapay%20Patrons&logo=liberapay&logoColor=white&style=for-the-badge&color=588157" alt="Liberapay Patrons" style="width: 90%; max-width: 160px;"/> <img src="https://img.shields.io/liberapay/patrons/CoMaps.svg?label=Liberapay%20Patrons&logo=liberapay&logoColor=white&style=for-the-badge&color=588157" alt="Liberapay Patrons"/>
</a> </a>
</p> </p>
</div> </div>
@@ -140,7 +140,7 @@ There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/m
## 💸 Funding ## 💸 Funding
CoMaps is free. To stay that way, it relies on your support. CoMaps is free. To fund development, we rely on your voluntary support ♥️
Donate via [OpenCollective](https://opencollective.com/comaps/donate) or [Liberapay](https://liberapay.com/CoMaps). Donate via [OpenCollective](https://opencollective.com/comaps/donate) or [Liberapay](https://liberapay.com/CoMaps).
The project's financial information is completely open and transparent at [our Open Collective](https://opencollective.com/comaps). The project's financial information is completely open and transparent at [our Open Collective](https://opencollective.com/comaps).

View File

@@ -138,8 +138,6 @@ android {
disable 'MissingTranslation' disable 'MissingTranslation'
// https://github.com/organicmaps/organicmaps/issues/3551 // https://github.com/organicmaps/organicmaps/issues/3551
disable 'MissingQuantity', 'UnusedQuantity' disable 'MissingQuantity', 'UnusedQuantity'
// https://github.com/organicmaps/organicmaps/issues/3550
disable 'ByteOrderMark'
// https://github.com/organicmaps/organicmaps/issues/1077 // https://github.com/organicmaps/organicmaps/issues/1077
disable 'CustomSplashScreen' disable 'CustomSplashScreen'
// https://github.com/organicmaps/organicmaps/issues/3610 // https://github.com/organicmaps/organicmaps/issues/3610

View File

@@ -0,0 +1,7 @@
• Data OpenStreetMap k 4. 8.
• vylepšené barvy mapy pro vodu, lesy, křoviny, různé vybavení, pěší zóny atd.
• přidány stanice lesní stráže, krytých parkovišť pro jízdní kola, únikových her, úschoven zavazadel, partnerských pošt
• vylepšeny výškové vrstevnice na 20 m pro některé oblíbené turistické oblasti
• podpora více zkratek a aliasů pro vyhledávání
• přidání ikon pro vyhledávání a záložky pro rychlé občerstvení, jízdní kola a dobíjecí stanice
• plynulejší pohyb šipky pro určení polohy

View File

@@ -1,9 +1,7 @@
Wir stellen vor: Das neue CoMaps-Logo! • OpenStreetMap-Daten vom 4. August
• Verbesserte Höhenlinien in vielen Regionen (Stufen von 20/50 m) • Verbesserte Farben für Wasser, Wälder, Gestrüpp, verschiedene Einrichtungen, Fussgängerbereiche etc.
Links zu Panoramax-Bildern für ausgewählte POIs Besucherstationen, überdachte Fahrradparkplätze, Escaperooms, Gepäckschließfächer, und Postpartner hinzugefügt
OpenStreetMap-Daten vom 13. Juli Konturhöhenlinien aktualisiert, bis zu 20m für beliebte Wanderregionen
Neue Farben für viele Objekte und Farben werden früher angezeigt Unterstützung für mehr Such-Abkürzungen und Synonyme
Öffnungszeiten werden beim Antippen eines POI angezeigt Such- und Lesezeichen-Symbole für Fast Food, Rad- und Lade-Stationen
Verschiedene Arten von Feuchtgebieten Der Positionspfeil bewegt sich gleichmässiger
• Neue Farben für Vegetation und andere Features; einige neue Icons
• Wandern: bessere Darstellung der Höhenlinien

View File

@@ -1,10 +1,7 @@
Introducing CoMaps logo! • OpenStreetMap data as of August 4
• improve map colors for water, forests, scrubs, various amenities, pedestrian areas etc.
upgrade altitude contour lines for many regions to 20 or 50 meters step add ranger stations, covered bicycle parkings, escape games, luggage lockers, post office partners
add Panoramax Picture links to selected POIs upgrade altitude contour lines to 20m step for some popular hiking regions
OpenStreetMap data as of July 13 support more search abbreviations and aliases
• add color fills to many features and display fills earlier for existing features • add search and bookmark icons for fast food, bicycle and charging stations
display opening hours state when selecting a POI more smooth position arrow movements
• split all wetlands into several distinct types
• update vegetation and other map colors, update some map icons
• outdoors: bolder altitude contour lines

View File

@@ -1,9 +1,7 @@
¡Presentamos el logo de CoMaps! • Datos de OpenStreetMap a fecha 2025.08.04
mejora de isolíneas con más detalle para muchas regiones Mejora de colores del mapa para agua, bosques, matorrales, servicios, zonas peatonales, etc.
añade enlaces de imágenes de Panoramax a POIs seleccionados Añadidas estaciones de guardabosques, aparcamientos cubiertos de bicis, juegos de escape, consignas y oficinas de correo
datos de OpenStreetMap a 13 de julio Nuevas curvas de nivel (20 m) en regiones populares para senderismo
añadidos rellenos de color a muchas características Más abreviaturas y alias de búsqueda
se muestra el estado de horarios de apertura al seleccionar un POI Iconos de búsqueda y marcadores para comida rápida, bicicletas y estaciones de recarga
se dividen los humedales en tipos distintos Más fluidez de la flecha de posición
• se actualiza la vegetación y otros colores del mapa, así como otros iconos
• exteriores: líneas de contorno de altitud más gruesas

View File

@@ -24,7 +24,7 @@ Sartu komunitatean eta lagundu maparik onena aplikatzen
• Lineaz kanpoko Wikipedia artikuluak • Lineaz kanpoko Wikipedia artikuluak
• Metroaren garraio geruza eta jarraibideak • Metroaren garraio geruza eta jarraibideak
• Arrastoen grabazioa • Arrastoen grabazioa
Laster-markak eta ibilbideak esportatu eta inportatu KML, KMZ, GPX formatuetan Markagailuak eta arrastoak esportatu eta inportatu KML, KMZ, GPX formatuetan
• Gauean erabiltzeko modu iluna • Gauean erabiltzeko modu iluna
• Hobetu mapako datuak guztiontzat oinarrizko editore integratua erabiliz • Hobetu mapako datuak guztiontzat oinarrizko editore integratua erabiliz

View File

@@ -0,0 +1 @@
ناوبری آسان نقشه - کشف بیشتر از سفر شما - توسط جامعه

View File

@@ -0,0 +1 @@
CoMaps - کوه نوردی، دوچرخه سواری و رانندگی افلاین و خصوصی

View File

@@ -1,7 +0,0 @@
Présentation du logo CoMaps !
• Amélioration des courbes daltitude à une précision de 20 ou 50 mètres pour de nombreuses régions
• Ajout d'un lien vers les images Panoramax des POI
• Données OpenStreetMap du 13 juillet
• Affichage de létat des heures douverture lors de la sélection dun POI
• Mise à jour du style(végétation et zones humides), mise à jour de certaines icônes de la carte
• Outdoors: Améliorations de la visibilité des courbes d'altitude

View File

@@ -1 +1 @@
Navigation cartographique facile - Vivez de grands voyages - Propulsé par la communauté Navigation de cartes facile - Découvrez le monde - Propulsé par la communauté

View File

@@ -0,0 +1 @@
Könnyű térképes navigáció - Fedezz fel többet az útjaidról - A közösség erejével

View File

@@ -0,0 +1,7 @@
• Dati di OpenStreetMap aggiornati al 4 Agosto
• Migliorati i colori per acqua, foreste, servizi etc
• Aggiunte le stazioni delle guardie forestali, i parcheggi coperti per bici, gli escape games e altri servizi
• Aggiornato l'intervallo delle isolinee a 20 m per le zone escursionistiche più popolari
• Aggiunto il supporto per un maggior numero di alias
• Aggiunte le icone per i fast food, i punti di ricarica e le biciclette
• Resi più fluidi i movimenti della freccia di posizione

View File

@@ -0,0 +1 @@
Lett kart navigasjon - Opplev mere på din reise - Drevet av felleskapet

View File

@@ -1,9 +0,0 @@
Wprowadzamy logo CoMaps!
• zwiększenie dokładności izolinii w wielu regionach w krokach 20 do 50 metrów
• dodanie linków do zdjęć z Panoramax do wybranych POI
• aktualizacja danych OpenStreetMap z 13 lipca
• dodanie wypełnienia kolorem dla wielu typów obiektów
• wyświetlanie stanu godzin otwarcia przy wyborze POI
• podział mokradeł na kilka typów
• aktualizacja koloru roślinności i innych kolorów, aktualizacja części ikon na mapie
• tryb outdoorowy: pogrubione warstwice wysokości

View File

@@ -1,9 +1,7 @@
Apresentamos o logo do CoMaps! • Dados OSM de 4/08
Curvas de nível mais detalhadas em muitas regiões Melhoria nas cores para água, florestas, matagais, serviços, áreas de pedestres, etc.
• Adicionados links de imagens do Panoramax para pontos de interesse selecionados • Adição de guarda-florestais, estacionamentos cobertos para bicicletas, jogos de fuga, armários para bagagem e parceiros postais
Dados OSM de 13/07 Melhoria na precisão de curvas de nível para 20 m em algumas regiões populares
Adicionados preenchimentos de cor a muitos elementos Suporte a mais abreviações para busca
Exibição de horário de funcionamento ao selecionar um ponto de interesse Adição de ícones de pesquisa e favoritos para fast food, bicicletas e estações de recarga
Divididas áreas úmidas em vários tipos distintos Movimentos mais suaves para seta de posição
• Atualizada cores/ícones para vegetação e outros elementos
• Ar livre: curvas de nível de altitude mais destacadas

View File

@@ -1,9 +1,7 @@
Представляем логотип CoMaps! • Карты OpenStreetMap от 4 августа
Линии высот для многих регионов с шагом 20м или 50м Улучшен цвет воды, леса, кустарников, различных объектов инфраструктуры, пешеходных зон и т.д.
Ссылки на изображения Panoramax к выбранным POI Добавлены лесничества, крытые велопарковки, квесты, камеры хранения
Карты OpenStreetMap от 13 июля Для некоторых популярных туристических регионов добавлены линии высот 20м
Заливки цветом ко многим объектам и более ранняя заливка для существующих объектов Поддержка дополнительных поисковых сокращений и синонимов
Показ часов работы при выборе POI Добавлены иконки меток и результатов поиска для фастфуда, велопарковок и зарядных станций
Разные водно-болотные угодья отличаются цветом Более плавное движение стрелки местоположения
• Обновлены цвета растительности и другие цвета на карте, изменены некоторые иконки
В стиле "Активный отдых" более четкие линии высот

View File

@@ -1,9 +1,7 @@
Представљамо CoMaps лого! • подаци из OpenStreetMap-а од 4. августа
ажуриране изохипсе за многе регионе на кораке од 20 или 50 метара побољшане боје на мапи за воду, шуме, жбуње, разне објекте, пешачке зоне итд.
• додате везе ка Panoramax сликама за изабране тачке интересовања (POI) • додате станице ренџера, наткривена паркинг места за бицикле, escape room-ови, ормарићи за пртљаг
подаци са OpenStreetMap-а од 13. јула унапређене изохипсе на кораке од 20 м за популарне планинарске регионе
додате боје за многе елементе и раније приказивање постојећих површина подршка за више скраћеница и алтернативних назива у претрази
приказ стања радног времена при избору POI-ја додате иконе за претрагу и обележавање за брзу храну, бицикле и станице за пуњење
мочваре подељене на неколико различитих типова равномерније кретање стрелице која приказује позицију
• ажуриране боје вегетације и других елемената на мапи, ажуриране поједине иконе
• на отвореном: наглашеније изохипсе

View File

@@ -0,0 +1 @@
Könnyű térképes navigáció - Fedezz fel többet az útjaidról - A közösség erejével

View File

@@ -0,0 +1 @@
CoMaps - Az adatvédő navigáció

View File

@@ -6,7 +6,7 @@
<!-- Requiring "android.hardware.touchscreen" here breaks DeX mode --> <!-- Requiring "android.hardware.touchscreen" here breaks DeX mode -->
<uses-feature <uses-feature
android:glEsVersion="0x00020000" android:glEsVersion="0x00030000"
android:required="true"/> android:required="true"/>
<uses-feature <uses-feature
android:name="android.hardware.wifi" android:name="android.hardware.wifi"

View File

@@ -150,14 +150,12 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
switch (item.newStatus) switch (item.newStatus)
{ {
case CountryItem.STATUS_DONE: case CountryItem.STATUS_DONE:
mAreResourcesDownloaded = true; mAreResourcesDownloaded = true;
showMap(); showMap();
return; return;
case CountryItem.STATUS_FAILED: case CountryItem.STATUS_FAILED: MapManager.showError(DownloadResourcesLegacyActivity.this, item, null); return;
MapManager.showError(DownloadResourcesLegacyActivity.this, item, null);
return;
} }
} }
} }

View File

@@ -23,6 +23,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class MapFragment extends BaseMwmFragment implements View.OnTouchListener, SurfaceHolder.Callback public class MapFragment extends BaseMwmFragment implements View.OnTouchListener, SurfaceHolder.Callback
{ {
private static final String TAG = MapFragment.class.getSimpleName(); private static final String TAG = MapFragment.class.getSimpleName();
@NonNull
private final Map mMap = new Map(DisplayType.Device); private final Map mMap = new Map(DisplayType.Device);
public void updateCompassOffset(int offsetX, int offsetY) public void updateCompassOffset(int offsetX, int offsetY)
@@ -84,6 +86,8 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener
{ {
Logger.d(TAG); Logger.d(TAG);
super.onAttach(context); super.onAttach(context);
mMap.setLocationHelper(MwmApplication.from(requireContext()).getLocationHelper());
mMap.setMapRenderingListener((MapRenderingListener) context); mMap.setMapRenderingListener((MapRenderingListener) context);
mMap.setCallbackUnsupported(this::reportUnsupported); mMap.setCallbackUnsupported(this::reportUnsupported);
} }
@@ -159,24 +163,24 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener
int pointerIndex = event.getActionIndex(); int pointerIndex = event.getActionIndex();
switch (action) switch (action)
{ {
case MotionEvent.ACTION_POINTER_UP -> action = Map.NATIVE_ACTION_UP; case MotionEvent.ACTION_POINTER_UP -> action = Map.NATIVE_ACTION_UP;
case MotionEvent.ACTION_UP -> case MotionEvent.ACTION_UP ->
{ {
action = Map.NATIVE_ACTION_UP; action = Map.NATIVE_ACTION_UP;
pointerIndex = 0; pointerIndex = 0;
} }
case MotionEvent.ACTION_POINTER_DOWN -> action = Map.NATIVE_ACTION_DOWN; case MotionEvent.ACTION_POINTER_DOWN -> action = Map.NATIVE_ACTION_DOWN;
case MotionEvent.ACTION_DOWN -> case MotionEvent.ACTION_DOWN ->
{ {
action = Map.NATIVE_ACTION_DOWN; action = Map.NATIVE_ACTION_DOWN;
pointerIndex = 0; pointerIndex = 0;
} }
case MotionEvent.ACTION_MOVE -> case MotionEvent.ACTION_MOVE ->
{ {
action = Map.NATIVE_ACTION_MOVE; action = Map.NATIVE_ACTION_MOVE;
pointerIndex = Map.INVALID_POINTER_MASK; pointerIndex = Map.INVALID_POINTER_MASK;
} }
case MotionEvent.ACTION_CANCEL -> action = Map.NATIVE_ACTION_CANCEL; case MotionEvent.ACTION_CANCEL -> action = Map.NATIVE_ACTION_CANCEL;
} }
Map.onTouch(action, event, pointerIndex); Map.onTouch(action, event, pointerIndex);
return true; return true;

View File

@@ -18,7 +18,6 @@ import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.content.res.Configuration; import android.content.res.Configuration;
@@ -28,7 +27,6 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@@ -66,7 +64,6 @@ import app.organicmaps.downloader.OnmapDownloader;
import app.organicmaps.editor.EditorActivity; import app.organicmaps.editor.EditorActivity;
import app.organicmaps.editor.EditorHostFragment; import app.organicmaps.editor.EditorHostFragment;
import app.organicmaps.editor.FeatureCategoryActivity; import app.organicmaps.editor.FeatureCategoryActivity;
import app.organicmaps.editor.OsmLoginActivity;
import app.organicmaps.editor.ReportFragment; import app.organicmaps.editor.ReportFragment;
import app.organicmaps.help.HelpActivity; import app.organicmaps.help.HelpActivity;
import app.organicmaps.intent.Factory; import app.organicmaps.intent.Factory;
@@ -82,7 +79,6 @@ import app.organicmaps.routing.ManageRouteBottomSheet;
import app.organicmaps.routing.NavigationController; import app.organicmaps.routing.NavigationController;
import app.organicmaps.routing.NavigationService; import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingBottomMenuListener; import app.organicmaps.routing.RoutingBottomMenuListener;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.routing.RoutingErrorDialogFragment; import app.organicmaps.routing.RoutingErrorDialogFragment;
import app.organicmaps.routing.RoutingPlanFragment; import app.organicmaps.routing.RoutingPlanFragment;
import app.organicmaps.routing.RoutingPlanInplaceController; import app.organicmaps.routing.RoutingPlanInplaceController;
@@ -100,7 +96,6 @@ import app.organicmaps.sdk.display.DisplayType;
import app.organicmaps.sdk.downloader.MapManager; import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.downloader.UpdateInfo; import app.organicmaps.sdk.downloader.UpdateInfo;
import app.organicmaps.sdk.editor.Editor; import app.organicmaps.sdk.editor.Editor;
import app.organicmaps.sdk.editor.OsmOAuth;
import app.organicmaps.sdk.location.LocationHelper; import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.location.LocationListener; import app.organicmaps.sdk.location.LocationListener;
import app.organicmaps.sdk.location.LocationState; import app.organicmaps.sdk.location.LocationState;
@@ -108,6 +103,7 @@ import app.organicmaps.sdk.location.SensorListener;
import app.organicmaps.sdk.location.TrackRecorder; import app.organicmaps.sdk.location.TrackRecorder;
import app.organicmaps.sdk.maplayer.isolines.IsolinesState; import app.organicmaps.sdk.maplayer.isolines.IsolinesState;
import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.search.SearchEngine; import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.settings.RoadType; import app.organicmaps.sdk.settings.RoadType;
@@ -115,7 +111,6 @@ import app.organicmaps.sdk.settings.UnitLocale;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.LocationUtils; import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.PowerManagment; import app.organicmaps.sdk.util.PowerManagment;
import app.organicmaps.sdk.util.ThemeSwitcher;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.widget.placepage.PlacePageData; import app.organicmaps.sdk.widget.placepage.PlacePageData;
@@ -125,6 +120,7 @@ import app.organicmaps.search.SearchFragment;
import app.organicmaps.settings.DrivingOptionsActivity; import app.organicmaps.settings.DrivingOptionsActivity;
import app.organicmaps.settings.SettingsActivity; import app.organicmaps.settings.SettingsActivity;
import app.organicmaps.util.SharingUtils; import app.organicmaps.util.SharingUtils;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.ThemeUtils; import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
@@ -290,7 +286,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
} }
processIntent(); processIntent();
migrateOAuthCredentials();
} }
/** /**
@@ -345,36 +340,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
} }
} }
private void migrateOAuthCredentials()
{
if (OsmOAuth.containsOAuth1Credentials())
{
// Remove old OAuth v1 secrets
OsmOAuth.clearOAuth1Credentials();
// Notify user to re-login
dismissAlertDialog();
final DialogInterface.OnClickListener navigateToLoginHandler =
(dialog, which) -> startActivity(new Intent(MwmActivity.this, OsmLoginActivity.class));
final int marginBase = getResources().getDimensionPixelSize(R.dimen.margin_base);
final float textSize = getResources().getDimension(R.dimen.line_spacing_extra_1);
final TextView text = new TextView(this);
text.setText(getText(R.string.alert_reauth_message));
text.setPadding(marginBase, marginBase, marginBase, marginBase);
text.setTextSize(textSize);
text.setMovementMethod(LinkMovementMethod.getInstance());
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.login_osm)
.setView(text)
.setPositiveButton(R.string.login, navigateToLoginHandler)
.setNegativeButton(R.string.cancel, null)
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
}
private static void checkMeasurementSystem() private static void checkMeasurementSystem()
{ {
UnitLocale.initializeCurrentUnits(); UnitLocale.initializeCurrentUnits();
@@ -683,29 +648,29 @@ public class MwmActivity extends BaseMwmFragmentActivity
mPointChooser.findViewById(R.id.done).setOnClickListener(v -> { mPointChooser.findViewById(R.id.done).setOnClickListener(v -> {
switch (ChoosePositionMode.get()) switch (ChoosePositionMode.get())
{ {
case Api: case Api:
final Intent apiResult = new Intent(); final Intent apiResult = new Intent();
final double[] center = Framework.nativeGetScreenRectCenter(); final double[] center = Framework.nativeGetScreenRectCenter();
apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]); apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]);
apiResult.putExtra(Const.EXTRA_POINT_LON, center[1]); apiResult.putExtra(Const.EXTRA_POINT_LON, center[1]);
apiResult.putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale()); apiResult.putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale());
setResult(Activity.RESULT_OK, apiResult); setResult(Activity.RESULT_OK, apiResult);
finish(); finish();
break; break;
case Editor: case Editor:
if (Framework.nativeIsDownloadedMapAtScreenCenter()) if (Framework.nativeIsDownloadedMapAtScreenCenter())
startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class)); startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class));
else else
{ {
dismissAlertDialog(); dismissAlertDialog();
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.message_invalid_feature_position) .setTitle(R.string.message_invalid_feature_position)
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.setOnDismissListener(dialog -> mAlertDialog = null) .setOnDismissListener(dialog -> mAlertDialog = null)
.show(); .show();
} }
break; break;
case None: throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()"); case None: throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()");
} }
closePositionChooser(); closePositionChooser();
}); });
@@ -772,9 +737,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
final View mapView = mMapFragment.getView(); final View mapView = mMapFragment.getView();
if (mapView != null) if (mapView != null)
{ {
int width = mapView.getWidth(); int width = mapView.getWidth();
int height = mapView.getHeight(); int height = mapView.getHeight();
Framework.nativeSetVisibleRect(0, 0, width, height); Framework.nativeSetVisibleRect(0, 0, width, height);
} }
} }
UiUtils.show(mPointChooser); UiUtils.show(mPointChooser);
@@ -972,24 +937,24 @@ public class MwmActivity extends BaseMwmFragmentActivity
{ {
switch (button) switch (button)
{ {
case zoomIn -> Map.zoomIn(); case zoomIn -> Map.zoomIn();
case zoomOut -> Map.zoomOut(); case zoomOut -> Map.zoomOut();
case myPosition -> case myPosition ->
{ {
Logger.i(LOCATION_TAG, "The location button pressed"); Logger.i(LOCATION_TAG, "The location button pressed");
// Calls onMyPositionModeChanged(mode + 1). // Calls onMyPositionModeChanged(mode + 1).
LocationState.nativeSwitchToNextMode(); LocationState.nativeSwitchToNextMode();
} }
case toggleMapLayer -> toggleMapLayerBottomSheet(); case toggleMapLayer -> toggleMapLayerBottomSheet();
case bookmarks -> showBookmarks(); case bookmarks -> showBookmarks();
case search -> showSearch(""); case search -> showSearch("");
case menu -> case menu ->
{ {
closeFloatingPanels(); closeFloatingPanels();
showBottomSheet(MAIN_MENU_ID); showBottomSheet(MAIN_MENU_ID);
} }
case help -> showHelp(); case help -> showHelp();
case trackRecordingStatus -> showTrackSaveDialog(); case trackRecordingStatus -> showTrackSaveDialog();
} }
} }
@@ -1223,21 +1188,22 @@ public class MwmActivity extends BaseMwmFragmentActivity
private void onIsolinesStateChanged(@NonNull IsolinesState type) private void onIsolinesStateChanged(@NonNull IsolinesState type)
{ {
if (type != IsolinesState.EXPIREDDATA) if (type == IsolinesState.NODATA)
{ {
type.activate(this, findViewById(R.id.coordinator), findViewById(R.id.menu_frame)); Toast.makeText(this, R.string.isolines_location_error_dialog, Toast.LENGTH_SHORT).show();
return;
} }
dismissAlertDialog(); if (type == IsolinesState.EXPIREDDATA)
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) {
.setTitle(R.string.downloader_update_maps) mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setMessage(R.string.isolines_activation_error_dialog) .setTitle(R.string.downloader_update_maps)
.setPositiveButton(R.string.ok, .setMessage(R.string.isolines_activation_error_dialog)
(dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class))) .setPositiveButton(
.setNegativeButton(R.string.cancel, null) R.string.ok, (dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class)))
.setOnDismissListener(dialog -> mAlertDialog = null) .setNegativeButton(R.string.cancel, null)
.show(); .setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
} }
@Override @Override
@@ -2428,18 +2394,18 @@ public class MwmActivity extends BaseMwmFragmentActivity
{ {
switch (keyCode) switch (keyCode)
{ {
case KeyEvent.KEYCODE_DPAD_DOWN: Map.zoomOut(); return true; case KeyEvent.KEYCODE_DPAD_DOWN: Map.zoomOut(); return true;
case KeyEvent.KEYCODE_DPAD_UP: Map.zoomIn(); return true; case KeyEvent.KEYCODE_DPAD_UP: Map.zoomIn(); return true;
case KeyEvent.KEYCODE_ESCAPE: case KeyEvent.KEYCODE_ESCAPE:
final Intent currIntent = getIntent(); final Intent currIntent = getIntent();
final String backUrl = Framework.nativeGetParsedBackUrl(); final String backUrl = Framework.nativeGetParsedBackUrl();
if (TextUtils.isEmpty(backUrl) || (currIntent != null && Factory.isStartedForApiResult(currIntent))) if (TextUtils.isEmpty(backUrl) || (currIntent != null && Factory.isStartedForApiResult(currIntent)))
{ {
finish(); finish();
return true; return true;
} }
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
default: return super.onKeyUp(keyCode, event); default: return super.onKeyUp(keyCode, event);
} }
} }

View File

@@ -18,7 +18,6 @@ import app.organicmaps.background.OsmUploadWork;
import app.organicmaps.downloader.DownloaderNotifier; import app.organicmaps.downloader.DownloaderNotifier;
import app.organicmaps.location.TrackRecordingService; import app.organicmaps.location.TrackRecordingService;
import app.organicmaps.routing.NavigationService; import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Map; import app.organicmaps.sdk.Map;
import app.organicmaps.sdk.OrganicMaps; import app.organicmaps.sdk.OrganicMaps;
import app.organicmaps.sdk.display.DisplayManager; import app.organicmaps.sdk.display.DisplayManager;
@@ -28,9 +27,11 @@ import app.organicmaps.sdk.location.SensorHelper;
import app.organicmaps.sdk.location.TrackRecorder; import app.organicmaps.sdk.location.TrackRecorder;
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
import app.organicmaps.sdk.maplayer.subway.SubwayManager; import app.organicmaps.sdk.maplayer.subway.SubwayManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.ConnectionState; import app.organicmaps.sdk.util.ConnectionState;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@@ -133,6 +134,8 @@ public class MwmApplication extends Application implements Application.ActivityL
public boolean initOrganicMaps(@NonNull Runnable onComplete) throws IOException public boolean initOrganicMaps(@NonNull Runnable onComplete) throws IOException
{ {
return mOrganicMaps.init(() -> { return mOrganicMaps.init(() -> {
ThemeSwitcher.INSTANCE.initialize(this);
ThemeSwitcher.INSTANCE.restart(false);
ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver); ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver);
onComplete.run(); onComplete.run();
}); });

View File

@@ -62,39 +62,39 @@ public class LocalBackupManager implements BookmarkManager.BookmarksSharingListe
ErrorCode errorCode = null; ErrorCode errorCode = null;
switch (result.getCode()) switch (result.getCode())
{ {
case BookmarkSharingResult.SUCCESS -> case BookmarkSharingResult.SUCCESS ->
{ {
if (!saveBackup(result)) if (!saveBackup(result))
{
Logger.e(TAG, "Failed to save backup. See system log above");
errorCode = ErrorCode.FILE_ERROR;
}
else
{
Logger.i(TAG, "Backup was created and saved successfully");
}
}
case BookmarkSharingResult.EMPTY_CATEGORY ->
{
errorCode = ErrorCode.EMPTY_CATEGORY;
Logger.e(TAG, "Failed to create backup. Category is empty");
}
case BookmarkSharingResult.ARCHIVE_ERROR ->
{
errorCode = ErrorCode.ARCHIVE_ERROR;
Logger.e(TAG, "Failed to create archive of bookmarks");
}
case BookmarkSharingResult.FILE_ERROR ->
{ {
Logger.e(TAG, "Failed to save backup. See system log above");
errorCode = ErrorCode.FILE_ERROR; errorCode = ErrorCode.FILE_ERROR;
Logger.e(TAG, "Failed create file for archive");
} }
default -> else
{ {
errorCode = ErrorCode.UNSUPPORTED; Logger.i(TAG, "Backup was created and saved successfully");
Logger.e(TAG, "Failed to create backup. Unknown error");
} }
} }
case BookmarkSharingResult.EMPTY_CATEGORY ->
{
errorCode = ErrorCode.EMPTY_CATEGORY;
Logger.e(TAG, "Failed to create backup. Category is empty");
}
case BookmarkSharingResult.ARCHIVE_ERROR ->
{
errorCode = ErrorCode.ARCHIVE_ERROR;
Logger.e(TAG, "Failed to create archive of bookmarks");
}
case BookmarkSharingResult.FILE_ERROR ->
{
errorCode = ErrorCode.FILE_ERROR;
Logger.e(TAG, "Failed create file for archive");
}
default ->
{
errorCode = ErrorCode.UNSUPPORTED;
Logger.e(TAG, "Failed to create backup. Unknown error");
}
}
ErrorCode finalErrorCode = errorCode; ErrorCode finalErrorCode = errorCode;
UiThread.run(() -> { UiThread.run(() -> {

View File

@@ -66,47 +66,47 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<Recyc
LayoutInflater inflater = LayoutInflater.from(parent.getContext()); LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) switch (viewType)
{ {
case TYPE_ACTION_HEADER -> case TYPE_ACTION_HEADER ->
{ {
View header = inflater.inflate(R.layout.item_bookmark_group_list_header, parent, false); View header = inflater.inflate(R.layout.item_bookmark_group_list_header, parent, false);
return new HeaderViewHolder(header); return new HeaderViewHolder(header);
} }
case TYPE_CATEGORY_ITEM -> case TYPE_CATEGORY_ITEM ->
{ {
View view = inflater.inflate(R.layout.item_bookmark_category, parent, false); View view = inflater.inflate(R.layout.item_bookmark_category, parent, false);
final CategoryViewHolder holder = new CategoryViewHolder(view); final CategoryViewHolder holder = new CategoryViewHolder(view);
view.setOnClickListener(new CategoryItemClickListener(holder)); view.setOnClickListener(new CategoryItemClickListener(holder));
view.setOnLongClickListener(new LongClickListener(holder)); view.setOnLongClickListener(new LongClickListener(holder));
return holder; return holder;
} }
case TYPE_ACTION_ADD -> case TYPE_ACTION_ADD ->
{ {
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false); View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> { item.setOnClickListener(v -> {
if (mCategoryListCallback != null) if (mCategoryListCallback != null)
mCategoryListCallback.onAddButtonClick(); mCategoryListCallback.onAddButtonClick();
}); });
return new Holders.GeneralViewHolder(item); return new Holders.GeneralViewHolder(item);
} }
case TYPE_ACTION_IMPORT -> case TYPE_ACTION_IMPORT ->
{ {
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false); View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> { item.setOnClickListener(v -> {
if (mCategoryListCallback != null) if (mCategoryListCallback != null)
mCategoryListCallback.onImportButtonClick(); mCategoryListCallback.onImportButtonClick();
}); });
return new Holders.GeneralViewHolder(item); return new Holders.GeneralViewHolder(item);
} }
case TYPE_ACTION_EXPORT_ALL_AS_KMZ -> case TYPE_ACTION_EXPORT_ALL_AS_KMZ ->
{ {
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false); View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> { item.setOnClickListener(v -> {
if (mCategoryListCallback != null) if (mCategoryListCallback != null)
mCategoryListCallback.onExportButtonClick(); mCategoryListCallback.onExportButtonClick();
}); });
return new Holders.GeneralViewHolder(item); return new Holders.GeneralViewHolder(item);
} }
default -> throw new AssertionError("Invalid item type: " + viewType); default -> throw new AssertionError("Invalid item type: " + viewType);
} }
} }
@@ -116,44 +116,44 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<Recyc
int type = getItemViewType(position); int type = getItemViewType(position);
switch (type) switch (type)
{ {
case TYPE_ACTION_HEADER -> case TYPE_ACTION_HEADER ->
{ {
HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder; HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;
headerViewHolder.setAction(mMassOperationAction, BookmarkManager.INSTANCE.areAllCategoriesInvisible()); headerViewHolder.setAction(mMassOperationAction, BookmarkManager.INSTANCE.areAllCategoriesInvisible());
headerViewHolder.getText().setText(R.string.bookmark_lists); headerViewHolder.getText().setText(R.string.bookmark_lists);
} }
case TYPE_CATEGORY_ITEM -> case TYPE_CATEGORY_ITEM ->
{ {
final BookmarkCategory category = getCategoryByPosition(toCategoryPosition(position)); final BookmarkCategory category = getCategoryByPosition(toCategoryPosition(position));
CategoryViewHolder categoryHolder = (CategoryViewHolder) holder; CategoryViewHolder categoryHolder = (CategoryViewHolder) holder;
categoryHolder.setEntity(category); categoryHolder.setEntity(category);
categoryHolder.setName(category.getName()); categoryHolder.setName(category.getName());
categoryHolder.setSize(); categoryHolder.setSize();
categoryHolder.setVisibilityState(category.isVisible()); categoryHolder.setVisibilityState(category.isVisible());
ToggleVisibilityClickListener visibilityListener = new ToggleVisibilityClickListener(categoryHolder); ToggleVisibilityClickListener visibilityListener = new ToggleVisibilityClickListener(categoryHolder);
categoryHolder.setVisibilityListener(visibilityListener); categoryHolder.setVisibilityListener(visibilityListener);
CategoryItemMoreClickListener moreClickListener = new CategoryItemMoreClickListener(categoryHolder); CategoryItemMoreClickListener moreClickListener = new CategoryItemMoreClickListener(categoryHolder);
categoryHolder.setMoreButtonClickListener(moreClickListener); categoryHolder.setMoreButtonClickListener(moreClickListener);
} }
case TYPE_ACTION_ADD -> case TYPE_ACTION_ADD ->
{ {
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder; Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_add_list); generalViewHolder.getImage().setImageResource(R.drawable.ic_add_list);
generalViewHolder.getText().setText(R.string.bookmarks_create_new_group); generalViewHolder.getText().setText(R.string.bookmarks_create_new_group);
} }
case TYPE_ACTION_IMPORT -> case TYPE_ACTION_IMPORT ->
{ {
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder; Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_import); generalViewHolder.getImage().setImageResource(R.drawable.ic_import);
generalViewHolder.getText().setText(R.string.bookmarks_import); generalViewHolder.getText().setText(R.string.bookmarks_import);
} }
case TYPE_ACTION_EXPORT_ALL_AS_KMZ -> case TYPE_ACTION_EXPORT_ALL_AS_KMZ ->
{ {
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder; Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_export); generalViewHolder.getImage().setImageResource(R.drawable.ic_export);
generalViewHolder.getText().setText(R.string.bookmarks_export); generalViewHolder.getText().setText(R.string.bookmarks_export);
} }
default -> throw new AssertionError("Invalid item type: " + type); default -> throw new AssertionError("Invalid item type: " + type);
} }
} }

View File

@@ -442,37 +442,37 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
Holders.BaseBookmarkHolder holder = null; Holders.BaseBookmarkHolder holder = null;
switch (viewType) switch (viewType)
{ {
case TYPE_TRACK: case TYPE_TRACK:
Holders.TrackViewHolder trackHolder = Holders.TrackViewHolder trackHolder =
new Holders.TrackViewHolder(inflater.inflate(R.layout.item_track, parent, false)); new Holders.TrackViewHolder(inflater.inflate(R.layout.item_track, parent, false));
trackHolder.setOnClickListener(mClickListener); trackHolder.setOnClickListener(mClickListener);
trackHolder.setOnLongClickListener(mLongClickListener); trackHolder.setOnLongClickListener(mLongClickListener);
trackHolder.setTrackIconClickListener(mIconClickListener); trackHolder.setTrackIconClickListener(mIconClickListener);
trackHolder.setMoreButtonClickListener(mMoreClickListener); trackHolder.setMoreButtonClickListener(mMoreClickListener);
holder = trackHolder; holder = trackHolder;
break; break;
case TYPE_BOOKMARK: case TYPE_BOOKMARK:
Holders.BookmarkViewHolder bookmarkHolder = Holders.BookmarkViewHolder bookmarkHolder =
new Holders.BookmarkViewHolder(inflater.inflate(R.layout.item_bookmark, parent, false)); new Holders.BookmarkViewHolder(inflater.inflate(R.layout.item_bookmark, parent, false));
bookmarkHolder.setOnClickListener(mClickListener); bookmarkHolder.setOnClickListener(mClickListener);
bookmarkHolder.setOnLongClickListener(mLongClickListener); bookmarkHolder.setOnLongClickListener(mLongClickListener);
holder = bookmarkHolder; holder = bookmarkHolder;
break; break;
case TYPE_SECTION: case TYPE_SECTION:
MaterialTextView tv = (MaterialTextView) inflater.inflate(R.layout.item_category_title, parent, false); MaterialTextView tv = (MaterialTextView) inflater.inflate(R.layout.item_category_title, parent, false);
holder = new Holders.SectionViewHolder(tv); holder = new Holders.SectionViewHolder(tv);
break; break;
case TYPE_DESC: case TYPE_DESC:
View desc = inflater.inflate(R.layout.item_category_description, parent, false); View desc = inflater.inflate(R.layout.item_category_description, parent, false);
MaterialTextView moreBtn = desc.findViewById(R.id.more_btn); MaterialTextView moreBtn = desc.findViewById(R.id.more_btn);
MaterialTextView text = desc.findViewById(R.id.text); MaterialTextView text = desc.findViewById(R.id.text);
MaterialTextView title = desc.findViewById(R.id.title); MaterialTextView title = desc.findViewById(R.id.title);
setMoreButtonVisibility(text, moreBtn); setMoreButtonVisibility(text, moreBtn);
holder = new Holders.DescriptionViewHolder(desc, mSectionsDataSource.getCategory()); holder = new Holders.DescriptionViewHolder(desc, mSectionsDataSource.getCategory());
text.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn)); text.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
moreBtn.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn)); moreBtn.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
title.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn)); title.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
break; break;
} }
if (holder == null) if (holder == null)

View File

@@ -35,6 +35,7 @@ import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
import app.organicmaps.sdk.bookmarks.data.CategoryDataSource; import app.organicmaps.sdk.bookmarks.data.CategoryDataSource;
import app.organicmaps.sdk.bookmarks.data.Icon; import app.organicmaps.sdk.bookmarks.data.Icon;
import app.organicmaps.sdk.bookmarks.data.KmlFileType; import app.organicmaps.sdk.bookmarks.data.KmlFileType;
import app.organicmaps.sdk.bookmarks.data.PredefinedColors;
import app.organicmaps.sdk.bookmarks.data.SortedBlock; import app.organicmaps.sdk.bookmarks.data.SortedBlock;
import app.organicmaps.sdk.bookmarks.data.Track; import app.organicmaps.sdk.bookmarks.data.Track;
import app.organicmaps.sdk.search.BookmarkSearchListener; import app.organicmaps.sdk.search.BookmarkSearchListener;
@@ -551,12 +552,12 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
switch (adapter.getItemViewType(position)) switch (adapter.getItemViewType(position))
{ {
case BookmarkListAdapter.TYPE_SECTION, BookmarkListAdapter.TYPE_DESC -> case BookmarkListAdapter.TYPE_SECTION, BookmarkListAdapter.TYPE_DESC ->
{ {
return; return;
} }
case BookmarkListAdapter.TYPE_BOOKMARK -> onBookmarkClicked(position, intent, adapter); case BookmarkListAdapter.TYPE_BOOKMARK -> onBookmarkClicked(position, intent, adapter);
case BookmarkListAdapter.TYPE_TRACK -> onTrackClicked(position, intent, adapter); case BookmarkListAdapter.TYPE_TRACK -> onTrackClicked(position, intent, adapter);
} }
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -592,7 +593,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
if (mTrack == null) if (mTrack == null)
return; return;
final Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putInt(BookmarkColorDialogFragment.ICON_TYPE, Icon.getColorPosition(mTrack.getColor())); args.putInt(BookmarkColorDialogFragment.ICON_COLOR, PredefinedColors.getPredefinedColorIndex(mTrack.getColor()));
final FragmentManager manager = getChildFragmentManager(); final FragmentManager manager = getChildFragmentManager();
String className = BookmarkColorDialogFragment.class.getName(); String className = BookmarkColorDialogFragment.class.getName();
final FragmentFactory factory = manager.getFragmentFactory(); final FragmentFactory factory = manager.getFragmentFactory();
@@ -601,7 +602,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
dialogFragment.setArguments(args); dialogFragment.setArguments(args);
dialogFragment.setOnColorSetListener((colorPos) -> { dialogFragment.setOnColorSetListener((colorPos) -> {
int from = mTrack.getColor(); int from = mTrack.getColor();
int to = BookmarkManager.ICONS.get(colorPos).argb(); int to = PredefinedColors.getColor(colorPos);
if (from == to) if (from == to)
return; return;
BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to); BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to);
@@ -621,22 +622,22 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
switch (type) switch (type)
{ {
case BookmarkListAdapter.TYPE_SECTION: case BookmarkListAdapter.TYPE_SECTION:
case BookmarkListAdapter.TYPE_DESC: case BookmarkListAdapter.TYPE_DESC:
// Do nothing here? // Do nothing here?
break; break;
case BookmarkListAdapter.TYPE_BOOKMARK: case BookmarkListAdapter.TYPE_BOOKMARK:
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition); final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition);
MenuBottomSheetFragment.newInstance(BOOKMARKS_MENU_ID, bookmark.getName()) MenuBottomSheetFragment.newInstance(BOOKMARKS_MENU_ID, bookmark.getName())
.show(getChildFragmentManager(), BOOKMARKS_MENU_ID); .show(getChildFragmentManager(), BOOKMARKS_MENU_ID);
break; break;
case BookmarkListAdapter.TYPE_TRACK: case BookmarkListAdapter.TYPE_TRACK:
final Track track = (Track) adapter.getItem(mSelectedPosition); final Track track = (Track) adapter.getItem(mSelectedPosition);
MenuBottomSheetFragment.newInstance(TRACK_MENU_ID, track.getName()) MenuBottomSheetFragment.newInstance(TRACK_MENU_ID, track.getName())
.show(getChildFragmentManager(), TRACK_MENU_ID); .show(getChildFragmentManager(), TRACK_MENU_ID);
break; break;
} }
} }
@@ -843,19 +844,19 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
{ {
switch (id) switch (id)
{ {
case BOOKMARKS_MENU_ID -> case BOOKMARKS_MENU_ID ->
{ {
return getBookmarkMenuItems(); return getBookmarkMenuItems();
} }
case TRACK_MENU_ID -> case TRACK_MENU_ID ->
{ {
final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition); final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
return getTrackMenuItems(track); return getTrackMenuItems(track);
} }
case OPTIONS_MENU_ID -> case OPTIONS_MENU_ID ->
{ {
return getOptionsMenuItems(); return getOptionsMenuItems();
} }
} }
return null; return null;
} }

View File

@@ -57,27 +57,27 @@ public enum BookmarksSharingHelper
switch (result.getCode()) switch (result.getCode())
{ {
case BookmarkSharingResult.SUCCESS -> case BookmarkSharingResult.SUCCESS ->
SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType()); SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType());
case BookmarkSharingResult.EMPTY_CATEGORY -> case BookmarkSharingResult.EMPTY_CATEGORY ->
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog) new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.bookmarks_error_title_share_empty) .setTitle(R.string.bookmarks_error_title_share_empty)
.setMessage(R.string.bookmarks_error_message_share_empty) .setMessage(R.string.bookmarks_error_message_share_empty)
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.show(); .show();
case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR -> case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR ->
{ {
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog) new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.dialog_routing_system_error) .setTitle(R.string.dialog_routing_system_error)
.setMessage(R.string.bookmarks_error_message_share_general) .setMessage(R.string.bookmarks_error_message_share_general)
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.show(); .show();
List<String> names = new ArrayList<>(); List<String> names = new ArrayList<>();
for (long categoryId : result.getCategoriesIds()) for (long categoryId : result.getCategoriesIds())
names.add(BookmarkManager.INSTANCE.getCategoryById(categoryId).getName()); names.add(BookmarkManager.INSTANCE.getCategoryById(categoryId).getName());
Logger.e(TAG, "Failed to share bookmark categories " + names + ", error code: " + result.getCode()); Logger.e(TAG, "Failed to share bookmark categories " + names + ", error code: " + result.getCode());
} }
default -> throw new AssertionError("Unsupported bookmark sharing code: " + result.getCode()); default -> throw new AssertionError("Unsupported bookmark sharing code: " + result.getCode());
} }
} }

View File

@@ -64,10 +64,10 @@ public class ChooseBookmarksSortingTypeFragment
{ {
switch (sortingType) switch (sortingType)
{ {
case BookmarkManager.SORT_BY_TYPE: return R.id.sort_by_type; case BookmarkManager.SORT_BY_TYPE: return R.id.sort_by_type;
case BookmarkManager.SORT_BY_DISTANCE: return R.id.sort_by_distance; case BookmarkManager.SORT_BY_DISTANCE: return R.id.sort_by_distance;
case BookmarkManager.SORT_BY_TIME: return R.id.sort_by_time; case BookmarkManager.SORT_BY_TIME: return R.id.sort_by_time;
case BookmarkManager.SORT_BY_NAME: return R.id.sort_by_name; case BookmarkManager.SORT_BY_NAME: return R.id.sort_by_name;
} }
} }
return R.id.sort_by_default; return R.id.sort_by_default;

View File

@@ -6,19 +6,26 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.DrawableRes;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.bookmarks.data.Icon; import app.organicmaps.sdk.bookmarks.data.PredefinedColors;
import app.organicmaps.util.Graphics; import app.organicmaps.util.Graphics;
import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.imageview.ShapeableImageView;
import java.util.List; import java.util.List;
import java.util.Objects;
public class IconsAdapter extends ArrayAdapter<Icon> public class ColorsAdapter extends ArrayAdapter<Integer>
{ {
@PredefinedColors.Color
private int mCheckedIconColor; private int mCheckedIconColor;
public IconsAdapter(Context context, List<Icon> list) @DrawableRes
private final int mIconResId;
public ColorsAdapter(Context context, List<Integer> list, @DrawableRes int iconResId)
{ {
super(context, 0, 0, list); super(context, 0, 0, list);
mIconResId = iconResId;
} }
@Override @Override
@@ -35,19 +42,19 @@ public class IconsAdapter extends ArrayAdapter<Icon>
else else
holder = (SpinnerViewHolder) convertView.getTag(); holder = (SpinnerViewHolder) convertView.getTag();
final Icon icon = getItem(position); @PredefinedColors.Color
final int color = Objects.requireNonNull(getItem(position));
Drawable circle; Drawable circle;
if (icon.getColor() == mCheckedIconColor) if (color == mCheckedIconColor)
{ {
circle = Graphics.drawCircleAndImage(getItem(position).argb(), R.dimen.track_circle_size, circle = Graphics.drawCircleAndImage(PredefinedColors.getColor(mCheckedIconColor), R.dimen.track_circle_size,
app.organicmaps.sdk.R.drawable.ic_bookmark_none, R.dimen.bookmark_icon_size, mIconResId, R.dimen.bookmark_icon_size, getContext());
getContext());
} }
else else
{ {
circle = circle = Graphics.drawCircle(PredefinedColors.getColor(color), R.dimen.select_color_circle_size,
Graphics.drawCircle(getItem(position).argb(), R.dimen.select_color_circle_size, getContext().getResources()); getContext().getResources());
} }
holder.icon.setImageDrawable(circle); holder.icon.setImageDrawable(circle);
return convertView; return convertView;

View File

@@ -26,7 +26,6 @@ import app.organicmaps.car.util.CurrentCountryChangedListener;
import app.organicmaps.car.util.IntentUtils; import app.organicmaps.car.util.IntentUtils;
import app.organicmaps.car.util.ThemeUtils; import app.organicmaps.car.util.ThemeUtils;
import app.organicmaps.car.util.UserActionRequired; import app.organicmaps.car.util.UserActionRequired;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.PlacePageActivationListener; import app.organicmaps.sdk.PlacePageActivationListener;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
@@ -34,6 +33,7 @@ import app.organicmaps.sdk.display.DisplayChangedListener;
import app.organicmaps.sdk.display.DisplayManager; import app.organicmaps.sdk.display.DisplayManager;
import app.organicmaps.sdk.display.DisplayType; import app.organicmaps.sdk.display.DisplayType;
import app.organicmaps.sdk.location.LocationState; import app.organicmaps.sdk.location.LocationState;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.LocationUtils; import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;

View File

@@ -27,7 +27,10 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac
{ {
private static final String TAG = SurfaceRenderer.class.getSimpleName(); private static final String TAG = SurfaceRenderer.class.getSimpleName();
@NonNull
private final CarContext mCarContext; private final CarContext mCarContext;
@NonNull
private final Map mMap = new Map(Car); private final Map mMap = new Map(Car);
@NonNull @NonNull
@@ -56,6 +59,7 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac
mSurface.release(); mSurface.release();
mSurface = surfaceContainer.getSurface(); mSurface = surfaceContainer.getSurface();
mMap.setLocationHelper(MwmApplication.from(mCarContext).getLocationHelper());
mMap.onSurfaceCreated(mCarContext, mSurface, mMap.onSurfaceCreated(mCarContext, mSurface,
new Rect(0, 0, surfaceContainer.getWidth(), surfaceContainer.getHeight()), new Rect(0, 0, surfaceContainer.getWidth(), surfaceContainer.getHeight()),
surfaceContainer.getDpi()); surfaceContainer.getDpi());

View File

@@ -28,11 +28,11 @@ import app.organicmaps.car.util.RoutingUtils;
import app.organicmaps.car.util.ThemeUtils; import app.organicmaps.car.util.ThemeUtils;
import app.organicmaps.car.util.UiHelpers; import app.organicmaps.car.util.UiHelpers;
import app.organicmaps.routing.NavigationService; import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.location.LocationHelper; import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.location.LocationListener; import app.organicmaps.sdk.location.LocationListener;
import app.organicmaps.sdk.routing.JunctionInfo; import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.sound.TtsPlayer; import app.organicmaps.sdk.sound.TtsPlayer;
import app.organicmaps.sdk.util.LocationUtils; import app.organicmaps.sdk.util.LocationUtils;

View File

@@ -35,11 +35,11 @@ import app.organicmaps.car.util.OnBackPressedCallback;
import app.organicmaps.car.util.RoutingHelpers; import app.organicmaps.car.util.RoutingHelpers;
import app.organicmaps.car.util.UiHelpers; import app.organicmaps.car.util.UiHelpers;
import app.organicmaps.routing.ResultCodesHelper; import app.organicmaps.routing.ResultCodesHelper;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router; import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.bookmarks.data.Metadata; import app.organicmaps.sdk.bookmarks.data.Metadata;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import java.util.Objects; import java.util.Objects;

View File

@@ -62,29 +62,29 @@ public final class SearchUiHelpers
CarColor color = Colors.DEFAULT; CarColor color = Colors.DEFAULT;
switch (searchResult.description.openNow) switch (searchResult.description.openNow)
{ {
case SearchResult.OPEN_NOW_YES: case SearchResult.OPEN_NOW_YES:
if (searchResult.description.minutesUntilClosed < 60) // less than 1 hour if (searchResult.description.minutesUntilClosed < 60) // less than 1 hour
{ {
final String time = searchResult.description.minutesUntilClosed + " " + carContext.getString(R.string.minute); final String time = searchResult.description.minutesUntilClosed + " " + carContext.getString(R.string.minute);
text = carContext.getString(R.string.closes_in, time); text = carContext.getString(R.string.closes_in, time);
color = Colors.OPENING_HOURS_CLOSES_SOON; color = Colors.OPENING_HOURS_CLOSES_SOON;
} }
else else
{ {
text = carContext.getString(R.string.editor_time_open); text = carContext.getString(R.string.editor_time_open);
color = Colors.OPENING_HOURS_OPEN; color = Colors.OPENING_HOURS_OPEN;
} }
break; break;
case SearchResult.OPEN_NOW_NO: case SearchResult.OPEN_NOW_NO:
if (searchResult.description.minutesUntilOpen < 60) // less than 1 hour if (searchResult.description.minutesUntilOpen < 60) // less than 1 hour
{ {
final String time = searchResult.description.minutesUntilOpen + " " + carContext.getString(R.string.minute); final String time = searchResult.description.minutesUntilOpen + " " + carContext.getString(R.string.minute);
text = carContext.getString(R.string.opens_in, time); text = carContext.getString(R.string.opens_in, time);
} }
else else
text = carContext.getString(R.string.closed); text = carContext.getString(R.string.closed);
color = Colors.OPENING_HOURS_CLOSED; color = Colors.OPENING_HOURS_CLOSED;
break; break;
} }
result.append(text); result.append(text);

View File

@@ -7,9 +7,9 @@ import androidx.car.app.CarContext;
import androidx.car.app.ScreenManager; import androidx.car.app.ScreenManager;
import app.organicmaps.car.screens.download.DownloadMapsScreen; import app.organicmaps.car.screens.download.DownloadMapsScreen;
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder; import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.downloader.CountryItem; import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager; import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
public class CurrentCountryChangedListener implements MapManager.CurrentCountryChangedListener public class CurrentCountryChangedListener implements MapManager.CurrentCountryChangedListener
{ {

View File

@@ -15,13 +15,13 @@ import app.organicmaps.car.CarAppService;
import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.SurfaceRenderer;
import app.organicmaps.car.screens.NavigationScreen; import app.organicmaps.car.screens.NavigationScreen;
import app.organicmaps.car.screens.search.SearchScreen; import app.organicmaps.car.screens.search.SearchScreen;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Map; import app.organicmaps.sdk.Map;
import app.organicmaps.sdk.api.ParsedSearchRequest; import app.organicmaps.sdk.api.ParsedSearchRequest;
import app.organicmaps.sdk.api.RequestType; import app.organicmaps.sdk.api.RequestType;
import app.organicmaps.sdk.display.DisplayManager; import app.organicmaps.sdk.display.DisplayManager;
import app.organicmaps.sdk.display.DisplayType; import app.organicmaps.sdk.display.DisplayType;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
public final class IntentUtils public final class IntentUtils
@@ -65,36 +65,36 @@ public final class IntentUtils
final ScreenManager screenManager = carContext.getCarService(ScreenManager.class); final ScreenManager screenManager = carContext.getCarService(ScreenManager.class);
switch (Framework.nativeParseAndSetApiUrl(uri.toString())) switch (Framework.nativeParseAndSetApiUrl(uri.toString()))
{ {
case RequestType.INCORRECT: return; case RequestType.INCORRECT: return;
case RequestType.MAP: case RequestType.MAP:
screenManager.popToRoot(); screenManager.popToRoot();
Map.executeMapApiRequest(); Map.executeMapApiRequest();
return; return;
case RequestType.SEARCH: case RequestType.SEARCH:
screenManager.popToRoot(); screenManager.popToRoot();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest(); final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
final double[] latlon = Framework.nativeGetParsedCenterLatLon(); final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null) if (latlon != null)
{ {
Framework.nativeStopLocationFollow(); Framework.nativeStopLocationFollow();
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
// We need to update viewport for search api manually because of drape engine // We need to update viewport for search api manually because of drape engine
// will not notify subscribers when search activity is shown. // will not notify subscribers when search activity is shown.
if (!request.mIsSearchOnMap) if (!request.mIsSearchOnMap)
Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
} }
final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer); final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer);
builder.setQuery(request.mQuery); builder.setQuery(request.mQuery);
if (request.mLocale != null) if (request.mLocale != null)
builder.setLocale(request.mLocale); builder.setLocale(request.mLocale);
screenManager.popToRoot(); screenManager.popToRoot();
screenManager.push(builder.build()); screenManager.push(builder.build());
return; return;
case RequestType.ROUTE: Logger.e(TAG, "Route API is not supported by Android Auto: " + uri); return; case RequestType.ROUTE: Logger.e(TAG, "Route API is not supported by Android Auto: " + uri); return;
case RequestType.CROSSHAIR: Logger.e(TAG, "Crosshair API is not supported by Android Auto: " + uri); return; case RequestType.CROSSHAIR: Logger.e(TAG, "Crosshair API is not supported by Android Auto: " + uri); return;
case RequestType.MENU: Logger.e(TAG, "Menu API is not supported by Android Auto: " + uri); return; case RequestType.MENU: Logger.e(TAG, "Menu API is not supported by Android Auto: " + uri); return;
case RequestType.SETTINGS: Logger.e(TAG, "Settings API is not supported by Android Auto: " + uri); case RequestType.SETTINGS: Logger.e(TAG, "Settings API is not supported by Android Auto: " + uri);
} }
} }

View File

@@ -8,8 +8,8 @@ import androidx.annotation.StringRes;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.car.app.CarContext; import androidx.car.app.CarContext;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.MapStyle; import app.organicmaps.sdk.MapStyle;
import app.organicmaps.sdk.routing.RoutingController;
public final class ThemeUtils public final class ThemeUtils
{ {

View File

@@ -171,20 +171,20 @@ public final class UiHelpers
int drawableRes; int drawableRes;
switch (locationMode) switch (locationMode)
{ {
case LocationState.PENDING_POSITION, LocationState.NOT_FOLLOW_NO_POSITION -> case LocationState.PENDING_POSITION, LocationState.NOT_FOLLOW_NO_POSITION ->
drawableRes = R.drawable.ic_location_off; drawableRes = R.drawable.ic_location_off;
case LocationState.NOT_FOLLOW -> drawableRes = R.drawable.ic_not_follow; case LocationState.NOT_FOLLOW -> drawableRes = R.drawable.ic_not_follow;
case LocationState.FOLLOW -> case LocationState.FOLLOW ->
{ {
drawableRes = R.drawable.ic_follow; drawableRes = R.drawable.ic_follow;
tintColor = Colors.LOCATION_TINT; tintColor = Colors.LOCATION_TINT;
} }
case LocationState.FOLLOW_AND_ROTATE -> case LocationState.FOLLOW_AND_ROTATE ->
{ {
drawableRes = R.drawable.ic_follow_and_rotate; drawableRes = R.drawable.ic_follow_and_rotate;
tintColor = Colors.LOCATION_TINT; tintColor = Colors.LOCATION_TINT;
} }
default -> throw new IllegalArgumentException("Invalid button mode: " + locationMode); default -> throw new IllegalArgumentException("Invalid button mode: " + locationMode);
} }
final CarIcon icon = final CarIcon icon =

View File

@@ -115,15 +115,15 @@ class BottomPanel
{ {
switch (status) switch (status)
{ {
case STATUS_UPDATABLE -> case STATUS_UPDATABLE ->
{ {
UpdateInfo info = MapManager.nativeGetUpdateInfo(root); UpdateInfo info = MapManager.nativeGetUpdateInfo(root);
setUpdateAllState(info); setUpdateAllState(info);
} // Special case for "Countries" node when no maps currently downloaded. } // Special case for "Countries" node when no maps currently downloaded.
case STATUS_DOWNLOADABLE, STATUS_DONE, STATUS_PARTLY -> show = false; case STATUS_DOWNLOADABLE, STATUS_DONE, STATUS_PARTLY -> show = false;
case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState(); case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState();
case STATUS_FAILED -> setRetryFailedStates(); case STATUS_FAILED -> setRetryFailedStates();
default -> throw new IllegalArgumentException("Inappropriate status for \"" + root + "\": " + status); default -> throw new IllegalArgumentException("Inappropriate status for \"" + root + "\": " + status);
} }
} }
else else
@@ -133,15 +133,15 @@ class BottomPanel
{ {
switch (status) switch (status)
{ {
case STATUS_UPDATABLE -> case STATUS_UPDATABLE ->
{ {
UpdateInfo info = MapManager.nativeGetUpdateInfo(root); UpdateInfo info = MapManager.nativeGetUpdateInfo(root);
setUpdateAllState(info); setUpdateAllState(info);
} }
case STATUS_DONE -> show = false; case STATUS_DONE -> show = false;
case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState(); case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState();
case STATUS_FAILED -> setRetryFailedStates(); case STATUS_FAILED -> setRetryFailedStates();
default -> setDownloadAllState(); default -> setDownloadAllState();
} }
} }
} }

View File

@@ -70,9 +70,9 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
switch (item.newStatus) switch (item.newStatus)
{ {
case CountryItem.STATUS_FAILED: updateViews(); return; case CountryItem.STATUS_FAILED: updateViews(); return;
case CountryItem.STATUS_DONE: exitFragment(); return; case CountryItem.STATUS_DONE: exitFragment(); return;
} }
break; break;

View File

@@ -20,9 +20,9 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.MwmActivity; import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.downloader.CountryItem; import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager; import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
@@ -287,41 +287,41 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
ArrayList<MenuBottomSheetItem> items = new ArrayList<>(); ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
switch (mSelectedItem.status) switch (mSelectedItem.status)
{ {
case CountryItem.STATUS_DOWNLOADABLE: items.add(getDownloadMenuItem()); break; case CountryItem.STATUS_DOWNLOADABLE: items.add(getDownloadMenuItem()); break;
case CountryItem.STATUS_UPDATABLE: case CountryItem.STATUS_UPDATABLE:
items.add(getUpdateMenuItem()); items.add(getUpdateMenuItem());
// Fallthrough // Fallthrough
case CountryItem.STATUS_DONE: case CountryItem.STATUS_DONE:
if (!mSelectedItem.isExpandable()) if (!mSelectedItem.isExpandable())
items.add(getExploreMenuItem()); items.add(getExploreMenuItem());
appendDeleteMenuItem(items);
break;
case CountryItem.STATUS_FAILED:
items.add(getCancelMenuItem());
if (mSelectedItem.present)
{
appendDeleteMenuItem(items); appendDeleteMenuItem(items);
break; items.add(getExploreMenuItem());
}
break;
case CountryItem.STATUS_FAILED: case CountryItem.STATUS_PROGRESS:
items.add(getCancelMenuItem()); case CountryItem.STATUS_APPLYING:
case CountryItem.STATUS_ENQUEUED:
items.add(getCancelMenuItem());
if (mSelectedItem.present) if (mSelectedItem.present)
{ items.add(getExploreMenuItem());
appendDeleteMenuItem(items); break;
items.add(getExploreMenuItem());
}
break;
case CountryItem.STATUS_PROGRESS: case CountryItem.STATUS_PARTLY:
case CountryItem.STATUS_APPLYING: items.add(getDownloadMenuItem());
case CountryItem.STATUS_ENQUEUED: appendDeleteMenuItem(items);
items.add(getCancelMenuItem()); break;
if (mSelectedItem.present)
items.add(getExploreMenuItem());
break;
case CountryItem.STATUS_PARTLY:
items.add(getDownloadMenuItem());
appendDeleteMenuItem(items);
break;
} }
return items; return items;
} }
@@ -372,20 +372,20 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
{ {
switch (mItem.status) switch (mItem.status)
{ {
case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING, case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING,
CountryItem.STATUS_ENQUEUED -> CountryItem.STATUS_ENQUEUED ->
processLongClick();
case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY ->
{
if (clickOnStatus)
onDownloadActionSelected(mItem, DownloaderAdapter.this);
else
processLongClick(); processLongClick();
case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY -> }
{ case CountryItem.STATUS_FAILED -> MapManager.warn3gAndRetry(mActivity, mItem.id, null);
if (clickOnStatus) case CountryItem.STATUS_UPDATABLE ->
onDownloadActionSelected(mItem, DownloaderAdapter.this); MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id));
else default -> throw new IllegalArgumentException("Inappropriate item status: " + mItem.status);
processLongClick();
}
case CountryItem.STATUS_FAILED -> MapManager.warn3gAndRetry(mActivity, mItem.id, null);
case CountryItem.STATUS_UPDATABLE ->
MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id));
default -> throw new IllegalArgumentException("Inappropriate item status: " + mItem.status);
} }
} }
@@ -535,33 +535,33 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
{ {
switch (ci.category) switch (ci.category)
{ {
case CountryItem.CATEGORY_NEAR_ME -> case CountryItem.CATEGORY_NEAR_ME ->
{
if (ci.category != prev)
{ {
if (ci.category != prev) headerId = CountryItem.CATEGORY_NEAR_ME;
{ mItemsAndHeader.add(new GenericItem(mActivity.getString(R.string.downloader_near_me_subtitle)));
headerId = CountryItem.CATEGORY_NEAR_ME;
mItemsAndHeader.add(new GenericItem(mActivity.getString(R.string.downloader_near_me_subtitle)));
prev = ci.category;
}
}
case CountryItem.CATEGORY_DOWNLOADED ->
{
if (ci.category != prev)
{
headerId = CountryItem.CATEGORY_DOWNLOADED;
mItemsAndHeader.add(new GenericItem(mActivity.getString(R.string.downloader_downloaded_subtitle)));
prev = ci.category;
}
}
default ->
{
int prevHeader = headerId;
headerId = CountryItem.CATEGORY_AVAILABLE + ci.name.charAt(0);
if (headerId != prevHeader)
mItemsAndHeader.add(new GenericItem(StringUtils.toUpperCase(ci.name.substring(0, 1))));
prev = ci.category; prev = ci.category;
} }
} }
case CountryItem.CATEGORY_DOWNLOADED ->
{
if (ci.category != prev)
{
headerId = CountryItem.CATEGORY_DOWNLOADED;
mItemsAndHeader.add(new GenericItem(mActivity.getString(R.string.downloader_downloaded_subtitle)));
prev = ci.category;
}
}
default ->
{
int prevHeader = headerId;
headerId = CountryItem.CATEGORY_AVAILABLE + ci.name.charAt(0);
if (headerId != prevHeader)
mItemsAndHeader.add(new GenericItem(StringUtils.toUpperCase(ci.name.substring(0, 1))));
prev = ci.category;
}
}
ci.headerId = headerId; ci.headerId = headerId;
} }
mItemsAndHeader.add(new GenericItem(ci)); mItemsAndHeader.add(new GenericItem(ci));

View File

@@ -24,8 +24,8 @@ import app.organicmaps.widget.PlaceholderView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapter> public class DownloaderFragment
implements MenuBottomSheetFragment.MenuBottomSheetInterface extends BaseMwmRecyclerFragment<DownloaderAdapter> implements MenuBottomSheetFragment.MenuBottomSheetInterface
{ {
private DownloaderToolbarController mToolbarController; private DownloaderToolbarController mToolbarController;
@@ -153,7 +153,8 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
mBottomPanel = new BottomPanel(this, view); mBottomPanel = new BottomPanel(this, view);
mToolbarController = new DownloaderToolbarController(view, requireActivity(), this); mToolbarController = new DownloaderToolbarController(view, requireActivity(), this);
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), mToolbarController.getBackPressedCallback()); requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(),
mToolbarController.getBackPressedCallback());
update(); update();
} }
@@ -195,7 +196,8 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
{ {
if (mAdapter == null) if (mAdapter == null)
mAdapter = new DownloaderAdapter(this); mAdapter = new DownloaderAdapter(this);
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), mAdapter.getBackPressedCallback()); requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(),
mAdapter.getBackPressedCallback());
return mAdapter; return mAdapter;
} }

View File

@@ -9,9 +9,9 @@ import androidx.core.view.ViewCompat;
import app.organicmaps.MwmActivity; import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.downloader.CountryItem; import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager; import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.ConnectionState; import app.organicmaps.sdk.util.ConnectionState;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;

View File

@@ -87,8 +87,8 @@ public class AdvancedTimetableFragment extends BaseMwmFragment implements View.O
private void setExampleDrawables(@DrawableRes int left, @DrawableRes int right) private void setExampleDrawables(@DrawableRes int left, @DrawableRes int right)
{ {
mExamplesTitle.setCompoundDrawablesRelativeWithIntrinsicBounds( mExamplesTitle.setCompoundDrawablesRelativeWithIntrinsicBounds(
Graphics.tint(requireActivity(), left, androidx.appcompat.R.attr.colorAccent), null, Graphics.tint(requireActivity(), left, com.google.android.material.R.attr.colorSecondary), null,
Graphics.tint(requireActivity(), right, androidx.appcompat.R.attr.colorAccent), null); Graphics.tint(requireActivity(), right, com.google.android.material.R.attr.colorSecondary), null);
} }
@Override @Override

View File

@@ -20,13 +20,13 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.base.BaseMwmFragment; import app.organicmaps.base.BaseMwmFragment;
import app.organicmaps.dialog.EditTextDialogFragment; import app.organicmaps.dialog.EditTextDialogFragment;
import app.organicmaps.editor.data.TimeFormatUtils;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.Metadata; import app.organicmaps.sdk.bookmarks.data.Metadata;
import app.organicmaps.sdk.editor.Editor; import app.organicmaps.sdk.editor.Editor;
import app.organicmaps.sdk.editor.OpeningHours; import app.organicmaps.sdk.editor.OpeningHours;
import app.organicmaps.sdk.editor.data.LocalizedName; import app.organicmaps.sdk.editor.data.LocalizedName;
import app.organicmaps.sdk.editor.data.LocalizedStreet; import app.organicmaps.sdk.editor.data.LocalizedStreet;
import app.organicmaps.editor.data.TimeFormatUtils;
import app.organicmaps.sdk.editor.data.Timetable; import app.organicmaps.sdk.editor.data.Timetable;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
@@ -623,11 +623,11 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
switch (Editor.nativeGetMapObjectStatus()) switch (Editor.nativeGetMapObjectStatus())
{ {
case Editor.CREATED -> mReset.setText(R.string.editor_remove_place_button); case Editor.CREATED -> mReset.setText(R.string.editor_remove_place_button);
case Editor.MODIFIED -> mReset.setText(R.string.editor_reset_edits_button); case Editor.MODIFIED -> mReset.setText(R.string.editor_reset_edits_button);
case Editor.UNTOUCHED -> mReset.setText(R.string.editor_place_doesnt_exist); case Editor.UNTOUCHED -> mReset.setText(R.string.editor_place_doesnt_exist);
case Editor.DELETED -> throw new IllegalStateException("Can't delete already deleted feature."); case Editor.DELETED -> throw new IllegalStateException("Can't delete already deleted feature.");
case Editor.OBSOLETE -> throw new IllegalStateException("Obsolete objects cannot be reverted."); case Editor.OBSOLETE -> throw new IllegalStateException("Obsolete objects cannot be reverted.");
} }
} }
@@ -641,11 +641,11 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
switch (Editor.nativeGetMapObjectStatus()) switch (Editor.nativeGetMapObjectStatus())
{ {
case Editor.CREATED -> rollback(Editor.CREATED); case Editor.CREATED -> rollback(Editor.CREATED);
case Editor.MODIFIED -> rollback(Editor.MODIFIED); case Editor.MODIFIED -> rollback(Editor.MODIFIED);
case Editor.UNTOUCHED -> placeDoesntExist(); case Editor.UNTOUCHED -> placeDoesntExist();
case Editor.DELETED -> throw new IllegalStateException("Can't delete already deleted feature."); case Editor.DELETED -> throw new IllegalStateException("Can't delete already deleted feature.");
case Editor.OBSOLETE -> throw new IllegalStateException("Obsolete objects cannot be reverted."); case Editor.OBSOLETE -> throw new IllegalStateException("Obsolete objects cannot be reverted.");
} }
} }

View File

@@ -173,8 +173,8 @@ public class EditorHostFragment
{ {
switch (mMode) switch (mMode)
{ {
case OPENING_HOURS, STREET, CUISINE, LANGUAGE, PHONE, SELF_SERVICE -> editMapObject(); case OPENING_HOURS, STREET, CUISINE, LANGUAGE, PHONE, SELF_SERVICE -> editMapObject();
default -> Utils.navigateToParent(requireActivity()); default -> Utils.navigateToParent(requireActivity());
} }
return true; return true;
} }
@@ -283,57 +283,57 @@ public class EditorHostFragment
{ {
switch (mMode) switch (mMode)
{ {
case OPENING_HOURS -> case OPENING_HOURS ->
{ {
final String timetables = ((TimetableContainerFragment) getChildFragmentManager().findFragmentByTag( final String timetables = ((TimetableContainerFragment) getChildFragmentManager().findFragmentByTag(
TimetableContainerFragment.class.getName())) TimetableContainerFragment.class.getName()))
.getTimetable(); .getTimetable();
Editor.nativeSetOpeningHours(timetables); Editor.nativeSetOpeningHours(timetables);
editMapObject(); editMapObject();
} }
case STREET -> case STREET ->
setStreet(((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName())) setStreet(
.getStreet()); ((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName())).getStreet());
case CUISINE -> case CUISINE ->
{ {
String[] cuisines = String[] cuisines =
((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName())) ((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName()))
.getCuisines(); .getCuisines();
Editor.nativeSetSelectedCuisines(cuisines); Editor.nativeSetSelectedCuisines(cuisines);
editMapObject(); editMapObject();
} }
case SELF_SERVICE -> case SELF_SERVICE ->
setSelection( setSelection(
Metadata.MetadataType.FMD_SELF_SERVICE, Metadata.MetadataType.FMD_SELF_SERVICE,
((SelfServiceFragment) getChildFragmentManager().findFragmentByTag(SelfServiceFragment.class.getName())) ((SelfServiceFragment) getChildFragmentManager().findFragmentByTag(SelfServiceFragment.class.getName()))
.getSelection()); .getSelection());
case LANGUAGE -> editMapObject(); case LANGUAGE -> editMapObject();
case MAP_OBJECT -> case MAP_OBJECT ->
{ {
if (!setEdits()) if (!setEdits())
return; return;
// Save object edits // Save object edits
if (!MwmApplication.prefs(requireContext()).contains(NOOB_ALERT_SHOWN)) if (!MwmApplication.prefs(requireContext()).contains(NOOB_ALERT_SHOWN))
{
showNoobDialog();
}
else
{
saveNote();
saveMapObjectEdits();
}
}
case PHONE ->
{ {
final String phone = showNoobDialog();
((PhoneFragment) getChildFragmentManager().findFragmentByTag(PhoneFragment.class.getName())).getPhone();
if (Editor.nativeIsPhoneValid(phone))
{
Editor.nativeSetPhone(phone);
editMapObject();
}
} }
else
{
saveNote();
saveMapObjectEdits();
}
}
case PHONE ->
{
final String phone =
((PhoneFragment) getChildFragmentManager().findFragmentByTag(PhoneFragment.class.getName())).getPhone();
if (Editor.nativeIsPhoneValid(phone))
{
Editor.nativeSetPhone(phone);
editMapObject();
}
}
} }
} }
} }

View File

@@ -9,7 +9,9 @@ import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.editor.data.FeatureCategory; import app.organicmaps.sdk.editor.data.FeatureCategory;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textview.MaterialTextView; import com.google.android.material.textview.MaterialTextView;
public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
@@ -21,6 +23,12 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
private final FeatureCategoryFragment mFragment; private final FeatureCategoryFragment mFragment;
private final FeatureCategory mSelectedCategory; private final FeatureCategory mSelectedCategory;
public interface FooterListener
{
void onNoteTextChanged(String newText);
void onSendNoteClicked();
}
public FeatureCategoryAdapter(@NonNull FeatureCategoryFragment host, @NonNull FeatureCategory[] categories, public FeatureCategoryAdapter(@NonNull FeatureCategoryFragment host, @NonNull FeatureCategory[] categories,
@Nullable FeatureCategory category) @Nullable FeatureCategory category)
{ {
@@ -47,19 +55,23 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{ {
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) switch (viewType)
{ {
case TYPE_CATEGORY -> case TYPE_CATEGORY ->
{ {
return new FeatureViewHolder( return new FeatureViewHolder(inflater.inflate(R.layout.item_feature_category, parent, false));
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category, parent, false)); }
} case TYPE_FOOTER ->
case TYPE_FOOTER -> {
{ return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false),
return new FooterViewHolder( (FooterListener) mFragment);
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false)); }
} default ->
default -> throw new IllegalArgumentException("Unsupported"); {
throw new IllegalArgumentException("Unsupported viewType: " + viewType);
}
} }
} }
@@ -70,6 +82,10 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
{ {
((FeatureViewHolder) holder).bind(position); ((FeatureViewHolder) holder).bind(position);
} }
else if (holder instanceof FooterViewHolder)
{
((FooterViewHolder) holder).bind(mFragment.getPendingNoteText());
}
} }
@Override @Override
@@ -105,11 +121,36 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
protected static class FooterViewHolder extends RecyclerView.ViewHolder protected static class FooterViewHolder extends RecyclerView.ViewHolder
{ {
FooterViewHolder(@NonNull View itemView) private final TextInputEditText mNoteEditText;
private final View mSendNoteButton;
FooterViewHolder(@NonNull View itemView, @NonNull FooterListener listener)
{ {
super(itemView); super(itemView);
MaterialTextView categoryUnsuitableText = itemView.findViewById(R.id.editor_category_unsuitable_text); MaterialTextView categoryUnsuitableText = itemView.findViewById(R.id.editor_category_unsuitable_text);
categoryUnsuitableText.setMovementMethod(LinkMovementMethod.getInstance()); categoryUnsuitableText.setMovementMethod(LinkMovementMethod.getInstance());
mNoteEditText = itemView.findViewById(R.id.note_edit_text);
mSendNoteButton = itemView.findViewById(R.id.send_note_button);
mSendNoteButton.setOnClickListener(v -> listener.onSendNoteClicked());
mNoteEditText.addTextChangedListener(new StringUtils.SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
final String str = s.toString();
listener.onNoteTextChanged(str);
mSendNoteButton.setEnabled(!str.trim().isEmpty());
}
});
}
public void bind(String pendingNoteText)
{
if (!mNoteEditText.getText().toString().equals(pendingNoteText))
{
mNoteEditText.setText(pendingNoteText);
if (pendingNoteText != null)
mNoteEditText.setSelection(pendingNoteText.length());
}
mSendNoteButton.setEnabled(pendingNoteText != null && !pendingNoteText.trim().isEmpty());
} }
} }

View File

@@ -2,28 +2,39 @@ package app.organicmaps.editor;
import static app.organicmaps.sdk.util.Utils.getLocalizedFeatureType; import static app.organicmaps.sdk.util.Utils.getLocalizedFeatureType;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.base.BaseMwmRecyclerFragment; import app.organicmaps.base.BaseMwmRecyclerFragment;
import app.organicmaps.dialog.EditTextDialogFragment;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.editor.Editor; import app.organicmaps.sdk.editor.Editor;
import app.organicmaps.sdk.editor.OsmOAuth;
import app.organicmaps.sdk.editor.data.FeatureCategory; import app.organicmaps.sdk.editor.data.FeatureCategory;
import app.organicmaps.sdk.util.Language; import app.organicmaps.sdk.util.Language;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import app.organicmaps.widget.SearchToolbarController; import app.organicmaps.widget.SearchToolbarController;
import app.organicmaps.widget.ToolbarController; import app.organicmaps.widget.ToolbarController;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
public class FeatureCategoryFragment extends BaseMwmRecyclerFragment<FeatureCategoryAdapter> public class FeatureCategoryFragment
extends BaseMwmRecyclerFragment<FeatureCategoryAdapter> implements FeatureCategoryAdapter.FooterListener
{ {
private FeatureCategory mSelectedCategory; private FeatureCategory mSelectedCategory;
protected ToolbarController mToolbarController; protected ToolbarController mToolbarController;
private static final String NOTE_CONFIRMATION_SHOWN = "NoteConfirmationAlertWasShown";
private static String mPendingNoteText = "";
public interface FeatureCategoryListener public interface FeatureCategoryListener
{ {
@@ -104,4 +115,71 @@ public class FeatureCategoryFragment extends BaseMwmRecyclerFragment<FeatureCate
else if (getParentFragment() instanceof FeatureCategoryListener) else if (getParentFragment() instanceof FeatureCategoryListener)
((FeatureCategoryListener) getParentFragment()).onFeatureCategorySelected(category); ((FeatureCategoryListener) getParentFragment()).onFeatureCategorySelected(category);
} }
public String getPendingNoteText()
{
return mPendingNoteText;
}
@Override
public void onNoteTextChanged(String newText)
{
mPendingNoteText = newText;
}
@Override
public void onSendNoteClicked()
{
final double[] center = Framework.nativeGetScreenRectCenter();
final double lat = center[0];
final double lon = center[1];
if (!MwmApplication.prefs(requireContext().getApplicationContext()).contains(NOTE_CONFIRMATION_SHOWN))
{
showNoteConfirmationDialog(lat, lon, mPendingNoteText);
}
else
{
Editor.nativeCreateStandaloneNote(lat, lon, mPendingNoteText);
mPendingNoteText = "";
Toast.makeText(requireContext(), R.string.osm_note_toast, Toast.LENGTH_SHORT).show();
if (!OsmOAuth.isAuthorized())
{
final Intent intent = new Intent(requireActivity(), OsmLoginActivity.class);
startActivity(intent);
}
requireActivity().finish();
}
}
// Duplicate of showNoobDialog()
private void showNoteConfirmationDialog(double lat, double lon, String noteText)
{
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
.setTitle(R.string.editor_share_to_all_dialog_title)
.setMessage(getString(R.string.editor_share_to_all_dialog_message_1) + " "
+ getString(R.string.editor_share_to_all_dialog_message_2))
.setPositiveButton(android.R.string.ok,
(dlg, which) -> {
MwmApplication.prefs(requireContext().getApplicationContext())
.edit()
.putBoolean(NOTE_CONFIRMATION_SHOWN, true)
.apply();
Editor.nativeCreateStandaloneNote(lat, lon, noteText);
mPendingNoteText = "";
Toast.makeText(requireContext(), R.string.osm_note_toast, Toast.LENGTH_SHORT).show();
if (!OsmOAuth.isAuthorized())
{
final Intent intent = new Intent(requireActivity(), OsmLoginActivity.class);
startActivity(intent);
}
requireActivity().finish();
})
.setNegativeButton(R.string.cancel, null)
.show();
}
} }

View File

@@ -149,7 +149,7 @@ public class HoursMinutesPickerFragment extends BaseMwmDialogFragment
tabView.setText(getResources().getString(R.string.editor_time_to)); tabView.setText(getResources().getString(R.string.editor_time_to));
tabView.setTextColor(textColor); tabView.setTextColor(textColor);
mTabs.addTab(mTabs.newTab().setCustomView(tabView), true); mTabs.addTab(mTabs.newTab().setCustomView(tabView), true);
mTabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { mTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override @Override
public void onTabSelected(TabLayout.Tab tab) public void onTabSelected(TabLayout.Tab tab)
{ {

View File

@@ -13,9 +13,9 @@ import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.editor.data.TimeFormatUtils;
import app.organicmaps.sdk.editor.OpeningHours; import app.organicmaps.sdk.editor.OpeningHours;
import app.organicmaps.sdk.editor.data.HoursMinutes; import app.organicmaps.sdk.editor.data.HoursMinutes;
import app.organicmaps.editor.data.TimeFormatUtils;
import app.organicmaps.sdk.editor.data.Timespan; import app.organicmaps.sdk.editor.data.Timespan;
import app.organicmaps.sdk.editor.data.Timetable; import app.organicmaps.sdk.editor.data.Timetable;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;

View File

@@ -162,8 +162,8 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet
switch (mMode) switch (mMode)
{ {
case SIMPLE -> setMode(Mode.ADVANCED, filledTimetables); case SIMPLE -> setMode(Mode.ADVANCED, filledTimetables);
case ADVANCED -> setMode(Mode.SIMPLE, filledTimetables); case ADVANCED -> setMode(Mode.SIMPLE, filledTimetables);
} }
} }

View File

@@ -42,8 +42,8 @@ public class FaqFragment extends BaseMwmFragment
{ {
switch (which) switch (which)
{ {
case 0 -> sendGeneralFeedback(); case 0 -> sendGeneralFeedback();
case 1 -> reportBug(); case 1 -> reportBug();
} }
} }
}; };

View File

@@ -10,7 +10,6 @@ import androidx.core.content.IntentCompat;
import app.organicmaps.MwmActivity; import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.editor.OsmLoginActivity; import app.organicmaps.editor.OsmLoginActivity;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Map; import app.organicmaps.sdk.Map;
import app.organicmaps.sdk.api.ParsedRoutingData; import app.organicmaps.sdk.api.ParsedRoutingData;
@@ -20,6 +19,7 @@ import app.organicmaps.sdk.api.RoutePoint;
import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
import app.organicmaps.sdk.bookmarks.data.FeatureId; import app.organicmaps.sdk.bookmarks.data.FeatureId;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine; import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.util.StorageUtils; import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.concurrency.ThreadPool; import app.organicmaps.sdk.util.concurrency.ThreadPool;
@@ -78,67 +78,67 @@ public class Factory
switch (Framework.nativeParseAndSetApiUrl(uri.toString())) switch (Framework.nativeParseAndSetApiUrl(uri.toString()))
{ {
case RequestType.INCORRECT: return false; case RequestType.INCORRECT: return false;
case RequestType.MAP: case RequestType.MAP:
SearchEngine.INSTANCE.cancelInteractiveSearch(); SearchEngine.INSTANCE.cancelInteractiveSearch();
Map.executeMapApiRequest(); Map.executeMapApiRequest();
return true; return true;
case RequestType.ROUTE: case RequestType.ROUTE:
SearchEngine.INSTANCE.cancelInteractiveSearch(); SearchEngine.INSTANCE.cancelInteractiveSearch();
final ParsedRoutingData data = Framework.nativeGetParsedRoutingData(); final ParsedRoutingData data = Framework.nativeGetParsedRoutingData();
RoutingController.get().setRouterType(data.mRouterType); RoutingController.get().setRouterType(data.mRouterType);
final RoutePoint from = data.mPoints[0]; final RoutePoint from = data.mPoints[0];
final RoutePoint to = data.mPoints[1]; final RoutePoint to = data.mPoints[1];
RoutingController.get().prepare( RoutingController.get().prepare(
MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, from.mName, "", from.mLat, from.mLon), MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, from.mName, "", from.mLat, from.mLon),
MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, to.mName, "", to.mLat, to.mLon)); MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, to.mName, "", to.mLat, to.mLon));
return true; return true;
case RequestType.SEARCH: case RequestType.SEARCH:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{ {
SearchEngine.INSTANCE.cancelInteractiveSearch(); Framework.nativeStopLocationFollow();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest(); Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
final double[] latlon = Framework.nativeGetParsedCenterLatLon(); // We need to update viewport for search api manually because of drape engine
if (latlon != null) // will not notify subscribers when search activity is shown.
{ if (!request.mIsSearchOnMap)
Framework.nativeStopLocationFollow(); Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
// We need to update viewport for search api manually because of drape engine
// will not notify subscribers when search activity is shown.
if (!request.mIsSearchOnMap)
Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
}
SearchActivity.start(target, request.mQuery, request.mLocale, request.mIsSearchOnMap);
return true;
} }
case RequestType.CROSSHAIR: SearchActivity.start(target, request.mQuery, request.mLocale, request.mIsSearchOnMap);
return true;
}
case RequestType.CROSSHAIR:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
target.showPositionChooserForAPI(Framework.nativeGetParsedAppName());
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{ {
SearchEngine.INSTANCE.cancelInteractiveSearch(); Framework.nativeStopLocationFollow();
target.showPositionChooserForAPI(Framework.nativeGetParsedAppName()); Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{
Framework.nativeStopLocationFollow();
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
}
return true;
}
case RequestType.OAUTH2:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
final String oauth2code = Framework.nativeGetParsedOAuth2Code();
OsmLoginActivity.OAuth2Callback(target, oauth2code);
return true;
} }
// Menu and Settings url types should be implemented to support deeplinking. return true;
case RequestType.MENU: }
case RequestType.SETTINGS: case RequestType.OAUTH2:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
final String oauth2code = Framework.nativeGetParsedOAuth2Code();
OsmLoginActivity.OAuth2Callback(target, oauth2code);
return true;
}
// Menu and Settings url types should be implemented to support deeplinking.
case RequestType.MENU:
case RequestType.SETTINGS:
} }
return false; return false;

View File

@@ -42,26 +42,26 @@ public class LayerBottomSheetItem
int buttonTextResource = R.string.layers_title; int buttonTextResource = R.string.layers_title;
switch (mode) switch (mode)
{ {
case OUTDOORS: case OUTDOORS:
disabledResource = R.attr.outdoorsMenuDisabled; disabledResource = R.attr.outdoorsMenuDisabled;
enabledResource = R.attr.outdoorsMenuEnabled; enabledResource = R.attr.outdoorsMenuEnabled;
buttonTextResource = R.string.button_layer_outdoor; buttonTextResource = R.string.button_layer_outdoor;
break; break;
case SUBWAY: case SUBWAY:
disabledResource = R.attr.subwayMenuDisabled; disabledResource = R.attr.subwayMenuDisabled;
enabledResource = R.attr.subwayMenuEnabled; enabledResource = R.attr.subwayMenuEnabled;
buttonTextResource = R.string.subway; buttonTextResource = R.string.subway;
break; break;
case ISOLINES: case ISOLINES:
disabledResource = R.attr.isoLinesMenuDisabled; disabledResource = R.attr.isoLinesMenuDisabled;
enabledResource = R.attr.isoLinesMenuEnabled; enabledResource = R.attr.isoLinesMenuEnabled;
buttonTextResource = R.string.button_layer_isolines; buttonTextResource = R.string.button_layer_isolines;
break; break;
case TRAFFIC: case TRAFFIC:
disabledResource = R.attr.trafficMenuDisabled; disabledResource = R.attr.trafficMenuDisabled;
enabledResource = R.attr.trafficMenuEnabled; enabledResource = R.attr.trafficMenuEnabled;
buttonTextResource = R.string.button_layer_traffic; buttonTextResource = R.string.button_layer_traffic;
break; break;
} }
int disabled = ThemeUtils.getResource(mContext, disabledResource); int disabled = ThemeUtils.getResource(mContext, disabledResource);
int enabled = ThemeUtils.getResource(mContext, enabledResource); int enabled = ThemeUtils.getResource(mContext, enabledResource);

View File

@@ -29,7 +29,7 @@ public class LayersButton extends FloatingActionButton
{ {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (mAreLayersActive) if (mAreLayersActive)
mergeDrawableStates(drawableState, new int[] {R.attr.layers_enabled}); mergeDrawableStates(drawableState, new int[] {R.attr.state_layers_enabled});
return drawableState; return drawableState;
} }

View File

@@ -16,6 +16,7 @@ import android.view.ViewTreeObserver;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.OptIn; import androidx.annotation.OptIn;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@@ -26,7 +27,6 @@ import app.organicmaps.MwmActivity;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.leftbutton.LeftButton; import app.organicmaps.leftbutton.LeftButton;
import app.organicmaps.leftbutton.LeftToggleButton; import app.organicmaps.leftbutton.LeftToggleButton;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.downloader.MapManager; import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.downloader.UpdateInfo; import app.organicmaps.sdk.downloader.UpdateInfo;
@@ -34,6 +34,7 @@ import app.organicmaps.sdk.location.TrackRecorder;
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
import app.organicmaps.sdk.maplayer.subway.SubwayManager; import app.organicmaps.sdk.maplayer.subway.SubwayManager;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager; import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.ThemeUtils; import app.organicmaps.util.ThemeUtils;
@@ -230,21 +231,21 @@ public class MapButtonsController extends Fragment
return; return;
switch (button) switch (button)
{ {
case zoom: UiUtils.showIf(show && Config.showZoomButtons(), buttonView); break; case zoom: UiUtils.showIf(show && Config.showZoomButtons(), buttonView); break;
case toggleMapLayer: case toggleMapLayer:
if (mToggleMapLayerButton != null) if (mToggleMapLayerButton != null)
UiUtils.showIf(show && !isInNavigationMode(), mToggleMapLayerButton); UiUtils.showIf(show && !isInNavigationMode(), mToggleMapLayerButton);
break; break;
case myPosition: case myPosition:
if (mNavMyPosition != null) if (mNavMyPosition != null)
mNavMyPosition.showButton(show); mNavMyPosition.showButton(show);
break; break;
case search: mSearchWheel.show(show); case search: mSearchWheel.show(show);
case bookmarks: case bookmarks:
case menu: UiUtils.showIf(show, buttonView); break; case menu: UiUtils.showIf(show, buttonView); break;
case trackRecordingStatus: case trackRecordingStatus:
UiUtils.showIf(show, buttonView); UiUtils.showIf(show, buttonView);
animateIconBlinking(show, (FloatingActionButton) buttonView); animateIconBlinking(show, (FloatingActionButton) buttonView);
} }
} }
@@ -295,7 +296,7 @@ public class MapButtonsController extends Fragment
mBadgeDrawable.setMaxCharacterCount(0); mBadgeDrawable.setMaxCharacterCount(0);
mBadgeDrawable.setHorizontalOffset(verticalOffset); mBadgeDrawable.setHorizontalOffset(verticalOffset);
mBadgeDrawable.setVerticalOffset(dpToPx(9, context)); mBadgeDrawable.setVerticalOffset(dpToPx(9, context));
mBadgeDrawable.setBackgroundColor(getResources().getColor(R.color.base_accent)); mBadgeDrawable.setBackgroundColor(ContextCompat.getColor(context, R.color.base_accent));
mBadgeDrawable.setVisible(enable); mBadgeDrawable.setVisible(enable);
BadgeUtils.attachBadgeDrawable(mBadgeDrawable, menuButton); BadgeUtils.attachBadgeDrawable(mBadgeDrawable, menuButton);
} }

View File

@@ -14,7 +14,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.routing.RoutingController; import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine; import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.sdk.util.concurrency.UiThread;
@@ -215,7 +215,7 @@ public class SearchWheel implements View.OnClickListener
final SearchOption searchOption = mMapButtonsViewModel.getSearchOption().getValue(); final SearchOption searchOption = mMapButtonsViewModel.getSearchOption().getValue();
mSearchButton.setImageDrawable(Graphics.tint( mSearchButton.setImageDrawable(Graphics.tint(
mSearchButton.getContext(), searchOption == null ? R.drawable.ic_routing_search_off : searchOption.mDrawableOff, mSearchButton.getContext(), searchOption == null ? R.drawable.ic_routing_search_off : searchOption.mDrawableOff,
androidx.appcompat.R.attr.colorAccent)); com.google.android.material.R.attr.colorSecondary));
} }
@Override @Override

View File

@@ -14,6 +14,7 @@ import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.maplayer.Mode; import app.organicmaps.sdk.maplayer.Mode;
import app.organicmaps.sdk.util.SharedPropertiesUtils; import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
import app.organicmaps.widget.recycler.SpanningLinearLayoutManager; import app.organicmaps.widget.recycler.SpanningLinearLayoutManager;
@@ -72,6 +73,9 @@ public class ToggleMapLayerFragment extends Fragment
Context context = v.getContext(); Context context = v.getContext();
SharedPropertiesUtils.setLayerMarkerShownForLayerMode(mode); SharedPropertiesUtils.setLayerMarkerShownForLayerMode(mode);
mode.setEnabled(context, !mode.isEnabled(context)); mode.setEnabled(context, !mode.isEnabled(context));
// TODO: dirty hack :(
if (mode == Mode.OUTDOORS)
ThemeSwitcher.INSTANCE.restart(true);
mAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
mMapButtonsController.updateLayerButton(); mMapButtonsController.updateLayerButton();
if (MwmApplication.from(context).getIsolinesManager().shouldShowNotification()) if (MwmApplication.from(context).getIsolinesManager().shouldShowNotification())

View File

@@ -11,10 +11,13 @@ import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.adapter.DisabledChildSimpleExpandableListAdapter; import app.organicmaps.adapter.DisabledChildSimpleExpandableListAdapter;
import app.organicmaps.base.BaseMwmDialogFragment; import app.organicmaps.base.BaseMwmDialogFragment;
import app.organicmaps.sdk.downloader.CountryItem; import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@@ -121,7 +124,7 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment
} }
listView.setAdapter(buildAdapter()); listView.setAdapter(buildAdapter());
listView.setChildDivider(new ColorDrawable(getResources().getColor(android.R.color.transparent))); listView.setChildDivider(new ColorDrawable(ContextCompat.getColor(requireContext(), android.R.color.transparent)));
UiUtils.waitLayout(listView, () -> { UiUtils.waitLayout(listView, () -> {
final int width = listView.getWidth(); final int width = listView.getWidth();

View File

@@ -11,14 +11,14 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@@ -63,26 +63,26 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
switch (mRoutePoints.get(position).mPointType) switch (mRoutePoints.get(position).mPointType)
{ {
case Start: // Starting point. case Start: // Starting point.
if (mRoutePoints.get(position).mIsMyPosition) if (mRoutePoints.get(position).mIsMyPosition)
iconId = R.drawable.ic_location_arrow_blue; iconId = R.drawable.ic_location_arrow_blue;
else else
iconId = R.drawable.route_point_start; iconId = R.drawable.route_point_start;
break; break;
case Intermediate: // Intermediate stop. case Intermediate: // Intermediate stop.
TypedArray iconArray = mContext.getResources().obtainTypedArray(R.array.route_stop_icons); TypedArray iconArray = mContext.getResources().obtainTypedArray(R.array.route_stop_icons);
iconId = iconArray.getResourceId(mRoutePoints.get(position).mIntermediateIndex, R.drawable.route_point_20); iconId = iconArray.getResourceId(mRoutePoints.get(position).mIntermediateIndex, R.drawable.route_point_20);
iconArray.recycle(); iconArray.recycle();
break; break;
case Finish: // Destination point. case Finish: // Destination point.
iconId = R.drawable.route_point_finish; iconId = R.drawable.route_point_finish;
break; break;
default: // Unknown route type. default: // Unknown route type.
iconId = R.drawable.warning_icon; iconId = R.drawable.warning_icon;
break; break;
} }
// Set icon widget. // Set icon widget.

View File

@@ -22,6 +22,7 @@ import app.organicmaps.R;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialog;

View File

@@ -18,6 +18,7 @@ import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router; import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager; import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.CarDirection; import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;

View File

@@ -35,6 +35,7 @@ import app.organicmaps.R;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.location.LocationHelper; import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.location.LocationListener; import app.organicmaps.sdk.location.LocationListener;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.sound.MediaPlayerWrapper; import app.organicmaps.sdk.sound.MediaPlayerWrapper;
import app.organicmaps.sdk.sound.TtsPlayer; import app.organicmaps.sdk.sound.TtsPlayer;

View File

@@ -23,76 +23,76 @@ public class ResultCodesHelper
int cancelBtnResId = android.R.string.cancel; int cancelBtnResId = android.R.string.cancel;
switch (errorCode) switch (errorCode)
{ {
case ResultCodes.NO_POSITION: case ResultCodes.NO_POSITION:
if (!MwmApplication.from(context).getLocationHelper().isActive()) if (!MwmApplication.from(context).getLocationHelper().isActive())
{ {
titleRes = R.string.dialog_routing_location_turn_on; titleRes = R.string.dialog_routing_location_turn_on;
messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on)); messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on));
} }
else else
{ {
titleRes = R.string.dialog_routing_check_gps; titleRes = R.string.dialog_routing_check_gps;
messages.add(resources.getString(R.string.dialog_routing_error_location_not_found)); messages.add(resources.getString(R.string.dialog_routing_error_location_not_found));
messages.add(resources.getString(R.string.dialog_routing_location_turn_wifi)); messages.add(resources.getString(R.string.dialog_routing_location_turn_wifi));
} }
break; break;
case ResultCodes.INCONSISTENT_MWM_ROUTE: case ResultCodes.INCONSISTENT_MWM_ROUTE:
case ResultCodes.ROUTING_FILE_NOT_EXIST: case ResultCodes.ROUTING_FILE_NOT_EXIST:
titleRes = R.string.routing_download_maps_along;
messages.add(resources.getString(R.string.routing_requires_all_map));
break;
case ResultCodes.START_POINT_NOT_FOUND:
titleRes = R.string.dialog_routing_change_start;
messages.add(resources.getString(R.string.dialog_routing_start_not_determined));
messages.add(resources.getString(R.string.dialog_routing_select_closer_start));
break;
case ResultCodes.END_POINT_NOT_FOUND:
titleRes = R.string.dialog_routing_change_end;
messages.add(resources.getString(R.string.dialog_routing_end_not_determined));
messages.add(resources.getString(R.string.dialog_routing_select_closer_end));
break;
case ResultCodes.INTERMEDIATE_POINT_NOT_FOUND:
titleRes = R.string.dialog_routing_change_intermediate;
messages.add(resources.getString(R.string.dialog_routing_intermediate_not_determined));
break;
case ResultCodes.DIFFERENT_MWM:
messages.add(resources.getString(R.string.routing_failed_cross_mwm_building));
break;
case ResultCodes.FILE_TOO_OLD:
titleRes = R.string.downloader_update_maps;
messages.add(resources.getString(R.string.downloader_mwm_migration_dialog));
break;
case ResultCodes.TRANSIT_ROUTE_NOT_FOUND_NO_NETWORK:
messages.add(resources.getString(R.string.transit_not_found));
break;
case ResultCodes.TRANSIT_ROUTE_NOT_FOUND_TOO_LONG_PEDESTRIAN:
titleRes = R.string.dialog_pedestrian_route_is_long_header;
messages.add(resources.getString(R.string.dialog_pedestrian_route_is_long_message));
cancelBtnResId = R.string.ok;
break;
case ResultCodes.ROUTE_NOT_FOUND:
case ResultCodes.ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR:
if (missingCount == 0)
{
titleRes = R.string.dialog_routing_unable_locate_route;
messages.add(resources.getString(R.string.dialog_routing_cant_build_route));
messages.add(resources.getString(R.string.dialog_routing_change_start_or_end));
}
else
{
titleRes = R.string.routing_download_maps_along; titleRes = R.string.routing_download_maps_along;
messages.add(resources.getString(R.string.routing_requires_all_map)); messages.add(resources.getString(R.string.routing_requires_all_map));
break; }
case ResultCodes.START_POINT_NOT_FOUND: break;
titleRes = R.string.dialog_routing_change_start; case ResultCodes.INTERNAL_ERROR:
messages.add(resources.getString(R.string.dialog_routing_start_not_determined)); titleRes = R.string.dialog_routing_system_error;
messages.add(resources.getString(R.string.dialog_routing_select_closer_start)); messages.add(resources.getString(R.string.dialog_routing_application_error));
break; messages.add(resources.getString(R.string.dialog_routing_try_again));
case ResultCodes.END_POINT_NOT_FOUND: break;
titleRes = R.string.dialog_routing_change_end; case ResultCodes.NEED_MORE_MAPS:
messages.add(resources.getString(R.string.dialog_routing_end_not_determined)); titleRes = R.string.dialog_routing_download_and_build_cross_route;
messages.add(resources.getString(R.string.dialog_routing_select_closer_end)); messages.add(resources.getString(R.string.dialog_routing_download_cross_route));
break; break;
case ResultCodes.INTERMEDIATE_POINT_NOT_FOUND:
titleRes = R.string.dialog_routing_change_intermediate;
messages.add(resources.getString(R.string.dialog_routing_intermediate_not_determined));
break;
case ResultCodes.DIFFERENT_MWM:
messages.add(resources.getString(R.string.routing_failed_cross_mwm_building));
break;
case ResultCodes.FILE_TOO_OLD:
titleRes = R.string.downloader_update_maps;
messages.add(resources.getString(R.string.downloader_mwm_migration_dialog));
break;
case ResultCodes.TRANSIT_ROUTE_NOT_FOUND_NO_NETWORK:
messages.add(resources.getString(R.string.transit_not_found));
break;
case ResultCodes.TRANSIT_ROUTE_NOT_FOUND_TOO_LONG_PEDESTRIAN:
titleRes = R.string.dialog_pedestrian_route_is_long_header;
messages.add(resources.getString(R.string.dialog_pedestrian_route_is_long_message));
cancelBtnResId = R.string.ok;
break;
case ResultCodes.ROUTE_NOT_FOUND:
case ResultCodes.ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR:
if (missingCount == 0)
{
titleRes = R.string.dialog_routing_unable_locate_route;
messages.add(resources.getString(R.string.dialog_routing_cant_build_route));
messages.add(resources.getString(R.string.dialog_routing_change_start_or_end));
}
else
{
titleRes = R.string.routing_download_maps_along;
messages.add(resources.getString(R.string.routing_requires_all_map));
}
break;
case ResultCodes.INTERNAL_ERROR:
titleRes = R.string.dialog_routing_system_error;
messages.add(resources.getString(R.string.dialog_routing_application_error));
messages.add(resources.getString(R.string.dialog_routing_try_again));
break;
case ResultCodes.NEED_MORE_MAPS:
titleRes = R.string.dialog_routing_download_and_build_cross_route;
messages.add(resources.getString(R.string.dialog_routing_download_cross_route));
break;
} }
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View File

@@ -32,6 +32,7 @@ import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut; import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.TransitRouteInfo; import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.routing.TransitStepInfo; import app.organicmaps.sdk.routing.TransitStepInfo;
@@ -39,6 +40,7 @@ import app.organicmaps.sdk.util.Distance;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.Graphics; import app.organicmaps.util.Graphics;
import app.organicmaps.util.ThemeUtils; import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.DotDividerItemDecoration; import app.organicmaps.widget.recycler.DotDividerItemDecoration;
import app.organicmaps.widget.recycler.MultilineLayoutManager; import app.organicmaps.widget.recycler.MultilineLayoutManager;
import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.imageview.ShapeableImageView;
@@ -117,10 +119,11 @@ final class RoutingBottomMenuController implements View.OnClickListener
private RoutingBottomMenuController(@NonNull Activity context, @NonNull View altitudeChartFrame, private RoutingBottomMenuController(@NonNull Activity context, @NonNull View altitudeChartFrame,
@NonNull View timeElevationLine, @NonNull View transitFrame, @NonNull View timeElevationLine, @NonNull View transitFrame,
@NonNull MaterialTextView error, @NonNull Button start, @NonNull ImageView altitudeChart, @NonNull MaterialTextView error, @NonNull Button start,
@NonNull MaterialTextView time, @NonNull MaterialTextView altitudeDifference, @NonNull ImageView altitudeChart, @NonNull MaterialTextView time,
@NonNull TextView timeVehicle, @Nullable MaterialTextView arrival, @NonNull MaterialTextView altitudeDifference, @NonNull TextView timeVehicle,
@NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener) @Nullable MaterialTextView arrival, @NonNull View actionFrame,
@Nullable RoutingBottomMenuListener listener)
{ {
mContext = context; mContext = context;
mAltitudeChartFrame = altitudeChartFrame; mAltitudeChartFrame = altitudeChartFrame;
@@ -191,8 +194,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
scrollToBottom(rv); scrollToBottom(rv);
MaterialTextView totalTimeView = mTransitFrame.findViewById(R.id.total_time); MaterialTextView totalTimeView = mTransitFrame.findViewById(R.id.total_time);
totalTimeView.setText( totalTimeView.setText(Utils.formatRoutingTime(mContext, info.getTotalTime(), R.dimen.text_size_routing_number));
RoutingController.formatRoutingTime(mContext, info.getTotalTime(), R.dimen.text_size_routing_number));
View dotView = mTransitFrame.findViewById(R.id.dot); View dotView = mTransitFrame.findViewById(R.id.dot);
View pedestrianIcon = mTransitFrame.findViewById(R.id.pedestrian_icon); View pedestrianIcon = mTransitFrame.findViewById(R.id.pedestrian_icon);
MaterialTextView distanceView = mTransitFrame.findViewById(R.id.total_distance); MaterialTextView distanceView = mTransitFrame.findViewById(R.id.total_distance);
@@ -261,9 +263,9 @@ final class RoutingBottomMenuController implements View.OnClickListener
{ {
UiUtils.show(mActionButton); UiUtils.show(mActionButton);
Drawable icon = ContextCompat.getDrawable(mContext, R.drawable.ic_location_crosshair); Drawable icon = ContextCompat.getDrawable(mContext, R.drawable.ic_location_crosshair);
int colorAccent = ContextCompat.getColor( int colorSecondary = ContextCompat.getColor(
mContext, UiUtils.getStyledResourceId(mContext, androidx.appcompat.R.attr.colorAccent)); mContext, UiUtils.getStyledResourceId(mContext, com.google.android.material.R.attr.colorSecondary));
mActionIcon.setImageDrawable(Graphics.tint(icon, colorAccent)); mActionIcon.setImageDrawable(Graphics.tint(icon, colorSecondary));
} }
else else
{ {
@@ -382,7 +384,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
if (mArrival != null) if (mArrival != null)
{ {
String arrivalTime = RoutingController.formatArrivalTime(rinfo.totalTimeInSeconds); String arrivalTime = Utils.formatArrivalTime(rinfo.totalTimeInSeconds);
mArrival.setText(arrivalTime); mArrival.setText(arrivalTime);
} }
} }
@@ -400,7 +402,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
{ {
CharSequence time = CharSequence time =
RoutingController.formatRoutingTime(context, routingInfo.totalTimeInSeconds, R.dimen.text_size_routing_number); Utils.formatRoutingTime(context, routingInfo.totalTimeInSeconds, R.dimen.text_size_routing_number);
SpannableStringBuilder builder = new SpannableStringBuilder(); SpannableStringBuilder builder = new SpannableStringBuilder();
initTimeBuilderSequence(context, time, builder); initTimeBuilderSequence(context, time, builder);

View File

@@ -13,11 +13,11 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentFactory; import androidx.fragment.app.FragmentFactory;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.downloader.CountryItem; import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager; import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.textview.MaterialTextView;
public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment
{ {

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