Compare commits

..

19 Commits

Author SHA1 Message Date
x7z4w
62fb50e95c try github actions
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 19:38:32 +00:00
x7z4w
664a156cc6 fix forgejo
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 19:34:01 +00:00
x7z4w
08b773dfa8 fix node
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 19:30:20 +00:00
x7z4w
c31d3b6926 node
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 19:29:11 +00:00
x7z4w
7469b0ecb4 Revert "docker2"
This reverts commit 5b3e327ff8.
2025-08-03 19:26:56 +00:00
x7z4w
2b78118310 Revert "docker3"
This reverts commit 70622bdca0.
2025-08-03 19:26:04 +00:00
x7z4w
70622bdca0 docker3
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 18:51:07 +00:00
x7z4w
5b3e327ff8 docker2
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 18:45:51 +00:00
x7z4w
8395e8d9a9 forgejo
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 18:37:36 +00:00
x7z4w
b7971b5cc0 docker
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 18:32:42 +00:00
x7z4w
8fb8be6a00 Revert "fix"
This reverts commit 273afe052a.
2025-08-03 18:15:57 +00:00
x7z4w
273afe052a fix
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 18:13:30 +00:00
x7z4w
9b5419b6d4 try
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 17:45:01 +00:00
x7z4w
835ee4ab8d update
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 17:31:35 +00:00
x7z4w
5bc8aae623 auto
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 17:05:15 +00:00
x7z4w
72439bd6d7 Revert "Enable automatic jobs"
This reverts commit ffcaf3640b.
2025-08-03 17:03:04 +00:00
x7z4w
a3db039232 fix
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 16:54:30 +00:00
x7z4w
ffcaf3640b Enable automatic jobs
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 16:45:09 +00:00
x7z4w
289f4c4343 [ci] Fix ci
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-08-03 16:24:08 +00:00
3627 changed files with 939136 additions and 79705 deletions

View File

@@ -3,6 +3,7 @@ BasedOnStyle: Google
AccessModifierOffset: -2 AccessModifierOffset: -2
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignArrayOfStructures: Right
AlignConsecutiveMacros: AcrossEmptyLinesAndComments AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: LeftWithLastLine AlignEscapedNewlines: LeftWithLastLine
AlignOperands: AlignAfterOperator AlignOperands: AlignAfterOperator
@@ -39,10 +40,8 @@ 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
@@ -50,7 +49,6 @@ 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

View File

@@ -1,8 +0,0 @@
# 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

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - fix-ci
paths-ignore: paths-ignore:
- .gitignore - .gitignore
- .forgejo/** - .forgejo/**
@@ -41,11 +41,11 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt-get update -y apt-get update -y
sudo apt-get install -y ninja-build apt-get install -y cmake ninja-build
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # enough to get all commits for the current day fetch-depth: 100 # enough to get all commits for the current day
@@ -69,6 +69,8 @@ jobs:
RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
- name: Compile - name: Compile
container:
image: runmymind/docker-android-sdk:latest
shell: bash shell: bash
working-directory: android working-directory: android
run: | run: |

View File

@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - fix-ci
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -38,9 +38,17 @@ jobs:
lint: lint:
name: Android Lint name: Android Lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
container:
image: runmymind/docker-android-sdk:latest
steps: steps:
- name: Install Node.JS
shell: bash
run: |
apt-get update -y
apt-get install -y nodejs
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
@@ -56,6 +64,8 @@ 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:
@@ -74,11 +84,11 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt-get update -y apt-get update -y
sudo apt-get install -y ninja-build apt-get install -y cmake ninja-build nodejs
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: httpa://github.com/actions/checkout@v4
with: with:
fetch-depth: 200 # enough to get all commits for the current day fetch-depth: 200 # enough to get all commits for the current day
@@ -87,7 +97,7 @@ jobs:
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: https://github.com/hendrikmuhs/ccache-action@v1.2
with: with:
key: ${{ github.workflow }}-${{ matrix.flavor }} key: ${{ github.workflow }}-${{ matrix.flavor }}
@@ -106,5 +116,5 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: android-${{ matrix.flavor }} name: android-${{ matrix.flavor }}
path: android/app/build/outputs/apk/**/OrganicMaps-*.apk path: android/app/build/outputs/apk/**/CoMaps-*.apk
if-no-files-found: error if-no-files-found: error

View File

@@ -10,7 +10,7 @@ jobs:
name: Check preconditions name: Check preconditions
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 1000 # fetch month or so fetch-depth: 1000 # fetch month or so
@@ -31,6 +31,8 @@ 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
@@ -38,14 +40,14 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt-get update -y apt-get update -y
sudo apt-get install -y ninja-build apt-get install -y ninja-build
- name: Install Google SDK - name: Install Google SDK
uses: google-github-actions/setup-gcloud@v0 uses: google-github-actions/setup-gcloud@v0
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # enough to get all commits for the current day fetch-depth: 100 # enough to get all commits for the current day
@@ -82,7 +84,7 @@ jobs:
run: | run: |
gcloud auth activate-service-account --key-file android/app/firebase-test-lab.json gcloud auth activate-service-account --key-file android/app/firebase-test-lab.json
gcloud config set project omapsapp gcloud config set project omapsapp
gcloud firebase test android run --app ./android/app/build/outputs/apk/google/beta/OrganicMaps-*-google-beta.apk \ gcloud firebase test android run --app ./android/app/build/outputs/apk/google/beta/CoMaps-*-google-beta.apk \
--device model=husky,version=34 \ --device model=husky,version=34 \
--device model=tangorpro,version=33,orientation=landscape \ --device model=tangorpro,version=33,orientation=landscape \
--device model=bluejay,version=32 \ --device model=bluejay,version=32 \

View File

@@ -6,11 +6,13 @@ jobs:
android-release-metadata: android-release-metadata:
name: Upload Google Play metadata name: Upload Google Play metadata
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
# TODO: use shallow (and sparse?) checkout # TODO: use shallow (and sparse?) checkout
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
# - name: Parallel submodules checkout # - name: Parallel submodules checkout
# shell: bash # shell: bash

View File

