Compare commits

..

1 Commits

Author SHA1 Message Date
Harry Bond
fe3df2e5c0 [fdroid] Release version 2025.08.13-8
Signed-off-by: Harry Bond <me@hbond.xyz>
2025-08-13 19:37:30 +01:00
3243 changed files with 77936 additions and 71491 deletions

View File

@@ -3,6 +3,7 @@ BasedOnStyle: Google
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: Right
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: LeftWithLastLine
AlignOperands: AlignAfterOperator
@@ -39,10 +40,8 @@ ColumnLimit: 120
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 4
DerivePointerAlignment: false
EmptyLineBeforeAccessModifier: Always
IncludeBlocks: Preserve
IndentAccessModifiers: false
IndentCaseLabels: false
IndentExternBlock: NoIndent
InsertBraces: false
InsertNewlineAtEOF: true
@@ -50,7 +49,6 @@ LambdaBodyIndentation: OuterScope
PackConstructorInitializers: CurrentLine
PointerAlignment: Middle
RemoveBracesLLVM: true
RemoveSemicolon: true
QualifierAlignment: Right
SpacesInContainerLiterals: false
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
pull_request:
paths:
- qt/res/linux/app.comaps.comaps.desktop
- qt/res/app.comaps.comaps.desktop
- .forgejo/workflows/desktop-file-check.yaml # Run check on self change
jobs:
@@ -16,7 +16,7 @@ jobs:
with:
fetch-depth: 1
sparse-checkout: |
qt/res/linux/app.comaps.comaps.desktop
qt/res/app.comaps.comaps.desktop
- name: Install desktop-file-validate tool
shell: bash
@@ -27,4 +27,4 @@ jobs:
- name: Validate desktop file
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.comaps.desktop && echo "Successfully validated .desktop file"

View File

@@ -23,10 +23,6 @@ jobs:
shell: bash
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
shell: bash
working-directory: android
@@ -66,7 +62,6 @@ jobs:
libxinerama-dev \
libxcursor-dev \
libxi-dev \
python3-protobuf \
zlib1g-dev
- 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: |
brew install qt \
optipng
pip3 install "protobuf<3.21" --break-system-packages
- name: Checkout sources
uses: actions/checkout@v4

2
.gitignore vendored
View File

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

View File

@@ -185,7 +185,7 @@ if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
endif()
# 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)
message(STATUS "Precompiled headers are ON")
@@ -227,22 +227,49 @@ endif()
# Used in qt/ and shaders/
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)
add_subdirectory(dev_sandbox)
omim_add_tool_subdirectory(feature_list)
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)
add_subdirectory(qt)
omim_add_tool_subdirectory(skin_generator)
endif()
if (GENERATOR_TOOL)
add_compile_options(-march=native -mtune=native)
message(STATUS "target CPU optimizations enabled, produced binaries will NOT work on a different CPU")
endif()
add_subdirectory(dev_sandbox)
endif()
omim_add_test_subdirectory(libs/qt_tstfrm)
omim_add_test_subdirectory(qt_tstfrm)
if (PLATFORM_ANDROID)
add_subdirectory(android/sdk/src/main/cpp)

View File

@@ -140,7 +140,7 @@ There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/m
## 💸 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).
The project's financial information is completely open and transparent at [our Open Collective](https://opencollective.com/comaps).

View File

@@ -1 +1 @@
version: 2025.03.02-7-FDroid+25030207
version: 2025.08.13-8-FDroid+25081308

View File

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

View File

@@ -150,12 +150,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
switch (item.newStatus)
{
case CountryItem.STATUS_DONE:
mAreResourcesDownloaded = true;
showMap();
return;
case CountryItem.STATUS_DONE:
mAreResourcesDownloaded = true;
showMap();
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
{
private static final String TAG = MapFragment.class.getSimpleName();
@SuppressWarnings("NonNullFieldNotInitialized")
@NonNull
private Map mMap;
private final Map mMap = new Map(DisplayType.Device);
public void updateCompassOffset(int offsetX, int offsetY)
{
@@ -87,7 +84,6 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener
{
Logger.d(TAG);
super.onAttach(context);
mMap = new Map(DisplayType.Device, MwmApplication.from(requireContext()).getLocationHelper());
mMap.setMapRenderingListener((MapRenderingListener) context);
mMap.setCallbackUnsupported(this::reportUnsupported);
}
@@ -163,24 +159,24 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener
int pointerIndex = event.getActionIndex();
switch (action)
{
case MotionEvent.ACTION_POINTER_UP -> action = Map.NATIVE_ACTION_UP;
case MotionEvent.ACTION_UP ->
{
action = Map.NATIVE_ACTION_UP;
pointerIndex = 0;
}
case MotionEvent.ACTION_POINTER_DOWN -> action = Map.NATIVE_ACTION_DOWN;
case MotionEvent.ACTION_DOWN ->
{
action = Map.NATIVE_ACTION_DOWN;
pointerIndex = 0;
}
case MotionEvent.ACTION_MOVE ->
{
action = Map.NATIVE_ACTION_MOVE;
pointerIndex = Map.INVALID_POINTER_MASK;
}
case MotionEvent.ACTION_CANCEL -> action = Map.NATIVE_ACTION_CANCEL;
case MotionEvent.ACTION_POINTER_UP -> action = Map.NATIVE_ACTION_UP;
case MotionEvent.ACTION_UP ->
{
action = Map.NATIVE_ACTION_UP;
pointerIndex = 0;
}
case MotionEvent.ACTION_POINTER_DOWN -> action = Map.NATIVE_ACTION_DOWN;
case MotionEvent.ACTION_DOWN ->
{
action = Map.NATIVE_ACTION_DOWN;
pointerIndex = 0;
}
case MotionEvent.ACTION_MOVE ->
{
action = Map.NATIVE_ACTION_MOVE;
pointerIndex = Map.INVALID_POINTER_MASK;
}
case MotionEvent.ACTION_CANCEL -> action = Map.NATIVE_ACTION_CANCEL;
}
Map.onTouch(action, event, pointerIndex);
return true;

View File

@@ -82,6 +82,7 @@ import app.organicmaps.routing.ManageRouteBottomSheet;
import app.organicmaps.routing.NavigationController;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingBottomMenuListener;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.routing.RoutingErrorDialogFragment;
import app.organicmaps.routing.RoutingPlanFragment;
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.maplayer.isolines.IsolinesState;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.search.SearchEngine;
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.LocationUtils;
import app.organicmaps.sdk.util.PowerManagment;
import app.organicmaps.sdk.util.ThemeSwitcher;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.sdk.util.log.Logger;
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.SettingsActivity;
import app.organicmaps.util.SharingUtils;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
@@ -683,29 +683,29 @@ public class MwmActivity extends BaseMwmFragmentActivity
mPointChooser.findViewById(R.id.done).setOnClickListener(v -> {
switch (ChoosePositionMode.get())
{
case Api:
final Intent apiResult = new Intent();
final double[] center = Framework.nativeGetScreenRectCenter();
apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]);
apiResult.putExtra(Const.EXTRA_POINT_LON, center[1]);
apiResult.putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale());
setResult(Activity.RESULT_OK, apiResult);
finish();
break;
case Editor:
if (Framework.nativeIsDownloadedMapAtScreenCenter())
startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class));
else
{
dismissAlertDialog();
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.message_invalid_feature_position)
.setPositiveButton(R.string.ok, null)
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
break;
case None: throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()");
case Api:
final Intent apiResult = new Intent();
final double[] center = Framework.nativeGetScreenRectCenter();
apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]);
apiResult.putExtra(Const.EXTRA_POINT_LON, center[1]);
apiResult.putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale());
setResult(Activity.RESULT_OK, apiResult);
finish();
break;
case Editor:
if (Framework.nativeIsDownloadedMapAtScreenCenter())
startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class));
else
{
dismissAlertDialog();
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.message_invalid_feature_position)
.setPositiveButton(R.string.ok, null)
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
break;
case None: throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()");
}
closePositionChooser();
});
@@ -772,9 +772,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
final View mapView = mMapFragment.getView();
if (mapView != null)
{
int width = mapView.getWidth();
int height = mapView.getHeight();
Framework.nativeSetVisibleRect(0, 0, width, height);
int width = mapView.getWidth();
int height = mapView.getHeight();
Framework.nativeSetVisibleRect(0, 0, width, height);
}
}
UiUtils.show(mPointChooser);
@@ -972,24 +972,24 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
switch (button)
{
case zoomIn -> Map.zoomIn();
case zoomOut -> Map.zoomOut();
case myPosition ->
{
Logger.i(LOCATION_TAG, "The location button pressed");
// Calls onMyPositionModeChanged(mode + 1).
LocationState.nativeSwitchToNextMode();
}
case toggleMapLayer -> toggleMapLayerBottomSheet();
case bookmarks -> showBookmarks();
case search -> showSearch("");
case menu ->
{
closeFloatingPanels();
showBottomSheet(MAIN_MENU_ID);
}
case help -> showHelp();
case trackRecordingStatus -> showTrackSaveDialog();
case zoomIn -> Map.zoomIn();
case zoomOut -> Map.zoomOut();
case myPosition ->
{
Logger.i(LOCATION_TAG, "The location button pressed");
// Calls onMyPositionModeChanged(mode + 1).
LocationState.nativeSwitchToNextMode();
}
case toggleMapLayer -> toggleMapLayerBottomSheet();
case bookmarks -> showBookmarks();
case search -> showSearch("");
case menu ->
{
closeFloatingPanels();
showBottomSheet(MAIN_MENU_ID);
}
case help -> showHelp();
case trackRecordingStatus -> showTrackSaveDialog();
}
}
@@ -1223,22 +1223,21 @@ public class MwmActivity extends BaseMwmFragmentActivity
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)
{
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.downloader_update_maps)
.setMessage(R.string.isolines_activation_error_dialog)
.setPositiveButton(
R.string.ok, (dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class)))
.setNegativeButton(R.string.cancel, null)
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
dismissAlertDialog();
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.downloader_update_maps)
.setMessage(R.string.isolines_activation_error_dialog)
.setPositiveButton(R.string.ok,
(dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class)))
.setNegativeButton(R.string.cancel, null)
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
@Override
@@ -2429,18 +2428,18 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_DOWN: Map.zoomOut(); return true;
case KeyEvent.KEYCODE_DPAD_UP: Map.zoomIn(); return true;
case KeyEvent.KEYCODE_ESCAPE:
final Intent currIntent = getIntent();
final String backUrl = Framework.nativeGetParsedBackUrl();
if (TextUtils.isEmpty(backUrl) || (currIntent != null && Factory.isStartedForApiResult(currIntent)))
{
finish();
return true;
}
return super.onKeyUp(keyCode, event);
default: return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_DPAD_DOWN: Map.zoomOut(); return true;
case KeyEvent.KEYCODE_DPAD_UP: Map.zoomIn(); return true;
case KeyEvent.KEYCODE_ESCAPE:
final Intent currIntent = getIntent();
final String backUrl = Framework.nativeGetParsedBackUrl();
if (TextUtils.isEmpty(backUrl) || (currIntent != null && Factory.isStartedForApiResult(currIntent)))
{
finish();
return true;
}
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.location.TrackRecordingService;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Map;
import app.organicmaps.sdk.OrganicMaps;
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.maplayer.isolines.IsolinesManager;
import app.organicmaps.sdk.maplayer.subway.SubwayManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.ConnectionState;
import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.Utils;
import java.io.IOException;
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
{
return mOrganicMaps.init(() -> {
ThemeSwitcher.INSTANCE.initialize(this);
ThemeSwitcher.INSTANCE.restart(false);
ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver);
onComplete.run();
});