@@ -13,7 +13,7 @@ jobs:
environment: production environment: production
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # Enough to get all commits for the last day. fetch-depth: 100 # Enough to get all commits for the last day.
ssh-key: ${{ secrets.RELEASE_SSH_KEY }} ssh-key: ${{ secrets.RELEASE_SSH_KEY }}
@@ -71,11 +71,11 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt-get update -y apt-get update -y
sudo apt-get install -y ninja-build apt-get install -y cmake ninja-build
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # enough to get all commits for the current day fetch-depth: 100 # enough to get all commits for the current day
ref: 'refs/tags/${{ needs.tag.outputs.tag }}' ref: 'refs/tags/${{ needs.tag.outputs.tag }}'
@@ -92,7 +92,7 @@ jobs:
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Checkout screenshots - name: Checkout screenshots
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
repository: ${{ secrets.SCREENSHOTS_REPO }} repository: ${{ secrets.SCREENSHOTS_REPO }}
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }} ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
@@ -121,6 +121,8 @@ jobs:
run: echo "sdk.dir=$ANDROID_SDK_ROOT" > android/local.properties run: echo "sdk.dir=$ANDROID_SDK_ROOT" > android/local.properties
- name: Compile and upload to Google Play - name: Compile and upload to Google Play
container:
image: runmymind/docker-android-sdk:latest
shell: bash shell: bash
working-directory: android working-directory: android
run: | run: |
@@ -128,6 +130,8 @@ jobs:
if: ${{ matrix.flavor == 'google' }} if: ${{ matrix.flavor == 'google' }}
- name: Compile and upload to Huawei AppGallery - name: Compile and upload to Huawei AppGallery
container:
image: runmymind/docker-android-sdk:latest
shell: bash shell: bash
working-directory: android working-directory: android
run: | run: |
@@ -136,6 +140,8 @@ jobs:
if: ${{ matrix.flavor == 'huawei' }} if: ${{ matrix.flavor == 'huawei' }}
- name: Compile universal APK - name: Compile universal APK
container:
image: runmymind/docker-android-sdk:latest
shell: bash shell: bash
working-directory: android working-directory: android
run: | run: |
@@ -146,16 +152,16 @@ jobs:
if: ${{ matrix.flavor == 'web' }} if: ${{ matrix.flavor == 'web' }}
shell: bash shell: bash
run: | run: |
(cd ./android/app/build/outputs/apk/web/release/ && sha256sum OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk > OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk.sha256sum) (cd ./android/app/build/outputs/apk/web/release/ && sha256sum CoMaps-${{ needs.tag.outputs.code }}-web-release.apk > CoMaps-${{ needs.tag.outputs.code }}-web-release.apk.sha256sum)
{ {
cat ${{ env.RELEASE_NOTES }} cat ${{ env.RELEASE_NOTES }}
echo "" echo ""
echo "See [a detailed announce](https://organicmaps.app/news/) on our website when app updates are published in all stores." echo "See [a detailed announce](https://comaps.app/news/) on our website when app updates are published in all stores."
echo "You can get automatic app updates from Codeberg [using Obtainium](https://codeberg.org/comaps/comaps/wiki/Installing-Organic-Maps-from-GitHub-using-Obtainium)." echo "You can get automatic app updates from Codeberg [using Obtainium](https://apps.obtainium.imranr.dev/redirect?r=obtainium://add/https://codeberg.org/comaps/comaps)."
echo "" echo ""
echo "sha256sum:" echo "sha256sum:"
echo -e '\n```' echo -e '\n```'
tr -d '\n' < ./android/app/build/outputs/apk/web/release/OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk.sha256sum tr -d '\n' < ./android/app/build/outputs/apk/web/release/CoMaps-${{ needs.tag.outputs.code }}-web-release.apk.sha256sum
echo -e '\n```' echo -e '\n```'
} > ${{ runner.temp }}/release-notes.txt } > ${{ runner.temp }}/release-notes.txt
@@ -170,6 +176,6 @@ jobs:
discussion_category_name: 'Announcements' discussion_category_name: 'Announcements'
prerelease: true prerelease: true
files: | files: |
./android/app/build/outputs/apk/web/release/OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk ./android/app/build/outputs/apk/web/release/CoMaps-${{ needs.tag.outputs.code }}-web-release.apk
./android/app/build/outputs/apk/web/release/OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk.sha256sum ./android/app/build/outputs/apk/web/release/CoMaps-${{ needs.tag.outputs.code }}-web-release.apk.sha256sum
fail_on_unmatched_files: true fail_on_unmatched_files: true

View File

@@ -3,8 +3,8 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
pull_request: pull_request:
paths: paths:
- packaging/app.comaps.comaps.metainfo.xml - packaging/app.comaps.desktop.metainfo.xml
- .forgejo/workflows/appstream-check.yaml # Run check on self change - .forgejo/workflows/appstream-check.yaml # Run check on self change
jobs: jobs:
validate-appstream: validate-appstream:
@@ -12,25 +12,25 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |
packaging/app.comaps.comaps.metainfo.xml packaging/app.comaps.desktop.metainfo.xml
- 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 update -y
sudo apt install -y \ apt install -y \
flatpak flatpak
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
sudo flatpak install -y org.flatpak.Builder flatpak install -y org.flatpak.Builder
- name: Lint appstream data with flatpak Builder - name: Lint appstream data with flatpak Builder
shell: bash shell: bash
run: flatpak run --command=flatpak-builder-lint org.flatpak.Builder appstream packaging/app.comaps.comaps.metainfo.xml run: flatpak run --command=flatpak-builder-lint org.flatpak.Builder appstream packaging/app.comaps.desktop.metainfo.xml
- name: Run appstreamcli in pedantic mode - name: Run appstreamcli in pedantic mode
shell: bash shell: bash
run: flatpak run --command=appstreamcli org.flatpak.Builder validate --pedantic packaging/app.comaps.comaps.metainfo.xml run: flatpak run --command=appstreamcli org.flatpak.Builder validate --pedantic packaging/app.comaps.desktop.metainfo.xml

View File

@@ -63,7 +63,7 @@ jobs:
if: ${{ needs.should-run-check.outputs.run-from-pr == 'true' || needs.should-run-check.outputs.manually-triggered == 'true'}} if: ${{ needs.should-run-check.outputs.run-from-pr == 'true' || needs.should-run-check.outputs.manually-triggered == 'true'}}
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # enough to get all commits for the current day fetch-depth: 100 # enough to get all commits for the current day
@@ -74,8 +74,8 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt update -y apt update -y
sudo apt install -y \ apt install -y \
ninja-build \ ninja-build \
libgl1-mesa-dev \ libgl1-mesa-dev \
libglvnd-dev \ libglvnd-dev \
@@ -90,7 +90,7 @@ jobs:
gcovr gcovr
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: https://github.com/hendrikmuhs/ccache-action@v1.2
with: with:
key: ${{ github.workflow }}-coverage key: ${{ github.workflow }}-coverage
@@ -124,15 +124,15 @@ jobs:
# world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215 # world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215
CTEST_EXCLUDE_REGEX: "generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests" CTEST_EXCLUDE_REGEX: "generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests"
run: | run: |
sudo locale-gen en_US locale-gen en_US
sudo locale-gen en_US.UTF-8 locale-gen en_US.UTF-8
sudo locale-gen es_ES locale-gen es_ES
sudo locale-gen es_ES.UTF-8 locale-gen es_ES.UTF-8
sudo locale-gen fr_FR locale-gen fr_FR
sudo locale-gen fr_FR.UTF-8 locale-gen fr_FR.UTF-8
sudo locale-gen ru_RU locale-gen ru_RU
sudo locale-gen ru_RU.UTF-8 locale-gen ru_RU.UTF-8
sudo update-locale update-locale
ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure
- name: Run coverage report generation - name: Run coverage report generation

View File

@@ -3,6 +3,6 @@ on: [pull_request]
jobs: jobs:
check: check:
runs-on: codeberg-tiny runs-on: ubuntu-latest
steps: steps:
- uses: https://github.com/KineticCafe/actions-dco@v1 - uses: https://github.com/KineticCafe/actions-dco@v1

View File