View File

@@ -62,39 +62,39 @@ public class LocalBackupManager implements BookmarkManager.BookmarksSharingListe
ErrorCode errorCode = null;
switch (result.getCode())
{
case BookmarkSharingResult.SUCCESS ->
{
if (!saveBackup(result))
case BookmarkSharingResult.SUCCESS ->
{
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;
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;
UiThread.run(() -> {

View File

@@ -66,47 +66,47 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<Recyc
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType)
{
case TYPE_ACTION_HEADER ->
{
View header = inflater.inflate(R.layout.item_bookmark_group_list_header, parent, false);
return new HeaderViewHolder(header);
}
case TYPE_CATEGORY_ITEM ->
{
View view = inflater.inflate(R.layout.item_bookmark_category, parent, false);
final CategoryViewHolder holder = new CategoryViewHolder(view);
view.setOnClickListener(new CategoryItemClickListener(holder));
view.setOnLongClickListener(new LongClickListener(holder));
return holder;
}
case TYPE_ACTION_ADD ->
{
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> {
if (mCategoryListCallback != null)
mCategoryListCallback.onAddButtonClick();
});
return new Holders.GeneralViewHolder(item);
}
case TYPE_ACTION_IMPORT ->
{
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> {
if (mCategoryListCallback != null)
mCategoryListCallback.onImportButtonClick();
});
return new Holders.GeneralViewHolder(item);
}
case TYPE_ACTION_EXPORT_ALL_AS_KMZ ->
{
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> {
if (mCategoryListCallback != null)
mCategoryListCallback.onExportButtonClick();
});
return new Holders.GeneralViewHolder(item);
}
default -> throw new AssertionError("Invalid item type: " + viewType);
case TYPE_ACTION_HEADER ->
{
View header = inflater.inflate(R.layout.item_bookmark_group_list_header, parent, false);
return new HeaderViewHolder(header);
}
case TYPE_CATEGORY_ITEM ->
{
View view = inflater.inflate(R.layout.item_bookmark_category, parent, false);
final CategoryViewHolder holder = new CategoryViewHolder(view);
view.setOnClickListener(new CategoryItemClickListener(holder));
view.setOnLongClickListener(new LongClickListener(holder));
return holder;
}
case TYPE_ACTION_ADD ->
{
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> {
if (mCategoryListCallback != null)
mCategoryListCallback.onAddButtonClick();
});
return new Holders.GeneralViewHolder(item);
}
case TYPE_ACTION_IMPORT ->
{
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> {
if (mCategoryListCallback != null)
mCategoryListCallback.onImportButtonClick();
});
return new Holders.GeneralViewHolder(item);
}
case TYPE_ACTION_EXPORT_ALL_AS_KMZ ->
{
View item = inflater.inflate(R.layout.item_bookmark_button, parent, false);
item.setOnClickListener(v -> {
if (mCategoryListCallback != null)
mCategoryListCallback.onExportButtonClick();
});
return new Holders.GeneralViewHolder(item);
}
default -> throw new AssertionError("Invalid item type: " + viewType);
}
}
@@ -116,44 +116,44 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<Recyc
int type = getItemViewType(position);
switch (type)
{
case TYPE_ACTION_HEADER ->
{
HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;
headerViewHolder.setAction(mMassOperationAction, BookmarkManager.INSTANCE.areAllCategoriesInvisible());
headerViewHolder.getText().setText(R.string.bookmark_lists);
}
case TYPE_CATEGORY_ITEM ->
{
final BookmarkCategory category = getCategoryByPosition(toCategoryPosition(position));
CategoryViewHolder categoryHolder = (CategoryViewHolder) holder;
categoryHolder.setEntity(category);
categoryHolder.setName(category.getName());
categoryHolder.setSize();
categoryHolder.setVisibilityState(category.isVisible());
ToggleVisibilityClickListener visibilityListener = new ToggleVisibilityClickListener(categoryHolder);
categoryHolder.setVisibilityListener(visibilityListener);
CategoryItemMoreClickListener moreClickListener = new CategoryItemMoreClickListener(categoryHolder);
categoryHolder.setMoreButtonClickListener(moreClickListener);
}
case TYPE_ACTION_ADD ->
{
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_add_list);
generalViewHolder.getText().setText(R.string.bookmarks_create_new_group);
}
case TYPE_ACTION_IMPORT ->
{
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_import);
generalViewHolder.getText().setText(R.string.bookmarks_import);
}
case TYPE_ACTION_EXPORT_ALL_AS_KMZ ->
{
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_export);
generalViewHolder.getText().setText(R.string.bookmarks_export);
}
default -> throw new AssertionError("Invalid item type: " + type);
case TYPE_ACTION_HEADER ->
{
HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;
headerViewHolder.setAction(mMassOperationAction, BookmarkManager.INSTANCE.areAllCategoriesInvisible());
headerViewHolder.getText().setText(R.string.bookmark_lists);
}
case TYPE_CATEGORY_ITEM ->
{
final BookmarkCategory category = getCategoryByPosition(toCategoryPosition(position));
CategoryViewHolder categoryHolder = (CategoryViewHolder) holder;
categoryHolder.setEntity(category);
categoryHolder.setName(category.getName());
categoryHolder.setSize();
categoryHolder.setVisibilityState(category.isVisible());
ToggleVisibilityClickListener visibilityListener = new ToggleVisibilityClickListener(categoryHolder);
categoryHolder.setVisibilityListener(visibilityListener);
CategoryItemMoreClickListener moreClickListener = new CategoryItemMoreClickListener(categoryHolder);
categoryHolder.setMoreButtonClickListener(moreClickListener);
}
case TYPE_ACTION_ADD ->
{
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_add_list);
generalViewHolder.getText().setText(R.string.bookmarks_create_new_group);
}
case TYPE_ACTION_IMPORT ->
{
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_import);
generalViewHolder.getText().setText(R.string.bookmarks_import);
}
case TYPE_ACTION_EXPORT_ALL_AS_KMZ ->
{
Holders.GeneralViewHolder generalViewHolder = (Holders.GeneralViewHolder) holder;
generalViewHolder.getImage().setImageResource(R.drawable.ic_export);
generalViewHolder.getText().setText(R.string.bookmarks_export);
}
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;
switch (viewType)
{
case TYPE_TRACK:
Holders.TrackViewHolder trackHolder =
new Holders.TrackViewHolder(inflater.inflate(R.layout.item_track, parent, false));
trackHolder.setOnClickListener(mClickListener);
trackHolder.setOnLongClickListener(mLongClickListener);
trackHolder.setTrackIconClickListener(mIconClickListener);
trackHolder.setMoreButtonClickListener(mMoreClickListener);
holder = trackHolder;
break;
case TYPE_BOOKMARK:
Holders.BookmarkViewHolder bookmarkHolder =
new Holders.BookmarkViewHolder(inflater.inflate(R.layout.item_bookmark, parent, false));
bookmarkHolder.setOnClickListener(mClickListener);
bookmarkHolder.setOnLongClickListener(mLongClickListener);
holder = bookmarkHolder;
break;
case TYPE_SECTION:
MaterialTextView tv = (MaterialTextView) inflater.inflate(R.layout.item_category_title, parent, false);
holder = new Holders.SectionViewHolder(tv);
break;
case TYPE_DESC:
View desc = inflater.inflate(R.layout.item_category_description, parent, false);
MaterialTextView moreBtn = desc.findViewById(R.id.more_btn);
MaterialTextView text = desc.findViewById(R.id.text);
MaterialTextView title = desc.findViewById(R.id.title);
setMoreButtonVisibility(text, moreBtn);
holder = new Holders.DescriptionViewHolder(desc, mSectionsDataSource.getCategory());
text.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
moreBtn.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
title.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
break;
case TYPE_TRACK:
Holders.TrackViewHolder trackHolder =
new Holders.TrackViewHolder(inflater.inflate(R.layout.item_track, parent, false));
trackHolder.setOnClickListener(mClickListener);
trackHolder.setOnLongClickListener(mLongClickListener);
trackHolder.setTrackIconClickListener(mIconClickListener);
trackHolder.setMoreButtonClickListener(mMoreClickListener);
holder = trackHolder;
break;
case TYPE_BOOKMARK:
Holders.BookmarkViewHolder bookmarkHolder =
new Holders.BookmarkViewHolder(inflater.inflate(R.layout.item_bookmark, parent, false));
bookmarkHolder.setOnClickListener(mClickListener);
bookmarkHolder.setOnLongClickListener(mLongClickListener);
holder = bookmarkHolder;
break;
case TYPE_SECTION:
MaterialTextView tv = (MaterialTextView) inflater.inflate(R.layout.item_category_title, parent, false);
holder = new Holders.SectionViewHolder(tv);
break;
case TYPE_DESC:
View desc = inflater.inflate(R.layout.item_category_description, parent, false);
MaterialTextView moreBtn = desc.findViewById(R.id.more_btn);
MaterialTextView text = desc.findViewById(R.id.text);
MaterialTextView title = desc.findViewById(R.id.title);
setMoreButtonVisibility(text, moreBtn);
holder = new Holders.DescriptionViewHolder(desc, mSectionsDataSource.getCategory());
text.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
moreBtn.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
title.setOnClickListener(v -> onMoreButtonClicked(text, moreBtn));
break;
}
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.Icon;
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.Track;
import app.organicmaps.sdk.search.BookmarkSearchListener;
@@ -552,12 +551,12 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
switch (adapter.getItemViewType(position))
{
case BookmarkListAdapter.TYPE_SECTION, BookmarkListAdapter.TYPE_DESC ->
{
return;
}
case BookmarkListAdapter.TYPE_BOOKMARK -> onBookmarkClicked(position, intent, adapter);
case BookmarkListAdapter.TYPE_TRACK -> onTrackClicked(position, intent, adapter);
case BookmarkListAdapter.TYPE_SECTION, BookmarkListAdapter.TYPE_DESC ->
{
return;
}
case BookmarkListAdapter.TYPE_BOOKMARK -> onBookmarkClicked(position, intent, adapter);
case BookmarkListAdapter.TYPE_TRACK -> onTrackClicked(position, intent, adapter);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -593,7 +592,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
if (mTrack == null)
return;
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();
String className = BookmarkColorDialogFragment.class.getName();
final FragmentFactory factory = manager.getFragmentFactory();
@@ -602,7 +601,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
dialogFragment.setArguments(args);
dialogFragment.setOnColorSetListener((colorPos) -> {
int from = mTrack.getColor();
int to = PredefinedColors.getColor(colorPos);
int to = BookmarkManager.ICONS.get(colorPos).argb();
if (from == to)
return;
BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to);
@@ -622,22 +621,22 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
switch (type)
{
case BookmarkListAdapter.TYPE_SECTION:
case BookmarkListAdapter.TYPE_DESC:
// Do nothing here?
break;
case BookmarkListAdapter.TYPE_SECTION:
case BookmarkListAdapter.TYPE_DESC:
// Do nothing here?
break;
case BookmarkListAdapter.TYPE_BOOKMARK:
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition);
MenuBottomSheetFragment.newInstance(BOOKMARKS_MENU_ID, bookmark.getName())
.show(getChildFragmentManager(), BOOKMARKS_MENU_ID);
break;
case BookmarkListAdapter.TYPE_BOOKMARK:
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition);
MenuBottomSheetFragment.newInstance(BOOKMARKS_MENU_ID, bookmark.getName())
.show(getChildFragmentManager(), BOOKMARKS_MENU_ID);
break;
case BookmarkListAdapter.TYPE_TRACK:
final Track track = (Track) adapter.getItem(mSelectedPosition);
MenuBottomSheetFragment.newInstance(TRACK_MENU_ID, track.getName())
.show(getChildFragmentManager(), TRACK_MENU_ID);
break;
case BookmarkListAdapter.TYPE_TRACK:
final Track track = (Track) adapter.getItem(mSelectedPosition);
MenuBottomSheetFragment.newInstance(TRACK_MENU_ID, track.getName())
.show(getChildFragmentManager(), TRACK_MENU_ID);
break;
}
}
@@ -844,19 +843,19 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
{
switch (id)
{
case BOOKMARKS_MENU_ID ->
{
return getBookmarkMenuItems();
}
case TRACK_MENU_ID ->
{
final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
return getTrackMenuItems(track);
}
case OPTIONS_MENU_ID ->
{
return getOptionsMenuItems();
}
case BOOKMARKS_MENU_ID ->
{
return getBookmarkMenuItems();
}
case TRACK_MENU_ID ->
{
final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
return getTrackMenuItems(track);
}
case OPTIONS_MENU_ID ->
{
return getOptionsMenuItems();
}
}
return null;
}

View File

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

View File

@@ -64,10 +64,10 @@ public class ChooseBookmarksSortingTypeFragment
{
switch (sortingType)
{
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_TIME: return R.id.sort_by_time;
case BookmarkManager.SORT_BY_NAME: return R.id.sort_by_name;
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_TIME: return R.id.sort_by_time;
case BookmarkManager.SORT_BY_NAME: return R.id.sort_by_name;
}
}
return R.id.sort_by_default;

View File

@@ -6,26 +6,19 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import androidx.annotation.DrawableRes;
import app.organicmaps.R;
import app.organicmaps.sdk.bookmarks.data.PredefinedColors;
import app.organicmaps.sdk.bookmarks.data.Icon;
import app.organicmaps.util.Graphics;
import com.google.android.material.imageview.ShapeableImageView;
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;
@DrawableRes
private final int mIconResId;
public ColorsAdapter(Context context, List<Integer> list, @DrawableRes int iconResId)
public IconsAdapter(Context context, List<Icon> list)
{
super(context, 0, 0, list);
mIconResId = iconResId;
}
@Override
@@ -42,19 +35,19 @@ public class ColorsAdapter extends ArrayAdapter<Integer>
else
holder = (SpinnerViewHolder) convertView.getTag();
@PredefinedColors.Color
final int color = Objects.requireNonNull(getItem(position));
final Icon icon = getItem(position);
Drawable circle;
if (color == mCheckedIconColor)
if (icon.getColor() == mCheckedIconColor)
{
circle = Graphics.drawCircleAndImage(PredefinedColors.getColor(mCheckedIconColor), R.dimen.track_circle_size,
mIconResId, R.dimen.bookmark_icon_size, getContext());
circle = Graphics.drawCircleAndImage(getItem(position).argb(), R.dimen.track_circle_size,
app.organicmaps.sdk.R.drawable.ic_bookmark_none, R.dimen.bookmark_icon_size,
getContext());
}
else
{
circle = Graphics.drawCircle(PredefinedColors.getColor(color), R.dimen.select_color_circle_size,
getContext().getResources());
circle =
Graphics.drawCircle(getItem(position).argb(), R.dimen.select_color_circle_size, getContext().getResources());
}
holder.icon.setImageDrawable(circle);
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.ThemeUtils;
import app.organicmaps.car.util.UserActionRequired;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.PlacePageActivationListener;
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.DisplayType;
import app.organicmaps.sdk.location.LocationState;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.LocationUtils;
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();
@NonNull
private final CarContext mCarContext;
@NonNull
private final Map mMap;
private final Map mMap = new Map(Car);
@NonNull
private Rect mVisibleArea = new Rect();
@@ -45,7 +42,6 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac
{
Logger.d(TAG, "SurfaceRenderer()");
mCarContext = carContext;
mMap = new Map(Car, MwmApplication.from(mCarContext).getLocationHelper());
mIsRunning = true;
lifecycle.addObserver(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.UiHelpers;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.location.LocationListener;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.sound.TtsPlayer;
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.UiHelpers;
import app.organicmaps.routing.ResultCodesHelper;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.bookmarks.data.Metadata;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.util.Config;
import java.util.Objects;

View File

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

View File

@@ -7,9 +7,9 @@ import androidx.car.app.CarContext;
import androidx.car.app.ScreenManager;
import app.organicmaps.car.screens.download.DownloadMapsScreen;
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
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.screens.NavigationScreen;
import app.organicmaps.car.screens.search.SearchScreen;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Map;
import app.organicmaps.sdk.api.ParsedSearchRequest;
import app.organicmaps.sdk.api.RequestType;
import app.organicmaps.sdk.display.DisplayManager;
import app.organicmaps.sdk.display.DisplayType;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.log.Logger;
public final class IntentUtils
@@ -65,36 +65,36 @@ public final class IntentUtils
final ScreenManager screenManager = carContext.getCarService(ScreenManager.class);
switch (Framework.nativeParseAndSetApiUrl(uri.toString()))
{
case RequestType.INCORRECT: return;
case RequestType.MAP:
screenManager.popToRoot();
Map.executeMapApiRequest();
return;
case RequestType.SEARCH:
screenManager.popToRoot();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{
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);
}
final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer);
builder.setQuery(request.mQuery);
if (request.mLocale != null)
builder.setLocale(request.mLocale);
case RequestType.INCORRECT: return;
case RequestType.MAP:
screenManager.popToRoot();
Map.executeMapApiRequest();
return;
case RequestType.SEARCH:
screenManager.popToRoot();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{
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);
}
final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer);
builder.setQuery(request.mQuery);
if (request.mLocale != null)
builder.setLocale(request.mLocale);
screenManager.popToRoot();
screenManager.push(builder.build());
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.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);
screenManager.popToRoot();
screenManager.push(builder.build());
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.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);
}
}

View File

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

View File

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

View File

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

View File

@@ -70,9 +70,9 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
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;

View File