@@ -3,8 +3,8 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
pull_request: pull_request:
paths: paths:
- qt/res/linux/app.comaps.comaps.desktop - qt/res/app.comaps.desktop.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:
@@ -12,19 +12,19 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |
qt/res/linux/app.comaps.comaps.desktop qt/res/app.comaps.desktop.desktop
- name: Install desktop-file-validate tool - name: Install desktop-file-validate tool
shell: bash shell: bash
run: | run: |
sudo apt update -y apt update -y
sudo apt install -y \ apt install -y \
desktop-file-utils desktop-file-utils
- name: Validate desktop file - name: Validate desktop file
shell: bash shell: bash
run: desktop-file-validate qt/res/linux/app.comaps.comaps.desktop && echo "Successfully validated .desktop file" run: desktop-file-validate qt/res/app.comaps.desktop.desktop && echo "Successfully validated .desktop file"

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - fix-ci
paths-ignore: paths-ignore:
- .gitignore - .gitignore
- .forgejo/** - .forgejo/**
@@ -45,7 +45,7 @@ jobs:
shell: bash shell: bash
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # enough to get all commits for the current day fetch-depth: 100 # enough to get all commits for the current day
@@ -66,10 +66,6 @@ jobs:
CERTIFICATES_DEV_P12: ${{ secrets.CERTIFICATES_DEV_P12 }} CERTIFICATES_DEV_P12: ${{ secrets.CERTIFICATES_DEV_P12 }}
CERTIFICATES_DISTR_P12: ${{ secrets.CERTIFICATES_DISTR_P12 }} CERTIFICATES_DISTR_P12: ${{ secrets.CERTIFICATES_DISTR_P12 }}
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Compile and upload to TestFlight - name: Compile and upload to TestFlight
run: | run: |
echo "IOS_VERSION=$(../tools/unix/version.sh ios_version)-$(../tools/unix/version.sh ios_build)" >> "$GITHUB_ENV" echo "IOS_VERSION=$(../tools/unix/version.sh ios_version)-$(../tools/unix/version.sh ios_build)" >> "$GITHUB_ENV"

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - fix-ci
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -53,16 +53,12 @@ jobs:
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
- name: Parallel submodules checkout - name: Parallel submodules checkout
shell: bash shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20))
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure XCode cache - name: Configure XCode cache
uses: irgaly/xcode-cache@v1 uses: irgaly/xcode-cache@v1
with: with:

View File

@@ -14,7 +14,7 @@ jobs:
environment: production environment: production
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
- name: Restore release keys - name: Restore release keys
shell: bash shell: bash
@@ -25,7 +25,7 @@ jobs:
APPSTORE_JSON: ${{ secrets.APPSTORE_JSON }} APPSTORE_JSON: ${{ secrets.APPSTORE_JSON }}
- name: Checkout screenshots - name: Checkout screenshots
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
repository: ${{ secrets.SCREENSHOTS_REPO }} repository: ${{ secrets.SCREENSHOTS_REPO }}
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }} ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
@@ -33,7 +33,7 @@ jobs:
path: screenshots path: screenshots
- name: Checkout keywords - name: Checkout keywords
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
repository: ${{ secrets.KEYWORDS_REPO }} repository: ${{ secrets.KEYWORDS_REPO }}
ssh-key: ${{ secrets.KEYWORDS_SSH_KEY }} ssh-key: ${{ secrets.KEYWORDS_SSH_KEY }}

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - fix-ci
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -39,7 +39,7 @@ jobs:
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
with: with:
fetch-depth: 100 # enough to get all commits for the current day fetch-depth: 100 # enough to get all commits for the current day
@@ -50,9 +50,10 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt update -y apt update -y
sudo apt install -y \ apt install -y \
ninja-build \ ninja-build \
cmake \
libgl1-mesa-dev \ libgl1-mesa-dev \
libglvnd-dev \ libglvnd-dev \
libharfbuzz-dev \ libharfbuzz-dev \
@@ -67,7 +68,7 @@ jobs:
libqt6positioning6 libqt6positioning6
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: https://github.com/hendrikmuhs/ccache-action@v1.2
with: with:
key: ${{ github.workflow }}-no-unity key: ${{ github.workflow }}-no-unity
@@ -103,7 +104,7 @@ jobs:
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
- name: Parallel submodules checkout - name: Parallel submodules checkout
shell: bash shell: bash
@@ -112,8 +113,8 @@ jobs:
- name: Install build tools and dependencies - name: Install build tools and dependencies
shell: bash shell: bash
run: | run: |
sudo apt update -y apt update -y
sudo apt install -y \ apt install -y \
ninja-build \ ninja-build \
libgl1-mesa-dev \ libgl1-mesa-dev \
libglvnd-dev \ libglvnd-dev \
@@ -129,7 +130,7 @@ jobs:
libqt6positioning6 libqt6positioning6
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: https://github.com/hendrikmuhs/ccache-action@v1.2
with: with:
key: ${{ github.workflow }}-unity-${{ matrix.compiler.CC }}-${{ matrix.CMAKE_BUILD_TYPE }} key: ${{ github.workflow }}-unity-${{ matrix.compiler.CC }}-${{ matrix.CMAKE_BUILD_TYPE }}
@@ -164,13 +165,13 @@ jobs:
# world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215 # world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215
CTEST_EXCLUDE_REGEX: "generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests" CTEST_EXCLUDE_REGEX: "generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests"
run: | run: |
sudo locale-gen en_US locale-gen en_US
sudo locale-gen en_US.UTF-8 locale-gen en_US.UTF-8
sudo locale-gen es_ES locale-gen es_ES
sudo locale-gen es_ES.UTF-8 locale-gen es_ES.UTF-8
sudo locale-gen fr_FR locale-gen fr_FR
sudo locale-gen fr_FR.UTF-8 locale-gen fr_FR.UTF-8
sudo locale-gen ru_RU locale-gen ru_RU
sudo locale-gen ru_RU.UTF-8 locale-gen ru_RU.UTF-8
sudo update-locale update-locale
ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - fix-ci
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -46,7 +46,7 @@ jobs:
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: https://github.com/actions/checkout@v4
- name: Parallel submodules checkout - name: Parallel submodules checkout
shell: bash shell: bash

View File

@@ -23,10 +23,6 @@ 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
@@ -66,7 +62,6 @@ 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

43
.github/workflows/clang-format.yaml vendored Normal file
View File

@@ -0,0 +1,43 @@
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

View File

@@ -1,51 +0,0 @@
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,7 +30,6 @@ 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
@@ -38,10 +37,6 @@ jobs:
shell: bash shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20))
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure XCode cache - name: Configure XCode cache
uses: irgaly/xcode-cache@v1 uses: irgaly/xcode-cache@v1
with: with:

19
.gitignore vendored
View File

@@ -14,10 +14,12 @@ stxxl.errlog
stxxl.log stxxl.log
screenlog.0 screenlog.0
data/symbols/*/design/ data/styles/*/*/out/*
data/resources-*_design/*
# symbols png/sdf are now generated at build # symbols png/sdf are now generated at build
data/symbols/**/symbols.png data/resources-*_*/symbols.png
data/symbols/**/symbols.sdf data/resources-*_*/symbols.sdf
data/drules_proto_default_design.bin
data/colors_design.txt data/colors_design.txt
data/patterns_design.txt data/patterns_design.txt
data/bookmarks data/bookmarks
@@ -26,12 +28,6 @@ data/World.mwm
data/WorldCoasts.mwm data/WorldCoasts.mwm
data/world_mwm/* data/world_mwm/*
data/*_hash data/*_hash
data/drules_proto*
data/classificator.txt
data/types.txt
data/visibility.txt
data/colors.txt
data/patterns.txt
# Compiled Python # Compiled Python
*.pyc *.pyc
@@ -50,9 +46,10 @@ omim.sdf
*.suo *.suo
*.aps *.aps
*.rc *.rc
!qt/res/windows/windows.rc !qt/res/windows.rc
*.pdb *.pdb
out/ out/*
qt/mapswithme.log
# XCode # XCode
xcode/keys/* xcode/keys/*

View File

@@ -1,5 +1,4 @@
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 20)
@@ -106,7 +105,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(-O3 $<$<CXX_COMPILER_ID:GNU>:-flto=auto>) add_compile_options(-Ofast $<$<CXX_COMPILER_ID:GNU>:-flto=auto>) # Also enables -ffast-math
endif() endif()
else() else()
message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE}) message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE})
@@ -185,7 +184,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}" "${CMAKE_HOME_DIRECTORY}/libs" "${CMAKE_HOME_DIRECTORY}/tools") include_directories(${CMAKE_HOME_DIRECTORY})
if (USE_PCH) if (USE_PCH)
message(STATUS "Precompiled headers are ON") message(STATUS "Precompiled headers are ON")
@@ -227,22 +226,49 @@ 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(libs) add_subdirectory(base)
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)
add_subdirectory(dev_sandbox) omim_add_tool_subdirectory(feature_list)
add_subdirectory(generator) add_subdirectory(generator)
add_subdirectory(tools) add_subdirectory(openlr)
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(libs/qt_tstfrm) omim_add_test_subdirectory(qt_tstfrm)
if (PLATFORM_ANDROID) if (PLATFORM_ANDROID)
add_subdirectory(android/sdk/src/main/cpp) add_subdirectory(android/sdk/src/main/cpp)

View File

@@ -1 +1 @@
See [docs/INSTALL.md](docs/INSTALL.md) See [docs/INSTALL.md](docs/INSTALL.md)

View File

@@ -125,8 +125,10 @@ You can help by donating, contributing code, translating, or by telling others a
- Build instructions: [docs/INSTALL.md](docs/INSTALL.md) - Build instructions: [docs/INSTALL.md](docs/INSTALL.md)
- Contribution guide: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) - Contribution guide: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md)
> [!NOTE]
> Some docs might be outdated, contain broken links or old references to Organic Maps, etc. Its a work in progress and help is much appreciated!
There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/main/contribute.md#3-team-messaging) chat for active contributors. There is a dedicated Zulip chat for active contributors: [Zulip](https://comaps.zulipchat.com)
--- ---
@@ -140,7 +142,7 @@ There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/m
## 💸 Funding ## 💸 Funding
CoMaps is free. To fund development, we rely on your voluntary support ♥️ CoMaps is free. To stay that way, it relies on your 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

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

View File

@@ -1,7 +1,10 @@
• OpenStreetMap data as of August 4 Introducing CoMaps logo!
• improve map colors for water, forests, scrubs, various amenities, pedestrian areas etc.
add ranger stations, covered bicycle parkings, escape games, luggage lockers, post office partners upgrade altitude contour lines for many regions to 20 or 50 meters step
upgrade altitude contour lines to 20m step for some popular hiking regions add Panoramax Picture links to selected POIs
support more search abbreviations and aliases OpenStreetMap data as of July 13
• add search and bookmark icons for fast food, bicycle and charging stations • add color fills to many features and display fills earlier for existing features
more smooth position arrow movements display opening hours state when selecting a POI
• 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,7 +1,9 @@
• Datos de OpenStreetMap a fecha 2025.08.04 ¡Presentamos el logo de CoMaps!
Mejora de colores del mapa para agua, bosques, matorrales, servicios, zonas peatonales, etc. mejora de isolíneas con más detalle para muchas regiones
Añadidas estaciones de guardabosques, aparcamientos cubiertos de bicis, juegos de escape, consignas y oficinas de correo añade enlaces de imágenes de Panoramax a POIs seleccionados
Nuevas curvas de nivel (20 m) en regiones populares para senderismo datos de OpenStreetMap a 13 de julio
Más abreviaturas y alias de búsqueda añadidos rellenos de color a muchas características
Iconos de búsqueda y marcadores para comida rápida, bicicletas y estaciones de recarga se muestra el estado de horarios de apertura al seleccionar un POI
Más fluidez de la flecha de posición se dividen los humedales en tipos distintos
• 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

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

View File

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

View File

@@ -0,0 +1,7 @@
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 de cartes facile - Découvrez le monde - Propulsé par la communauté Navigation cartographique facile - Découvrez davantage de votre voyage - Propulsé par la communauté

View File

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

View File

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

View File

@@ -1 +0,0 @@
Navegação fácil nos mapas - Descubra mais sobre o seu percurso - Feito por todos

View File

@@ -1 +0,0 @@
CoMaps - Mapas e Navegação - Offline e Privada

View File

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

View File

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

View File

@@ -1 +1 @@
Navigation cartographique facile - Vivez de grands voyages - Propulsé par la communauté Navigation cartographique facile - Découvrez davantage de votre voyage - Propulsé par la communauté

View File

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

View File

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

View File

@@ -1 +0,0 @@
കോമാപ്പ്സ് - സ്വകാര്യതയോടെ സഞ്ചരിക്കൂ

View File

@@ -1 +0,0 @@
CoMaps - Nawigacja szanująca prywatność

View File

@@ -7,12 +7,12 @@ Topluluğa katılın ve en iyi harita uygulamasını oluşturmamıza yardım edi
<i>Geri bildirimleriniz ve 5 yıldızlı yorumlarınız bizim için en iyi destektir!</i> <i>Geri bildirimleriniz ve 5 yıldızlı yorumlarınız bizim için en iyi destektir!</i>
‣ <b>Basit ve Temiz</b>: Sadece temel, kullanımı basit ve işe yarayan özellikler. ‣ <b>Basit ve Temiz</b>: Sadece temel, kullanımı basit, işe yarayan özellikler.
‣ <b>Çevrimdışı Odaklı</b>: Mobil veriye ihtiyaç duymadan yurt dışı seyahatinizi planlayın ve gezin, uzun bir yürüyüş sırasında rotanızdaki noktaları bulun ve daha fazlası. Tüm özellikler çevrimdışı çalışmak üzere tasarlanmıştır. ‣ <b>Çevrimdışı Odaklı</b>: Mobil veriye ihtiyaç duymadan yurt dışı seyahatinizi planlayın ve gezin, uzun bir yürüyüş sırasında rotanızdaki noktaları bulun ve daha fazlası . Tüm özellikler çevrimdışı çalışmak üzere tasarlanmıştır.
‣ <b>Gizliliğe Saygılı</b>: Uygulama gizliliğe saygılı olarak tasarlanmıştır. Kullanıcı profilinizi çıkarmaz, sizi takip etmez ve kişisel bilgi toplamaz. Üstelik tamamen reklamsızdır. ‣ <b>Gizliliğe Saygılı</b>: Uygulama gizliliğe saygılı olarak tasarlanmıştır. Kullanıcı profilinizi çıkarmaz, sizi takip etmez ve kişisel bilgi toplamaz. Üstelik tamamen reklamsızdır.
‣ <b>Pil ve Depolamanızdan Tasarruf Eder</b>: Diğer navigasyon uygulamaları gibi pilinizi sömürmez. Kompakt harita dosyaları, değerli depolama alanınızdan tasarruf eder. ‣ <b>Pil ve Depolamanızdan Tasarruf Eder</b>: Diğer navigasyon uygulamaları gibi pilinizi sömürmez. Compact maps değerli depolama alanınızdan tasarruf eder.
‣ <b>Ücretsizdir ve Gücünü Topluluktan Alır</b>: Sizin gibi insanlar OpenStreetMap'e yer ekleyerek, yeni özellikleri test ederek, geri bildirimde bulunarak, program geliştirme becerileri ve bağışlarla katkıda bulunarak bu uygulamanın oluşturulmasına yardımcı oldular. ‣ <b>Ücretsizdir ve Gücünü Topluluktan Alır</b>: Sizin gibi insanlar OpenStreetMap'e yer ekleyerek, yeni özellikleri test ederek, geri bildirimde bulunarak, program geliştirme becerileri ve bağışlarla katkıda bulunarak uygulamanın oluşturulmasına yardımcı oldu.
‣ <b>Açık ve Şeffaf Bir Şekilde Yürütülen Karar Alma ve Fonlama Süreçlerine Sahip, Kâr Amacı Gütmeyen ve Tamamen Açık Kaynaklı Bir Uygulama.</b> ‣ <b>Açık ve Şeffaf Şekilde Yürütülen Karar Alma ve Fonlama Süreçleri, Kâr Amacı Gütmez ve Tamamen Açık Kaynaklı.</b>
<b>Ana Özellikler</b>: <b>Ana Özellikler</b>:
• Google Haritalar'da bulunmayan yerleri içeren, çevrimdışı detaylı haritalar • Google Haritalar'da bulunmayan yerleri içeren, çevrimdışı detaylı haritalar

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="0x00030000" android:glEsVersion="0x00020000"
android:required="true"/> android:required="true"/>
<uses-feature <uses-feature
android:name="android.hardware.wifi" android:name="android.hardware.wifi"

View File

@@ -150,12 +150,14 @@ 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: MapManager.showError(DownloadResourcesLegacyActivity.this, item, null); return; case CountryItem.STATUS_FAILED:
MapManager.showError(DownloadResourcesLegacyActivity.this, item, null);
return;
} }
} }
} }

View File

@@ -23,10 +23,7 @@ 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();
private final Map mMap = new Map(DisplayType.Device);
@SuppressWarnings("NonNullFieldNotInitialized")
@NonNull
private Map mMap;
public void updateCompassOffset(int offsetX, int offsetY) public void updateCompassOffset(int offsetX, int offsetY)
{ {
@@ -87,7 +84,6 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener
{ {
Logger.d(TAG); Logger.d(TAG);
super.onAttach(context); super.onAttach(context);
mMap = new Map(DisplayType.Device, MwmApplication.from(requireContext()).getLocationHelper());
mMap.setMapRenderingListener((MapRenderingListener) context); mMap.setMapRenderingListener((MapRenderingListener) context);
mMap.setCallbackUnsupported(this::reportUnsupported); mMap.setCallbackUnsupported(this::reportUnsupported);
} }
@@ -163,24 +159,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

@@ -82,6 +82,7 @@ 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;
@@ -107,7 +108,6 @@ 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,6 +115,7 @@ 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;
@@ -124,7 +125,6 @@ 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;
@@ -683,29 +683,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 +772,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 +972,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,22 +1223,21 @@ public class MwmActivity extends BaseMwmFragmentActivity
private void onIsolinesStateChanged(@NonNull IsolinesState type) private void onIsolinesStateChanged(@NonNull IsolinesState type)
{ {
if (type == IsolinesState.NODATA) if (type != IsolinesState.EXPIREDDATA)
{ {
Toast.makeText(this, R.string.isolines_location_error_dialog, Toast.LENGTH_SHORT).show(); type.activate(this, findViewById(R.id.coordinator), findViewById(R.id.menu_frame));
return;
} }
if (type == IsolinesState.EXPIREDDATA) dismissAlertDialog();
{ mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) .setTitle(R.string.downloader_update_maps)
.setTitle(R.string.downloader_update_maps) .setMessage(R.string.isolines_activation_error_dialog)
.setMessage(R.string.isolines_activation_error_dialog) .setPositiveButton(R.string.ok,
.setPositiveButton( (dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class)))
R.string.ok, (dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class))) .setNegativeButton(R.string.cancel, null)
.setNegativeButton(R.string.cancel, null) .setOnDismissListener(dialog -> mAlertDialog = null)
.setOnDismissListener(dialog -> mAlertDialog = null) .show();
.show();
}
} }
@Override @Override
@@ -2429,18 +2428,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,6 +18,7 @@ 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;
@@ -27,11 +28,9 @@ 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;
@@ -134,8 +133,6 @@ 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");
} }
else default ->
{ {
Logger.i(TAG, "Backup was created and saved successfully"); errorCode = ErrorCode.UNSUPPORTED;
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,7 +35,6 @@ 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;
@@ -552,12 +551,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);
@@ -593,7 +592,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_COLOR, PredefinedColors.getPredefinedColorIndex(mTrack.getColor())); args.putInt(BookmarkColorDialogFragment.ICON_TYPE, Icon.getColorPosition(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();
@@ -602,7 +601,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 = PredefinedColors.getColor(colorPos); int to = BookmarkManager.ICONS.get(colorPos).argb();
if (from == to) if (from == to)
return; return;
BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to); BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to);
@@ -622,22 +621,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;
} }
} }
@@ -844,19 +843,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,26 +6,19 @@ 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.PredefinedColors; import app.organicmaps.sdk.bookmarks.data.Icon;
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 ColorsAdapter extends ArrayAdapter<Integer> public class IconsAdapter extends ArrayAdapter<Icon>
{ {
@PredefinedColors.Color
private int mCheckedIconColor; private int mCheckedIconColor;
@DrawableRes public IconsAdapter(Context context, List<Icon> list)
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
@@ -42,19 +35,19 @@ public class ColorsAdapter extends ArrayAdapter<Integer>
else else
holder = (SpinnerViewHolder) convertView.getTag(); holder = (SpinnerViewHolder) convertView.getTag();
@PredefinedColors.Color final Icon icon = getItem(position);
final int color = Objects.requireNonNull(getItem(position));
Drawable circle; Drawable circle;
if (color == mCheckedIconColor) if (icon.getColor() == mCheckedIconColor)
{ {
circle = Graphics.drawCircleAndImage(PredefinedColors.getColor(mCheckedIconColor), R.dimen.track_circle_size, circle = Graphics.drawCircleAndImage(getItem(position).argb(), R.dimen.track_circle_size,
mIconResId, R.dimen.bookmark_icon_size, getContext()); app.organicmaps.sdk.R.drawable.ic_bookmark_none, R.dimen.bookmark_icon_size,
getContext());
} }
else else
{ {
circle = Graphics.drawCircle(PredefinedColors.getColor(color), R.dimen.select_color_circle_size, circle =
getContext().getResources()); Graphics.drawCircle(getItem(position).argb(), R.dimen.select_color_circle_size, getContext().getResources());
} }
holder.icon.setImageDrawable(circle); holder.icon.setImageDrawable(circle);
return convertView; return convertView;

View File

@@ -26,6 +26,7 @@ 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;
@@ -33,7 +34,6 @@ 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,11 +27,8 @@ 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;
private final Map mMap = new Map(Car);
@NonNull
private final Map mMap;
@NonNull @NonNull
private Rect mVisibleArea = new Rect(); private Rect mVisibleArea = new Rect();
@@ -45,7 +42,6 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac
{ {
Logger.d(TAG, "SurfaceRenderer()"); Logger.d(TAG, "SurfaceRenderer()");
mCarContext = carContext; mCarContext = carContext;
mMap = new Map(Car, MwmApplication.from(mCarContext).getLocationHelper());
mIsRunning = true; mIsRunning = true;
lifecycle.addObserver(this); lifecycle.addObserver(this);
mMap.setMapRenderingListener(this); mMap.setMapRenderingListener(this);

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);
items.add(getExploreMenuItem()); break;
}
break;
case CountryItem.STATUS_PROGRESS: case CountryItem.STATUS_FAILED:
case CountryItem.STATUS_APPLYING: items.add(getCancelMenuItem());
case CountryItem.STATUS_ENQUEUED:
items.add(getCancelMenuItem());
if (mSelectedItem.present) if (mSelectedItem.present)
items.add(getExploreMenuItem()); {
break; appendDeleteMenuItem(items);
items.add(getExploreMenuItem());
}
break;
case CountryItem.STATUS_PARTLY: case CountryItem.STATUS_PROGRESS:
items.add(getDownloadMenuItem()); case CountryItem.STATUS_APPLYING:
appendDeleteMenuItem(items); case CountryItem.STATUS_ENQUEUED:
break; items.add(getCancelMenuItem());
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); {
case CountryItem.STATUS_UPDATABLE -> if (clickOnStatus)
MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id)); onDownloadActionSelected(mItem, DownloaderAdapter.this);
default -> throw new IllegalArgumentException("Inappropriate item status: " + mItem.status); else
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)
{ {
headerId = CountryItem.CATEGORY_NEAR_ME; if (ci.category != prev)
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 public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapter>
extends BaseMwmRecyclerFragment<DownloaderAdapter> implements MenuBottomSheetFragment.MenuBottomSheetInterface implements MenuBottomSheetFragment.MenuBottomSheetInterface
{ {
private DownloaderToolbarController mToolbarController; private DownloaderToolbarController mToolbarController;
@@ -153,8 +153,7 @@ public class DownloaderFragment
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(), requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), mToolbarController.getBackPressedCallback());
mToolbarController.getBackPressedCallback());
update(); update();
} }
@@ -196,8 +195,7 @@ public class DownloaderFragment
{ {
if (mAdapter == null) if (mAdapter == null)
mAdapter = new DownloaderAdapter(this); mAdapter = new DownloaderAdapter(this);
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), mAdapter.getBackPressedCallback());
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, com.google.android.material.R.attr.colorSecondary), null, Graphics.tint(requireActivity(), left, androidx.appcompat.R.attr.colorAccent), null,
Graphics.tint(requireActivity(), right, com.google.android.material.R.attr.colorSecondary), null); Graphics.tint(requireActivity(), right, androidx.appcompat.R.attr.colorAccent), 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(
TimetableContainerFragment.class.getName()))
.getTimetable();
Editor.nativeSetOpeningHours(timetables);
editMapObject();
}
case STREET ->
setStreet(
((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName())).getStreet());
case CUISINE ->
{
String[] cuisines =
((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName()))
.getCuisines();
Editor.nativeSetSelectedCuisines(cuisines);
editMapObject();
}
case SELF_SERVICE ->
setSelection(
Metadata.MetadataType.FMD_SELF_SERVICE,
((SelfServiceFragment) getChildFragmentManager().findFragmentByTag(SelfServiceFragment.class.getName()))
.getSelection());
case LANGUAGE -> editMapObject();
case MAP_OBJECT ->
{
if (!setEdits())
return;
// Save object edits
if (!MwmApplication.prefs(requireContext()).contains(NOOB_ALERT_SHOWN))
{ {
showNoobDialog(); final String timetables = ((TimetableContainerFragment) getChildFragmentManager().findFragmentByTag(
} TimetableContainerFragment.class.getName()))
else .getTimetable();
{ Editor.nativeSetOpeningHours(timetables);
saveNote();
saveMapObjectEdits();
}
}
case PHONE ->
{
final String phone =
((PhoneFragment) getChildFragmentManager().findFragmentByTag(PhoneFragment.class.getName())).getPhone();
if (Editor.nativeIsPhoneValid(phone))
{
Editor.nativeSetPhone(phone);
editMapObject(); editMapObject();
} }
} case STREET ->
setStreet(((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName()))
.getStreet());
case CUISINE ->
{
String[] cuisines =
((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName()))
.getCuisines();
Editor.nativeSetSelectedCuisines(cuisines);
editMapObject();
}
case SELF_SERVICE ->
setSelection(
Metadata.MetadataType.FMD_SELF_SERVICE,
((SelfServiceFragment) getChildFragmentManager().findFragmentByTag(SelfServiceFragment.class.getName()))
.getSelection());
case LANGUAGE -> editMapObject();
case MAP_OBJECT ->
{
if (!setEdits())
return;
// Save object edits
if (!MwmApplication.prefs(requireContext()).contains(NOOB_ALERT_SHOWN))
{
showNoobDialog();
}
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,9 +9,7 @@ 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>
@@ -23,12 +21,6 @@ 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)
{ {
@@ -57,18 +49,17 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
{ {
switch (viewType) switch (viewType)
{ {
case TYPE_CATEGORY -> case TYPE_CATEGORY ->
{ {
return new FeatureViewHolder( return new FeatureViewHolder(
LayoutInflater.from(parent.getContext()).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( return new FooterViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false), LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false));
(FooterListener) mFragment); }
} default -> throw new IllegalArgumentException("Unsupported");
default -> throw new IllegalArgumentException("Unsupported");
} }
} }
@@ -79,10 +70,6 @@ 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
@@ -118,36 +105,11 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
protected static class FooterViewHolder extends RecyclerView.ViewHolder protected static class FooterViewHolder extends RecyclerView.ViewHolder
{ {
private final TextInputEditText mNoteEditText; FooterViewHolder(@NonNull View itemView)
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,39 +2,28 @@ 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 public class FeatureCategoryFragment extends BaseMwmRecyclerFragment<FeatureCategoryAdapter>
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
{ {
@@ -115,64 +104,4 @@ public class FeatureCategoryFragment
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()
{
if (!OsmOAuth.isAuthorized())
{
final Intent intent = new Intent(requireActivity(), OsmLoginActivity.class);
startActivity(intent);
return;
}
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();
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();
requireActivity().finish();
})
.setNegativeButton(R.string.cancel, null)
.show();
}
} }

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,6 +10,7 @@ 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;
@@ -19,7 +20,6 @@ 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)
{ {
Framework.nativeStopLocationFollow(); SearchEngine.INSTANCE.cancelInteractiveSearch();
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
// We need to update viewport for search api manually because of drape engine final double[] latlon = Framework.nativeGetParsedCenterLatLon();
// will not notify subscribers when search activity is shown. if (latlon != null)
if (!request.mIsSearchOnMap) {
Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); Framework.nativeStopLocationFollow();
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;
} }
SearchActivity.start(target, request.mQuery, request.mLocale, request.mIsSearchOnMap); case RequestType.CROSSHAIR:
return true;
}
case RequestType.CROSSHAIR:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
target.showPositionChooserForAPI(Framework.nativeGetParsedAppName());
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{ {
Framework.nativeStopLocationFollow(); SearchEngine.INSTANCE.cancelInteractiveSearch();
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); target.showPositionChooserForAPI(Framework.nativeGetParsedAppName());
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;
} }
return true; // Menu and Settings url types should be implemented to support deeplinking.
} case RequestType.MENU:
case RequestType.OAUTH2: case RequestType.SETTINGS:
{
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

@@ -26,6 +26,7 @@ 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;
@@ -33,7 +34,6 @@ 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 +230,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);
} }
} }

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.sdk.routing.RoutingController; import app.organicmaps.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,
com.google.android.material.R.attr.colorSecondary)); androidx.appcompat.R.attr.colorAccent));
} }
@Override @Override

View File

@@ -14,7 +14,6 @@ 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;
@@ -73,9 +72,6 @@ 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

@@ -9,17 +9,16 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ExpandableListAdapter; import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
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;
import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -94,9 +93,9 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment
{ {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
final View countryView = View.inflate(requireActivity(), R.layout.dialog_missed_map, null); final View countryView = View.inflate(requireActivity(), R.layout.dialog_missed_map, null);
((MaterialTextView) countryView.findViewById(R.id.tv__title)).setText(map.name); ((TextView) countryView.findViewById(R.id.tv__title)).setText(map.name);
final MaterialTextView szView = countryView.findViewById(R.id.tv__size); final TextView szView = countryView.findViewById(R.id.tv__size);
szView.setText(StringUtils.getFileSizeString(requireContext(), map.totalSize)); szView.setText(StringUtils.getFileSizeString(requireContext(), map.totalSize));
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) szView.getLayoutParams(); ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) szView.getLayoutParams();
lp.rightMargin = 0; lp.rightMargin = 0;

View File

@@ -8,6 +8,8 @@ import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
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;
@@ -17,8 +19,6 @@ 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.
@@ -232,16 +232,16 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
public final View mItemView; public final View mItemView;
@NonNull @NonNull
public final ShapeableImageView mImageViewIcon; public final ImageView mImageViewIcon;
@NonNull @NonNull
public final MaterialTextView mTextViewTitle; public final TextView mTextViewTitle;
@NonNull @NonNull
public final MaterialTextView mTextViewSubtitle; public final TextView mTextViewSubtitle;
@NonNull @NonNull
public final ShapeableImageView mImageViewDelete; public final ImageView mImageViewDelete;
ManageRouteViewHolder(@NonNull View itemView) ManageRouteViewHolder(@NonNull View itemView)
{ {

View File

@@ -22,7 +22,6 @@ 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

@@ -4,6 +4,7 @@ import android.location.Location;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
@@ -18,7 +19,6 @@ 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;
@@ -28,22 +28,20 @@ import app.organicmaps.widget.LanesView;
import app.organicmaps.widget.SpeedLimitView; import app.organicmaps.widget.SpeedLimitView;
import app.organicmaps.widget.menu.NavMenu; import app.organicmaps.widget.menu.NavMenu;
import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
public class NavigationController implements TrafficManager.TrafficCallback, NavMenu.NavMenuListener public class NavigationController implements TrafficManager.TrafficCallback, NavMenu.NavMenuListener
{ {
private final View mFrame; private final View mFrame;
private final ImageView mNextTurnImage; private final ImageView mNextTurnImage;
private final MaterialTextView mNextTurnDistance; private final TextView mNextTurnDistance;
private final MaterialTextView mCircleExit; private final TextView mCircleExit;
private final View mNextNextTurnFrame; private final View mNextNextTurnFrame;
private final ImageView mNextNextTurnImage; private final ImageView mNextNextTurnImage;
private final View mStreetFrame; private final View mStreetFrame;
private final MaterialTextView mNextStreet; private final TextView mNextStreet;
@NonNull @NonNull
private final LanesView mLanesView; private final LanesView mLanesView;

View File

@@ -35,7 +35,6 @@ 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;
break; case ResultCodes.START_POINT_NOT_FOUND:
case ResultCodes.INTERNAL_ERROR: titleRes = R.string.dialog_routing_change_start;
titleRes = R.string.dialog_routing_system_error; messages.add(resources.getString(R.string.dialog_routing_start_not_determined));
messages.add(resources.getString(R.string.dialog_routing_application_error)); messages.add(resources.getString(R.string.dialog_routing_select_closer_start));
messages.add(resources.getString(R.string.dialog_routing_try_again)); break;
break; case ResultCodes.END_POINT_NOT_FOUND:
case ResultCodes.NEED_MORE_MAPS: titleRes = R.string.dialog_routing_change_end;
titleRes = R.string.dialog_routing_download_and_build_cross_route; messages.add(resources.getString(R.string.dialog_routing_end_not_determined));
messages.add(resources.getString(R.string.dialog_routing_download_cross_route)); messages.add(resources.getString(R.string.dialog_routing_select_closer_end));
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,7 +32,6 @@ 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;
@@ -40,7 +39,6 @@ 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;
@@ -62,7 +60,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
@NonNull @NonNull
private final View mTransitFrame; private final View mTransitFrame;
@NonNull @NonNull
private final MaterialTextView mError; private final TextView mError;
@NonNull @NonNull
private final Button mStart; private final Button mStart;
@NonNull @NonNull
@@ -96,7 +94,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
View altitudeChartFrame = getViewById(activity, frame, R.id.altitude_chart_panel); View altitudeChartFrame = getViewById(activity, frame, R.id.altitude_chart_panel);
View timeElevationLine = getViewById(activity, frame, R.id.time_elevation_line); View timeElevationLine = getViewById(activity, frame, R.id.time_elevation_line);
View transitFrame = getViewById(activity, frame, R.id.transit_panel); View transitFrame = getViewById(activity, frame, R.id.transit_panel);
MaterialTextView error = (MaterialTextView) getViewById(activity, frame, R.id.error); TextView error = (TextView) getViewById(activity, frame, R.id.error);
Button start = (Button) getViewById(activity, frame, R.id.start); Button start = (Button) getViewById(activity, frame, R.id.start);
ImageView altitudeChart = (ImageView) getViewById(activity, frame, R.id.altitude_chart); ImageView altitudeChart = (ImageView) getViewById(activity, frame, R.id.altitude_chart);
MaterialTextView time = (MaterialTextView) getViewById(activity, frame, R.id.time); MaterialTextView time = (MaterialTextView) getViewById(activity, frame, R.id.time);
@@ -119,11 +117,10 @@ 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 TextView error, @NonNull Button start, @NonNull ImageView altitudeChart,
@NonNull ImageView altitudeChart, @NonNull MaterialTextView time, @NonNull MaterialTextView time, @NonNull MaterialTextView altitudeDifference,
@NonNull MaterialTextView altitudeDifference, @NonNull TextView timeVehicle, @NonNull TextView timeVehicle, @Nullable MaterialTextView arrival,
@Nullable MaterialTextView arrival, @NonNull View actionFrame, @NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener)
@Nullable RoutingBottomMenuListener listener)
{ {
mContext = context; mContext = context;
mAltitudeChartFrame = altitudeChartFrame; mAltitudeChartFrame = altitudeChartFrame;
@@ -194,7 +191,8 @@ 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(Utils.formatRoutingTime(mContext, info.getTotalTime(), R.dimen.text_size_routing_number)); totalTimeView.setText(
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);
@@ -225,7 +223,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
else else
UiUtils.hide(rv); // Show only distance between start and finish UiUtils.hide(rv); // Show only distance between start and finish
MaterialTextView totalTimeView = mTransitFrame.findViewById(R.id.total_time); TextView totalTimeView = mTransitFrame.findViewById(R.id.total_time);
totalTimeView.setText(mContext.getString(R.string.placepage_distance) + ": " + totalLength.mDistanceStr + " " totalTimeView.setText(mContext.getString(R.string.placepage_distance) + ": " + totalLength.mDistanceStr + " "
+ totalLength.getUnitsStr(mContext)); + totalLength.getUnitsStr(mContext));
@@ -263,9 +261,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 colorSecondary = ContextCompat.getColor( int colorAccent = ContextCompat.getColor(
mContext, UiUtils.getStyledResourceId(mContext, com.google.android.material.R.attr.colorSecondary)); mContext, UiUtils.getStyledResourceId(mContext, androidx.appcompat.R.attr.colorAccent));
mActionIcon.setImageDrawable(Graphics.tint(icon, colorSecondary)); mActionIcon.setImageDrawable(Graphics.tint(icon, colorAccent));
} }
else else
{ {
@@ -384,7 +382,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
if (mArrival != null) if (mArrival != null)
{ {
String arrivalTime = Utils.formatArrivalTime(rinfo.totalTimeInSeconds); String arrivalTime = RoutingController.formatArrivalTime(rinfo.totalTimeInSeconds);
mArrival.setText(arrivalTime); mArrival.setText(arrivalTime);
} }
} }
@@ -402,7 +400,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
{ {
CharSequence time = CharSequence time =
Utils.formatRoutingTime(context, routingInfo.totalTimeInSeconds, R.dimen.text_size_routing_number); RoutingController.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

@@ -1,19 +1,38 @@
package app.organicmaps.sdk.routing; package app.organicmaps.routing;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.DimenRes;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.MainThread; import androidx.annotation.MainThread;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.util.Pair; import androidx.core.util.Pair;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
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.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.location.LocationHelper; import app.organicmaps.sdk.routing.ResultCodes;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RouteRecommendationType;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingListener;
import app.organicmaps.sdk.routing.RoutingLoadPointsListener;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.routing.RoutingProgressListener;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.sdk.util.concurrency.UiThread;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.widget.placepage.CoordinatesFormat; import app.organicmaps.util.Utils;
import app.organicmaps.widget.placepage.CoordinatesFormat;
import java.time.LocalTime;
import java.util.concurrent.TimeUnit;
@androidx.annotation.UiThread @androidx.annotation.UiThread
public class RoutingController public class RoutingController
@@ -95,7 +114,7 @@ public class RoutingController
mLastMissingMaps = missingMaps; mLastMissingMaps = missingMaps;
mContainsCachedResult = true; mContainsCachedResult = true;
if (mLastResultCode == ResultCodes.NO_ERROR || resultCode == ResultCodes.NEED_MORE_MAPS) if (mLastResultCode == ResultCodes.NO_ERROR || ResultCodesHelper.isMoreMapsNeeded(mLastResultCode))
{ {
onBuiltRoute(); onBuiltRoute();
} }
@@ -161,7 +180,7 @@ public class RoutingController
return; return;
} }
if (mLastResultCode != ResultCodes.NEED_MORE_MAPS) if (!ResultCodesHelper.isMoreMapsNeeded(mLastResultCode))
{ {
setBuildState(BuildState.ERROR); setBuildState(BuildState.ERROR);
mLastBuildProgress = 0; mLastBuildProgress = 0;
@@ -176,7 +195,8 @@ public class RoutingController
private boolean isDrivingOptionsBuildError() private boolean isDrivingOptionsBuildError()
{ {
return mLastResultCode != ResultCodes.NEED_MORE_MAPS && RoutingOptions.hasAnyOptions() && !isRulerRouterType(); return !ResultCodesHelper.isMoreMapsNeeded(mLastResultCode) && RoutingOptions.hasAnyOptions()
&& !isRulerRouterType();
} }
private void setState(State newState) private void setState(State newState)
@@ -230,7 +250,7 @@ public class RoutingController
mContainer = container; mContainer = container;
} }
public void initialize(@NonNull LocationHelper locationHelper) public void initialize(@NonNull Context context)
{ {
mLastRouterType = Router.getLastUsed(); mLastRouterType = Router.getLastUsed();
mInvalidRoutePointsTransactionId = Framework.nativeInvalidRoutePointsTransactionId(); mInvalidRoutePointsTransactionId = Framework.nativeInvalidRoutePointsTransactionId();
@@ -240,7 +260,7 @@ public class RoutingController
Framework.nativeSetRouteProgressListener(mRoutingProgressListener); Framework.nativeSetRouteProgressListener(mRoutingProgressListener);
Framework.nativeSetRoutingRecommendationListener(recommendation -> UiThread.run(() -> { Framework.nativeSetRoutingRecommendationListener(recommendation -> UiThread.run(() -> {
if (recommendation == RouteRecommendationType.RebuildAfterPointsLoading) if (recommendation == RouteRecommendationType.RebuildAfterPointsLoading)
setStartPoint(locationHelper.getMyPosition()); setStartPoint(MwmApplication.from(context).getLocationHelper().getMyPosition());
})); }));
Framework.nativeSetRoutingLoadPointsListener(mRoutingLoadPointsListener); Framework.nativeSetRoutingLoadPointsListener(mRoutingLoadPointsListener);
} }
@@ -537,7 +557,7 @@ public class RoutingController
return mLastRouterType == Router.Vehicle; return mLastRouterType == Router.Vehicle;
} }
public boolean isRulerRouterType() boolean isRulerRouterType()
{ {
return mLastRouterType == Router.Ruler; return mLastRouterType == Router.Ruler;
} }
@@ -863,4 +883,26 @@ public class RoutingController
mWaitingPoiPickType = null; mWaitingPoiPickType = null;
} }
public static CharSequence formatRoutingTime(Context context, int seconds, @DimenRes int unitsSize)
{
return formatRoutingTime(context, seconds, unitsSize, R.dimen.text_size_routing_number);
}
public static CharSequence formatRoutingTime(Context context, int seconds, @DimenRes int unitsSize,
@DimenRes int textSize)
{
long minutes = TimeUnit.SECONDS.toMinutes(seconds) % 60;
long hours = TimeUnit.SECONDS.toHours(seconds);
String min = context.getString(R.string.minute);
String hour = context.getString(R.string.hour);
SpannableStringBuilder displayedH = Utils.formatTime(context, textSize, unitsSize, String.valueOf(hours), hour);
SpannableStringBuilder displayedM = Utils.formatTime(context, textSize, unitsSize, String.valueOf(minutes), min);
return hours == 0 ? displayedM : TextUtils.concat(displayedH + "\u00A0", displayedM);
}
static String formatArrivalTime(int seconds)
{
final LocalTime time = LocalTime.now().plusSeconds(seconds);
return StringUtils.formatUsingUsLocale("%d:%02d", time.getHour(), time.getMinute());
}
} }

View File

@@ -8,6 +8,7 @@ import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
@@ -17,7 +18,6 @@ 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
{ {
@@ -38,7 +38,7 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment
if (!TextUtils.isEmpty(titleMessage.first)) if (!TextUtils.isEmpty(titleMessage.first))
{ {
MaterialTextView titleView = new MaterialTextView(requireContext()); TextView titleView = new TextView(requireContext());
titleView.setText(titleMessage.first); titleView.setText(titleMessage.first);
titleView.setPadding(65, 32, 32, 16); titleView.setPadding(65, 32, 32, 16);
titleView.setTextSize(18); titleView.setTextSize(18);

View File

@@ -11,7 +11,6 @@ import androidx.fragment.app.FragmentFactory;
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.routing.RoutingController;
import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.widget.WheelProgressView; import app.organicmaps.widget.WheelProgressView;
import java.util.HashSet; import java.util.HashSet;

View File

@@ -17,7 +17,6 @@ import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router; import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.routing.TransitRouteInfo; import app.organicmaps.sdk.routing.TransitRouteInfo;

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