@@ -20,9 +20,9 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
@@ -287,41 +287,41 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
switch (mSelectedItem.status)
{
case CountryItem.STATUS_DOWNLOADABLE: items.add(getDownloadMenuItem()); break;
case CountryItem.STATUS_DOWNLOADABLE: items.add(getDownloadMenuItem()); break;
case CountryItem.STATUS_UPDATABLE:
items.add(getUpdateMenuItem());
// Fallthrough
case CountryItem.STATUS_UPDATABLE:
items.add(getUpdateMenuItem());
// Fallthrough
case CountryItem.STATUS_DONE:
if (!mSelectedItem.isExpandable())
items.add(getExploreMenuItem());
appendDeleteMenuItem(items);
break;
case CountryItem.STATUS_FAILED:
items.add(getCancelMenuItem());
if (mSelectedItem.present)
{
case CountryItem.STATUS_DONE:
if (!mSelectedItem.isExpandable())
items.add(getExploreMenuItem());
appendDeleteMenuItem(items);
items.add(getExploreMenuItem());
}
break;
break;
case CountryItem.STATUS_PROGRESS:
case CountryItem.STATUS_APPLYING:
case CountryItem.STATUS_ENQUEUED:
items.add(getCancelMenuItem());
case CountryItem.STATUS_FAILED:
items.add(getCancelMenuItem());
if (mSelectedItem.present)
items.add(getExploreMenuItem());
break;
if (mSelectedItem.present)
{
appendDeleteMenuItem(items);
items.add(getExploreMenuItem());
}
break;
case CountryItem.STATUS_PARTLY:
items.add(getDownloadMenuItem());
appendDeleteMenuItem(items);
break;
case CountryItem.STATUS_PROGRESS:
case CountryItem.STATUS_APPLYING:
case CountryItem.STATUS_ENQUEUED:
items.add(getCancelMenuItem());
if (mSelectedItem.present)
items.add(getExploreMenuItem());
break;
case CountryItem.STATUS_PARTLY:
items.add(getDownloadMenuItem());
appendDeleteMenuItem(items);
break;
}
return items;
}
@@ -372,20 +372,20 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
{
switch (mItem.status)
{
case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING,
CountryItem.STATUS_ENQUEUED ->
processLongClick();
case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY ->
{
if (clickOnStatus)
onDownloadActionSelected(mItem, DownloaderAdapter.this);
else
case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING,
CountryItem.STATUS_ENQUEUED ->
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);
case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY ->
{
if (clickOnStatus)
onDownloadActionSelected(mItem, DownloaderAdapter.this);
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)
{
case CountryItem.CATEGORY_NEAR_ME ->
{
if (ci.category != prev)
case CountryItem.CATEGORY_NEAR_ME ->
{
headerId = CountryItem.CATEGORY_NEAR_ME;
mItemsAndHeader.add(new GenericItem(mActivity.getString(R.string.downloader_near_me_subtitle)));
if (ci.category != prev)
{
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;
}
}
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;
}
mItemsAndHeader.add(new GenericItem(ci));

View File

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

View File

@@ -9,9 +9,9 @@ import androidx.core.view.ViewCompat;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.ConnectionState;
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)
{
mExamplesTitle.setCompoundDrawablesRelativeWithIntrinsicBounds(
Graphics.tint(requireActivity(), left, com.google.android.material.R.attr.colorSecondary), null,
Graphics.tint(requireActivity(), right, com.google.android.material.R.attr.colorSecondary), null);
Graphics.tint(requireActivity(), left, androidx.appcompat.R.attr.colorAccent), null,
Graphics.tint(requireActivity(), right, androidx.appcompat.R.attr.colorAccent), null);
}
@Override

View File

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

View File

@@ -173,8 +173,8 @@ public class EditorHostFragment
{
switch (mMode)
{
case OPENING_HOURS, STREET, CUISINE, LANGUAGE, PHONE, SELF_SERVICE -> editMapObject();
default -> Utils.navigateToParent(requireActivity());
case OPENING_HOURS, STREET, CUISINE, LANGUAGE, PHONE, SELF_SERVICE -> editMapObject();
default -> Utils.navigateToParent(requireActivity());
}
return true;
}
@@ -283,57 +283,57 @@ public class EditorHostFragment
{
switch (mMode)
{
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))
case OPENING_HOURS ->
{
showNoobDialog();
}
else
{
saveNote();
saveMapObjectEdits();
}
}
case PHONE ->
{
final String phone =
((PhoneFragment) getChildFragmentManager().findFragmentByTag(PhoneFragment.class.getName())).getPhone();
if (Editor.nativeIsPhoneValid(phone))
{
Editor.nativeSetPhone(phone);
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();
}
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 app.organicmaps.R;
import app.organicmaps.sdk.editor.data.FeatureCategory;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textview.MaterialTextView;
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 FeatureCategory mSelectedCategory;
public interface FooterListener
{
void onNoteTextChanged(String newText);
void onSendNoteClicked();
}
public FeatureCategoryAdapter(@NonNull FeatureCategoryFragment host, @NonNull FeatureCategory[] categories,
@Nullable FeatureCategory category)
{
@@ -57,18 +49,17 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
{
switch (viewType)
{
case TYPE_CATEGORY ->
{
return new FeatureViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category, parent, false));
}
case TYPE_FOOTER ->
{
return new FooterViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false),
(FooterListener) mFragment);
}
default -> throw new IllegalArgumentException("Unsupported");
case TYPE_CATEGORY ->
{
return new FeatureViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category, parent, false));
}
case TYPE_FOOTER ->
{
return new FooterViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false));
}
default -> throw new IllegalArgumentException("Unsupported");
}
}
@@ -79,10 +70,6 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
{
((FeatureViewHolder) holder).bind(position);
}
else if (holder instanceof FooterViewHolder)
{
((FooterViewHolder) holder).bind(mFragment.getPendingNoteText());
}
}
@Override
@@ -118,36 +105,11 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
protected static class FooterViewHolder extends RecyclerView.ViewHolder
{
private final TextInputEditText mNoteEditText;
private final View mSendNoteButton;
FooterViewHolder(@NonNull View itemView, @NonNull FooterListener listener)
FooterViewHolder(@NonNull View itemView)
{
super(itemView);
MaterialTextView categoryUnsuitableText = itemView.findViewById(R.id.editor_category_unsuitable_text);
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 android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
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.OsmOAuth;
import app.organicmaps.sdk.editor.data.FeatureCategory;
import app.organicmaps.sdk.util.Language;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.SearchToolbarController;
import app.organicmaps.widget.ToolbarController;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Arrays;
import java.util.Comparator;
public class FeatureCategoryFragment
extends BaseMwmRecyclerFragment<FeatureCategoryAdapter> implements FeatureCategoryAdapter.FooterListener
public class FeatureCategoryFragment extends BaseMwmRecyclerFragment<FeatureCategoryAdapter>
{
private FeatureCategory mSelectedCategory;
protected ToolbarController mToolbarController;
private static final String NOTE_CONFIRMATION_SHOWN = "NoteConfirmationAlertWasShown";
private static String mPendingNoteText = "";
public interface FeatureCategoryListener
{
@@ -115,64 +104,4 @@ public class FeatureCategoryFragment
else if (getParentFragment() instanceof FeatureCategoryListener)
((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.recyclerview.widget.RecyclerView;
import app.organicmaps.R;
import app.organicmaps.editor.data.TimeFormatUtils;
import app.organicmaps.sdk.editor.OpeningHours;
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.Timetable;
import app.organicmaps.sdk.util.UiUtils;

View File

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

View File

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

View File

@@ -10,6 +10,7 @@ import androidx.core.content.IntentCompat;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.editor.OsmLoginActivity;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Map;
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.FeatureId;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.concurrency.ThreadPool;
@@ -78,67 +78,67 @@ public class Factory
switch (Framework.nativeParseAndSetApiUrl(uri.toString()))
{
case RequestType.INCORRECT: return false;
case RequestType.INCORRECT: return false;
case RequestType.MAP:
SearchEngine.INSTANCE.cancelInteractiveSearch();
Map.executeMapApiRequest();
return true;
case RequestType.MAP:
SearchEngine.INSTANCE.cancelInteractiveSearch();
Map.executeMapApiRequest();
return true;
case RequestType.ROUTE:
SearchEngine.INSTANCE.cancelInteractiveSearch();
final ParsedRoutingData data = Framework.nativeGetParsedRoutingData();
RoutingController.get().setRouterType(data.mRouterType);
final RoutePoint from = data.mPoints[0];
final RoutePoint to = data.mPoints[1];
RoutingController.get().prepare(
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));
return true;
case RequestType.SEARCH:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
case RequestType.ROUTE:
SearchEngine.INSTANCE.cancelInteractiveSearch();
final ParsedRoutingData data = Framework.nativeGetParsedRoutingData();
RoutingController.get().setRouterType(data.mRouterType);
final RoutePoint from = data.mPoints[0];
final RoutePoint to = data.mPoints[1];
RoutingController.get().prepare(
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));
return true;
case RequestType.SEARCH:
{
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);
SearchEngine.INSTANCE.cancelInteractiveSearch();
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
{
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);
return true;
}
case RequestType.CROSSHAIR:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
target.showPositionChooserForAPI(Framework.nativeGetParsedAppName());
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
if (latlon != null)
case RequestType.CROSSHAIR:
{
Framework.nativeStopLocationFollow();
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
SearchEngine.INSTANCE.cancelInteractiveSearch();
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;
}
case RequestType.OAUTH2:
{
SearchEngine.INSTANCE.cancelInteractiveSearch();
final String oauth2code = Framework.nativeGetParsedOAuth2Code();
OsmLoginActivity.OAuth2Callback(target, oauth2code);
return true;
}
// Menu and Settings url types should be implemented to support deeplinking.
case RequestType.MENU:
case RequestType.SETTINGS:
// Menu and Settings url types should be implemented to support deeplinking.
case RequestType.MENU:
case RequestType.SETTINGS:
}
return false;

View File

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

View File

@@ -26,6 +26,7 @@ import app.organicmaps.MwmActivity;
import app.organicmaps.R;
import app.organicmaps.leftbutton.LeftButton;
import app.organicmaps.leftbutton.LeftToggleButton;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.downloader.MapManager;
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.subway.SubwayManager;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.ThemeUtils;
@@ -230,21 +230,21 @@ public class MapButtonsController extends Fragment
return;
switch (button)
{
case zoom: UiUtils.showIf(show && Config.showZoomButtons(), buttonView); break;
case toggleMapLayer:
if (mToggleMapLayerButton != null)
UiUtils.showIf(show && !isInNavigationMode(), mToggleMapLayerButton);
break;
case myPosition:
if (mNavMyPosition != null)
mNavMyPosition.showButton(show);
break;
case search: mSearchWheel.show(show);
case bookmarks:
case menu: UiUtils.showIf(show, buttonView); break;
case trackRecordingStatus:
UiUtils.showIf(show, buttonView);
animateIconBlinking(show, (FloatingActionButton) buttonView);
case zoom: UiUtils.showIf(show && Config.showZoomButtons(), buttonView); break;
case toggleMapLayer:
if (mToggleMapLayerButton != null)
UiUtils.showIf(show && !isInNavigationMode(), mToggleMapLayerButton);
break;
case myPosition:
if (mNavMyPosition != null)
mNavMyPosition.showButton(show);
break;
case search: mSearchWheel.show(show);
case bookmarks:
case menu: UiUtils.showIf(show, buttonView); break;
case trackRecordingStatus:
UiUtils.showIf(show, buttonView);
animateIconBlinking(show, (FloatingActionButton) buttonView);
}
}

View File

@@ -14,7 +14,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
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.util.UiUtils;
import app.organicmaps.sdk.util.concurrency.UiThread;
@@ -215,7 +215,7 @@ public class SearchWheel implements View.OnClickListener
final SearchOption searchOption = mMapButtonsViewModel.getSearchOption().getValue();
mSearchButton.setImageDrawable(Graphics.tint(
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

View File

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

View File

@@ -15,7 +15,6 @@ import app.organicmaps.R;
import app.organicmaps.adapter.DisabledChildSimpleExpandableListAdapter;
import app.organicmaps.base.BaseMwmDialogFragment;
import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,76 +23,76 @@ public class ResultCodesHelper
int cancelBtnResId = android.R.string.cancel;
switch (errorCode)
{
case ResultCodes.NO_POSITION:
if (!MwmApplication.from(context).getLocationHelper().isActive())
{
titleRes = R.string.dialog_routing_location_turn_on;
messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on));
}
else
{
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_location_turn_wifi));
}
break;
case ResultCodes.INCONSISTENT_MWM_ROUTE:
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
{
case ResultCodes.NO_POSITION:
if (!MwmApplication.from(context).getLocationHelper().isActive())
{
titleRes = R.string.dialog_routing_location_turn_on;
messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on));
}
else
{
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_location_turn_wifi));
}
break;
case ResultCodes.INCONSISTENT_MWM_ROUTE:
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.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;
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;
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();

View File

@@ -32,7 +32,6 @@ import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.TransitRouteInfo;
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.util.Graphics;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.DotDividerItemDecoration;
import app.organicmaps.widget.recycler.MultilineLayoutManager;
import com.google.android.material.imageview.ShapeableImageView;
@@ -119,11 +117,10 @@ final class RoutingBottomMenuController implements View.OnClickListener
private RoutingBottomMenuController(@NonNull Activity context, @NonNull View altitudeChartFrame,
@NonNull View timeElevationLine, @NonNull View transitFrame,
@NonNull MaterialTextView error, @NonNull Button start,
@NonNull ImageView altitudeChart, @NonNull MaterialTextView time,
@NonNull MaterialTextView altitudeDifference, @NonNull TextView timeVehicle,
@Nullable MaterialTextView arrival, @NonNull View actionFrame,
@Nullable RoutingBottomMenuListener listener)
@NonNull MaterialTextView error, @NonNull Button start, @NonNull ImageView altitudeChart,
@NonNull MaterialTextView time, @NonNull MaterialTextView altitudeDifference,
@NonNull TextView timeVehicle, @Nullable MaterialTextView arrival,
@NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener)
{
mContext = context;
mAltitudeChartFrame = altitudeChartFrame;
@@ -194,7 +191,8 @@ final class RoutingBottomMenuController implements View.OnClickListener
scrollToBottom(rv);
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 pedestrianIcon = mTransitFrame.findViewById(R.id.pedestrian_icon);
MaterialTextView distanceView = mTransitFrame.findViewById(R.id.total_distance);
@@ -263,9 +261,9 @@ final class RoutingBottomMenuController implements View.OnClickListener
{
UiUtils.show(mActionButton);
Drawable icon = ContextCompat.getDrawable(mContext, R.drawable.ic_location_crosshair);
int colorSecondary = ContextCompat.getColor(
mContext, UiUtils.getStyledResourceId(mContext, com.google.android.material.R.attr.colorSecondary));
mActionIcon.setImageDrawable(Graphics.tint(icon, colorSecondary));
int colorAccent = ContextCompat.getColor(
mContext, UiUtils.getStyledResourceId(mContext, androidx.appcompat.R.attr.colorAccent));
mActionIcon.setImageDrawable(Graphics.tint(icon, colorAccent));
}
else
{
@@ -384,7 +382,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
if (mArrival != null)
{
String arrivalTime = Utils.formatArrivalTime(rinfo.totalTimeInSeconds);
String arrivalTime = RoutingController.formatArrivalTime(rinfo.totalTimeInSeconds);
mArrival.setText(arrivalTime);
}
}
@@ -402,7 +400,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
{
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();
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 androidx.annotation.DimenRes;
import androidx.annotation.IntRange;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.util.Pair;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.bookmarks.data.FeatureId;
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.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
public class RoutingController
@@ -95,7 +114,7 @@ public class RoutingController
mLastMissingMaps = missingMaps;
mContainsCachedResult = true;
if (mLastResultCode == ResultCodes.NO_ERROR || resultCode == ResultCodes.NEED_MORE_MAPS)
if (mLastResultCode == ResultCodes.NO_ERROR || ResultCodesHelper.isMoreMapsNeeded(mLastResultCode))
{
onBuiltRoute();
}
@@ -161,7 +180,7 @@ public class RoutingController
return;
}
if (mLastResultCode != ResultCodes.NEED_MORE_MAPS)
if (!ResultCodesHelper.isMoreMapsNeeded(mLastResultCode))
{
setBuildState(BuildState.ERROR);
mLastBuildProgress = 0;
@@ -176,7 +195,8 @@ public class RoutingController
private boolean isDrivingOptionsBuildError()
{
return mLastResultCode != ResultCodes.NEED_MORE_MAPS && RoutingOptions.hasAnyOptions() && !isRulerRouterType();
return !ResultCodesHelper.isMoreMapsNeeded(mLastResultCode) && RoutingOptions.hasAnyOptions()
&& !isRulerRouterType();
}
private void setState(State newState)
@@ -230,7 +250,7 @@ public class RoutingController
mContainer = container;
}
public void initialize(@NonNull LocationHelper locationHelper)
public void initialize(@NonNull Context context)
{
mLastRouterType = Router.getLastUsed();
mInvalidRoutePointsTransactionId = Framework.nativeInvalidRoutePointsTransactionId();
@@ -240,7 +260,7 @@ public class RoutingController
Framework.nativeSetRouteProgressListener(mRoutingProgressListener);
Framework.nativeSetRoutingRecommendationListener(recommendation -> UiThread.run(() -> {
if (recommendation == RouteRecommendationType.RebuildAfterPointsLoading)
setStartPoint(locationHelper.getMyPosition());
setStartPoint(MwmApplication.from(context).getLocationHelper().getMyPosition());
}));
Framework.nativeSetRoutingLoadPointsListener(mRoutingLoadPointsListener);
}
@@ -537,7 +557,7 @@ public class RoutingController
return mLastRouterType == Router.Vehicle;
}
public boolean isRulerRouterType()
boolean isRulerRouterType()
{
return mLastRouterType == Router.Ruler;
}
@@ -863,4 +883,26 @@ public class RoutingController
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

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

View File

@@ -11,7 +11,6 @@ import androidx.fragment.app.FragmentFactory;
import app.organicmaps.R;
import app.organicmaps.sdk.downloader.CountryItem;
import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.widget.WheelProgressView;
import java.util.HashSet;

View File

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

View File

@@ -10,7 +10,6 @@ import app.organicmaps.MwmActivity;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmFragment;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.RoutingController;
public class RoutingPlanFragment extends BaseMwmFragment
{

View File

@@ -4,9 +4,9 @@ import android.content.Context;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.Surface;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.BuildConfig;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.display.DisplayType;
import app.organicmaps.sdk.location.LocationHelper;
@@ -53,12 +53,8 @@ public final class Map
public static final int INVALID_POINTER_MASK = 0xFF;
public static final int INVALID_TOUCH_ID = -1;
@NonNull
private final DisplayType mDisplayType;
@NonNull
private final LocationHelper mLocationHelper;
private int mCurrentCompassOffsetX;
private int mCurrentCompassOffsetY;
private int mBottomWidgetOffsetX;
@@ -79,10 +75,9 @@ public final class Map
private static int sCurrentDpi = 0;
public Map(@NonNull DisplayType mapType, @NonNull LocationHelper locationHelper)
public Map(DisplayType mapType)
{
mDisplayType = mapType;
mLocationHelper = locationHelper;
onCreate(false);
}
@@ -174,7 +169,9 @@ public final class Map
mRequireResize = false;
setupWidgets(context, surfaceFrame.width(), surfaceFrame.height());
final boolean firstStart = mLocationHelper.isInFirstRun();
final LocationHelper locationHelper = MwmApplication.from(context).getLocationHelper();
final boolean firstStart = locationHelper.isInFirstRun();
if (!nativeCreateEngine(surface, surfaceDpi, firstStart, mLaunchByDeepLink, BuildConfig.VERSION_CODE,
ROMUtils.isCustomROM()))
{
@@ -185,7 +182,7 @@ public final class Map
sCurrentDpi = surfaceDpi;
if (firstStart)
UiThread.runLater(mLocationHelper::onExitFromFirstRun);
UiThread.runLater(locationHelper::onExitFromFirstRun);
mSurfaceCreated = true;
mSurfaceAttached = true;

View File

@@ -7,8 +7,8 @@ import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
import app.organicmaps.sdk.bookmarks.data.Icon;
import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround;
import app.organicmaps.sdk.editor.OsmOAuth;
import app.organicmaps.sdk.location.LocationHelper;
@@ -16,16 +16,16 @@ import app.organicmaps.sdk.location.SensorHelper;
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
import app.organicmaps.sdk.maplayer.subway.SubwayManager;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.settings.StoragePathManager;
import app.organicmaps.sdk.sound.TtsPlayer;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.ThemeSwitcher;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.util.log.LogsManager;
import app.organicmaps.settings.StoragePathManager;
import java.io.IOException;
public final class OrganicMaps implements DefaultLifecycleObserver
@@ -96,11 +96,9 @@ public final class OrganicMaps implements DefaultLifecycleObserver
Android7RootCertificateWorkaround.initializeIfNeeded(mContext);
Icon.loadDefaultIcons(mContext.getResources(), mContext.getPackageName());
mSensorHelper = new SensorHelper(mContext);
mLocationHelper = new LocationHelper(mContext, mSensorHelper);
mIsolinesManager = new IsolinesManager();
mIsolinesManager = new IsolinesManager(mContext);
mSubwayManager = new SubwayManager(mContext);
}
@@ -176,10 +174,12 @@ public final class OrganicMaps implements DefaultLifecycleObserver
nativeInitFramework(onComplete);
initNativeStrings();
ThemeSwitcher.INSTANCE.initialize(mContext);
SearchEngine.INSTANCE.initialize();
BookmarkManager.loadBookmarks();
TtsPlayer.INSTANCE.initialize(mContext);
RoutingController.get().initialize(mLocationHelper);
ThemeSwitcher.INSTANCE.restart(false);
RoutingController.get().initialize(mContext);
TrafficManager.INSTANCE.initialize();
mSubwayManager.initialize();
mIsolinesManager.initialize();

View File

@@ -10,12 +10,12 @@ import java.lang.annotation.RetentionPolicy;
public @interface RequestType
{
// Represents url_scheme::ParsedMapApi::UrlType from c++ part.
int INCORRECT = 0;
int MAP = 1;
int ROUTE = 2;
int SEARCH = 3;
int CROSSHAIR = 4;
int OAUTH2 = 5;
int MENU = 6;
int SETTINGS = 7;
public static final int INCORRECT = 0;
public static final int MAP = 1;
public static final int ROUTE = 2;
public static final int SEARCH = 3;
public static final int CROSSHAIR = 4;
public static final int OAUTH2 = 5;
public static final int MENU = 6;
public static final int SETTINGS = 7;
}

View File

@@ -41,6 +41,8 @@ public enum BookmarkManager {
// These values have to match the values of kml::CompilationType from kml/types.hpp
public static final int CATEGORY = 0;
public static final List<Icon> ICONS = new ArrayList<>();
private static final String[] BOOKMARKS_EXTENSIONS = Framework.nativeGetBookmarksFilesExts();
private static final String TAG = BookmarkManager.class.getSimpleName();
@@ -68,6 +70,26 @@ public enum BookmarkManager {
@Nullable
private OnElevationActivePointChangedListener mOnElevationActivePointChangedListener;
static
{
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_RED, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_PINK, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_PURPLE, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_DEEPPURPLE, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_BLUE, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_LIGHTBLUE, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_CYAN, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_TEAL, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_GREEN, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_LIME, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_YELLOW, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_ORANGE, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_DEEPORANGE, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_BROWN, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_GRAY, Icon.BOOKMARK_ICON_TYPE_NONE));
ICONS.add(new Icon(Icon.PREDEFINED_COLOR_BLUEGRAY, Icon.BOOKMARK_ICON_TYPE_NONE));
}
public void toggleCategoryVisibility(@NonNull BookmarkCategory category)
{
boolean isVisible = isVisible(category.getId());
@@ -320,7 +342,7 @@ public enum BookmarkManager {
nativeShowBookmarkCategoryOnMap(catId);
}
@PredefinedColors.Color
@Icon.PredefinedColor
public int getLastEditedColor()
{
return nativeGetLastEditedColor();
@@ -596,7 +618,7 @@ public enum BookmarkManager {
return nativeGetBookmarkXY(bookmarkId);
}
@PredefinedColors.Color
@Icon.PredefinedColor
public int getBookmarkColor(@IntRange(from = 0) long bookmarkId)
{
return nativeGetBookmarkColor(bookmarkId);
@@ -630,7 +652,7 @@ public enum BookmarkManager {
}
public void setBookmarkParams(@IntRange(from = 0) long bookmarkId, @NonNull String name,
@PredefinedColors.Color int color, @NonNull String descr)
@Icon.PredefinedColor int color, @NonNull String descr)
{
nativeSetBookmarkParams(bookmarkId, name, color, descr);
}
@@ -786,7 +808,7 @@ public enum BookmarkManager {
@Nullable
private native Bookmark nativeAddBookmarkToLastEditedCategory(double lat, double lon);
@PredefinedColors.Color
@Icon.PredefinedColor
private native int nativeGetLastEditedColor();
private static native void nativeLoadBookmarksFile(@NonNull String path, boolean isTemporaryFile);
@@ -852,7 +874,7 @@ public enum BookmarkManager {
@NonNull
private static native ParcelablePointD nativeGetBookmarkXY(@IntRange(from = 0) long bookmarkId);
@PredefinedColors.Color
@Icon.PredefinedColor
private static native int nativeGetBookmarkColor(@IntRange(from = 0) long bookmarkId);
private static native int nativeGetBookmarkIcon(@IntRange(from = 0) long bookmarkId);
@@ -867,13 +889,12 @@ public enum BookmarkManager {
private static native String nativeEncode2Ge0Url(@IntRange(from = 0) long bookmarkId, boolean addName);
private static native void nativeSetBookmarkParams(@IntRange(from = 0) long bookmarkId, @NonNull String name,
@PredefinedColors.Color int color, @NonNull String descr);
@Icon.PredefinedColor int color, @NonNull String descr);
private static native void nativeChangeTrackColor(@IntRange(from = 0) long trackId,
@PredefinedColors.Color int color);
private static native void nativeChangeTrackColor(@IntRange(from = 0) long trackId, @Icon.PredefinedColor int color);
private static native void nativeSetTrackParams(@IntRange(from = 0) long trackId, @NonNull String name,
@PredefinedColors.Color int color, @NonNull String descr);
@Icon.PredefinedColor int color, @NonNull String descr);
private static native void nativeChangeBookmarkCategory(@IntRange(from = 0) long oldCatId,
@IntRange(from = 0) long newCatId,

View File

@@ -1,29 +1,108 @@
package app.organicmaps.sdk.bookmarks.data;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.BuildConfig;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.log.Logger;
import androidx.annotation.IntDef;
import app.organicmaps.sdk.R;
import com.google.common.base.Objects;
import dalvik.annotation.optimization.FastNative;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class Icon implements Parcelable
{
private static final String TAG = Icon.class.getSimpleName();
@Retention(RetentionPolicy.SOURCE)
@IntDef({PREDEFINED_COLOR_NONE, PREDEFINED_COLOR_RED, PREDEFINED_COLOR_BLUE, PREDEFINED_COLOR_PURPLE,
PREDEFINED_COLOR_YELLOW, PREDEFINED_COLOR_PINK, PREDEFINED_COLOR_BROWN, PREDEFINED_COLOR_GREEN,
PREDEFINED_COLOR_ORANGE, PREDEFINED_COLOR_DEEPPURPLE, PREDEFINED_COLOR_LIGHTBLUE, PREDEFINED_COLOR_CYAN,
PREDEFINED_COLOR_TEAL, PREDEFINED_COLOR_LIME, PREDEFINED_COLOR_DEEPORANGE, PREDEFINED_COLOR_GRAY,
PREDEFINED_COLOR_BLUEGRAY})
@interface PredefinedColor
{}
static final int PREDEFINED_COLOR_NONE = 0;
static final int PREDEFINED_COLOR_RED = 1;
static final int PREDEFINED_COLOR_BLUE = 2;
static final int PREDEFINED_COLOR_PURPLE = 3;
static final int PREDEFINED_COLOR_YELLOW = 4;
static final int PREDEFINED_COLOR_PINK = 5;
static final int PREDEFINED_COLOR_BROWN = 6;
static final int PREDEFINED_COLOR_GREEN = 7;
static final int PREDEFINED_COLOR_ORANGE = 8;
static final int PREDEFINED_COLOR_DEEPPURPLE = 9;
static final int PREDEFINED_COLOR_LIGHTBLUE = 10;
static final int PREDEFINED_COLOR_CYAN = 11;
static final int PREDEFINED_COLOR_TEAL = 12;
static final int PREDEFINED_COLOR_LIME = 13;
static final int PREDEFINED_COLOR_DEEPORANGE = 14;
static final int PREDEFINED_COLOR_GRAY = 15;
static final int PREDEFINED_COLOR_BLUEGRAY = 16;
private static int shift(int v, int bitCount)
{
return v << bitCount;
}
private static int toARGB(int r, int g, int b)
{
return shift(255, 24) + shift(r, 16) + shift(g, 8) + b;
}
/// @note Important! Should be synced with kml/types.hpp/PredefinedColor
/// @todo Values can be taken from Core.
private static final int[] ARGB_COLORS = {toARGB(229, 27, 35), // none
toARGB(229, 27, 35), // red
toARGB(0, 110, 199), // blue
toARGB(156, 39, 176), // purple
toARGB(255, 200, 0), // yellow
toARGB(255, 65, 130), // pink
toARGB(121, 85, 72), // brown
toARGB(56, 142, 60), // green
toARGB(255, 160, 0), // orange
toARGB(102, 57, 191), // deeppurple
toARGB(36, 156, 242), // lightblue
toARGB(20, 190, 205), // cyan
toARGB(0, 165, 140), // teal
toARGB(147, 191, 57), // lime
toARGB(240, 100, 50), // deeporange
toARGB(115, 115, 115), // gray
toARGB(89, 115, 128)}; // bluegray
static final int BOOKMARK_ICON_TYPE_NONE = 0;
/// @note Important! Should be synced with kml/types.hpp/BookmarkIcon
/// @todo Can make better: take name-by-type from Core and make a concat: "R.drawable.ic_bookmark_" + name.
// First icon should be "none" <-> BOOKMARK_ICON_TYPE_NONE.
@DrawableRes
private static int[] sTypeIcons = null;
private static final int[] TYPE_ICONS = {
R.drawable.ic_bookmark_none, R.drawable.ic_bookmark_hotel, R.drawable.ic_bookmark_animals,
R.drawable.ic_bookmark_buddhism, R.drawable.ic_bookmark_building, R.drawable.ic_bookmark_christianity,
R.drawable.ic_bookmark_entertainment, R.drawable.ic_bookmark_money, R.drawable.ic_bookmark_food,
R.drawable.ic_bookmark_gas, R.drawable.ic_bookmark_judaism, R.drawable.ic_bookmark_medicine,
R.drawable.ic_bookmark_mountain, R.drawable.ic_bookmark_museum, R.drawable.ic_bookmark_islam,
R.drawable.ic_bookmark_park, R.drawable.ic_bookmark_parking, R.drawable.ic_bookmark_shop,
R.drawable.ic_bookmark_sights, R.drawable.ic_bookmark_swim, R.drawable.ic_bookmark_water,
R.drawable.ic_bookmark_bar, R.drawable.ic_bookmark_transport, R.drawable.ic_bookmark_viewpoint,
R.drawable.ic_bookmark_sport,
R.drawable.ic_bookmark_none, // pub
R.drawable.ic_bookmark_none, // art
R.drawable.ic_bookmark_none, // bank
R.drawable.ic_bookmark_none, // cafe
R.drawable.ic_bookmark_none, // pharmacy
R.drawable.ic_bookmark_none, // stadium
R.drawable.ic_bookmark_none, // theatre
R.drawable.ic_bookmark_none, // information
R.drawable.ic_bookmark_none, // ChargingStation
R.drawable.ic_bookmark_none, // BicycleParking
R.drawable.ic_bookmark_none, // BicycleParkingCovered
R.drawable.ic_bookmark_none, // BicycleRental
R.drawable.ic_bookmark_none // FastFood
};
@PredefinedColors.Color
@PredefinedColor
private final int mColor;
private final int mType;
public Icon(@PredefinedColors.Color int color, int type)
public Icon(@PredefinedColor int color, int type)
{
mColor = color;
mType = type;
@@ -48,29 +127,31 @@ public class Icon implements Parcelable
mType = in.readInt();
}
@PredefinedColors.Color
@PredefinedColor
public int getColor()
{
return mColor;
}
@ColorInt
public int argb()
{
return PredefinedColors.getColor(mColor);
return ARGB_COLORS[mColor];
}
public static int getColorPosition(int color)
{
for (int index = 1; index < ARGB_COLORS.length; index++)
{
if (ARGB_COLORS[index] == color)
return index;
}
return -1;
}
@DrawableRes
public int getResId()
{
// loadDefaultIcons should be called
assert (sTypeIcons != null);
return sTypeIcons[mType];
}
public int getType()
{
return mType;
return TYPE_ICONS[mType];
}
@Override
@@ -100,29 +181,4 @@ public class Icon implements Parcelable
return new Icon[size];
}
};
static public void loadDefaultIcons(@NonNull Resources resources, @NonNull String packageName)
{
final String[] names = nativeGetBookmarkIconNames();
int[] icons = new int[names.length];
for (int i = 0; i < names.length; i++)
{
final String name = StringUtils.toSnakeCase(names[i]);
icons[i] = resources.getIdentifier("ic_bookmark_" + name, "drawable", packageName);
if (icons[i] == 0)
{
Logger.e(TAG, "Error getting icon for " + name);
// Force devs to add an icon for each bookmark type.
if (BuildConfig.DEBUG)
throw new RuntimeException("Error getting icon for " + name);
icons[i] = app.organicmaps.sdk.R.drawable.ic_bookmark_none; // Fallback icon
}
}
sTypeIcons = icons;
}
@FastNative
@NonNull
private static native String[] nativeGetBookmarkIconNames();
}

View File

@@ -1,50 +0,0 @@
package app.organicmaps.sdk.bookmarks.data;
import androidx.annotation.ColorInt;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import dalvik.annotation.optimization.FastNative;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.stream.IntStream;
public class PredefinedColors
{
@Retention(RetentionPolicy.SOURCE)
@IntRange(from = 0)
public @interface Color
{}
/// @note Color format: ARGB
@ColorInt
private static final int[] PREDEFINED_COLORS = nativeGetPredefinedColors();
@ColorInt
public static int getColor(int index)
{
return PREDEFINED_COLORS[index];
}
@PredefinedColors.Color
public static List<Integer> getAllPredefinedColors()
{
// 0 is reserved for "no color" option.
return IntStream.range(1, PREDEFINED_COLORS.length).boxed().toList();
}
public static int getPredefinedColorIndex(@ColorInt int color)
{
// 0 is reserved for "no color" option.
for (int index = 1; index < PREDEFINED_COLORS.length; index++)
{
if (PREDEFINED_COLORS[index] == color)
return index;
}
return -1;
}
@FastNative
@NonNull
private static native int[] nativeGetPredefinedColors();
}

View File

@@ -161,7 +161,6 @@ public final class Editor
public static native void nativeCreateNote(String text);
public static native void nativePlaceDoesNotExist(@NonNull String comment);
public static native void nativeRollbackMapObject();
public static native void nativeCreateStandaloneNote(double lat, double lon, String text);
/**
* @return all cuisines keys.

View File

@@ -16,12 +16,13 @@ import androidx.annotation.UiThread;
import androidx.core.content.ContextCompat;
import androidx.core.location.GnssStatusCompat;
import androidx.core.location.LocationManagerCompat;
import app.organicmaps.MwmApplication;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Map;
import app.organicmaps.sdk.bookmarks.data.FeatureId;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.NetworkPolicy;

View File

@@ -45,16 +45,16 @@ public class SensorHelper implements SensorEventListener
mLastAccuracy = event.accuracy;
switch (mLastAccuracy)
{
case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: break;
case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
for (SensorListener listener : mListeners)
listener.onCompassCalibrationRecommended();
break;
case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
case SensorManager.SENSOR_STATUS_UNRELIABLE:
default:
for (SensorListener listener : mListeners)
listener.onCompassCalibrationRequired();
case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: break;
case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
for (SensorListener listener : mListeners)
listener.onCompassCalibrationRecommended();
break;
case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
case SensorManager.SENSOR_STATUS_UNRELIABLE:
default:
for (SensorListener listener : mListeners)
listener.onCompassCalibrationRequired();
}
}

View File

@@ -6,6 +6,7 @@ import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
import app.organicmaps.sdk.maplayer.subway.SubwayManager;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.util.ThemeSwitcher;
public enum Mode
{
@@ -60,8 +61,7 @@ public enum Mode
public void setEnabled(@NonNull Context context, boolean isEnabled)
{
Framework.nativeSetOutdoorsLayerEnabled(isEnabled);
// TODO: ThemeSwitcher is outside sdk package. Properly fix dependencies
// ThemeSwitcher.INSTANCE.restart(true);
ThemeSwitcher.INSTANCE.restart(true);
}
};

View File

@@ -1,12 +1,18 @@
package app.organicmaps.sdk.maplayer.isolines;
import android.content.Context;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.Framework;
public class IsolinesManager
{
@NonNull
private final OnIsolinesChangedListener mListener = new OnIsolinesChangedListener();
private final OnIsolinesChangedListener mListener;
public IsolinesManager(@NonNull Context context)
{
mListener = new OnIsolinesChangedListener(context);
}
static public boolean isEnabled()
{

View File

@@ -1,9 +1,40 @@
package app.organicmaps.sdk.maplayer.isolines;
import android.content.Context;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.R;
import app.organicmaps.util.Utils;
public enum IsolinesState
{
DISABLED,
ENABLED,
EXPIREDDATA,
NODATA;
EXPIREDDATA {
@Override
public void activate(@NonNull Context context, @Nullable View view, @Nullable View viewAbove)
{
if (view != null)
Utils.showSnackbar(context, view, viewAbove, R.string.isolines_activation_error_dialog);
else
Toast.makeText(context, R.string.isolines_activation_error_dialog, Toast.LENGTH_SHORT).show();
}
},
NODATA {
@Override
public void activate(@NonNull Context context, @Nullable View view, @Nullable View viewAbove)
{
if (view != null)
Utils.showSnackbar(context, view, viewAbove, R.string.isolines_location_error_dialog);
else
Toast.makeText(context, R.string.isolines_location_error_dialog, Toast.LENGTH_SHORT).show();
}
};
public void activate(@NonNull Context context, @Nullable View viewAbove, @Nullable View view)
{
/* Do nothing by default */
}
}

View File

@@ -1,22 +1,33 @@
package app.organicmaps.sdk.maplayer.isolines;
import android.content.Context;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
class OnIsolinesChangedListener
{
@Nullable
@NonNull
private final Context mContext;
private IsolinesErrorDialogListener mListener;
OnIsolinesChangedListener(@NonNull Context app)
{
mContext = app;
}
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public void onStateChanged(int type)
{
IsolinesState state = IsolinesState.values()[type];
if (mListener == null)
{
state.activate(mContext, null, null);
return;
mListener.onStateChanged(IsolinesState.values()[type]);
}
mListener.onStateChanged(state);
}
public void attach(@NonNull IsolinesErrorDialogListener listener)

View File

@@ -34,10 +34,10 @@ public final class RoutePointInfo implements Parcelable
{
switch (markType)
{
case 0: mMarkType = RouteMarkType.Start; break;
case 1: mMarkType = RouteMarkType.Intermediate; break;
case 2: mMarkType = RouteMarkType.Finish; break;
default: throw new IllegalArgumentException("Mark type is not valid = " + markType);
case 0: mMarkType = RouteMarkType.Start; break;
case 1: mMarkType = RouteMarkType.Intermediate; break;
case 2: mMarkType = RouteMarkType.Finish; break;
default: throw new IllegalArgumentException("Mark type is not valid = " + markType);
}
mIntermediateIndex = intermediateIndex;

View File

@@ -1,6 +1,7 @@
package app.organicmaps.sdk.sound;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
@@ -9,9 +10,9 @@ import android.provider.Settings;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.text.TextUtils;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.R;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.concurrency.UiThread;
import app.organicmaps.sdk.util.log.Logger;
@@ -42,9 +43,6 @@ public enum TtsPlayer
private static final float SPEECH_RATE = 1.0f;
private static final int TTS_SPEAK_DELAY_MILLIS = 50;
@Nullable
private static List<Pair<String, String>> sSupportedLanguages = null;
public static Runnable sOnReloadCallback = null;
private ContentObserver mTtsEngineObserver;
@@ -288,15 +286,19 @@ public enum TtsPlayer
private boolean getUsableLanguages(List<LanguageData> outList)
{
for (final Pair<String, String> langNamePair : getSupportedLanguages())
Resources resources = mContext.getResources();
String[] codes = resources.getStringArray(R.array.tts_languages_supported);
String[] names = resources.getStringArray(R.array.tts_language_names);
for (int i = 0; i < codes.length; i++)
{
try
{
outList.add(new LanguageData(langNamePair.first, langNamePair.second, mTts));
outList.add(new LanguageData(codes[i], names[i], mTts));
}
catch (LanguageData.NotAvailableException ex)
catch (LanguageData.NotAvailableException ignored)
{
Logger.w(TAG, "Failed to get usable languages " + ex.getMessage());
Logger.w(TAG, "Failed to get usable languages " + ignored.getMessage());
}
catch (IllegalArgumentException e)
{
@@ -349,20 +351,8 @@ public enum TtsPlayer
return res;
}
@NonNull
private List<Pair<String, String>> getSupportedLanguages()
{
if (sSupportedLanguages == null)
{
sSupportedLanguages = nativeGetSupportedLanguages();
}
return sSupportedLanguages;
}
private native static void nativeEnableTurnNotifications(boolean enable);
private native static boolean nativeAreTurnNotificationsEnabled();
private native static void nativeSetTurnNotificationsLocale(String code);
private native static String nativeGetTurnNotificationsLocale();
@NonNull
private native static List<Pair<String, String>> nativeGetSupportedLanguages();
}

View File

@@ -231,7 +231,7 @@ public final class Config
return defaultTheme;
}
public static void setCurrentUiTheme(@NonNull Context context, @NonNull String theme)
static void setCurrentUiTheme(@NonNull Context context, @NonNull String theme)
{
if (getCurrentUiTheme(context).equals(theme))
return;

View File

@@ -1,5 +1,7 @@
package app.organicmaps.sdk.util;
import app.organicmaps.BuildConfig;
public final class Constants
{
public static final int KB = 1024;
@@ -34,6 +36,13 @@ public final class Constants
private Url() {}
}
public static class Email
{
public static final String SUPPORT = BuildConfig.SUPPORT_MAIL;
private Email() {}
}
public static class Package
{
public static final String FB_PACKAGE = "com.facebook.katana";

View File

@@ -28,13 +28,13 @@ public class LocationUtils
double correction = 0;
switch (displayOrientation)
{
case Surface.ROTATION_0 ->
{
return angle;
}
case Surface.ROTATION_90 -> correction = Math.PI / 2.0;
case Surface.ROTATION_180 -> correction = Math.PI;
case Surface.ROTATION_270 -> correction = (3.0 * Math.PI / 2.0);
case Surface.ROTATION_0 ->
{
return angle;
}
case Surface.ROTATION_90 -> correction = Math.PI / 2.0;
case Surface.ROTATION_180 -> correction = Math.PI;
case Surface.ROTATION_270 -> correction = (3.0 * Math.PI / 2.0);
}
return correctAngle(angle, correction);

View File

@@ -11,10 +11,6 @@ import java.util.Locale;
public class StringUtils
{
public static String toSnakeCase(String input)
{
return input.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase();
}
public static String formatUsingUsLocale(String pattern, Object... args)
{
return String.format(Locale.US, pattern, args);

View File

@@ -1,4 +1,4 @@
package app.organicmaps.util;
package app.organicmaps.sdk.util;
import android.app.Activity;
import android.app.UiModeManager;
@@ -10,11 +10,12 @@ import androidx.appcompat.app.AppCompatDelegate;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.downloader.DownloaderStatusIcon;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.MapStyle;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.display.DisplayManager;
import app.organicmaps.sdk.util.concurrency.UiThread;
import app.organicmaps.util.ThemeUtils;
import java.util.Calendar;
public enum ThemeSwitcher
@@ -149,7 +150,6 @@ public enum ThemeSwitcher
*
* @return theme_light/dark string
*/
@NonNull
private String calcAutoTheme()
{
String defaultTheme = mContext.getResources().getString(R.string.theme_default);

View File

@@ -146,11 +146,11 @@ public final class Logger
{
switch (level)
{
case Log.VERBOSE: return 'V';
case Log.DEBUG: return 'D';
case Log.INFO: return 'I';
case Log.WARN: return 'W';
case Log.ERROR: return 'E';
case Log.VERBOSE: return 'V';
case Log.DEBUG: return 'D';
case Log.INFO: return 'I';
case Log.WARN: return 'W';
case Log.ERROR: return 'E';
}
assert false : "Unknown log level " + level;
return '_';

View File

@@ -65,7 +65,7 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
@AttrRes
int getTintAttr()
{
return com.google.android.material.R.attr.colorSecondary;
return androidx.appcompat.R.attr.colorAccent;
}
abstract TextView getTitleView();
@@ -149,39 +149,39 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
switch (result.description.openNow)
{
case SearchResult.OPEN_NOW_YES ->
{
if (result.description.minutesUntilClosed < 60) // less than 1 hour
case SearchResult.OPEN_NOW_YES ->
{
final String time = result.description.minutesUntilClosed + " " + resources.getString(R.string.minute);
final String string = resources.getString(R.string.closes_in, time);
if (result.description.minutesUntilClosed < 60) // less than 1 hour
{
final String time = result.description.minutesUntilClosed + " " + resources.getString(R.string.minute);
final String string = resources.getString(R.string.closes_in, time);
UiUtils.setTextAndShow(mOpen, string);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
UiUtils.setTextAndShow(mOpen, string);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
}
else
{
UiUtils.setTextAndShow(mOpen, resources.getString(R.string.editor_time_open));
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_green));
}
}
else
case SearchResult.OPEN_NOW_NO ->
{
UiUtils.setTextAndShow(mOpen, resources.getString(R.string.editor_time_open));
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_green));
}
}
case SearchResult.OPEN_NOW_NO ->
{
if (result.description.minutesUntilOpen < 60) // less than 1 hour
{
final String time = result.description.minutesUntilOpen + " " + resources.getString(R.string.minute);
final String string = resources.getString(R.string.opens_in, time);
if (result.description.minutesUntilOpen < 60) // less than 1 hour
{
final String time = result.description.minutesUntilOpen + " " + resources.getString(R.string.minute);
final String string = resources.getString(R.string.opens_in, time);
UiUtils.setTextAndShow(mOpen, string);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_red));
UiUtils.setTextAndShow(mOpen, string);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_red));
}
else
{
UiUtils.setTextAndShow(mOpen, resources.getString(R.string.closed));
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_red));
}
}
else
{
UiUtils.setTextAndShow(mOpen, resources.getString(R.string.closed));
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_red));
}
}
default -> UiUtils.hide(mOpen);
default -> UiUtils.hide(mOpen);
}
}

View File

@@ -26,12 +26,12 @@ import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmFragment;
import app.organicmaps.downloader.CountrySuggestFragment;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.FeatureId;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.downloader.MapManager;
import app.organicmaps.sdk.location.LocationListener;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.search.SearchListener;
import app.organicmaps.sdk.search.SearchRecents;

View File

@@ -8,7 +8,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.search.SearchRecents;
import app.organicmaps.util.Graphics;
import app.organicmaps.widget.SearchToolbarController;
@@ -49,32 +49,32 @@ class SearchHistoryAdapter extends RecyclerView.Adapter<SearchHistoryAdapter.Vie
switch (type)
{
case TYPE_ITEM:
res = new ViewHolder(
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_recent, viewGroup, false));
res.mText.setOnClickListener(v -> mSearchToolbarController.setQuery(res.mText.getText()));
break;
case TYPE_ITEM:
res = new ViewHolder(
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_recent, viewGroup, false));
res.mText.setOnClickListener(v -> mSearchToolbarController.setQuery(res.mText.getText()));
break;
case TYPE_CLEAR:
res = new ViewHolder(
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_clear_history, viewGroup, false));
res.mText.setOnClickListener(v -> {
SearchRecents.clear();
notifyDataSetChanged();
});
break;
case TYPE_CLEAR:
res = new ViewHolder(
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_clear_history, viewGroup, false));
res.mText.setOnClickListener(v -> {
SearchRecents.clear();
notifyDataSetChanged();
});
break;
case TYPE_MY_POSITION:
res = new ViewHolder(
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_my_position, viewGroup, false));
res.mText.setOnClickListener(v -> {
RoutingController.get().onPoiSelected(
MwmApplication.from(viewGroup.getContext()).getLocationHelper().getMyPosition());
mSearchToolbarController.onUpClick();
});
break;
case TYPE_MY_POSITION:
res = new ViewHolder(
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_my_position, viewGroup, false));
res.mText.setOnClickListener(v -> {
RoutingController.get().onPoiSelected(
MwmApplication.from(viewGroup.getContext()).getLocationHelper().getMyPosition());
mSearchToolbarController.onUpClick();
});
break;
default: throw new IllegalArgumentException("Unsupported ViewHolder type given");
default: throw new IllegalArgumentException("Unsupported ViewHolder type given");
}
Graphics.tint(res.mText);

View File

@@ -10,7 +10,7 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmRecyclerFragment;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.widget.PlaceholderView;
import app.organicmaps.widget.SearchToolbarController;

View File

@@ -92,7 +92,7 @@ class TabAdapter extends FragmentPagerAdapter
editor.putInt(Config.KEY_PREF_LAST_SEARCHED_TAB, tab.getPosition());
editor.apply();
super.onTabSelected(tab);
Graphics.tint(mContext, tab.getIcon(), com.google.android.material.R.attr.colorSecondary);
Graphics.tint(mContext, tab.getIcon(), androidx.appcompat.R.attr.colorAccent);
}
@Override

View File

@@ -11,7 +11,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmToolbarFragment;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.settings.RoadType;
import java.util.ArrayList;

View File

@@ -35,8 +35,8 @@ import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.NetworkPolicy;
import app.organicmaps.sdk.util.PowerManagment;
import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.ThemeSwitcher;
import app.organicmaps.sdk.util.log.LogsManager;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.Utils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;

View File

@@ -1,4 +1,4 @@
package app.organicmaps.sdk.settings;
package app.organicmaps.settings;
/**
* Represents storage option.

View File

@@ -11,8 +11,6 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import app.organicmaps.R;
import app.organicmaps.sdk.settings.StorageItem;
import app.organicmaps.sdk.settings.StoragePathManager;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.ThemeUtils;

View File

@@ -12,8 +12,6 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.settings.StorageItem;
import app.organicmaps.sdk.settings.StoragePathManager;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.concurrency.ThreadPool;

View File

@@ -1,4 +1,4 @@
package app.organicmaps.sdk.settings;
package app.organicmaps.settings;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -28,7 +28,7 @@ public class StoragePathManager
private static final String TAG = StoragePathManager.class.getSimpleName();
private static final String DATA_FILE_EXT = Framework.nativeGetDataFileExt();
private static final String[] MOVABLE_EXTS = Framework.nativeGetMovableFilesExts();
public static final FilenameFilter MOVABLE_FILES_FILTER = (dir, filename) ->
static final FilenameFilter MOVABLE_FILES_FILTER = (dir, filename) ->
{
for (String ext : MOVABLE_EXTS)
if (filename.endsWith(ext))
@@ -37,7 +37,7 @@ public class StoragePathManager
return false;
};
public interface OnStorageListChangedListener
interface OnStorageListChangedListener
{
void onStorageListChanged(List<StorageItem> storageItems, int currentStorageIndex);
}

View File

@@ -326,10 +326,10 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment
final String ttsLinkText = getString(R.string.prefs_languages_information_off_link);
final Spannable link = new SpannableString(ttsLinkText + "");
// Set link color.
link.setSpan(new ForegroundColorSpan(ContextCompat.getColor(
requireContext(),
UiUtils.getStyledResourceId(requireContext(), com.google.android.material.R.attr.colorSecondary))),
0, ttsLinkText.length(), 0);
link.setSpan(
new ForegroundColorSpan(ContextCompat.getColor(
requireContext(), UiUtils.getStyledResourceId(requireContext(), androidx.appcompat.R.attr.colorAccent))),
0, ttsLinkText.length(), 0);
ttsLangInfoLink.setSummary(link);
final String ttsInfoUrl = requireActivity().getString(R.string.tts_info_link);

View File

@@ -41,15 +41,12 @@ import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.util.Constants;
import app.organicmaps.sdk.util.Distance;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.sdk.util.concurrency.UiThread;
import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.util.log.LogsManager;
import com.google.android.material.snackbar.Snackbar;
import java.lang.ref.WeakReference;
import java.time.LocalTime;
import java.util.concurrent.TimeUnit;
@Keep
public class Utils
@@ -262,7 +259,7 @@ public class Utils
subject =
activity.getString(R.string.project_name) + " Bug Report" + (TextUtils.isEmpty(subject) ? "" : ": " + subject);
LogsManager.INSTANCE.zipLogs(
new SupportInfoWithLogsCallback(launcher, activity, subject, body, BuildConfig.SUPPORT_MAIL));
new SupportInfoWithLogsCallback(launcher, activity, subject, body, Constants.Email.SUPPORT));
}
// TODO: Don't send logs with general feedback, send system information only (version, device name, connectivity,
@@ -271,7 +268,7 @@ public class Utils
@NonNull Activity activity)
{
LogsManager.INSTANCE.zipLogs(new SupportInfoWithLogsCallback(
launcher, activity, activity.getString(R.string.project_name) + " Feedback", "", BuildConfig.SUPPORT_MAIL));
launcher, activity, activity.getString(R.string.project_name) + " Feedback", "", Constants.Email.SUPPORT));
}
public static void navigateToParent(@NonNull Activity activity)
@@ -463,30 +460,4 @@ public class Utils
return getPackageInfoOld(manager, packageName, flags);
return manager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags));
}
@NonNull
public static CharSequence formatRoutingTime(Context context, int seconds, @DimenRes int unitsSize)
{
return formatRoutingTime(context, seconds, unitsSize, R.dimen.text_size_routing_number);
}
@NonNull
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);
}
@NonNull
public static String formatArrivalTime(int seconds)
{
final LocalTime time = LocalTime.now().plusSeconds(seconds);
return StringUtils.formatUsingUsLocale("%d:%02d", time.getHour(), time.getMinute());
}
}

View File

@@ -240,8 +240,7 @@ public class SearchToolbarController extends ToolbarController implements View.O
}
@NonNull
public OnBackPressedCallback getBackPressedCallback()
{
public OnBackPressedCallback getBackPressedCallback() {
return mBackPressedCallback;
}
}

View File

@@ -52,7 +52,7 @@ public class MyPositionButton
if (mode == LocationState.FOLLOW || mode == LocationState.FOLLOW_AND_ROTATE
|| mode == LocationState.PENDING_POSITION)
{
colorAttr = com.google.android.material.R.attr.colorSecondary;
colorAttr = androidx.appcompat.R.attr.colorAccent;
if (mode == LocationState.PENDING_POSITION)
sizeDimen = R.dimen.map_button_size;
else

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