From 8acebd22f9218921d287d69ba54cceeaa0e8ba4e Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 19 May 2020 14:33:53 +0200 Subject: [PATCH 0001/1366] Initial refactoring --- OsmAnd/src/net/osmand/aidl/ConnectedApp.java | 4 +- .../core/android/MapRendererContext.java | 2 +- .../src/net/osmand/data/FavouritePoint.java | 4 +- .../osmand/plus/AppVersionUpgradeOnInit.java | 153 ++ .../net/osmand/plus/ContextMenuAdapter.java | 7 +- OsmAnd/src/net/osmand/plus/OsmandPlugin.java | 35 +- .../activities/FavoritesTreeFragment.java | 7 +- .../osmand/plus/activities/MapActivity.java | 3 +- .../plus/activities/MapActivityLayers.java | 2 +- .../plus/activities/SettingsBaseActivity.java | 4 +- .../SettingsNavigationActivity.java | 7 +- .../audionotes/AudioVideoNotesPlugin.java | 4 +- .../SortByMenuBottomSheetDialogFragment.java | 4 +- .../chooseplan/OsmLiveCancelledDialog.java | 2 +- .../DashboardSettingsDialogFragment.java | 2 +- .../plus/development/TestVoiceActivity.java | 6 +- .../osmand/plus/dialogs/ConfigureMapMenu.java | 37 +- .../osmand/plus/dialogs/RasterMapMenu.java | 9 +- ...endAnalyticsBottomSheetDialogFragment.java | 2 +- .../plus/download/DownloadIndexesThread.java | 2 +- .../net/osmand/plus/helpers/GpxUiHelper.java | 7 +- .../net/osmand/plus/helpers/LockHelper.java | 2 +- .../plus/inapp/InAppPurchaseHelper.java | 2 +- .../plus/liveupdates/LiveUpdatesFragment.java | 15 +- .../plus/liveupdates/LiveUpdatesHelper.java | 15 +- .../LiveUpdatesSettingsDialogFragment.java | 11 +- .../PerformLiveUpdateAsyncTask.java | 5 +- .../plus/mapcontextmenu/CollapsableView.java | 2 +- .../MapContextMenuFragment.java | 3 +- .../controllers/MapMarkerMenuController.java | 4 +- ...rdinateInputBottomSheetDialogFragment.java | 5 +- .../CoordinateInputDialogFragment.java | 4 +- .../DirectionIndicationDialogFragment.java | 2 +- .../MonitoringSettingsFragment.java | 9 +- .../TrackActivityFragmentAdapter.java | 3 +- .../osmand/plus/osmedit/OsmEditingPlugin.java | 5 +- .../net/osmand/plus/osmedit/OsmNotesMenu.java | 4 +- .../parkingpoint/ParkingPositionPlugin.java | 2 +- .../plus/rastermaps/MapUnderlayAction.java | 3 +- .../rastermaps/OsmandRasterMapsPlugin.java | 4 +- .../plus/render/MapRenderRepositories.java | 2 +- .../RegionAddressRepositoryBinary.java | 2 +- .../AvoidRoadsBottomSheetDialogFragment.java | 6 +- .../MapRouteInfoMenu.java | 4 +- .../RoutingOptionsHelper.java | 8 +- .../osmand/plus/routing/RouteProvider.java | 2 +- .../plus/routing/TransportRoutingHelper.java | 3 +- .../BooleanAccessibilityPreference.java | 33 + .../settings/backend/BooleanPreference.java | 23 + .../settings/backend/CommonPreference.java | 234 ++ .../backend/ContextMenuItemsPreference.java | 48 + .../backend/ContextMenuItemsSettings.java | 96 + .../backend/EnumStringPreference.java | 45 + .../settings/backend/FloatPreference.java | 27 + .../backend/ImpassableRoadsStorage.java | 194 ++ .../plus/settings/backend/IntPreference.java | 27 + .../backend/IntermediatePointsStorage.java | 23 + .../backend/ListStringPreference.java | 127 + .../plus/settings/backend/LongPreference.java | 27 + .../backend/MainContextMenuItemsSettings.java | 45 + .../backend/OsmAndPreferencesDataStore.java | 120 + .../settings/backend/OsmandPreference.java | 43 + .../plus/settings/backend/OsmandSettings.java | 2079 +++-------------- .../backend/PreferenceWithListener.java | 49 + .../plus/settings/backend/SettingsHelper.java | 14 +- .../backend/SettingsMapPointsStorage.java | 141 ++ .../settings/backend/StringPreference.java | 26 + .../BooleanPreferenceBottomSheet.java | 7 +- ...ecalculateRouteInDeviationBottomSheet.java | 3 +- .../fragments/BaseSettingsFragment.java | 7 +- .../fragments/ConfigureMenuItemsFragment.java | 18 +- .../fragments/RouteParametersFragment.java | 17 +- .../fragments/VehicleParametersFragment.java | 4 +- .../preferences/ListPreferenceEx.java | 10 +- .../MultiSelectBooleanPreference.java | 10 +- .../plus/srtmplugin/ContourLinesAction.java | 4 +- .../plus/srtmplugin/ContourLinesMenu.java | 9 +- .../osmand/plus/srtmplugin/SRTMPlugin.java | 14 +- .../plus/transport/TransportLinesMenu.java | 2 +- .../net/osmand/plus/views/AidlMapLayer.java | 2 +- .../src/net/osmand/plus/views/GPXLayer.java | 2 +- .../osmand/plus/views/MapControlsLayer.java | 5 +- .../osmand/plus/views/RulerControlLayer.java | 3 +- .../plus/views/TransportStopsLayer.java | 3 +- .../mapwidgets/MapInfoWidgetsFactory.java | 3 +- .../views/mapwidgets/MapWidgetRegistry.java | 2 +- .../mapwidgets/RouteInfoWidgetsFactory.java | 4 +- .../plus/voice/MediaCommandPlayerImpl.java | 4 +- .../plus/voice/TTSCommandPlayerImpl.java | 4 +- ...pediaOptionsBottomSheetDialogFragment.java | 4 +- ...oyageOptionsBottomSheetDialogFragment.java | 4 +- 91 files changed, 2089 insertions(+), 1907 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/MainContextMenuItemsSettings.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/PreferenceWithListener.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java diff --git a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java index a8b709972e..e1375b6838 100644 --- a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java +++ b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java @@ -15,7 +15,7 @@ import net.osmand.AndroidUtils; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.views.AidlMapLayer; @@ -54,7 +54,7 @@ public class ConnectedApp implements Comparable { private Map layers = new ConcurrentHashMap<>(); private Map mapLayers = new ConcurrentHashMap<>(); - private OsmandSettings.CommonPreference layersPref; + private CommonPreference layersPref; private String pack; private String name; diff --git a/OsmAnd/src/net/osmand/core/android/MapRendererContext.java b/OsmAnd/src/net/osmand/core/android/MapRendererContext.java index 03d88fa11c..d65880877c 100644 --- a/OsmAnd/src/net/osmand/core/android/MapRendererContext.java +++ b/OsmAnd/src/net/osmand/core/android/MapRendererContext.java @@ -25,7 +25,7 @@ import net.osmand.core.jni.ResolvedMapStyle; import net.osmand.core.jni.SwigUtilities; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.render.RendererRegistry; import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRuleStorageProperties; diff --git a/OsmAnd/src/net/osmand/data/FavouritePoint.java b/OsmAnd/src/net/osmand/data/FavouritePoint.java index 3f7d74b412..d6a99b8916 100644 --- a/OsmAnd/src/net/osmand/data/FavouritePoint.java +++ b/OsmAnd/src/net/osmand/data/FavouritePoint.java @@ -9,8 +9,8 @@ import androidx.annotation.StringRes; import net.osmand.GPXUtilities.WptPt; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings.BooleanPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.BooleanPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.parkingpoint.ParkingPositionPlugin; import net.osmand.util.Algorithms; diff --git a/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java b/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java index e4f720fa14..a3d4589201 100644 --- a/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java +++ b/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java @@ -3,6 +3,22 @@ package net.osmand.plus; import android.annotation.SuppressLint; import android.content.SharedPreferences; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; + +import net.osmand.data.FavouritePoint; +import net.osmand.data.LatLon; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.EnumStringPreference; +import net.osmand.plus.settings.backend.OsmandPreference; +import net.osmand.util.Algorithms; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + class AppVersionUpgradeOnInit { public static final String FIRST_TIME_APP_RUN = "FIRST_TIME_APP_RUN"; //$NON-NLS-1$ public static final String VERSION_INSTALLED_NUMBER = "VERSION_INSTALLED_NUMBER"; //$NON-NLS-1$ @@ -154,4 +170,141 @@ class AppVersionUpgradeOnInit { public boolean isFirstTime() { return firstTime; } + + private OsmandPreference[] generalPrefs = new OsmandPreference[]{ + EXTERNAL_INPUT_DEVICE, + CENTER_POSITION_ON_MAP, + ROTATE_MAP, + MAP_SCREEN_ORIENTATION, + LIVE_MONITORING_URL, + LIVE_MONITORING_MAX_INTERVAL_TO_SEND, + LIVE_MONITORING_INTERVAL, + LIVE_MONITORING, + SHOW_TRIP_REC_NOTIFICATION, + AUTO_SPLIT_RECORDING, + SAVE_TRACK_MIN_SPEED, + SAVE_TRACK_PRECISION, + SAVE_TRACK_MIN_DISTANCE, + SAVE_TRACK_INTERVAL, + TRACK_STORAGE_DIRECTORY, + SAVE_HEADING_TO_GPX, + DISABLE_RECORDING_ONCE_APP_KILLED, + SAVE_TRACK_TO_GPX, + SAVE_GLOBAL_TRACK_REMEMBER, + SAVE_GLOBAL_TRACK_INTERVAL, + MAP_EMPTY_STATE_ALLOWED, + DO_NOT_USE_ANIMATIONS, + USE_KALMAN_FILTER_FOR_COMPASS, + USE_MAGNETIC_FIELD_SENSOR_COMPASS, + USE_TRACKBALL_FOR_MOVEMENTS, + SPEED_SYSTEM, + ANGULAR_UNITS, + METRIC_SYSTEM, + DRIVING_REGION, + DRIVING_REGION_AUTOMATIC + }; + + public void migratePreferences() { + migrateEnumPreferences(); + SharedPreferences globalSharedPreferences = (SharedPreferences) globalPreferences; + Map globalPrefsMap = globalSharedPreferences.getAll(); + for (String key : globalPrefsMap.keySet()) { + OsmandPreference pref = getPreference(key); + if (pref instanceof CommonPreference) { + CommonPreference commonPreference = (CommonPreference) pref; + if (!commonPreference.global) { + for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { + if (!commonPreference.isSetForMode(mode) && !commonPreference.hasDefaultValueForMode(mode)) { + setPreference(key, globalPrefsMap.get(key), mode); + } + } + } + } + } + SharedPreferences defaultProfilePreferences = (SharedPreferences) getProfilePreferences(ApplicationMode.DEFAULT); + Map defaultPrefsMap = defaultProfilePreferences.getAll(); + for (String key : defaultPrefsMap.keySet()) { + OsmandPreference pref = getPreference(key); + if (pref instanceof CommonPreference) { + CommonPreference commonPreference = (CommonPreference) pref; + if (commonPreference.global && !commonPreference.isSet()) { + setPreference(key, defaultPrefsMap.get(key)); + } + } + } + for (OsmandPreference pref : generalPrefs) { + if (pref instanceof CommonPreference) { + CommonPreference commonPref = (CommonPreference) pref; + Object defaultVal = commonPref.getModeValue(ApplicationMode.DEFAULT); + for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { + if (!commonPref.isSetForMode(mode) && !commonPref.hasDefaultValueForMode(mode)) { + setPreference(commonPref.getId(), defaultVal, mode); + } + } + } + } + + String json = settingsAPI.getString(globalPreferences, "custom_app_profiles", ""); + if (!Algorithms.isEmpty(json)) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); + Type t = new TypeToken>() { + }.getType(); + List customProfiles = gson.fromJson(json, t); + if (!Algorithms.isEmpty(customProfiles)) { + for (ApplicationMode.ApplicationModeBean modeBean : customProfiles) { + ApplicationMode.ApplicationModeBuilder builder = ApplicationMode.fromModeBean(ctx, modeBean); + ApplicationMode.saveProfile(builder, ctx); + } + } + } + } + + public void migrateEnumPreferences() { + for (OsmandPreference pref : registeredPreferences.values()) { + if (pref instanceof EnumStringPreference) { + EnumStringPreference enumPref = (EnumStringPreference) pref; + if (enumPref.isGlobal()) { + migrateEnumPref(enumPref, (SharedPreferences) globalPreferences); + } else { + for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { + migrateEnumPref(enumPref, (SharedPreferences) getProfilePreferences(mode)); + } + } + } + } + } + + private void migrateEnumPref(EnumStringPreference enumPref, SharedPreferences sharedPreferences) { + Object value = sharedPreferences.getAll().get(enumPref.getId()); + if (value instanceof Integer) { + int enumIndex = (int) value; + if (enumIndex >= 0 && enumIndex < enumPref.values.length) { + Enum savedValue = enumPref.values[enumIndex]; + enumPref.setValue(sharedPreferences, savedValue); + } + } + } + + public void migrateHomeWorkParkingToFavorites() { + FavouritesDbHelper favorites = ctx.getFavorites(); + + LatLon homePoint = null; + float lat = settingsAPI.getFloat(globalPreferences, "home_point_lat", 0); + float lon = settingsAPI.getFloat(globalPreferences, "home_point_lon", 0); + if (lat != 0 || lon != 0) { + homePoint = new LatLon(lat, lon); + } + LatLon workPoint = null; + lat = settingsAPI.getFloat(globalPreferences, "work_point_lat", 0); + lon = settingsAPI.getFloat(globalPreferences, "work_point_lon", 0); + if (lat != 0 || lon != 0) { + workPoint = new LatLon(lat, lon); + } + if (homePoint != null) { + favorites.setSpecialPoint(homePoint, FavouritePoint.SpecialPointType.HOME, null); + } + if (workPoint != null) { + favorites.setSpecialPoint(workPoint, FavouritePoint.SpecialPointType.WORK, null); + } + } } diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 4777ec73d8..f067564530 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -36,9 +36,8 @@ import net.osmand.plus.activities.actions.AppModeDialog; import net.osmand.plus.dialogs.ConfigureMapMenu; import net.osmand.plus.dialogs.HelpArticleDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.ContextMenuItemsPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.ContextMenuItemsPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -629,7 +628,7 @@ public class ContextMenuAdapter { return makeDeleteAction(prefs.toArray(new OsmandPreference[prefs.size()])); } - private static void resetSetting(ApplicationMode appMode, OsmandSettings.OsmandPreference preference, boolean profileOnly) { + private static void resetSetting(ApplicationMode appMode, OsmandPreference preference, boolean profileOnly) { if (profileOnly) { preference.resetModeToDefault(appMode); } else { diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java index d10e4e6b7f..a2eab459b2 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java @@ -41,7 +41,8 @@ import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.parkingpoint.ParkingPositionPlugin; import net.osmand.plus.quickaction.QuickActionType; import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.skimapsplugin.SkiMapsPlugin; import net.osmand.plus.srtmplugin.SRTMPlugin; @@ -73,7 +74,7 @@ public abstract class OsmandPlugin { protected OsmandApplication app; - protected List pluginPreferences = new ArrayList<>(); + protected List pluginPreferences = new ArrayList<>(); private boolean active; private String installURL = null; @@ -111,7 +112,7 @@ public abstract class OsmandPlugin { return null; } - public List getPreferences() { + public List getPreferences() { return pluginPreferences; } @@ -841,44 +842,44 @@ public abstract class OsmandPlugin { } } - protected OsmandSettings.CommonPreference registerBooleanPreference(OsmandApplication app, String prefId, boolean defValue) { - OsmandSettings.CommonPreference preference = app.getSettings().registerBooleanPreference(prefId, defValue); + protected CommonPreference registerBooleanPreference(OsmandApplication app, String prefId, boolean defValue) { + CommonPreference preference = app.getSettings().registerBooleanPreference(prefId, defValue); pluginPreferences.add(preference); return preference; } - private OsmandSettings.CommonPreference registerBooleanAccessibilityPreference(OsmandApplication app, String prefId, boolean defValue) { - OsmandSettings.CommonPreference preference = app.getSettings().registerBooleanAccessibilityPreference(prefId, defValue); + private CommonPreference registerBooleanAccessibilityPreference(OsmandApplication app, String prefId, boolean defValue) { + CommonPreference preference = app.getSettings().registerBooleanAccessibilityPreference(prefId, defValue); pluginPreferences.add(preference); return preference; } - protected OsmandSettings.CommonPreference registerStringPreference(OsmandApplication app, String prefId, String defValue) { - OsmandSettings.CommonPreference preference = app.getSettings().registerStringPreference(prefId, defValue); + protected CommonPreference registerStringPreference(OsmandApplication app, String prefId, String defValue) { + CommonPreference preference = app.getSettings().registerStringPreference(prefId, defValue); pluginPreferences.add(preference); return preference; } - protected OsmandSettings.CommonPreference registerIntPreference(OsmandApplication app, String prefId, int defValue) { - OsmandSettings.CommonPreference preference = app.getSettings().registerIntPreference(prefId, defValue); + protected CommonPreference registerIntPreference(OsmandApplication app, String prefId, int defValue) { + CommonPreference preference = app.getSettings().registerIntPreference(prefId, defValue); pluginPreferences.add(preference); return preference; } - protected OsmandSettings.CommonPreference registerLongPreference(OsmandApplication app, String prefId, long defValue) { - OsmandSettings.CommonPreference preference = app.getSettings().registerLongPreference(prefId, defValue); + protected CommonPreference registerLongPreference(OsmandApplication app, String prefId, long defValue) { + CommonPreference preference = app.getSettings().registerLongPreference(prefId, defValue); pluginPreferences.add(preference); return preference; } - protected OsmandSettings.CommonPreference registerFloatPreference(OsmandApplication app, String prefId, float defValue) { - OsmandSettings.CommonPreference preference = app.getSettings().registerFloatPreference(prefId, defValue); + protected CommonPreference registerFloatPreference(OsmandApplication app, String prefId, float defValue) { + CommonPreference preference = app.getSettings().registerFloatPreference(prefId, defValue); pluginPreferences.add(preference); return preference; } - protected OsmandSettings.CommonPreference registerEnumIntPreference(OsmandApplication app, String prefId, Enum defaultValue, Enum[] values, Class clz) { - OsmandSettings.CommonPreference preference = app.getSettings().registerEnumIntPreference(prefId, defaultValue, values, clz); + protected CommonPreference registerEnumIntPreference(OsmandApplication app, String prefId, Enum defaultValue, Enum[] values, Class clz) { + CommonPreference preference = app.getSettings().registerEnumIntPreference(prefId, defaultValue, values, clz); pluginPreferences.add(preference); return preference; } diff --git a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java index 71084c00e2..af1024c690 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java @@ -44,6 +44,7 @@ import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.FavouritesDbHelper.FavoritesListener; import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -97,7 +98,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen private Set groupsToDelete = new LinkedHashSet<>(); private ActionMode actionMode; private Drawable arrowImageDisabled; - private HashMap> preferenceCache = new HashMap<>(); + private HashMap> preferenceCache = new HashMap<>(); private View footerView; private Location lastLocation; private float lastHeading; @@ -763,8 +764,8 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen } } - private OsmandSettings.OsmandPreference getGroupExpandedPreference(String groupName) { - OsmandSettings.OsmandPreference preference = preferenceCache.get(groupName); + private OsmandPreference getGroupExpandedPreference(String groupName) { + OsmandPreference preference = preferenceCache.get(groupName); if (preference == null) { String groupKey = groupName + GROUP_EXPANDED_POSTFIX; preference = getSettings().registerBooleanPreference(groupKey, false); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 8a65f81d7a..5202f00c60 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -77,6 +77,7 @@ import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; @@ -548,7 +549,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven @Override public void requestPrivateAccessRouting() { if (!settings.FORCE_PRIVATE_ACCESS_ROUTING_ASKED.getModeValue(getRoutingHelper().getAppMode())) { - final OsmandSettings.CommonPreference allowPrivate + final CommonPreference allowPrivate = settings.getCustomRoutingBooleanProperty(GeneralRouter.ALLOW_PRIVATE, false); final List modes = ApplicationMode.values(app); for (ApplicationMode mode : modes) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index ae8af82440..5f872bc5ac 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -28,7 +28,7 @@ import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.activities.MapActivity.ShowQuickSearchMode; diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java index 525b9e0d02..686627bd61 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java @@ -26,8 +26,8 @@ import net.osmand.PlatformUtil; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.profiles.AppProfileArrayAdapter; import net.osmand.plus.profiles.ProfileDataObject; diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java index 1cdca6db8f..4ef400af38 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java @@ -35,9 +35,10 @@ import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.AutoZoomMap; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings.SpeedConstants; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -406,7 +407,7 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { } public static boolean isRoutingParameterSelected(OsmandSettings settings, ApplicationMode am, RoutingParameter routingParameter) { - final OsmandSettings.CommonPreference property = + final CommonPreference property = settings.getCustomRoutingBooleanProperty(routingParameter.getId(), routingParameter.getDefaultBoolean()); if(am != null) { return property.getModeValue(am); @@ -416,7 +417,7 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { } public static void setRoutingParameterSelected(OsmandSettings settings, ApplicationMode am, String routingParameterId, boolean defaultBoolean, boolean isChecked) { - final OsmandSettings.CommonPreference property = settings.getCustomRoutingBooleanProperty(routingParameterId, defaultBoolean); + final CommonPreference property = settings.getCustomRoutingBooleanProperty(routingParameterId, defaultBoolean); if (am != null) { property.setModeValue(am, isChecked); } else { diff --git a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java index d8d32df458..cabbcad3ce 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java @@ -53,8 +53,8 @@ import net.osmand.plus.ContextMenuAdapter.ItemClickListener; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java index de1208a735..2e228874b0 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java @@ -3,7 +3,7 @@ package net.osmand.plus.audionotes; import android.os.Bundle; import android.view.View; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings.NotesSortByMode; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; @@ -53,7 +53,7 @@ public class SortByMenuBottomSheetDialogFragment extends MenuBottomSheetDialogFr } private void selectSortByMode(NotesSortByMode mode) { - final OsmandSettings.CommonPreference sortByMode = getMyApplication().getSettings().NOTES_SORT_BY_MODE; + final CommonPreference sortByMode = getMyApplication().getSettings().NOTES_SORT_BY_MODE; if (sortByMode.get() != mode) { sortByMode.set(mode); if (listener != null) { diff --git a/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java b/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java index 788b605eec..76c5ca0823 100644 --- a/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java +++ b/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java @@ -24,7 +24,7 @@ import androidx.fragment.app.FragmentManager; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndDialogFragment; diff --git a/OsmAnd/src/net/osmand/plus/dashboard/tools/DashboardSettingsDialogFragment.java b/OsmAnd/src/net/osmand/plus/dashboard/tools/DashboardSettingsDialogFragment.java index 8b7e47a941..3495cadb32 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/tools/DashboardSettingsDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/tools/DashboardSettingsDialogFragment.java @@ -25,7 +25,7 @@ import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java index 674b9e067d..cc1268bd3e 100644 --- a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java @@ -19,7 +19,7 @@ import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.activities.OsmandActionBarActivity; import net.osmand.plus.routing.data.StreetName; @@ -149,7 +149,7 @@ public class TestVoiceActivity extends OsmandActionBarActivity { v += "\n \u25CF BT SCO: The current app profile is not set to use 'Phone call audio'."; } - OsmandSettings.OsmandPreference pref = ((OsmandApplication) getApplication()).getSettings().VOICE_PROMPT_DELAY[stream]; + OsmandPreference pref = ((OsmandApplication) getApplication()).getSettings().VOICE_PROMPT_DELAY[stream]; if(pref != null) { v += "\n \u25CF Voice prompt delay for selected output: " + pref.get() + "\u00A0ms"; } @@ -288,7 +288,7 @@ public class TestVoiceActivity extends OsmandActionBarActivity { } if (description.startsWith("\u25BA (11.2)")) { int ams = ((OsmandApplication) getApplication()).getSettings().AUDIO_MANAGER_STREAM.get(); - OsmandSettings.OsmandPreference pref = ((OsmandApplication) getApplication()).getSettings().VOICE_PROMPT_DELAY[ams]; + OsmandPreference pref = ((OsmandApplication) getApplication()).getSettings().VOICE_PROMPT_DELAY[ams]; if (pref != null) { if (pref.get() >= 3000) { pref.set(0); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 4c3378c77e..69ab2273c0 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -37,9 +37,10 @@ import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.ListStringPreference; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.ListStringPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -571,7 +572,7 @@ public class ConfigureMapMenu { public boolean onContextMenuClick(final ArrayAdapter ad, int itemId, final int pos, boolean isChecked, int[] viewCoordinates) { final OsmandMapTileView view = activity.getMapView(); - final OsmandSettings.OsmandPreference mapDensity = view.getSettings().MAP_DENSITY; + final OsmandPreference mapDensity = view.getSettings().MAP_DENSITY; AlertDialog.Builder bld = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes)); int p = (int) (mapDensity.get() * 100); final TIntArrayList tlist = new TIntArrayList(new int[]{25, 33, 50, 75, 100, 125, 150, 200, 300, 400}); @@ -858,25 +859,25 @@ public class ConfigureMapMenu { @ColorInt final int selectedProfileColor) { final List ps = new ArrayList<>(); - final List> prefs = new ArrayList<>(); + final List> prefs = new ArrayList<>(); Iterator it = customRules.iterator(); while (it.hasNext()) { RenderingRuleProperty p = it.next(); if (category.equals(p.getCategory()) && p.isBoolean()) { ps.add(p); - final OsmandSettings.CommonPreference pref = activity.getMyApplication().getSettings() + final CommonPreference pref = activity.getMyApplication().getSettings() .getCustomRenderBooleanProperty(p.getAttrName()); prefs.add(pref); it.remove(); } } if (prefs.size() > 0) { - final List> includedPrefs = new ArrayList<>(); + final List> includedPrefs = new ArrayList<>(); if (customRulesIncluded != null) { for (RenderingRuleProperty p : customRulesIncluded) { if (!p.isBoolean()) { - final OsmandSettings.CommonPreference pref = activity.getMyApplication().getSettings() + final CommonPreference pref = activity.getMyApplication().getSettings() .getCustomRenderProperty(p.getAttrName()); includedPrefs.add(pref); } @@ -914,14 +915,14 @@ public class ConfigureMapMenu { .setId(id) .setIcon(icon).setListener(clickListener); boolean selected = false; - for (OsmandSettings.CommonPreference p : prefs) { + for (CommonPreference p : prefs) { if (p.get()) { selected = true; break; } } if (!selected && includedPrefs.size() > 0) { - for (OsmandSettings.CommonPreference p : includedPrefs) { + for (CommonPreference p : includedPrefs) { if (!Algorithms.isEmpty(p.get())) { selected = true; break; @@ -958,17 +959,17 @@ public class ConfigureMapMenu { return null; } - protected String getDescription(final List> prefs, - final List> includedPrefs) { + protected String getDescription(final List> prefs, + final List> includedPrefs) { int count = 0; int enabled = 0; - for (OsmandSettings.CommonPreference p : prefs) { + for (CommonPreference p : prefs) { count++; if (p.get()) { enabled++; } } - for (OsmandSettings.CommonPreference p : includedPrefs) { + for (CommonPreference p : includedPrefs) { count++; if (!Algorithms.isEmpty(p.get())) { enabled++; @@ -1039,11 +1040,11 @@ public class ConfigureMapMenu { prefs.get(i).set(tempPrefs[i]); selected |= tempPrefs[i]; } - final List> includedPrefs = new ArrayList<>(); + final List> includedPrefs = new ArrayList<>(); if (customRulesIncluded != null) { for (RenderingRuleProperty p : customRulesIncluded) { if (p.getAttrName().equals(HIKING_ROUTES_OSMC_ATTR)) { - final OsmandSettings.CommonPreference pref = activity.getMyApplication().getSettings() + final CommonPreference pref = activity.getMyApplication().getSettings() .getCustomRenderProperty(p.getAttrName()); includedPrefs.add(pref); if (hikingRouteOSMCValue == 0) { @@ -1077,7 +1078,7 @@ public class ConfigureMapMenu { if (customRulesIncluded != null) { for (RenderingRuleProperty p : customRulesIncluded) { if (!p.isBoolean()) { - final OsmandSettings.CommonPreference pref = activity.getMyApplication().getSettings() + final CommonPreference pref = activity.getMyApplication().getSettings() .getCustomRenderProperty(p.getAttrName()); View spinnerView = View.inflate(new ContextThemeWrapper(activity, themeRes), R.layout.spinner_rule_layout, null); @@ -1214,7 +1215,7 @@ public class ConfigureMapMenu { final String propertyDescr = SettingsActivity.getStringPropertyDescription(view.getContext(), p.getAttrName(), p.getName()); if (p.isBoolean()) { - final OsmandSettings.CommonPreference pref = view.getApplication().getSettings() + final CommonPreference pref = view.getApplication().getSettings() .getCustomRenderBooleanProperty(p.getAttrName()); return ContextMenuItem.createBuilder(propertyName) .setId(id) @@ -1230,7 +1231,7 @@ public class ConfigureMapMenu { .setSelected(pref.get()) .createItem(); } else { - final OsmandSettings.CommonPreference pref = view.getApplication().getSettings() + final CommonPreference pref = view.getApplication().getSettings() .getCustomRenderProperty(p.getAttrName()); final String descr; if (!Algorithms.isEmpty(pref.get())) { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java index 44d50db194..f62f16016c 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java @@ -10,6 +10,7 @@ import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; @@ -39,9 +40,9 @@ public class RasterMapMenu { final OsmandSettings settings = app.getSettings(); final OsmandRasterMapsPlugin plugin = OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class); assert plugin != null; - final OsmandSettings.CommonPreference mapTransparencyPreference; - final OsmandSettings.CommonPreference mapTypePreference; - final OsmandSettings.CommonPreference exMapTypePreference; + final CommonPreference mapTransparencyPreference; + final CommonPreference mapTypePreference; + final CommonPreference exMapTypePreference; final LayerTransparencySeekbarMode currentMapTypeSeekbarMode = type == RasterMapType.OVERLAY ? LayerTransparencySeekbarMode.OVERLAY : LayerTransparencySeekbarMode.UNDERLAY; @StringRes final int mapTypeString; @@ -62,7 +63,7 @@ public class RasterMapMenu { throw new RuntimeException("Unexpected raster map type"); } - final OsmandSettings.CommonPreference hidePolygonsPref = + final CommonPreference hidePolygonsPref = mapActivity.getMyApplication().getSettings().getCustomRenderBooleanProperty("noPolygons"); String mapTypeDescr = mapTypePreference.get(); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java index f84ac5239e..983315c503 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java @@ -19,7 +19,7 @@ import androidx.fragment.app.FragmentManager; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton; diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 4b0dd632aa..80ce6cfb27 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -22,7 +22,7 @@ import net.osmand.map.WorldRegion; import net.osmand.map.WorldRegion.RegionParams; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.base.BasicProgressAsyncTask; diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index 356f8c9870..443f42922f 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -80,6 +80,7 @@ import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -513,9 +514,9 @@ public class GpxUiHelper { } else { final View apprTitleView = View.inflate(new ContextThemeWrapper(activity, themeRes), R.layout.select_gpx_appearance_title, null); - final OsmandSettings.CommonPreference prefWidth + final CommonPreference prefWidth = app.getSettings().getCustomRenderProperty(CURRENT_TRACK_WIDTH_ATTR); - final OsmandSettings.CommonPreference prefColor + final CommonPreference prefColor = app.getSettings().getCustomRenderProperty(CURRENT_TRACK_COLOR_ATTR); updateAppearanceTitle(activity, app, trackWidthProp, renderer, apprTitleView, prefWidth.get(), prefColor.get()); @@ -567,7 +568,7 @@ public class GpxUiHelper { public void onClick(DialogInterface dialog, int which) { if (gpxAppearanceParams.size() > 0) { for (Map.Entry entry : gpxAppearanceParams.entrySet()) { - final OsmandSettings.CommonPreference pref + final CommonPreference pref = app.getSettings().getCustomRenderProperty(entry.getKey()); pref.set(entry.getValue()); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/LockHelper.java b/OsmAnd/src/net/osmand/plus/helpers/LockHelper.java index 34d31e1489..1d4faa4304 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/LockHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/LockHelper.java @@ -17,7 +17,7 @@ import androidx.annotation.Nullable; import net.osmand.plus.OsmAndAppCustomization.OsmAndAppCustomizationListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.routing.VoiceRouter.VoiceMessageListener; import java.util.List; diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java index 2fe36e624d..baa7c140f0 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java @@ -23,7 +23,7 @@ import net.osmand.AndroidNetworkUtils.RequestResponse; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index f96ebf4ff6..a4cff566d2 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -35,6 +35,7 @@ import androidx.fragment.app.FragmentManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -312,7 +313,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc } public void add(LocalIndexInfo info) { - OsmandSettings.CommonPreference preference = preferenceLiveUpdatesOn( + CommonPreference preference = preferenceLiveUpdatesOn( info.getFileName(), getSettings()); if (preference.get()) { dataShouldUpdate.add(info); @@ -324,7 +325,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc public void notifyLiveUpdatesChanged() { Set changedSet = new HashSet<>(); for (LocalIndexInfo localIndexInfo : dataShouldUpdate) { - OsmandSettings.CommonPreference preference = + CommonPreference preference = preferenceLiveUpdatesOn(localIndexInfo.getFileName(), getSettings()); if (!preference.get()) { changedSet.add(localIndexInfo); @@ -334,7 +335,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc dataShouldNotUpdate.addAll(changedSet); changedSet.clear(); for (LocalIndexInfo localIndexInfo : dataShouldNotUpdate) { - OsmandSettings.CommonPreference preference = + CommonPreference preference = preferenceLiveUpdatesOn(localIndexInfo.getFileName(), getSettings()); if (preference.get()) { changedSet.add(localIndexInfo); @@ -475,9 +476,9 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc PendingIntent alarmIntent = getPendingIntent(getActivity(), fileName); if (enable) { - final OsmandSettings.CommonPreference updateFrequencyPreference = + final CommonPreference updateFrequencyPreference = preferenceUpdateFrequency(fileName, getSettings()); - final OsmandSettings.CommonPreference timeOfDayPreference = + final CommonPreference timeOfDayPreference = preferenceTimeOfDayToUpdate(fileName, getSettings()); UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; @@ -572,7 +573,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc public void bindLocalIndexInfo(@NonNull final String item, boolean isLastChild) { OsmandApplication context = fragment.getMyActivity().getMyApplication(); - final OsmandSettings.CommonPreference shouldUpdatePreference = + final CommonPreference shouldUpdatePreference = preferenceLiveUpdatesOn(item, fragment.getSettings()); IncrementalChangesManager changesManager = context.getResourceManager().getChangesManager(); @@ -602,7 +603,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc Algorithms.getFileNameWithoutExtension(new File(item)); final long timestamp = changesManager.getTimestamp(fileNameWithoutExtension); final long lastCheck = preferenceLastCheck(item, fragment.getSettings()).get(); - OsmandSettings.CommonPreference liveUpdateOn = preferenceLiveUpdatesOn(item, fragment.getSettings()); + CommonPreference liveUpdateOn = preferenceLiveUpdatesOn(item, fragment.getSettings()); if(liveUpdateOn.get() && lastCheck != DEFAULT_LAST_CHECK) { String lastCheckString = formatDateTime(fragment.getActivity(), lastCheck ); descriptionTextView.setText(context.getString(R.string.last_update, lastCheckString)); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java index ec4afd6861..ce9d3d9c5b 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java @@ -8,6 +8,7 @@ import android.os.AsyncTask; import androidx.annotation.NonNull; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.OsmandActionBarActivity; @@ -32,7 +33,7 @@ public class LiveUpdatesHelper { public static final int DEFAULT_LAST_CHECK = -1; - private static OsmandSettings.CommonPreference checkPref(OsmandSettings.CommonPreference p) { + private static CommonPreference checkPref(CommonPreference p) { if (p.isSet()) { T vl = p.get(); p = p.makeGlobal(); @@ -44,37 +45,37 @@ public class LiveUpdatesHelper { } return p; } - public static OsmandSettings.CommonPreference preferenceForLocalIndex( + public static CommonPreference preferenceForLocalIndex( String fileName, OsmandSettings settings) { final String settingId = fileName + LIVE_UPDATES_ON_POSTFIX; return checkPref(settings.registerBooleanPreference(settingId, false)); } - public static OsmandSettings.CommonPreference preferenceLiveUpdatesOn( + public static CommonPreference preferenceLiveUpdatesOn( String fileName, OsmandSettings settings) { final String settingId = fileName + LIVE_UPDATES_ON_POSTFIX; return checkPref(settings.registerBooleanPreference(settingId, false)); } - public static OsmandSettings.CommonPreference preferenceDownloadViaWiFi( + public static CommonPreference preferenceDownloadViaWiFi( String fileName, OsmandSettings settings) { final String settingId = fileName + DOWNLOAD_VIA_WIFI_POSTFIX; return checkPref(settings.registerBooleanPreference(settingId, false)); } - public static OsmandSettings.CommonPreference preferenceUpdateFrequency( + public static CommonPreference preferenceUpdateFrequency( String fileName, OsmandSettings settings) { final String settingId = fileName + UPDATE_TIMES_POSTFIX; return checkPref(settings.registerIntPreference(settingId, UpdateFrequency.HOURLY.ordinal())); } - public static OsmandSettings.CommonPreference preferenceTimeOfDayToUpdate( + public static CommonPreference preferenceTimeOfDayToUpdate( String fileName, OsmandSettings settings) { final String settingId = fileName + TIME_OF_DAY_TO_UPDATE_POSTFIX; return checkPref(settings.registerIntPreference(settingId, TimeOfDay.NIGHT.ordinal())); } - public static OsmandSettings.CommonPreference preferenceLastCheck( + public static CommonPreference preferenceLastCheck( String fileName, OsmandSettings settings) { final String settingId = fileName + LAST_UPDATE_ATTEMPT_ON_POSTFIX; return checkPref(settings.registerLongPreference(settingId, DEFAULT_LAST_CHECK)); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java index d3f8f2ed4e..d27e733d7a 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java @@ -23,6 +23,7 @@ import androidx.fragment.app.DialogFragment; import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.download.AbstractDownloadActivity; @@ -85,7 +86,7 @@ public class LiveUpdatesSettingsDialogFragment extends DialogFragment { final long lastCheck = preferenceLastCheck(fileName, getSettings()).get(); - OsmandSettings.CommonPreference preference = preferenceLiveUpdatesOn(fileName, + CommonPreference preference = preferenceLiveUpdatesOn(fileName, getSettings()); if (preference.get() && lastCheck != DEFAULT_LAST_CHECK) { String lastCheckString = formatDateTime(getActivity(), lastCheck); @@ -94,13 +95,13 @@ public class LiveUpdatesSettingsDialogFragment extends DialogFragment { lastUpdateTextView.setVisibility(View.GONE); } - final OsmandSettings.CommonPreference liveUpdatePreference = + final CommonPreference liveUpdatePreference = preferenceForLocalIndex(fileName, getSettings()); - final OsmandSettings.CommonPreference downloadViaWiFiPreference = + final CommonPreference downloadViaWiFiPreference = preferenceDownloadViaWiFi(fileName, getSettings()); - final OsmandSettings.CommonPreference updateFrequencyPreference = + final CommonPreference updateFrequencyPreference = preferenceUpdateFrequency(fileName, getSettings()); - final OsmandSettings.CommonPreference timeOfDayPreference = + final CommonPreference timeOfDayPreference = preferenceTimeOfDayToUpdate(fileName, getSettings()); downloadOverWiFiCheckBox.setChecked(!liveUpdatePreference.get() || downloadViaWiFiPreference.get()); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java index c95ac1a2a6..4cebb245f9 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java @@ -9,6 +9,7 @@ import androidx.annotation.NonNull; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.download.AbstractDownloadActivity; @@ -50,7 +51,7 @@ public class PerformLiveUpdateAsyncTask activity.setSupportProgressBarIndeterminateVisibility(true); } final OsmandApplication myApplication = getMyApplication(); - OsmandSettings.CommonPreference lastCheckPreference = + CommonPreference lastCheckPreference = LiveUpdatesHelper.preferenceLastCheck(localIndexFileName, myApplication.getSettings()); lastCheckPreference.set(System.currentTimeMillis()); } @@ -148,7 +149,7 @@ public class PerformLiveUpdateAsyncTask public static void tryRescheduleDownload(@NonNull Context context, @NonNull OsmandSettings settings, @NonNull String localIndexFileName) { - final OsmandSettings.CommonPreference updateFrequencyPreference = + final CommonPreference updateFrequencyPreference = preferenceUpdateFrequency(localIndexFileName, settings); final Integer frequencyOrdinal = updateFrequencyPreference.get(); if (LiveUpdatesHelper.UpdateFrequency.values()[frequencyOrdinal] diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/CollapsableView.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/CollapsableView.java index 5daa14ba27..394547f570 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/CollapsableView.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/CollapsableView.java @@ -4,7 +4,7 @@ import android.view.View; import androidx.annotation.NonNull; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.mapcontextmenu.MenuBuilder.CollapseExpandListener; public class CollapsableView { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java index 99da51fc51..1bfa41fc13 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java @@ -57,6 +57,7 @@ import net.osmand.plus.ContextMenuItem; import net.osmand.plus.LockableScrollView; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.MainContextMenuItemsSettings; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -569,7 +570,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo // Action buttons ContextMenuAdapter adapter = menu.getActionsContextMenuAdapter(false); List items = adapter.getVisibleItems(); - List mainIds = ((OsmandSettings.MainContextMenuItemsSettings) app.getSettings().CONTEXT_MENU_ACTIONS_ITEMS.get()).getMainIds(); + List mainIds = ((MainContextMenuItemsSettings) app.getSettings().CONTEXT_MENU_ACTIONS_ITEMS.get()).getMainIds(); ContextMenuAdapter mainAdapter = new ContextMenuAdapter(requireMyApplication()); ContextMenuAdapter additionalAdapter = new ContextMenuAdapter(requireMyApplication()); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java index 5641f125ec..f0061440ad 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java @@ -13,7 +13,7 @@ import androidx.core.content.ContextCompat; import net.osmand.data.PointDescription; import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.MapMarkersHelper.MapMarker; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.MapMarkerDialogHelper; @@ -56,7 +56,7 @@ public class MapMarkerMenuController extends MenuController { public void buttonPressed() { MapActivity activity = getMapActivity(); if (activity != null) { - OsmandSettings.OsmandPreference indication + OsmandPreference indication = activity.getMyApplication().getSettings().MARKERS_DISTANCE_INDICATION_ENABLED; if (!indication.get()) { indication.set(true); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputBottomSheetDialogFragment.java index cf769223f1..f3bf7cfb7a 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputBottomSheetDialogFragment.java @@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; @@ -83,7 +84,7 @@ public class CoordinateInputBottomSheetDialogFragment extends MenuBottomSheetDia @Override public void onClick(View v) { if (listener != null) { - OsmandSettings.CommonPreference pref = settings.COORDS_INPUT_TWO_DIGITS_LONGTITUDE; + CommonPreference pref = settings.COORDS_INPUT_TWO_DIGITS_LONGTITUDE; pref.set(!pref.get()); listener.onInputSettingsChanged(); } @@ -108,7 +109,7 @@ public class CoordinateInputBottomSheetDialogFragment extends MenuBottomSheetDia @Override public void onClick(View v) { if (listener != null) { - OsmandSettings.CommonPreference pref = settings.COORDS_INPUT_USE_RIGHT_SIDE; + CommonPreference pref = settings.COORDS_INPUT_USE_RIGHT_SIDE; pref.set(!pref.get()); listener.onHandChanged(); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java index 2059bcf25e..4cef32026c 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java @@ -66,7 +66,7 @@ import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.Version; @@ -1020,7 +1020,7 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm } private void changeOsmandKeyboardSetting() { - OsmandSettings.OsmandPreference pref = getMyApplication().getSettings().COORDS_INPUT_USE_OSMAND_KEYBOARD; + OsmandPreference pref = getMyApplication().getSettings().COORDS_INPUT_USE_OSMAND_KEYBOARD; pref.set(!pref.get()); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java index ee5a632281..292da8aa8b 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java @@ -33,7 +33,7 @@ import net.osmand.AndroidUtils; import net.osmand.plus.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.MapMarkersMode; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java index 5a0a21f0e9..2efe004611 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java @@ -13,7 +13,8 @@ import androidx.preference.Preference; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndAppCustomization; import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; @@ -288,11 +289,11 @@ public class MonitoringSettingsFragment extends BaseSettingsFragment @Override public void onApplyPreferenceChange(String prefId, boolean applyToAllProfiles, Object newValue) { if (SAVE_GLOBAL_TRACK_INTERVAL.equals(prefId)) { - OsmandSettings.OsmandPreference pref = settings.getPreference(prefId); + OsmandPreference pref = settings.getPreference(prefId); if (newValue instanceof Boolean) { applyPreference(settings.SAVE_GLOBAL_TRACK_REMEMBER.getId(), applyToAllProfiles, false); - } else if (pref instanceof OsmandSettings.CommonPreference - && !((OsmandSettings.CommonPreference) pref).hasDefaultValueForMode(getSelectedAppMode())) { + } else if (pref instanceof CommonPreference + && !((CommonPreference) pref).hasDefaultValueForMode(getSelectedAppMode())) { applyPreference(SAVE_GLOBAL_TRACK_INTERVAL, applyToAllProfiles, newValue); applyPreference(settings.SAVE_GLOBAL_TRACK_REMEMBER.getId(), applyToAllProfiles, true); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java index 25d9d7450a..d45804b496 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java @@ -49,6 +49,7 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -760,7 +761,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { } if (color == 0) { final RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer(); - final OsmandSettings.CommonPreference prefColor + final CommonPreference prefColor = app.getSettings().getCustomRenderProperty(CURRENT_TRACK_COLOR_ATTR); color = ConfigureMapMenu.GpxAppearanceAdapter.parseTrackColor(renderer, prefColor.get()); } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index 157188fbb1..abab2339d9 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -30,6 +30,7 @@ import net.osmand.plus.ContextMenuAdapter.ItemClickListener; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.EnumAdapter; @@ -355,7 +356,7 @@ public class OsmEditingPlugin extends OsmandPlugin { @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { if (itemId == R.string.layer_osm_bugs) { - OsmandSettings.OsmandPreference showOsmBugs = settings.SHOW_OSM_BUGS; + OsmandPreference showOsmBugs = settings.SHOW_OSM_BUGS; showOsmBugs.set(isChecked); adapter.getItem(pos).setColorRes(showOsmBugs.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); @@ -378,7 +379,7 @@ public class OsmEditingPlugin extends OsmandPlugin { @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { if (itemId == R.string.layer_osm_edits) { - OsmandSettings.OsmandPreference showOsmEdits = settings.SHOW_OSM_EDITS; + OsmandPreference showOsmEdits = settings.SHOW_OSM_EDITS; showOsmEdits.set(isChecked); adapter.getItem(pos).setColorRes(showOsmEdits.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java index 65a2dfe3ee..0eefb8b51a 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java @@ -14,8 +14,8 @@ import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java index c0461e6931..1521d70352 100644 --- a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java +++ b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java @@ -29,7 +29,7 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java index 12f6f909cf..d938174c1f 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java @@ -15,6 +15,7 @@ import com.google.gson.reflect.TypeToken; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; @@ -144,7 +145,7 @@ public class MapUnderlayAction extends SwitchableAction> { } - final OsmandSettings.CommonPreference hidePolygonsPref = + final CommonPreference hidePolygonsPref = activity.getMyApplication().getSettings().getCustomRenderBooleanProperty("noPolygons"); hidePolygonsPref.set(hasUnderlay); diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java index 9194949691..02b1e8dac7 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java @@ -35,7 +35,7 @@ import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; @@ -626,7 +626,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { OsmandMapTileView mapView = mapActivity.getMapView(); CommonPreference mapTypePreference; CommonPreference exMapTypePreference; - OsmandSettings.CommonPreference mapTransparencyPreference; + CommonPreference mapTransparencyPreference; //boolean isMapSelected; MapTileLayer layer; diff --git a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java index 048de5ddb9..dc68f23d0b 100644 --- a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java @@ -43,7 +43,7 @@ import net.osmand.plus.OsmAndAppCustomization.OsmAndAppCustomizationListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.development.OsmandDevelopmentPlugin; import net.osmand.plus.render.OsmandRenderer.RenderingContext; diff --git a/OsmAnd/src/net/osmand/plus/resources/RegionAddressRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/resources/RegionAddressRepositoryBinary.java index 6da4f7ecab..702028d851 100644 --- a/OsmAnd/src/net/osmand/plus/resources/RegionAddressRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/resources/RegionAddressRepositoryBinary.java @@ -18,7 +18,7 @@ import net.osmand.data.MapObject; import net.osmand.data.QuadRect; import net.osmand.data.QuadTree; import net.osmand.data.Street; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.resources.ResourceManager.BinaryMapReaderResource; import net.osmand.plus.resources.ResourceManager.BinaryMapReaderResourceType; import net.osmand.util.MapUtils; diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java index 9d7a8f3ab1..78773b5171 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java @@ -20,7 +20,7 @@ import androidx.fragment.app.Fragment; import net.osmand.AndroidUtils; import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -292,7 +292,7 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr GeneralRouter.RoutingParameter parameter = routingOptionsHelper.getRoutingPrefsForAppModeById(app.getRoutingHelper().getAppMode(), parameterId); if (parameter != null) { boolean checked = entry.getValue(); - OsmandSettings.CommonPreference preference = app.getSettings().getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); + CommonPreference preference = app.getSettings().getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); preference.setModeValue(app.getRoutingHelper().getAppMode(), checked); } } @@ -318,7 +318,7 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr List avoidParameters = routingOptionsHelper.getAvoidRoutingPrefsForAppMode(app.getRoutingHelper().getAppMode()); for (GeneralRouter.RoutingParameter parameter : avoidParameters) { - OsmandSettings.CommonPreference preference = app.getSettings().getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); + CommonPreference preference = app.getSettings().getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); res.put(parameter.getId(), preference.getModeValue(app.getRoutingHelper().getAppMode())); } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java index 8ffcc49b10..f36fc056e7 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java @@ -54,8 +54,8 @@ import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java index 3fed04affc..14ab797699 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java @@ -26,6 +26,8 @@ import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; @@ -186,7 +188,7 @@ public class RoutingOptionsHelper { public void applyVoiceProvider(MapActivity mapActivity, String provider, boolean applyAllModes) { OsmandApplication app = mapActivity.getMyApplication(); ApplicationMode selectedAppMode = app.getRoutingHelper().getAppMode(); - OsmandSettings.OsmandPreference VP = app.getSettings().VOICE_PROVIDER; + OsmandPreference VP = app.getSettings().VOICE_PROVIDER; if (applyAllModes) { for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { VP.setModeValue(mode, provider); @@ -662,7 +664,7 @@ public class RoutingOptionsHelper { } public boolean isSelected(OsmandSettings settings) { - final OsmandSettings.CommonPreference property = + final CommonPreference property = settings.getCustomRoutingBooleanProperty(routingParameter.getId(), routingParameter.getDefaultBoolean()); if (am != null) { return property.getModeValue(am); @@ -672,7 +674,7 @@ public class RoutingOptionsHelper { } public void setSelected(OsmandSettings settings, boolean isChecked) { - final OsmandSettings.CommonPreference property = + final CommonPreference property = settings.getCustomRoutingBooleanProperty(routingParameter.getId(), routingParameter.getDefaultBoolean()); if (am != null) { property.setModeValue(am, isChecked); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 2d121ccecf..eaff07dec2 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -22,7 +22,7 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; diff --git a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java index e2f196cf48..54b159c9eb 100644 --- a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java @@ -16,6 +16,7 @@ import net.osmand.osm.edit.Node; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.render.NativeOsmandLibrary; @@ -478,7 +479,7 @@ public class TransportRoutingHelper { GeneralRouter.RoutingParameter pr = e.getValue(); String vl; if(pr.getType() == GeneralRouter.RoutingParameterType.BOOLEAN) { - OsmandSettings.CommonPreference pref = settings.getCustomRoutingBooleanProperty(key, pr.getDefaultBoolean()); + CommonPreference pref = settings.getCustomRoutingBooleanProperty(key, pr.getDefaultBoolean()); Boolean bool = pref.getModeValue(params.mode); vl = bool ? "true" : null; } else { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java new file mode 100644 index 0000000000..7a796b6a6a --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java @@ -0,0 +1,33 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.plus.ApplicationMode; + +class BooleanAccessibilityPreference extends BooleanPreference { + + private OsmandSettings osmandSettings; + + BooleanAccessibilityPreference(OsmandSettings osmandSettings, String id, boolean defaultValue) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + } + + @Override + public Boolean get() { + return osmandSettings.ctx.accessibilityEnabled() ? super.get() : getDefaultValue(); + } + + @Override + public Boolean getModeValue(ApplicationMode mode) { + return osmandSettings.ctx.accessibilityEnabledForMode(mode) ? super.getModeValue(mode) : getDefaultValue(); + } + + @Override + public boolean set(Boolean obj) { + return osmandSettings.ctx.accessibilityEnabled() && super.set(obj); + } + + @Override + public boolean setModeValue(ApplicationMode mode, Boolean obj) { + return osmandSettings.ctx.accessibilityEnabledForMode(mode) && super.setModeValue(mode, obj); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java new file mode 100644 index 0000000000..3a1c0cd363 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java @@ -0,0 +1,23 @@ +package net.osmand.plus.settings.backend; + +public class BooleanPreference extends CommonPreference { + + BooleanPreference(OsmandSettings osmandSettings, String id, boolean defaultValue) { + super(osmandSettings, id, defaultValue); + } + + @Override + protected Boolean getValue(Object prefs, Boolean defaultValue) { + return osmandSettings.settingsAPI.getBoolean(prefs, getId(), defaultValue); + } + + @Override + protected boolean setValue(Object prefs, Boolean val) { + return osmandSettings.settingsAPI.edit(prefs).putBoolean(getId(), val).commit(); + } + + @Override + public Boolean parseString(String s) { + return Boolean.parseBoolean(s); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java new file mode 100644 index 0000000000..4e1e69f1b4 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java @@ -0,0 +1,234 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.plus.ApplicationMode; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class CommonPreference extends PreferenceWithListener { + private OsmandSettings osmandSettings; + private final String id; + private boolean global; + private T cachedValue; + private Object cachedPreference; + private boolean cache; + private Map defaultValues; + private T defaultValue; + + + public CommonPreference(OsmandSettings osmandSettings, String id, T defaultValue) { + this.osmandSettings = osmandSettings; + this.id = id; + this.defaultValue = defaultValue; + osmandSettings.registerInternalPreference(id, this); + } + + // Methods to possibly override + protected abstract T getValue(Object prefs, T defaultValue); + + protected abstract boolean setValue(Object prefs, T val); + + public abstract T parseString(String s); + + protected String toString(T o) { + return o == null ? null : o.toString(); + } + + + // common methods + + public final CommonPreference makeGlobal() { + global = true; + return this; + } + + public final CommonPreference cache() { + cache = true; + return this; + } + + public final CommonPreference makeProfile() { + global = false; + return this; + } + + protected final Object getPreferences() { + return osmandSettings.getPreferences(global); + + } + + public final void setModeDefaultValue(ApplicationMode mode, T defValue) { + if (defaultValues == null) { + defaultValues = new LinkedHashMap(); + } + defaultValues.put(mode, defValue); + } + + // TODO final + @Override + public boolean setModeValue(ApplicationMode mode, T obj) { + if (global) { + return set(obj); + } + + Object profilePrefs = osmandSettings.getProfilePreferences(mode); + boolean valueSaved = setValue(profilePrefs, obj); + if (valueSaved && cache && cachedPreference == profilePrefs) { + cachedValue = obj; + } + fireEvent(obj); + + return valueSaved; + } + + // TODO final + public T getProfileDefaultValue(ApplicationMode mode) { + if (global) { + return defaultValue; + } + if (defaultValues != null && defaultValues.containsKey(mode)) { + return defaultValues.get(mode); + } + ApplicationMode pt = mode.getParent(); + if (pt != null) { + return getProfileDefaultValue(pt); + } + return defaultValue; + } + + public final boolean hasDefaultValues() { + return defaultValues != null && !defaultValues.isEmpty(); + } + + public final boolean hasDefaultValueForMode(ApplicationMode mode) { + return defaultValues != null && defaultValues.containsKey(mode); + } + + // TODO final + protected T getDefaultValue() { + return getProfileDefaultValue(osmandSettings.currentMode); + } + + @Override + public final void overrideDefaultValue(T newDefaultValue) { + this.defaultValue = newDefaultValue; + } + + + + // TODO final + @Override + public T getModeValue(ApplicationMode mode) { + if (global) { + return get(); + } + T defaultV = getProfileDefaultValue(mode); + return getValue(osmandSettings.getProfilePreferences(mode), defaultV); + } + + // TODO final + @Override + public T get() { + if (cache && cachedValue != null && cachedPreference == getPreferences()) { + return cachedValue; + } + cachedPreference = getPreferences(); + cachedValue = getValue(cachedPreference, getProfileDefaultValue(osmandSettings.currentMode)); + return cachedValue; + } + + @Override + public final String getId() { + return id; + } + + @Override + public final void resetToDefault() { + T o = getProfileDefaultValue(osmandSettings.currentMode); + set(o); + } + + @Override + public final void resetModeToDefault(ApplicationMode mode) { + if (global) { + resetToDefault(); + } else { + T o = getProfileDefaultValue(mode); + setModeValue(mode, o); + } + } + + // TODO final + @Override + public boolean set(T obj) { + Object prefs = getPreferences(); + if (setValue(prefs, obj)) { + cachedValue = obj; + cachedPreference = prefs; + fireEvent(obj); + return true; + } + return false; + } + + public final boolean isSet() { + return osmandSettings.isSet(global, getId()); + } + + public boolean isSetForMode(ApplicationMode mode) { + return osmandSettings.isSet(mode, getId()); + } + + public final boolean isGlobal() { + return global; + } + + // TODO final + @Override + public boolean writeToJson(JSONObject json, ApplicationMode appMode) throws JSONException { + if (appMode != null) { + if (!global) { + String value = asStringModeValue(appMode); + if (value != null) { + json.put(getId(), value); + } + return true; + } + } else if (global) { + String value = asString(); + if (value != null) { + json.put(getId(), value); + } + return true; + } + return false; + } + // TODO final + @Override + public void readFromJson(JSONObject json, ApplicationMode appMode) throws JSONException { + if (appMode != null) { + if (!global) { + String modeValue = json.getString(getId()); + setModeValue(appMode, parseString(modeValue)); + } + } else if (global) { + String globalValue = json.getString(getId()); + set(parseString(globalValue)); + } + } + + @Override + public final String asString() { + T o = get(); + return toString(o); + } + + @Override + public final String asStringModeValue(ApplicationMode m) { + T v = getModeValue(m); + return toString(v); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java new file mode 100644 index 0000000000..a671d6141b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java @@ -0,0 +1,48 @@ +package net.osmand.plus.settings.backend; + +import androidx.annotation.NonNull; + +public class ContextMenuItemsPreference extends CommonPreference { + private OsmandSettings osmandSettings; + @NonNull + private String idScheme; + + ContextMenuItemsPreference(OsmandSettings osmandSettings, String id, @NonNull String idScheme, @NonNull ContextMenuItemsSettings defValue) { + super(id, defValue); + this.osmandSettings = osmandSettings; + this.idScheme = idScheme; + } + + @Override + protected ContextMenuItemsSettings getValue(Object prefs, ContextMenuItemsSettings defaultValue) { + String s = osmandSettings.settingsAPI.getString(prefs, getId(), ""); + return readValue(s); + } + + @Override + protected boolean setValue(Object prefs, ContextMenuItemsSettings val) { + return osmandSettings.settingsAPI.edit(prefs).putString(getId(), val.writeToJsonString(idScheme)).commit(); + } + + + @Override + protected String toString(ContextMenuItemsSettings o) { + return o.writeToJsonString(idScheme); + } + + @Override + public ContextMenuItemsSettings parseString(String s) { + return readValue(s); + } + + private ContextMenuItemsSettings readValue(String s) { + ContextMenuItemsSettings value = getDefaultValue().newInstance(); + value.readFromJsonString(s, idScheme); + return value; + } + + @NonNull + public String getIdScheme() { + return idScheme; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java new file mode 100644 index 0000000000..85046ba00a --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java @@ -0,0 +1,96 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.util.Algorithms; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import androidx.annotation.NonNull; + +public class ContextMenuItemsSettings implements Serializable { + private static final String HIDDEN = "hidden"; + private static final String ORDER = "order"; + private List hiddenIds = new ArrayList<>(); + private List orderIds = new ArrayList<>(); + + public ContextMenuItemsSettings() { + + } + + public ContextMenuItemsSettings(@NonNull List hiddenIds, @NonNull List orderIds) { + this.hiddenIds = hiddenIds; + this.orderIds = orderIds; + } + + public ContextMenuItemsSettings newInstance() { + return new ContextMenuItemsSettings(); + } + + public void readFromJsonString(String jsonString, @NonNull String idScheme) { + if (Algorithms.isEmpty(jsonString)) { + return; + } + try { + JSONObject json = new JSONObject(jsonString); + readFromJson(json, idScheme); + } catch (JSONException e) { + OsmandSettings.LOG.error("Error converting to json string: " + e); + } + } + + public void readFromJson(JSONObject json, String idScheme) { + hiddenIds = readIdsList(json.optJSONArray(HIDDEN), idScheme); + orderIds = readIdsList(json.optJSONArray(ORDER), idScheme); + } + + protected List readIdsList(JSONArray jsonArray, @NonNull String idScheme) { + List list = new ArrayList<>(); + if (jsonArray != null) { + for (int i = 0; i < jsonArray.length(); i++) { + String id = jsonArray.optString(i); + list.add(idScheme + id); + } + } + return list; + } + + public String writeToJsonString(@NonNull String idScheme) { + try { + JSONObject json = new JSONObject(); + writeToJson(json, idScheme); + return json.toString(); + } catch (JSONException e) { + OsmandSettings.LOG.error("Error converting to json string: " + e); + } + return ""; + } + + public void writeToJson(JSONObject json, String idScheme) throws JSONException { + json.put(HIDDEN, getJsonArray(hiddenIds, idScheme)); + json.put(ORDER, getJsonArray(orderIds, idScheme)); + } + + protected JSONArray getJsonArray(List ids, @NonNull String idScheme) { + JSONArray jsonArray = new JSONArray(); + if (ids != null && !ids.isEmpty()) { + for (String id : ids) { + jsonArray.put(id.replace(idScheme, "")); + } + } + return jsonArray; + } + + public List getHiddenIds() { + return Collections.unmodifiableList(hiddenIds); + } + + public List getOrderIds() { + return Collections.unmodifiableList(orderIds); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java new file mode 100644 index 0000000000..d8d01e4091 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java @@ -0,0 +1,45 @@ +package net.osmand.plus.settings.backend; + +public class EnumStringPreference> extends CommonPreference { + + private OsmandSettings osmandSettings; + private final E[] values; + + EnumStringPreference(OsmandSettings osmandSettings, String id, E defaultValue, E[] values) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + this.values = values; + } + + @Override + protected E getValue(Object prefs, E defaultValue) { + try { + String name = osmandSettings.settingsAPI.getString(prefs, getId(), defaultValue.name()); + E value = parseString(name); + return value != null ? value : defaultValue; + } catch (ClassCastException ex) { + setValue(prefs, defaultValue); + } + return defaultValue; + } + + @Override + protected boolean setValue(Object prefs, E val) { + return osmandSettings.settingsAPI.edit(prefs).putString(getId(), val.name()).commit(); + } + + @Override + protected String toString(E o) { + return o.name(); + } + + @Override + public E parseString(String s) { + for (E value : values) { + if (value.name().equals(s)) { + return value; + } + } + return null; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java new file mode 100644 index 0000000000..9c10a314f9 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java @@ -0,0 +1,27 @@ +package net.osmand.plus.settings.backend; + +public class FloatPreference extends CommonPreference { + + + private OsmandSettings osmandSettings; + + FloatPreference(OsmandSettings osmandSettings, String id, float defaultValue) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + } + + @Override + protected Float getValue(Object prefs, Float defaultValue) { + return osmandSettings.settingsAPI.getFloat(prefs, getId(), defaultValue); + } + + @Override + protected boolean setValue(Object prefs, Float val) { + return osmandSettings.settingsAPI.edit(prefs).putFloat(getId(), val).commit(); + } + + @Override + public Float parseString(String s) { + return Float.parseFloat(s); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java new file mode 100644 index 0000000000..dacadbf149 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java @@ -0,0 +1,194 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.data.LatLon; +import net.osmand.data.PointDescription; +import net.osmand.plus.helpers.AvoidSpecificRoads; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +class ImpassableRoadsStorage extends SettingsMapPointsStorage { + + private OsmandSettings osmandSettings; + protected String roadsIdsKey; + protected String appModeKey; + + public ImpassableRoadsStorage(OsmandSettings osmandSettings) { + this.osmandSettings = osmandSettings; + pointsKey = OsmandSettings.IMPASSABLE_ROAD_POINTS; + descriptionsKey = OsmandSettings.IMPASSABLE_ROADS_DESCRIPTIONS; + roadsIdsKey = OsmandSettings.IMPASSABLE_ROADS_IDS; + appModeKey = OsmandSettings.IMPASSABLE_ROADS_APP_MODE_KEYS; + } + + public List getRoadIds(int size) { + List list = new ArrayList<>(); + String roadIds = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, roadsIdsKey, ""); + if (roadIds.trim().length() > 0) { + StringTokenizer tok = new StringTokenizer(roadIds, ","); + while (tok.hasMoreTokens() && list.size() <= size) { + list.add(Long.parseLong(tok.nextToken())); + } + } + while (list.size() < size) { + list.add(0L); + } + return list; + } + + public List getAppModeKeys(int size) { + List list = new ArrayList<>(); + String roadIds = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, appModeKey, ""); + if (roadIds.trim().length() > 0) { + StringTokenizer tok = new StringTokenizer(roadIds, ","); + while (tok.hasMoreTokens() && list.size() <= size) { + list.add(tok.nextToken()); + } + } + while (list.size() < size) { + list.add(""); + } + return list; + } + + public List getImpassableRoadsInfo() { + List points = getPoints(); + List roadIds = getRoadIds(points.size()); + List appModeKeys = getAppModeKeys(points.size()); + List descriptions = getPointDescriptions(points.size()); + + List avoidRoadsInfo = new ArrayList<>(); + + for (int i = 0; i < points.size(); i++) { + LatLon latLon = points.get(i); + PointDescription description = PointDescription.deserializeFromString(descriptions.get(i), null); + + AvoidSpecificRoads.AvoidRoadInfo avoidRoadInfo = new AvoidSpecificRoads.AvoidRoadInfo(); + avoidRoadInfo.id = roadIds.get(i); + avoidRoadInfo.latitude = latLon.getLatitude(); + avoidRoadInfo.longitude = latLon.getLongitude(); + avoidRoadInfo.name = description.getName(); + avoidRoadInfo.appModeKey = appModeKeys.get(i); + avoidRoadsInfo.add(avoidRoadInfo); + } + + return avoidRoadsInfo; + } + + public boolean addImpassableRoadInfo(AvoidSpecificRoads.AvoidRoadInfo avoidRoadInfo) { + List points = getPoints(); + List roadIds = getRoadIds(points.size()); + List appModeKeys = getAppModeKeys(points.size()); + List descriptions = getPointDescriptions(points.size()); + + roadIds.add(0, avoidRoadInfo.id); + points.add(0, new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude)); + appModeKeys.add(0, avoidRoadInfo.appModeKey); + descriptions.add(0, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name))); + + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + } + + public boolean updateImpassableRoadInfo(AvoidSpecificRoads.AvoidRoadInfo avoidRoadInfo) { + List points = getPoints(); + + int index = points.indexOf(new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude)); + if (index != -1) { + List roadIds = getRoadIds(points.size()); + List appModeKeys = getAppModeKeys(points.size()); + List descriptions = getPointDescriptions(points.size()); + + roadIds.set(index, avoidRoadInfo.id); + appModeKeys.set(index, avoidRoadInfo.appModeKey); + descriptions.set(index, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name))); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + } + return false; + } + + @Override + public boolean deletePoint(int index) { + List points = getPoints(); + List roadIds = getRoadIds(points.size()); + List appModeKeys = getAppModeKeys(points.size()); + List descriptions = getPointDescriptions(points.size()); + + if (index < points.size()) { + points.remove(index); + roadIds.remove(index); + appModeKeys.remove(index); + descriptions.remove(index); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + } + return false; + } + + @Override + public boolean deletePoint(LatLon latLon) { + List points = getPoints(); + List roadIds = getRoadIds(points.size()); + List appModeKeys = getAppModeKeys(points.size()); + List descriptions = getPointDescriptions(points.size()); + + int index = points.indexOf(latLon); + if (index != -1) { + points.remove(index); + roadIds.remove(index); + appModeKeys.remove(index); + descriptions.remove(index); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + } + return false; + } + + @Override + public boolean movePoint(LatLon latLonEx, LatLon latLonNew) { + List points = getPoints(); + List roadIds = getRoadIds(points.size()); + List appModeKeys = getAppModeKeys(points.size()); + List descriptions = getPointDescriptions(points.size()); + + int i = points.indexOf(latLonEx); + if (i != -1) { + points.set(i, latLonNew); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + } else { + return false; + } + } + + public boolean saveAvoidRoadData(List points, List descriptions, + List roadIds, List appModeKeys) { + return savePoints(points, descriptions) && saveRoadIds(roadIds) && saveAppModeKeys(appModeKeys); + } + + public boolean saveRoadIds(List roadIds) { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = roadIds.iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + return osmandSettings.settingsAPI.edit(osmandSettings.globalPreferences) + .putString(roadsIdsKey, stringBuilder.toString()) + .commit(); + } + + public boolean saveAppModeKeys(List appModeKeys) { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = appModeKeys.iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + return osmandSettings.settingsAPI.edit(osmandSettings.globalPreferences) + .putString(appModeKey, stringBuilder.toString()) + .commit(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java new file mode 100644 index 0000000000..3c040821b9 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java @@ -0,0 +1,27 @@ +package net.osmand.plus.settings.backend; + +class IntPreference extends CommonPreference { + + + private OsmandSettings osmandSettings; + + IntPreference(OsmandSettings osmandSettings, String id, int defaultValue) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + } + + @Override + protected Integer getValue(Object prefs, Integer defaultValue) { + return osmandSettings.settingsAPI.getInt(prefs, getId(), defaultValue); + } + + @Override + protected boolean setValue(Object prefs, Integer val) { + return osmandSettings.settingsAPI.edit(prefs).putInt(getId(), val).commit(); + } + + @Override + public Integer parseString(String s) { + return Integer.parseInt(s); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java new file mode 100644 index 0000000000..aaf90f0efd --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java @@ -0,0 +1,23 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.data.LatLon; + +import java.util.List; + +class IntermediatePointsStorage extends SettingsMapPointsStorage { + + private OsmandSettings osmandSettings; + + public IntermediatePointsStorage(OsmandSettings osmandSettings) { + this.osmandSettings = osmandSettings; + pointsKey = OsmandSettings.INTERMEDIATE_POINTS; + descriptionsKey = OsmandSettings.INTERMEDIATE_POINTS_DESCRIPTION; + } + + @Override + public boolean savePoints(List ps, List ds) { + boolean res = super.savePoints(ps, ds); + osmandSettings.backupTargetPoints(); + return res; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java new file mode 100644 index 0000000000..81b7a01f60 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java @@ -0,0 +1,127 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.plus.ApplicationMode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ListStringPreference extends StringPreference { + + private OsmandSettings osmandSettings; + private String delimiter; + + ListStringPreference(OsmandSettings osmandSettings, String id, String defaultValue, String delimiter) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + this.delimiter = delimiter; + } + + public boolean addValue(String res) { + return addModeValue(osmandSettings.getApplicationMode(), res); + } + + public boolean addModeValue(ApplicationMode appMode, String res) { + String vl = getModeValue(appMode); + if (vl == null || vl.isEmpty()) { + vl = res + delimiter; + } else { + vl = vl + res + delimiter; + } + setModeValue(appMode, vl); + return true; + } + + public void clearAll() { + clearAllForProfile(osmandSettings.getApplicationMode()); + } + + public void clearAllForProfile(ApplicationMode appMode) { + setModeValue(appMode, ""); + } + + public boolean containsValue(String res) { + return containsValue(osmandSettings.getApplicationMode(), res); + } + + public boolean containsValue(ApplicationMode appMode, String res) { + String vl = getModeValue(appMode); + String r = res + delimiter; + return vl.startsWith(r) || vl.contains(delimiter + r); + } + + public boolean removeValue(String res) { + return removeValueForProfile(osmandSettings.getApplicationMode(), res); + } + + public boolean removeValueForProfile(ApplicationMode appMode, String res) { + String vl = getModeValue(appMode); + String r = res + delimiter; + if(vl != null) { + if(vl.startsWith(r)) { + vl = vl.substring(r.length()); + setModeValue(appMode, vl); + return true; + } else { + int it = vl.indexOf(delimiter + r); + if(it >= 0) { + vl = vl.substring(0, it + delimiter.length()) + vl.substring(it + delimiter.length() + r.length()); + } + setModeValue(appMode, vl); + return true; + } + } + return false; + } + + public List getStringsList() { + return getStringsListForProfile(osmandSettings.getApplicationMode()); + } + + public List getStringsListForProfile(ApplicationMode appMode) { + final String listAsString = getModeValue(appMode); + if (listAsString != null) { + if (listAsString.contains(delimiter)) { + return Arrays.asList(listAsString.split(delimiter)); + } else { + return new ArrayList() { + {add(listAsString);} + }; + } + } + return null; + } + + public void setStringsList(List values) { + setStringsListForProfile(osmandSettings.getApplicationMode(), values); + } + + public void setStringsListForProfile(ApplicationMode appMode, List values) { + if (values == null || values.size() == 0) { + setModeValue(appMode, null); + return; + } + clearAllForProfile(appMode); + for (String value : values) { + addModeValue(appMode, value); + } + } + + public boolean setModeValues(ApplicationMode mode, List values) { + if (values == null || values.size() == 0) { + setModeValue(mode,null); + return false; + } + clearAll(); + String vl = get(); + for (String value : values) { + addValue(value); + if (vl == null || vl.isEmpty()) { + vl = value + delimiter; + } else { + vl = vl + value + delimiter; + } + } + return setModeValue(mode, vl); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java new file mode 100644 index 0000000000..8993919e23 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java @@ -0,0 +1,27 @@ +package net.osmand.plus.settings.backend; + +class LongPreference extends CommonPreference { + + + private OsmandSettings osmandSettings; + + LongPreference(OsmandSettings osmandSettings, String id, long defaultValue) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + } + + @Override + protected Long getValue(Object prefs, Long defaultValue) { + return osmandSettings.settingsAPI.getLong(prefs, getId(), defaultValue); + } + + @Override + protected boolean setValue(Object prefs, Long val) { + return osmandSettings.settingsAPI.edit(prefs).putLong(getId(), val).commit(); + } + + @Override + public Long parseString(String s) { + return Long.parseLong(s); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/MainContextMenuItemsSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/MainContextMenuItemsSettings.java new file mode 100644 index 0000000000..51407a36ba --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/MainContextMenuItemsSettings.java @@ -0,0 +1,45 @@ +package net.osmand.plus.settings.backend; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import androidx.annotation.NonNull; + +public class MainContextMenuItemsSettings extends ContextMenuItemsSettings { + private static final String MAIN = "main"; + private List mainIds = new ArrayList<>(); + + public MainContextMenuItemsSettings() { + + } + + public MainContextMenuItemsSettings(@NonNull List mainIds, @NonNull List hiddenIds, @NonNull List orderIds) { + super(hiddenIds, orderIds); + this.mainIds = mainIds; + } + + @Override + public ContextMenuItemsSettings newInstance() { + return new MainContextMenuItemsSettings(); + } + + @Override + public void readFromJson(JSONObject json, String idScheme) { + super.readFromJson(json, idScheme); + mainIds = readIdsList(json.optJSONArray(MAIN), idScheme); + } + + @Override + public void writeToJson(JSONObject json, String idScheme) throws JSONException { + super.writeToJson(json, idScheme); + json.put(MAIN, getJsonArray(mainIds, idScheme)); + } + + public List getMainIds() { + return Collections.unmodifiableList(mainIds); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java new file mode 100644 index 0000000000..0a6f464b77 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java @@ -0,0 +1,120 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.plus.ApplicationMode; + +import java.util.Set; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.PreferenceDataStore; + +public class OsmAndPreferencesDataStore extends PreferenceDataStore { + + private OsmandSettings osmandSettings; + private ApplicationMode appMode; + + public OsmAndPreferencesDataStore(OsmandSettings osmandSettings, @NonNull ApplicationMode appMode) { + this.osmandSettings = osmandSettings; + this.appMode = appMode; + } + + @Override + public void putString(String key, @Nullable String value) { + osmandSettings.setPreference(key, value, appMode); + } + + @Override + public void putStringSet(String key, @Nullable Set values) { + osmandSettings.setPreference(key, values, appMode); + } + + @Override + public void putInt(String key, int value) { + osmandSettings.setPreference(key, value, appMode); + } + + @Override + public void putLong(String key, long value) { + osmandSettings.setPreference(key, value, appMode); + } + + @Override + public void putFloat(String key, float value) { + osmandSettings.setPreference(key, value, appMode); + } + + @Override + public void putBoolean(String key, boolean value) { + osmandSettings.setPreference(key, value, appMode); + } + + public void putValue(String key, Object value) { + osmandSettings.setPreference(key, value, appMode); + } + + @Nullable + @Override + public String getString(String key, @Nullable String defValue) { + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof StringPreference) { + return ((StringPreference) preference).getModeValue(appMode); + } else { + Object value = preference.getModeValue(appMode); + if (value != null) { + return value.toString(); + } + } + return defValue; + } + + @Nullable + @Override + public Set getStringSet(String key, @Nullable Set defValues) { + return super.getStringSet(key, defValues); + } + + @Override + public int getInt(String key, int defValue) { + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof OsmandSettings.IntPreference) { + return ((OsmandSettings.IntPreference) preference).getModeValue(appMode); + } + return defValue; + } + + @Override + public long getLong(String key, long defValue) { + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof OsmandSettings.LongPreference) { + return ((OsmandSettings.LongPreference) preference).getModeValue(appMode); + } + return defValue; + } + + @Override + public float getFloat(String key, float defValue) { + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof FloatPreference) { + return ((FloatPreference) preference).getModeValue(appMode); + } + return defValue; + } + + @Override + public boolean getBoolean(String key, boolean defValue) { + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof BooleanPreference) { + return ((BooleanPreference) preference).getModeValue(appMode); + } + return defValue; + } + + @Nullable + public Object getValue(String key, Object defValue) { + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference != null) { + return preference.getModeValue(appMode); + } + return defValue; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java new file mode 100644 index 0000000000..ae9a3f5e3a --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java @@ -0,0 +1,43 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.StateChangedListener; +import net.osmand.plus.ApplicationMode; + +import org.json.JSONException; +import org.json.JSONObject; + +public interface OsmandPreference { + T get(); + + boolean set(T obj); + + boolean setModeValue(ApplicationMode m, T obj); + + T getModeValue(ApplicationMode m); + + String getId(); + + void resetToDefault(); + + void resetModeToDefault(ApplicationMode m); + + void overrideDefaultValue(T newDefaultValue); + + void addListener(StateChangedListener listener); + + void removeListener(StateChangedListener listener); + + boolean isSet(); + + boolean isSetForMode(ApplicationMode m); + + boolean writeToJson(JSONObject json, ApplicationMode appMode) throws JSONException; + + void readFromJson(JSONObject json, ApplicationMode appMode) throws JSONException; + + String asString(); + + String asStringModeValue(ApplicationMode m); + + T parseString(String s); +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 24b01d96dc..93705e3c69 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -18,18 +18,11 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.core.util.Pair; -import androidx.preference.PreferenceDataStore; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; -import net.osmand.StateChangedListener; import net.osmand.ValueHolder; import net.osmand.aidl.OsmandAidlApi; -import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.map.ITileSource; @@ -37,9 +30,6 @@ import net.osmand.map.TileSourceManager; import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.ApplicationMode; -import net.osmand.plus.ApplicationMode.ApplicationModeBean; -import net.osmand.plus.ApplicationMode.ApplicationModeBuilder; -import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; @@ -63,15 +53,11 @@ import net.osmand.render.RenderingRulesStorage; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; -import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.IOException; -import java.io.Serializable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -79,7 +65,6 @@ import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -96,83 +81,6 @@ public class OsmandSettings { public static final int VERSION = 1; - public interface OsmandPreference { - T get(); - - boolean set(T obj); - - boolean setModeValue(ApplicationMode m, T obj); - - T getModeValue(ApplicationMode m); - - String getId(); - - void resetToDefault(); - - void resetModeToDefault(ApplicationMode m); - - void overrideDefaultValue(T newDefaultValue); - - void addListener(StateChangedListener listener); - - void removeListener(StateChangedListener listener); - - boolean isSet(); - - boolean isSetForMode(ApplicationMode m); - - boolean writeToJson(JSONObject json, ApplicationMode appMode) throws JSONException; - - void readFromJson(JSONObject json, ApplicationMode appMode) throws JSONException; - - String asString(); - - String asStringModeValue(ApplicationMode m); - - T parseString(String s); - } - - private abstract class PreferenceWithListener implements OsmandPreference { - private List>> l = null; - - @Override - public synchronized void addListener(StateChangedListener listener) { - if (l == null) { - l = new LinkedList>>(); - } - if (!l.contains(new WeakReference>(listener))) { - l.add(new WeakReference>(listener)); - } - } - - public synchronized void fireEvent(T value) { - if (l != null) { - Iterator>> it = l.iterator(); - while (it.hasNext()) { - StateChangedListener t = it.next().get(); - if (t == null) { - it.remove(); - } else { - t.stateChanged(value); - } - } - } - } - - @Override - public synchronized void removeListener(StateChangedListener listener) { - if (l != null) { - Iterator>> it = l.iterator(); - while (it.hasNext()) { - StateChangedListener t = it.next().get(); - if (t == listener) { - it.remove(); - } - } - } - } - } - // These settings are stored in SharedPreferences private static final String CUSTOM_SHARED_PREFERENCES_PREFIX = "net.osmand.customsettings."; private static final String SHARED_PREFERENCES_NAME = "net.osmand.settings"; @@ -182,16 +90,29 @@ public class OsmandSettings { /// Settings variables private final OsmandApplication ctx; private SettingsAPI settingsAPI; - private Object globalPreferences; - private Object profilePreferences; - private ApplicationMode currentMode; - private Map> registeredPreferences = - new LinkedHashMap>(); + Object globalPreferences; + Object profilePreferences; + ApplicationMode currentMode; + Map> registeredPreferences = + new LinkedHashMap>(); + // cache variables private long lastTimeInternetConnectionChecked = 0; private boolean internetConnectionAvailable = true; + // TODO variable + Map> customBooleanRendersProps = new LinkedHashMap>(); + Map> customRoutingProps = new LinkedHashMap>(); + Map> customBooleanRoutingProps = new LinkedHashMap>(); + Map> customRendersProps = new LinkedHashMap>(); + private IntermediatePointsStorage intermediatePointsStorage = new IntermediatePointsStorage(this); + private ImpassableRoadsStorage mImpassableRoadsStorage = new ImpassableRoadsStorage(this); + + private Object objectToShow; + private boolean editObjectToShow; + private String searchRequestToShow; + protected OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI) { ctx = clientContext; @@ -237,8 +158,8 @@ public class OsmandSettings { return settingsAPI; } - public PreferencesDataStore getDataStore(@Nullable ApplicationMode appMode) { - return new PreferencesDataStore(appMode != null ? appMode : APPLICATION_MODE.get()); + public OsmAndPreferencesDataStore getDataStore(@Nullable ApplicationMode appMode) { + return new OsmAndPreferencesDataStore(this, appMode != null ? appMode : APPLICATION_MODE.get()); } public static String getSharedPreferencesName(ApplicationMode mode) { @@ -263,109 +184,7 @@ public class OsmandSettings { return globalPreferences != null && globalPreferences.getBoolean(SETTING_CUSTOMIZED_ID, false); } - public void migratePreferences() { - migrateEnumPreferences(); - SharedPreferences globalSharedPreferences = (SharedPreferences) globalPreferences; - Map globalPrefsMap = globalSharedPreferences.getAll(); - for (String key : globalPrefsMap.keySet()) { - OsmandPreference pref = getPreference(key); - if (pref instanceof CommonPreference) { - CommonPreference commonPreference = (CommonPreference) pref; - if (!commonPreference.global) { - for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { - if (!commonPreference.isSetForMode(mode) && !commonPreference.hasDefaultValueForMode(mode)) { - setPreference(key, globalPrefsMap.get(key), mode); - } - } - } - } - } - SharedPreferences defaultProfilePreferences = (SharedPreferences) getProfilePreferences(ApplicationMode.DEFAULT); - Map defaultPrefsMap = defaultProfilePreferences.getAll(); - for (String key : defaultPrefsMap.keySet()) { - OsmandPreference pref = getPreference(key); - if (pref instanceof CommonPreference) { - CommonPreference commonPreference = (CommonPreference) pref; - if (commonPreference.global && !commonPreference.isSet()) { - setPreference(key, defaultPrefsMap.get(key)); - } - } - } - for (OsmandPreference pref : generalPrefs) { - if (pref instanceof CommonPreference) { - CommonPreference commonPref = (CommonPreference) pref; - Object defaultVal = commonPref.getModeValue(ApplicationMode.DEFAULT); - for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { - if (!commonPref.isSetForMode(mode) && !commonPref.hasDefaultValueForMode(mode)) { - setPreference(commonPref.getId(), defaultVal, mode); - } - } - } - } - String json = settingsAPI.getString(globalPreferences, "custom_app_profiles", ""); - if (!Algorithms.isEmpty(json)) { - Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); - Type t = new TypeToken>() { - }.getType(); - List customProfiles = gson.fromJson(json, t); - if (!Algorithms.isEmpty(customProfiles)) { - for (ApplicationModeBean modeBean : customProfiles) { - ApplicationModeBuilder builder = ApplicationMode.fromModeBean(ctx, modeBean); - ApplicationMode.saveProfile(builder, ctx); - } - } - } - } - - public void migrateEnumPreferences() { - for (OsmandPreference pref : registeredPreferences.values()) { - if (pref instanceof EnumStringPreference) { - EnumStringPreference enumPref = (EnumStringPreference) pref; - if (enumPref.isGlobal()) { - migrateEnumPref(enumPref, (SharedPreferences) globalPreferences); - } else { - for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { - migrateEnumPref(enumPref, (SharedPreferences) getProfilePreferences(mode)); - } - } - } - } - } - - private void migrateEnumPref(EnumStringPreference enumPref, SharedPreferences sharedPreferences) { - Object value = sharedPreferences.getAll().get(enumPref.getId()); - if (value instanceof Integer) { - int enumIndex = (int) value; - if (enumIndex >= 0 && enumIndex < enumPref.values.length) { - Enum savedValue = enumPref.values[enumIndex]; - enumPref.setValue(sharedPreferences, savedValue); - } - } - } - - public void migrateHomeWorkParkingToFavorites() { - FavouritesDbHelper favorites = ctx.getFavorites(); - - LatLon homePoint = null; - float lat = settingsAPI.getFloat(globalPreferences, "home_point_lat", 0); - float lon = settingsAPI.getFloat(globalPreferences, "home_point_lon", 0); - if (lat != 0 || lon != 0) { - homePoint = new LatLon(lat, lon); - } - LatLon workPoint = null; - lat = settingsAPI.getFloat(globalPreferences, "work_point_lat", 0); - lon = settingsAPI.getFloat(globalPreferences, "work_point_lon", 0); - if (lat != 0 || lon != 0) { - workPoint = new LatLon(lat, lon); - } - if (homePoint != null) { - favorites.setSpecialPoint(homePoint, FavouritePoint.SpecialPointType.HOME, null); - } - if (workPoint != null) { - favorites.setSpecialPoint(workPoint, FavouritePoint.SpecialPointType.WORK, null); - } - } public Object getProfilePreferences(ApplicationMode mode) { return settingsAPI.getPreferenceObject(getSharedPreferencesName(mode)); @@ -714,697 +533,98 @@ public class OsmandSettings { } } - - /////////////// PREFERENCES classes //////////////// - - public abstract class CommonPreference extends PreferenceWithListener { - private final String id; - private boolean global; - private T cachedValue; - private Object cachedPreference; - private boolean cache; - private Map defaultValues; - private T defaultValue; - - - public CommonPreference(String id, T defaultValue) { - this.id = id; - this.defaultValue = defaultValue; - registeredPreferences.put(id, this); - } - - // Methods to possibly override - protected abstract T getValue(Object prefs, T defaultValue); - - protected abstract boolean setValue(Object prefs, T val); - - public abstract T parseString(String s); - - protected String toString(T o) { - return o == null ? null : o.toString(); - } - - - // common methods - - public final CommonPreference makeGlobal() { - global = true; - return this; - } - - public final CommonPreference cache() { - cache = true; - return this; - } - - public final CommonPreference makeProfile() { - global = false; - return this; - } - - protected final Object getPreferences() { - return global ? globalPreferences : profilePreferences; - } - - public final void setModeDefaultValue(ApplicationMode mode, T defValue) { - if (defaultValues == null) { - defaultValues = new LinkedHashMap(); - } - defaultValues.put(mode, defValue); - } - - // TODO final - @Override - public boolean setModeValue(ApplicationMode mode, T obj) { - if (global) { - return set(obj); - } - - Object profilePrefs = getProfilePreferences(mode); - boolean valueSaved = setValue(profilePrefs, obj); - if (valueSaved && cache && cachedPreference == profilePrefs) { - cachedValue = obj; - } - fireEvent(obj); - - return valueSaved; - } - - // TODO final - public T getProfileDefaultValue(ApplicationMode mode) { - if (global) { - return defaultValue; - } - if (defaultValues != null && defaultValues.containsKey(mode)) { - return defaultValues.get(mode); - } - ApplicationMode pt = mode.getParent(); - if (pt != null) { - return getProfileDefaultValue(pt); - } - return defaultValue; - } - - public final boolean hasDefaultValues() { - return defaultValues != null && !defaultValues.isEmpty(); - } - - public final boolean hasDefaultValueForMode(ApplicationMode mode) { - return defaultValues != null && defaultValues.containsKey(mode); - } - - // TODO final - protected T getDefaultValue() { - return getProfileDefaultValue(currentMode); - } - - @Override - public final void overrideDefaultValue(T newDefaultValue) { - this.defaultValue = newDefaultValue; - } - - - - // TODO final - @Override - public T getModeValue(ApplicationMode mode) { - if (global) { - return get(); - } - T defaultV = getProfileDefaultValue(mode); - return getValue(getProfilePreferences(mode), defaultV); - } - - // TODO final - @Override - public T get() { - if (cache && cachedValue != null && cachedPreference == getPreferences()) { - return cachedValue; - } - cachedPreference = getPreferences(); - cachedValue = getValue(cachedPreference, getProfileDefaultValue(currentMode)); - return cachedValue; - } - - @Override - public final String getId() { - return id; - } - - @Override - public final void resetToDefault() { - T o = getProfileDefaultValue(currentMode); - set(o); - } - - @Override - public final void resetModeToDefault(ApplicationMode mode) { - if (global) { - resetToDefault(); - } else { - T o = getProfileDefaultValue(mode); - setModeValue(mode, o); - } - } - - // TODO final - @Override - public boolean set(T obj) { - Object prefs = getPreferences(); - if (setValue(prefs, obj)) { - cachedValue = obj; - cachedPreference = prefs; - fireEvent(obj); - return true; - } - return false; - } - - public final boolean isSet() { - return settingsAPI.contains(getPreferences(), getId()); - } - - public boolean isSetForMode(ApplicationMode mode) { - return settingsAPI.contains(getProfilePreferences(mode), getId()); - } - - public final boolean isGlobal() { - return global; - } - - // TODO final - @Override - public boolean writeToJson(JSONObject json, ApplicationMode appMode) throws JSONException { - if (appMode != null) { - if (!global) { - String value = asStringModeValue(appMode); - if (value != null) { - json.put(getId(), value); - } - return true; - } - } else if (global) { - String value = asString(); - if (value != null) { - json.put(getId(), value); - } - return true; - } - return false; - } - // TODO final - @Override - public void readFromJson(JSONObject json, ApplicationMode appMode) throws JSONException { - if (appMode != null) { - if (!global) { - String modeValue = json.getString(getId()); - setModeValue(appMode, parseString(modeValue)); - } - } else if (global) { - String globalValue = json.getString(getId()); - set(parseString(globalValue)); - } - } - - @Override - public final String asString() { - T o = get(); - return toString(o); - } - - @Override - public final String asStringModeValue(ApplicationMode m) { - T v = getModeValue(m); - return toString(v); - } + void registerInternalPreference(String id, CommonPreference tCommonPreference) { + registeredPreferences.put(id, tCommonPreference); } - public class BooleanPreference extends CommonPreference { - - - private BooleanPreference(String id, boolean defaultValue) { - super(id, defaultValue); - } - - @Override - protected Boolean getValue(Object prefs, Boolean defaultValue) { - return settingsAPI.getBoolean(prefs, getId(), defaultValue); - } - - @Override - protected boolean setValue(Object prefs, Boolean val) { - return settingsAPI.edit(prefs).putBoolean(getId(), val).commit(); - } - - @Override - public Boolean parseString(String s) { - return Boolean.parseBoolean(s); - } + boolean isSet(boolean global, String id) { + return settingsAPI.contains(getPreferences(global), id); } - private class BooleanAccessibilityPreference extends BooleanPreference { - - private BooleanAccessibilityPreference(String id, boolean defaultValue) { - super(id, defaultValue); - } - - @Override - public Boolean get() { - return ctx.accessibilityEnabled() ? super.get() : getDefaultValue(); - } - - @Override - public Boolean getModeValue(ApplicationMode mode) { - return ctx.accessibilityEnabledForMode(mode) ? super.getModeValue(mode) : getDefaultValue(); - } - - @Override - public boolean set(Boolean obj) { - return ctx.accessibilityEnabled() && super.set(obj); - } - - @Override - public boolean setModeValue(ApplicationMode mode, Boolean obj) { - return ctx.accessibilityEnabledForMode(mode) && super.setModeValue(mode, obj); - } + boolean isSet(ApplicationMode m, String id) { + return settingsAPI.contains(getProfilePreferences(m), id); } - private class IntPreference extends CommonPreference { - - - private IntPreference(String id, int defaultValue) { - super(id, defaultValue); - } - - @Override - protected Integer getValue(Object prefs, Integer defaultValue) { - return settingsAPI.getInt(prefs, getId(), defaultValue); - } - - @Override - protected boolean setValue(Object prefs, Integer val) { - return settingsAPI.edit(prefs).putInt(getId(), val).commit(); - } - - @Override - public Integer parseString(String s) { - return Integer.parseInt(s); - } + Object getPreferences(boolean global) { + return global ? globalPreferences : profilePreferences; } - private class LongPreference extends CommonPreference { - - private LongPreference(String id, long defaultValue) { - super(id, defaultValue); - } - - @Override - protected Long getValue(Object prefs, Long defaultValue) { - return settingsAPI.getLong(prefs, getId(), defaultValue); - } - - @Override - protected boolean setValue(Object prefs, Long val) { - return settingsAPI.edit(prefs).putLong(getId(), val).commit(); - } - - @Override - public Long parseString(String s) { - return Long.parseLong(s); + @SuppressWarnings("unchecked") + public CommonPreference registerBooleanPreference(String id, boolean defValue) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + BooleanPreference p = new BooleanPreference(this, id, defValue); + registeredPreferences.put(id, p); + return p; } - public class FloatPreference extends CommonPreference { - - - private FloatPreference(String id, float defaultValue) { - super(id, defaultValue); - } - - @Override - protected Float getValue(Object prefs, Float defaultValue) { - return settingsAPI.getFloat(prefs, getId(), defaultValue); - } - - @Override - protected boolean setValue(Object prefs, Float val) { - return settingsAPI.edit(prefs).putFloat(getId(), val).commit(); - } - - @Override - public Float parseString(String s) { - return Float.parseFloat(s); + @SuppressWarnings("unchecked") + public CommonPreference registerBooleanAccessibilityPreference(String id, boolean defValue) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + BooleanPreference p = new BooleanAccessibilityPreference(this, id, defValue); + registeredPreferences.put(id, p); + return p; } - public class StringPreference extends CommonPreference { - - private StringPreference(String id, String defaultValue) { - super(id, defaultValue); - } - - @Override - protected String getValue(Object prefs, String defaultValue) { - return settingsAPI.getString(prefs, getId(), defaultValue); - } - - @Override - protected boolean setValue(Object prefs, String val) { - return settingsAPI.edit(prefs).putString(getId(), (val != null) ? val.trim() : val).commit(); - } - - @Override - public String parseString(String s) { - return s; - } - } - - public class ListStringPreference extends StringPreference { - - private String delimiter; - - private ListStringPreference(String id, String defaultValue, String delimiter) { - super(id, defaultValue); - this.delimiter = delimiter; - } - - public boolean addValue(String res) { - return addModeValue(getApplicationMode(), res); - } - - public boolean addModeValue(ApplicationMode appMode, String res) { - String vl = getModeValue(appMode); - if (vl == null || vl.isEmpty()) { - vl = res + delimiter; - } else { - vl = vl + res + delimiter; - } - setModeValue(appMode, vl); - return true; - } - - public void clearAll() { - clearAllForProfile(getApplicationMode()); - } - - public void clearAllForProfile(ApplicationMode appMode) { - setModeValue(appMode, ""); - } - - public boolean containsValue(String res) { - return containsValue(getApplicationMode(), res); - } - - public boolean containsValue(ApplicationMode appMode, String res) { - String vl = getModeValue(appMode); - String r = res + delimiter; - return vl.startsWith(r) || vl.contains(delimiter + r); - } - - public boolean removeValue(String res) { - return removeValueForProfile(getApplicationMode(), res); - } - - public boolean removeValueForProfile(ApplicationMode appMode, String res) { - String vl = getModeValue(appMode); - String r = res + delimiter; - if(vl != null) { - if(vl.startsWith(r)) { - vl = vl.substring(r.length()); - setModeValue(appMode, vl); - return true; - } else { - int it = vl.indexOf(delimiter + r); - if(it >= 0) { - vl = vl.substring(0, it + delimiter.length()) + vl.substring(it + delimiter.length() + r.length()); - } - setModeValue(appMode, vl); - return true; - } - } - return false; - } - - public List getStringsList() { - return getStringsListForProfile(getApplicationMode()); - } - - public List getStringsListForProfile(ApplicationMode appMode) { - final String listAsString = getModeValue(appMode); - if (listAsString != null) { - if (listAsString.contains(delimiter)) { - return Arrays.asList(listAsString.split(delimiter)); - } else { - return new ArrayList() { - {add(listAsString);} - }; - } - } - return null; - } - - public void setStringsList(List values) { - setStringsListForProfile(getApplicationMode(), values); - } - - public void setStringsListForProfile(ApplicationMode appMode, List values) { - if (values == null || values.size() == 0) { - setModeValue(appMode, null); - return; - } - clearAllForProfile(appMode); - for (String value : values) { - addModeValue(appMode, value); - } - } - - public boolean setModeValues(ApplicationMode mode, List values) { - if (values == null || values.size() == 0) { - setModeValue(mode,null); - return false; - } - clearAll(); - String vl = get(); - for (String value : values) { - addValue(value); - if (vl == null || vl.isEmpty()) { - vl = value + delimiter; - } else { - vl = vl + value + delimiter; - } - } - return setModeValue(mode, vl); + @SuppressWarnings("unchecked") + public CommonPreference registerStringPreference(String id, String defValue) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + StringPreference p = new StringPreference(this, id, defValue); + registeredPreferences.put(id, p); + return p; } - public class ContextMenuItemsPreference extends CommonPreference { - @NonNull - private String idScheme; - - private ContextMenuItemsPreference(String id, @NonNull String idScheme, @NonNull ContextMenuItemsSettings defValue) { - super(id, defValue); - this.idScheme = idScheme; - } - - @Override - protected ContextMenuItemsSettings getValue(Object prefs, ContextMenuItemsSettings defaultValue) { - String s = settingsAPI.getString(prefs, getId(), ""); - return readValue(s); - } - - @Override - protected boolean setValue(Object prefs, ContextMenuItemsSettings val) { - return settingsAPI.edit(prefs).putString(getId(), val.writeToJsonString(idScheme)).commit(); - } - - - @Override - protected String toString(ContextMenuItemsSettings o) { - return o.writeToJsonString(idScheme); - } - - @Override - public ContextMenuItemsSettings parseString(String s) { - return readValue(s); - } - - private ContextMenuItemsSettings readValue(String s) { - ContextMenuItemsSettings value = getDefaultValue().newInstance(); - value.readFromJsonString(s, idScheme); - return value; - } - - @NonNull - public String getIdScheme() { - return idScheme; + @SuppressWarnings("unchecked") + public CommonPreference registerIntPreference(String id, int defValue) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + IntPreference p = new IntPreference(this, id, defValue); + registeredPreferences.put(id, p); + return p; } - public static class ContextMenuItemsSettings implements Serializable { - private static final String HIDDEN = "hidden"; - private static final String ORDER = "order"; - private List hiddenIds = new ArrayList<>(); - private List orderIds = new ArrayList<>(); - - public ContextMenuItemsSettings() { - - } - - public ContextMenuItemsSettings(@NonNull List hiddenIds, @NonNull List orderIds) { - this.hiddenIds = hiddenIds; - this.orderIds = orderIds; - } - - public ContextMenuItemsSettings newInstance() { - return new ContextMenuItemsSettings(); - } - - public void readFromJsonString(String jsonString, @NonNull String idScheme) { - if (Algorithms.isEmpty(jsonString)) { - return; - } - try { - JSONObject json = new JSONObject(jsonString); - readFromJson(json, idScheme); - } catch (JSONException e) { - LOG.error("Error converting to json string: " + e); - } - } - - public void readFromJson(JSONObject json, String idScheme) { - hiddenIds = readIdsList(json.optJSONArray(HIDDEN), idScheme); - orderIds = readIdsList(json.optJSONArray(ORDER), idScheme); - } - - protected List readIdsList(JSONArray jsonArray, @NonNull String idScheme) { - List list = new ArrayList<>(); - if (jsonArray != null) { - for (int i = 0; i < jsonArray.length(); i++) { - String id = jsonArray.optString(i); - list.add(idScheme + id); - } - } - return list; - } - - public String writeToJsonString(@NonNull String idScheme) { - try { - JSONObject json = new JSONObject(); - writeToJson(json, idScheme); - return json.toString(); - } catch (JSONException e) { - LOG.error("Error converting to json string: " + e); - } - return ""; - } - - public void writeToJson(JSONObject json, String idScheme) throws JSONException { - json.put(HIDDEN, getJsonArray(hiddenIds, idScheme)); - json.put(ORDER, getJsonArray(orderIds, idScheme)); - } - - protected JSONArray getJsonArray(List ids, @NonNull String idScheme) { - JSONArray jsonArray = new JSONArray(); - if (ids != null && !ids.isEmpty()) { - for (String id : ids) { - jsonArray.put(id.replace(idScheme, "")); - } - } - return jsonArray; - } - - public List getHiddenIds() { - return Collections.unmodifiableList(hiddenIds); - } - - public List getOrderIds() { - return Collections.unmodifiableList(orderIds); + @SuppressWarnings("unchecked") + public CommonPreference registerLongPreference(String id, long defValue) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + LongPreference p = new LongPreference(this, id, defValue); + registeredPreferences.put(id, p); + return p; } - public static class MainContextMenuItemsSettings extends ContextMenuItemsSettings { - private static final String MAIN = "main"; - private List mainIds = new ArrayList<>(); - - public MainContextMenuItemsSettings() { - - } - - public MainContextMenuItemsSettings(@NonNull List mainIds, @NonNull List hiddenIds, @NonNull List orderIds) { - super(hiddenIds, orderIds); - this.mainIds = mainIds; - } - - @Override - public ContextMenuItemsSettings newInstance() { - return new MainContextMenuItemsSettings(); - } - - @Override - public void readFromJson(JSONObject json, String idScheme) { - super.readFromJson(json, idScheme); - mainIds = readIdsList(json.optJSONArray(MAIN), idScheme); - } - - @Override - public void writeToJson(JSONObject json, String idScheme) throws JSONException { - super.writeToJson(json, idScheme); - json.put(MAIN, getJsonArray(mainIds, idScheme)); - } - - public List getMainIds() { - return Collections.unmodifiableList(mainIds); + @SuppressWarnings("unchecked") + public CommonPreference registerFloatPreference(String id, float defValue) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + FloatPreference p = new FloatPreference(this, id, defValue); + registeredPreferences.put(id, p); + return p; } - public class EnumStringPreference> extends CommonPreference { - - private final E[] values; - - private EnumStringPreference(String id, E defaultValue, E[] values) { - super(id, defaultValue); - this.values = values; - } - - @Override - protected E getValue(Object prefs, E defaultValue) { - try { - String name = settingsAPI.getString(prefs, getId(), defaultValue.name()); - E value = parseString(name); - return value != null ? value : defaultValue; - } catch (ClassCastException ex) { - setValue(prefs, defaultValue); - } - return defaultValue; - } - - @Override - protected boolean setValue(Object prefs, E val) { - return settingsAPI.edit(prefs).putString(getId(), val.name()).commit(); - } - - @Override - protected String toString(E o) { - return o.name(); - } - - @Override - public E parseString(String s) { - for (E value : values) { - if (value.name().equals(s)) { - return value; - } - } - return null; + @SuppressWarnings("unchecked") + public CommonPreference registerEnumIntPreference(String id, Enum defaultValue, Enum[] values, Class clz) { + if (registeredPreferences.containsKey(id)) { + return (CommonPreference) registeredPreferences.get(id); } + EnumStringPreference p = new EnumStringPreference(this, id, defaultValue, values); + registeredPreferences.put(id, p); + return p; } - ///////////// PREFERENCES classes //////////////// + ///////////////////// PREFERENCES //////////////// public static final String NUMBER_OF_FREE_DOWNLOADS_ID = "free_downloads_v3"; // this value string is synchronized with settings_pref.xml preference name - private final OsmandPreference PLUGINS = new StringPreference("enabled_plugins", MapillaryPlugin.ID).makeGlobal(); + private final OsmandPreference PLUGINS = new StringPreference(this, "enabled_plugins", MapillaryPlugin.ID).makeGlobal(); public Set getEnabledPlugins() { String plugs = PLUGINS.get(); @@ -1453,124 +673,54 @@ public class OsmandSettings { } - @SuppressWarnings("unchecked") - public CommonPreference registerBooleanPreference(String id, boolean defValue) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - BooleanPreference p = new BooleanPreference(id, defValue); - registeredPreferences.put(id, p); - return p; - } + public final CommonPreference RULER_MODE = new EnumStringPreference<>(this, "ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal(); - @SuppressWarnings("unchecked") - public CommonPreference registerBooleanAccessibilityPreference(String id, boolean defValue) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - BooleanPreference p = new BooleanAccessibilityPreference(id, defValue); - registeredPreferences.put(id, p); - return p; - } + public final OsmandPreference SHOW_COMPASS_CONTROL_RULER = new BooleanPreference(this, "show_compass_ruler", true).makeGlobal(); - @SuppressWarnings("unchecked") - public CommonPreference registerStringPreference(String id, String defValue) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - StringPreference p = new StringPreference(id, defValue); - registeredPreferences.put(id, p); - return p; - } + public final CommonPreference SHOW_LINES_TO_FIRST_MARKERS = new BooleanPreference(this, "show_lines_to_first_markers", false).makeProfile(); + public final CommonPreference SHOW_ARROWS_TO_FIRST_MARKERS = new BooleanPreference(this, "show_arrows_to_first_markers", false).makeProfile(); - @SuppressWarnings("unchecked") - public CommonPreference registerIntPreference(String id, int defValue) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - IntPreference p = new IntPreference(id, defValue); - registeredPreferences.put(id, p); - return p; - } + public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES_ASKED = new BooleanPreference(this, "wikivoyage_show_images_asked", false).makeGlobal(); + public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES = new EnumStringPreference<>(this, "wikivoyage_show_imgs", WikiArticleShowImages.OFF, WikiArticleShowImages.values()).makeGlobal(); + public final CommonPreference SHOW_WIKIPEDIA_POI = new BooleanPreference(this, "show_wikipedia_poi", false).makeProfile(); + public final CommonPreference GLOBAL_WIKIPEDIA_POI_ENABLED = new BooleanPreference(this, "global_wikipedia_poi_enabled", false).makeProfile(); + public final ListStringPreference WIKIPEDIA_POI_ENABLED_LANGUAGES = (ListStringPreference) new ListStringPreference(this, "wikipedia_poi_enabled_languages", null, ",").makeProfile().cache(); - @SuppressWarnings("unchecked") - public CommonPreference registerLongPreference(String id, long defValue) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - LongPreference p = new LongPreference(id, defValue); - registeredPreferences.put(id, p); - return p; - } + public final CommonPreference SELECT_MARKER_ON_SINGLE_TAP = new BooleanPreference(this, "select_marker_on_single_tap", false).makeProfile(); + public final CommonPreference KEEP_PASSED_MARKERS_ON_MAP = new BooleanPreference(this, "keep_passed_markers_on_map", true).makeProfile(); - @SuppressWarnings("unchecked") - public CommonPreference registerFloatPreference(String id, float defValue) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - FloatPreference p = new FloatPreference(id, defValue); - registeredPreferences.put(id, p); - return p; - } + public final CommonPreference COORDS_INPUT_USE_RIGHT_SIDE = new BooleanPreference(this, "coords_input_use_right_side", true).makeGlobal(); + public final OsmandPreference COORDS_INPUT_FORMAT = new EnumStringPreference<>(this, "coords_input_format", Format.DD_MM_MMM, Format.values()).makeGlobal(); + public final CommonPreference COORDS_INPUT_USE_OSMAND_KEYBOARD = new BooleanPreference(this, "coords_input_use_osmand_keyboard", Build.VERSION.SDK_INT >= 16).makeGlobal(); + public final CommonPreference COORDS_INPUT_TWO_DIGITS_LONGTITUDE = new BooleanPreference(this, "coords_input_two_digits_longitude", false).makeGlobal(); - @SuppressWarnings("unchecked") - public CommonPreference registerEnumIntPreference(String id, Enum defaultValue, Enum[] values, Class clz) { - if (registeredPreferences.containsKey(id)) { - return (CommonPreference) registeredPreferences.get(id); - } - EnumStringPreference p = new EnumStringPreference(id, defaultValue, values); - registeredPreferences.put(id, p); - return p; - } + public final CommonPreference USE_MAPILLARY_FILTER = new BooleanPreference(this, "use_mapillary_filters", false).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_USER_KEY = new StringPreference(this, "mapillary_filter_user_key", "").makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_USERNAME = new StringPreference(this, "mapillary_filter_username", "").makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_FROM_DATE = new LongPreference(this, "mapillary_filter_from_date", 0).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_TO_DATE = new LongPreference(this, "mapillary_filter_to_date", 0).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_PANO = new BooleanPreference(this, "mapillary_filter_pano", false).makeGlobal(); - public final CommonPreference RULER_MODE = new EnumStringPreference<>("ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal(); + public final CommonPreference USE_FAST_RECALCULATION = new BooleanPreference(this, "use_fast_recalculation", true).makeGlobal().cache(); + public final CommonPreference FORCE_PRIVATE_ACCESS_ROUTING_ASKED = new BooleanPreference(this, "force_private_access_routing", false).makeProfile().cache(); - public final OsmandPreference SHOW_COMPASS_CONTROL_RULER = new BooleanPreference("show_compass_ruler", true).makeGlobal(); + public final CommonPreference SHOW_CARD_TO_CHOOSE_DRAWER = new BooleanPreference(this, "show_card_to_choose_drawer", false).makeGlobal(); + public final CommonPreference SHOW_DASHBOARD_ON_START = new BooleanPreference(this, "should_show_dashboard_on_start", false).makeGlobal(); + public final CommonPreference SHOW_DASHBOARD_ON_MAP_SCREEN = new BooleanPreference(this, "show_dashboard_on_map_screen", false).makeGlobal(); + public final CommonPreference SHOW_OSMAND_WELCOME_SCREEN = new BooleanPreference(this, "show_osmand_welcome_screen", true).makeGlobal(); - public final CommonPreference SHOW_LINES_TO_FIRST_MARKERS = new BooleanPreference("show_lines_to_first_markers", false).makeProfile(); - public final CommonPreference SHOW_ARROWS_TO_FIRST_MARKERS = new BooleanPreference("show_arrows_to_first_markers", false).makeProfile(); + public final CommonPreference API_NAV_DRAWER_ITEMS_JSON = new StringPreference(this, "api_nav_drawer_items_json", "{}").makeGlobal(); + public final CommonPreference API_CONNECTED_APPS_JSON = new StringPreference(this, "api_connected_apps_json", "[]").makeGlobal(); + public final CommonPreference NAV_DRAWER_LOGO = new StringPreference(this, "drawer_logo", "").makeProfile(); + public final CommonPreference NAV_DRAWER_URL = new StringPreference(this, "drawer_url", "").makeProfile(); - public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES_ASKED = new BooleanPreference("wikivoyage_show_images_asked", false).makeGlobal(); - public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES = new EnumStringPreference<>("wikivoyage_show_imgs", WikiArticleShowImages.OFF, WikiArticleShowImages.values()).makeGlobal(); - public final CommonPreference SHOW_WIKIPEDIA_POI = new BooleanPreference("show_wikipedia_poi", false).makeProfile(); - public final CommonPreference GLOBAL_WIKIPEDIA_POI_ENABLED = new BooleanPreference("global_wikipedia_poi_enabled", false).makeProfile(); - public final ListStringPreference WIKIPEDIA_POI_ENABLED_LANGUAGES = (ListStringPreference) new ListStringPreference("wikipedia_poi_enabled_languages", null, ",").makeProfile().cache(); + public final CommonPreference NUMBER_OF_STARTS_FIRST_XMAS_SHOWN = new IntPreference(this, "number_of_starts_first_xmas_shown", 0).makeGlobal(); - public final CommonPreference SELECT_MARKER_ON_SINGLE_TAP = new BooleanPreference("select_marker_on_single_tap", false).makeProfile(); - public final CommonPreference KEEP_PASSED_MARKERS_ON_MAP = new BooleanPreference("keep_passed_markers_on_map", true).makeProfile(); + public final OsmandPreference AVAILABLE_APP_MODES = new StringPreference(this, "available_application_modes", "car,bicycle,pedestrian,public_transport,").makeGlobal().cache(); - public final CommonPreference COORDS_INPUT_USE_RIGHT_SIDE = new BooleanPreference("coords_input_use_right_side", true).makeGlobal(); - public final OsmandPreference COORDS_INPUT_FORMAT = new EnumStringPreference<>("coords_input_format", Format.DD_MM_MMM, Format.values()).makeGlobal(); - public final CommonPreference COORDS_INPUT_USE_OSMAND_KEYBOARD = new BooleanPreference("coords_input_use_osmand_keyboard", Build.VERSION.SDK_INT >= 16).makeGlobal(); - public final CommonPreference COORDS_INPUT_TWO_DIGITS_LONGTITUDE = new BooleanPreference("coords_input_two_digits_longitude", false).makeGlobal(); + public final OsmandPreference LAST_FAV_CATEGORY_ENTERED = new StringPreference(this, "last_fav_category", "").makeGlobal(); - public final CommonPreference USE_MAPILLARY_FILTER = new BooleanPreference("use_mapillary_filters", false).makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_USER_KEY = new StringPreference("mapillary_filter_user_key", "").makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_USERNAME = new StringPreference("mapillary_filter_username", "").makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_FROM_DATE = new LongPreference("mapillary_filter_from_date", 0).makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_TO_DATE = new LongPreference("mapillary_filter_to_date", 0).makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_PANO = new BooleanPreference("mapillary_filter_pano", false).makeGlobal(); - - public final CommonPreference USE_FAST_RECALCULATION = new BooleanPreference("use_fast_recalculation", true).makeGlobal().cache(); - public final CommonPreference FORCE_PRIVATE_ACCESS_ROUTING_ASKED = new BooleanPreference("force_private_access_routing", false).makeProfile().cache(); - - public final CommonPreference SHOW_CARD_TO_CHOOSE_DRAWER = new BooleanPreference("show_card_to_choose_drawer", false).makeGlobal(); - public final CommonPreference SHOW_DASHBOARD_ON_START = new BooleanPreference("should_show_dashboard_on_start", false).makeGlobal(); - public final CommonPreference SHOW_DASHBOARD_ON_MAP_SCREEN = new BooleanPreference("show_dashboard_on_map_screen", false).makeGlobal(); - public final CommonPreference SHOW_OSMAND_WELCOME_SCREEN = new BooleanPreference("show_osmand_welcome_screen", true).makeGlobal(); - - public final CommonPreference API_NAV_DRAWER_ITEMS_JSON = new StringPreference("api_nav_drawer_items_json", "{}").makeGlobal(); - public final CommonPreference API_CONNECTED_APPS_JSON = new StringPreference("api_connected_apps_json", "[]").makeGlobal(); - public final CommonPreference NAV_DRAWER_LOGO = new StringPreference("drawer_logo", "").makeProfile(); - public final CommonPreference NAV_DRAWER_URL = new StringPreference("drawer_url", "").makeProfile(); - - public final CommonPreference NUMBER_OF_STARTS_FIRST_XMAS_SHOWN = new IntPreference("number_of_starts_first_xmas_shown", 0).makeGlobal(); - - public final OsmandPreference AVAILABLE_APP_MODES = new StringPreference("available_application_modes", "car,bicycle,pedestrian,public_transport,").makeGlobal().cache(); - - public final OsmandPreference LAST_FAV_CATEGORY_ENTERED = new StringPreference("last_fav_category", "").makeGlobal(); - - public final OsmandPreference DEFAULT_APPLICATION_MODE = new CommonPreference("default_application_mode_string", ApplicationMode.DEFAULT) { + public final OsmandPreference DEFAULT_APPLICATION_MODE = new CommonPreference(this, "default_application_mode_string", ApplicationMode.DEFAULT) { @Override protected ApplicationMode getValue(Object prefs, ApplicationMode defaultValue) { @@ -1616,7 +766,7 @@ public class OsmandSettings { } }.makeGlobal(); - public final OsmandPreference LAST_ROUTE_APPLICATION_MODE = new CommonPreference("last_route_application_mode_backup_string", ApplicationMode.DEFAULT) { + public final OsmandPreference LAST_ROUTE_APPLICATION_MODE = new CommonPreference(this, "last_route_application_mode_backup_string", ApplicationMode.DEFAULT) { @Override protected ApplicationMode getValue(Object prefs, ApplicationMode defaultValue) { @@ -1657,11 +807,11 @@ public class OsmandSettings { } }.makeGlobal(); - public final OsmandPreference FIRST_MAP_IS_DOWNLOADED = new BooleanPreference( + public final OsmandPreference FIRST_MAP_IS_DOWNLOADED = new BooleanPreference(this, "first_map_is_downloaded", false); - public final CommonPreference DRIVING_REGION_AUTOMATIC = new BooleanPreference("driving_region_automatic", true).makeProfile().cache(); - public final OsmandPreference DRIVING_REGION = new EnumStringPreference( + public final CommonPreference DRIVING_REGION_AUTOMATIC = new BooleanPreference(this, "driving_region_automatic", true).makeProfile().cache(); + public final OsmandPreference DRIVING_REGION = new EnumStringPreference(this, "default_driving_region", DrivingRegion.EUROPE_ASIA, DrivingRegion.values()) { protected boolean setValue(Object prefs, DrivingRegion val) { if (val != null) { @@ -1693,7 +843,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often - public final OsmandPreference METRIC_SYSTEM = new EnumStringPreference( + public final OsmandPreference METRIC_SYSTEM = new EnumStringPreference(this, "default_metric_system", MetricsConstants.KILOMETERS_AND_METERS, MetricsConstants.values()) { protected MetricsConstants getDefaultValue() { return DRIVING_REGION.get().defMetrics; @@ -1703,8 +853,8 @@ public class OsmandSettings { //public final OsmandPreference COORDINATES_FORMAT = new IntPreference("coordinates_format", PointDescription.FORMAT_DEGREES).makeGlobal(); - public final OsmandPreference ANGULAR_UNITS = new EnumStringPreference( - "angular_measurement", AngularConstants.DEGREES, AngularConstants.values()).makeProfile(); + public final OsmandPreference ANGULAR_UNITS = new EnumStringPreference(this, + "angular_measurement", AngularConstants.DEGREES, AngularConstants.values()).makeProfile(); public static final String LAST_START_LAT = "last_searched_lat"; //$NON-NLS-1$ public static final String LAST_START_LON = "last_searched_lon"; //$NON-NLS-1$ @@ -1730,7 +880,7 @@ public class OsmandSettings { putFloat(LAST_START_LON, (float) lon).commit(); } - public final OsmandPreference SPEED_SYSTEM = new EnumStringPreference( + public final OsmandPreference SPEED_SYSTEM = new EnumStringPreference(this, "default_speed_system", SpeedConstants.KILOMETERS_PER_HOUR, SpeedConstants.values()) { @Override @@ -1759,25 +909,25 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often - public final OsmandPreference DIRECTION_STYLE = new EnumStringPreference( + public final OsmandPreference DIRECTION_STYLE = new EnumStringPreference(this, "direction_style", RelativeDirectionStyle.SIDEWISE, RelativeDirectionStyle.values()).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often - public final OsmandPreference ACCESSIBILITY_MODE = new EnumStringPreference( + public final OsmandPreference ACCESSIBILITY_MODE = new EnumStringPreference(this, "accessibility_mode", AccessibilityMode.DEFAULT, AccessibilityMode.values()).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference SPEECH_RATE = - new FloatPreference("speech_rate", 1f).makeProfile(); + new FloatPreference(this, "speech_rate", 1f).makeProfile(); public final OsmandPreference ARRIVAL_DISTANCE_FACTOR = - new FloatPreference("arrival_distance_factor", 1f).makeProfile(); + new FloatPreference(this, "arrival_distance_factor", 1f).makeProfile(); public final OsmandPreference SPEED_LIMIT_EXCEED = - new FloatPreference("speed_limit_exceed", 5f).makeProfile(); + new FloatPreference(this, "speed_limit_exceed", 5f).makeProfile(); - public final CommonPreference DEFAULT_SPEED = new FloatPreference("default_speed", 10f).makeProfile().cache(); + public final CommonPreference DEFAULT_SPEED = new FloatPreference(this, "default_speed", 10f).makeProfile().cache(); { DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.DEFAULT, 1.5f); @@ -1789,13 +939,13 @@ public class OsmandSettings { DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.SKI, 1.38f); } - public final OsmandPreference MIN_SPEED = new FloatPreference( + public final OsmandPreference MIN_SPEED = new FloatPreference(this, "min_speed", 0f).makeProfile().cache(); - public final OsmandPreference MAX_SPEED = new FloatPreference( + public final OsmandPreference MAX_SPEED = new FloatPreference(this, "max_speed", 0f).makeProfile().cache(); - public final CommonPreference ICON_RES_NAME = new StringPreference("app_mode_icon_res_name", "ic_world_globe_dark").makeProfile().cache(); + public final CommonPreference ICON_RES_NAME = new StringPreference(this, "app_mode_icon_res_name", "ic_world_globe_dark").makeProfile().cache(); { ICON_RES_NAME.setModeDefaultValue(ApplicationMode.DEFAULT, "ic_world_globe_dark"); @@ -1808,13 +958,13 @@ public class OsmandSettings { ICON_RES_NAME.setModeDefaultValue(ApplicationMode.SKI, "ic_action_skiing"); } - public final CommonPreference ICON_COLOR = new EnumStringPreference<>("app_mode_icon_color", ProfileIconColors.DEFAULT, ProfileIconColors.values()).makeProfile().cache(); + public final CommonPreference ICON_COLOR = new EnumStringPreference<>(this, "app_mode_icon_color", ProfileIconColors.DEFAULT, ProfileIconColors.values()).makeProfile().cache(); - public final CommonPreference USER_PROFILE_NAME = new StringPreference("user_profile_name", "").makeProfile().cache(); + public final CommonPreference USER_PROFILE_NAME = new StringPreference(this, "user_profile_name", "").makeProfile().cache(); - public final CommonPreference PARENT_APP_MODE = new StringPreference("parent_app_mode", null).makeProfile().cache(); + public final CommonPreference PARENT_APP_MODE = new StringPreference(this, "parent_app_mode", null).makeProfile().cache(); - public final CommonPreference ROUTING_PROFILE = new StringPreference("routing_profile", "").makeProfile().cache(); + public final CommonPreference ROUTING_PROFILE = new StringPreference(this, "routing_profile", "").makeProfile().cache(); { ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.CAR, "car"); @@ -1826,13 +976,13 @@ public class OsmandSettings { ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.SKI, "ski"); } - public final CommonPreference ROUTE_SERVICE = new EnumStringPreference<>("route_service", RouteService.OSMAND, RouteService.values()).makeProfile().cache(); + public final CommonPreference ROUTE_SERVICE = new EnumStringPreference<>(this, "route_service", RouteService.OSMAND, RouteService.values()).makeProfile().cache(); { ROUTE_SERVICE.setModeDefaultValue(ApplicationMode.AIRCRAFT, RouteService.STRAIGHT); } - public final CommonPreference NAVIGATION_ICON = new EnumStringPreference<>("navigation_icon", NavigationIcon.DEFAULT, NavigationIcon.values()).makeProfile().cache(); + public final CommonPreference NAVIGATION_ICON = new EnumStringPreference<>(this, "navigation_icon", NavigationIcon.DEFAULT, NavigationIcon.values()).makeProfile().cache(); { NAVIGATION_ICON.setModeDefaultValue(ApplicationMode.DEFAULT, NavigationIcon.DEFAULT); @@ -1843,7 +993,7 @@ public class OsmandSettings { NAVIGATION_ICON.setModeDefaultValue(ApplicationMode.SKI, NavigationIcon.DEFAULT); } - public final CommonPreference LOCATION_ICON = new EnumStringPreference<>("location_icon", LocationIcon.DEFAULT, LocationIcon.values()).makeProfile().cache(); + public final CommonPreference LOCATION_ICON = new EnumStringPreference<>(this, "location_icon", LocationIcon.DEFAULT, LocationIcon.values()).makeProfile().cache(); { LOCATION_ICON.setModeDefaultValue(ApplicationMode.DEFAULT, LocationIcon.DEFAULT); @@ -1854,26 +1004,26 @@ public class OsmandSettings { LOCATION_ICON.setModeDefaultValue(ApplicationMode.SKI, LocationIcon.BICYCLE); } - public final CommonPreference APP_MODE_ORDER = new IntPreference("app_mode_order", 0).makeProfile().cache(); + public final CommonPreference APP_MODE_ORDER = new IntPreference(this, "app_mode_order", 0).makeProfile().cache(); public final OsmandPreference SWITCH_MAP_DIRECTION_TO_COMPASS = - new FloatPreference("speed_for_map_to_direction_of_movement", 0f).makeProfile(); + new FloatPreference(this, "speed_for_map_to_direction_of_movement", 0f).makeProfile(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference USE_TRACKBALL_FOR_MOVEMENTS = - new BooleanPreference("use_trackball_for_movements", true).makeProfile(); + new BooleanPreference(this, "use_trackball_for_movements", true).makeProfile(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference ACCESSIBILITY_SMART_AUTOANNOUNCE = - new BooleanAccessibilityPreference("accessibility_smart_autoannounce", true).makeProfile(); + new BooleanAccessibilityPreference(this, "accessibility_smart_autoannounce", true).makeProfile(); // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often - public final OsmandPreference ACCESSIBILITY_AUTOANNOUNCE_PERIOD = new IntPreference("accessibility_autoannounce_period", 10000).makeProfile().cache(); + public final OsmandPreference ACCESSIBILITY_AUTOANNOUNCE_PERIOD = new IntPreference(this, "accessibility_autoannounce_period", 10000).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DISABLE_OFFROUTE_RECALC = - new BooleanAccessibilityPreference("disable_offroute_recalc", false).makeProfile(); + new BooleanAccessibilityPreference(this, "disable_offroute_recalc", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name // public final OsmandPreference DISABLE_WRONG_DIRECTION_RECALC = @@ -1881,103 +1031,103 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DIRECTION_AUDIO_FEEDBACK = - new BooleanAccessibilityPreference("direction_audio_feedback", false).makeProfile(); + new BooleanAccessibilityPreference(this, "direction_audio_feedback", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DIRECTION_HAPTIC_FEEDBACK = - new BooleanAccessibilityPreference("direction_haptic_feedback", false).makeProfile(); + new BooleanAccessibilityPreference(this, "direction_haptic_feedback", false).makeProfile(); // magnetic field doesn'torkmost of the time on some phones - public final OsmandPreference USE_MAGNETIC_FIELD_SENSOR_COMPASS = new BooleanPreference("use_magnetic_field_sensor_compass", false).makeProfile().cache(); - public final OsmandPreference USE_KALMAN_FILTER_FOR_COMPASS = new BooleanPreference("use_kalman_filter_compass", true).makeProfile().cache(); + public final OsmandPreference USE_MAGNETIC_FIELD_SENSOR_COMPASS = new BooleanPreference(this, "use_magnetic_field_sensor_compass", false).makeProfile().cache(); + public final OsmandPreference USE_KALMAN_FILTER_FOR_COMPASS = new BooleanPreference(this, "use_kalman_filter_compass", true).makeProfile().cache(); - public final OsmandPreference DO_NOT_SHOW_STARTUP_MESSAGES = new BooleanPreference("do_not_show_startup_messages", false).makeGlobal().cache(); - public final OsmandPreference SHOW_DOWNLOAD_MAP_DIALOG = new BooleanPreference("show_download_map_dialog", true).makeGlobal().cache(); - public final OsmandPreference DO_NOT_USE_ANIMATIONS = new BooleanPreference("do_not_use_animations", false).makeProfile().cache(); + public final OsmandPreference DO_NOT_SHOW_STARTUP_MESSAGES = new BooleanPreference(this, "do_not_show_startup_messages", false).makeGlobal().cache(); + public final OsmandPreference SHOW_DOWNLOAD_MAP_DIALOG = new BooleanPreference(this, "show_download_map_dialog", true).makeGlobal().cache(); + public final OsmandPreference DO_NOT_USE_ANIMATIONS = new BooleanPreference(this, "do_not_use_animations", false).makeProfile().cache(); - public final OsmandPreference SEND_ANONYMOUS_MAP_DOWNLOADS_DATA = new BooleanPreference("send_anonymous_map_downloads_data", false).makeGlobal().cache(); - public final OsmandPreference SEND_ANONYMOUS_APP_USAGE_DATA = new BooleanPreference("send_anonymous_app_usage_data", false).makeGlobal().cache(); - public final OsmandPreference SEND_ANONYMOUS_DATA_REQUEST_PROCESSED = new BooleanPreference("send_anonymous_data_request_processed", false).makeGlobal().cache(); - public final OsmandPreference SEND_ANONYMOUS_DATA_REQUESTS_COUNT = new IntPreference("send_anonymous_data_requests_count", 0).makeGlobal().cache(); - public final OsmandPreference SEND_ANONYMOUS_DATA_LAST_REQUEST_NS = new IntPreference("send_anonymous_data_last_request_ns", -1).makeGlobal().cache(); + public final OsmandPreference SEND_ANONYMOUS_MAP_DOWNLOADS_DATA = new BooleanPreference(this, "send_anonymous_map_downloads_data", false).makeGlobal().cache(); + public final OsmandPreference SEND_ANONYMOUS_APP_USAGE_DATA = new BooleanPreference(this, "send_anonymous_app_usage_data", false).makeGlobal().cache(); + public final OsmandPreference SEND_ANONYMOUS_DATA_REQUEST_PROCESSED = new BooleanPreference(this, "send_anonymous_data_request_processed", false).makeGlobal().cache(); + public final OsmandPreference SEND_ANONYMOUS_DATA_REQUESTS_COUNT = new IntPreference(this, "send_anonymous_data_requests_count", 0).makeGlobal().cache(); + public final OsmandPreference SEND_ANONYMOUS_DATA_LAST_REQUEST_NS = new IntPreference(this, "send_anonymous_data_last_request_ns", -1).makeGlobal().cache(); - public final OsmandPreference MAP_EMPTY_STATE_ALLOWED = new BooleanPreference("map_empty_state_allowed", false).makeProfile().cache(); + public final OsmandPreference MAP_EMPTY_STATE_ALLOWED = new BooleanPreference(this, "map_empty_state_allowed", false).makeProfile().cache(); - public final CommonPreference TEXT_SCALE = new FloatPreference("text_scale", 1f).makeProfile().cache(); + public final CommonPreference TEXT_SCALE = new FloatPreference(this, "text_scale", 1f).makeProfile().cache(); { TEXT_SCALE.setModeDefaultValue(ApplicationMode.CAR, 1.25f); } - public final CommonPreference MAP_DENSITY = new FloatPreference("map_density_n", 1f).makeProfile().cache(); + public final CommonPreference MAP_DENSITY = new FloatPreference(this, "map_density_n", 1f).makeProfile().cache(); { MAP_DENSITY.setModeDefaultValue(ApplicationMode.CAR, 1.5f); } - public final OsmandPreference SHOW_POI_LABEL = new BooleanPreference("show_poi_label", false).makeProfile(); + public final OsmandPreference SHOW_POI_LABEL = new BooleanPreference(this, "show_poi_label", false).makeProfile(); - public final OsmandPreference SHOW_MAPILLARY = new BooleanPreference("show_mapillary", false).makeProfile(); - public final OsmandPreference MAPILLARY_FIRST_DIALOG_SHOWN = new BooleanPreference("mapillary_first_dialog_shown", false).makeGlobal(); - public final OsmandPreference ONLINE_PHOTOS_ROW_COLLAPSED = new BooleanPreference("mapillary_menu_collapsed", true).makeGlobal(); - public final OsmandPreference WEBGL_SUPPORTED = new BooleanPreference("webgl_supported", true).makeGlobal(); + public final OsmandPreference SHOW_MAPILLARY = new BooleanPreference(this, "show_mapillary", false).makeProfile(); + public final OsmandPreference MAPILLARY_FIRST_DIALOG_SHOWN = new BooleanPreference(this, "mapillary_first_dialog_shown", false).makeGlobal(); + public final OsmandPreference ONLINE_PHOTOS_ROW_COLLAPSED = new BooleanPreference(this, "mapillary_menu_collapsed", true).makeGlobal(); + public final OsmandPreference WEBGL_SUPPORTED = new BooleanPreference(this, "webgl_supported", true).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference PREFERRED_LOCALE = new StringPreference("preferred_locale", "").makeGlobal(); + public final OsmandPreference PREFERRED_LOCALE = new StringPreference(this, "preferred_locale", "").makeGlobal(); - public final OsmandPreference MAP_PREFERRED_LOCALE = new StringPreference("map_preferred_locale", "").makeGlobal().cache(); - public final OsmandPreference MAP_TRANSLITERATE_NAMES = new BooleanPreference("map_transliterate_names", false).makeGlobal().cache(); + public final OsmandPreference MAP_PREFERRED_LOCALE = new StringPreference(this, "map_preferred_locale", "").makeGlobal().cache(); + public final OsmandPreference MAP_TRANSLITERATE_NAMES = new BooleanPreference(this, "map_transliterate_names", false).makeGlobal().cache(); public boolean usingEnglishNames() { return MAP_PREFERRED_LOCALE.get().equals("en"); } // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference USER_NAME = new StringPreference("user_name", "").makeGlobal(); + public final OsmandPreference USER_NAME = new StringPreference(this, "user_name", "").makeGlobal(); public static final String BILLING_USER_DONATION_WORLD_PARAMETER = ""; public static final String BILLING_USER_DONATION_NONE_PARAMETER = "none"; - public final OsmandPreference INAPPS_READ = new BooleanPreference("inapps_read", false).makeGlobal(); + public final OsmandPreference INAPPS_READ = new BooleanPreference(this, "inapps_read", false).makeGlobal(); - public final OsmandPreference BILLING_USER_ID = new StringPreference("billing_user_id", "").makeGlobal(); - public final OsmandPreference BILLING_USER_TOKEN = new StringPreference("billing_user_token", "").makeGlobal(); - public final OsmandPreference BILLING_USER_NAME = new StringPreference("billing_user_name", "").makeGlobal(); - public final OsmandPreference BILLING_USER_EMAIL = new StringPreference("billing_user_email", "").makeGlobal(); - public final OsmandPreference BILLING_USER_COUNTRY = new StringPreference("billing_user_country", "").makeGlobal(); - public final OsmandPreference BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", BILLING_USER_DONATION_NONE_PARAMETER).makeGlobal(); - public final OsmandPreference BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal(); - public final OsmandPreference BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal(); - public final OsmandPreference BILLING_PURCHASE_TOKENS_SENT = new StringPreference("billing_purchase_tokens_sent", "").makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASED = new BooleanPreference("billing_live_updates_purchased", false).makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_TIME = new LongPreference("live_updates_purchase_cancelled_time", 0).makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN = new BooleanPreference("live_updates_purchase_cancelled_first_dlg_shown", false).makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN = new BooleanPreference("live_updates_purchase_cancelled_second_dlg_shown", false).makeGlobal(); - public final OsmandPreference FULL_VERSION_PURCHASED = new BooleanPreference("billing_full_version_purchased", false).makeGlobal(); - public final OsmandPreference DEPTH_CONTOURS_PURCHASED = new BooleanPreference("billing_sea_depth_purchased", false).makeGlobal(); - public final OsmandPreference EMAIL_SUBSCRIBED = new BooleanPreference("email_subscribed", false).makeGlobal(); + public final OsmandPreference BILLING_USER_ID = new StringPreference(this, "billing_user_id", "").makeGlobal(); + public final OsmandPreference BILLING_USER_TOKEN = new StringPreference(this, "billing_user_token", "").makeGlobal(); + public final OsmandPreference BILLING_USER_NAME = new StringPreference(this, "billing_user_name", "").makeGlobal(); + public final OsmandPreference BILLING_USER_EMAIL = new StringPreference(this, "billing_user_email", "").makeGlobal(); + public final OsmandPreference BILLING_USER_COUNTRY = new StringPreference(this, "billing_user_country", "").makeGlobal(); + public final OsmandPreference BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference(this, "billing_user_country_download_name", BILLING_USER_DONATION_NONE_PARAMETER).makeGlobal(); + public final OsmandPreference BILLING_HIDE_USER_NAME = new BooleanPreference(this, "billing_hide_user_name", false).makeGlobal(); + public final OsmandPreference BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference(this, "billing_purchase_token_sent", false).makeGlobal(); + public final OsmandPreference BILLING_PURCHASE_TOKENS_SENT = new StringPreference(this, "billing_purchase_tokens_sent", "").makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASED = new BooleanPreference(this, "billing_live_updates_purchased", false).makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_TIME = new LongPreference(this, "live_updates_purchase_cancelled_time", 0).makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN = new BooleanPreference(this, "live_updates_purchase_cancelled_first_dlg_shown", false).makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN = new BooleanPreference(this, "live_updates_purchase_cancelled_second_dlg_shown", false).makeGlobal(); + public final OsmandPreference FULL_VERSION_PURCHASED = new BooleanPreference(this, "billing_full_version_purchased", false).makeGlobal(); + public final OsmandPreference DEPTH_CONTOURS_PURCHASED = new BooleanPreference(this, "billing_sea_depth_purchased", false).makeGlobal(); + public final OsmandPreference EMAIL_SUBSCRIBED = new BooleanPreference(this, "email_subscribed", false).makeGlobal(); - public final OsmandPreference DISCOUNT_ID = new IntPreference("discount_id", 0).makeGlobal(); - public final OsmandPreference DISCOUNT_SHOW_NUMBER_OF_STARTS = new IntPreference("number_of_starts_on_discount_show", 0).makeGlobal(); - public final OsmandPreference DISCOUNT_TOTAL_SHOW = new IntPreference("discount_total_show", 0).makeGlobal(); - public final OsmandPreference DISCOUNT_SHOW_DATETIME_MS = new LongPreference("show_discount_datetime_ms", 0).makeGlobal(); + public final OsmandPreference DISCOUNT_ID = new IntPreference(this, "discount_id", 0).makeGlobal(); + public final OsmandPreference DISCOUNT_SHOW_NUMBER_OF_STARTS = new IntPreference(this, "number_of_starts_on_discount_show", 0).makeGlobal(); + public final OsmandPreference DISCOUNT_TOTAL_SHOW = new IntPreference(this, "discount_total_show", 0).makeGlobal(); + public final OsmandPreference DISCOUNT_SHOW_DATETIME_MS = new LongPreference(this, "show_discount_datetime_ms", 0).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference USER_OSM_BUG_NAME = - new StringPreference("user_osm_bug_name", "NoName/OsmAnd").makeGlobal(); + new StringPreference(this, "user_osm_bug_name", "NoName/OsmAnd").makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference USER_PASSWORD = - new StringPreference("user_password", "").makeGlobal(); + new StringPreference(this, "user_password", "").makeGlobal(); // this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition - public final OsmandPreference OFFLINE_EDITION = new BooleanPreference("offline_osm_editing", true).makeGlobal(); + public final OsmandPreference OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public final CommonPreference DAYNIGHT_MODE = - new EnumStringPreference("daynight_mode", DayNightMode.DAY, DayNightMode.values()); + new EnumStringPreference(this, "daynight_mode", DayNightMode.DAY, DayNightMode.values()); { DAYNIGHT_MODE.makeProfile().cache(); @@ -1987,7 +1137,7 @@ public class OsmandSettings { } // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference AUTO_ZOOM_MAP = new BooleanPreference("auto_zoom_map_on_off", false).makeProfile().cache(); + public final CommonPreference AUTO_ZOOM_MAP = new BooleanPreference(this, "auto_zoom_map_on_off", false).makeProfile().cache(); { AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.CAR, true); AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.BICYCLE, false); @@ -1995,7 +1145,7 @@ public class OsmandSettings { } public final CommonPreference AUTO_ZOOM_MAP_SCALE = - new EnumStringPreference("auto_zoom_map_scale", AutoZoomMap.FAR, + new EnumStringPreference(this, "auto_zoom_map_scale", AutoZoomMap.FAR, AutoZoomMap.values()).makeProfile().cache(); { AUTO_ZOOM_MAP_SCALE.setModeDefaultValue(ApplicationMode.CAR, AutoZoomMap.FAR); @@ -2003,7 +1153,7 @@ public class OsmandSettings { AUTO_ZOOM_MAP_SCALE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, AutoZoomMap.CLOSE); } - public final CommonPreference DELAY_TO_START_NAVIGATION = new IntPreference("delay_to_start_navigation", -1) { + public final CommonPreference DELAY_TO_START_NAVIGATION = new IntPreference(this, "delay_to_start_navigation", -1) { protected Integer getDefaultValue() { if (DEFAULT_APPLICATION_MODE.get().isDerivedRoutingFrom(ApplicationMode.CAR)) { @@ -2013,16 +1163,16 @@ public class OsmandSettings { } }.makeGlobal().cache(); - public final CommonPreference SNAP_TO_ROAD = new BooleanPreference("snap_to_road", false).makeProfile().cache(); + public final CommonPreference SNAP_TO_ROAD = new BooleanPreference(this, "snap_to_road", false).makeProfile().cache(); { SNAP_TO_ROAD.setModeDefaultValue(ApplicationMode.CAR, true); SNAP_TO_ROAD.setModeDefaultValue(ApplicationMode.BICYCLE, true); } - public final CommonPreference INTERRUPT_MUSIC = new BooleanPreference("interrupt_music", false).makeProfile(); + public final CommonPreference INTERRUPT_MUSIC = new BooleanPreference(this, "interrupt_music", false).makeProfile(); - public final CommonPreference ENABLE_PROXY = new BooleanPreference("enable_proxy", false) { + public final CommonPreference ENABLE_PROXY = new BooleanPreference(this, "enable_proxy", false) { @Override protected boolean setValue(Object prefs, Boolean val) { boolean valueSaved = super.setValue(prefs, val); @@ -2033,21 +1183,21 @@ public class OsmandSettings { } }.makeGlobal(); - public final CommonPreference PROXY_HOST = new StringPreference("proxy_host", "127.0.0.1").makeGlobal(); - public final CommonPreference PROXY_PORT = new IntPreference("proxy_port", 8118).makeGlobal(); - public final CommonPreference USER_ANDROID_ID = new StringPreference("user_android_id", "").makeGlobal(); + public final CommonPreference PROXY_HOST = new StringPreference(this, "proxy_host", "127.0.0.1").makeGlobal(); + public final CommonPreference PROXY_PORT = new IntPreference(this, "proxy_port", 8118).makeGlobal(); + public final CommonPreference USER_ANDROID_ID = new StringPreference(this, "user_android_id", "").makeGlobal(); - public final CommonPreference USE_SYSTEM_SCREEN_TIMEOUT = new BooleanPreference("use_system_screen_timeout", false).makeGlobal(); + public final CommonPreference USE_SYSTEM_SCREEN_TIMEOUT = new BooleanPreference(this, "use_system_screen_timeout", false).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public static final String SAVE_CURRENT_TRACK = "save_current_track"; //$NON-NLS-1$ - public final CommonPreference SAVE_GLOBAL_TRACK_TO_GPX = new BooleanPreference("save_global_track_to_gpx", false).makeGlobal().cache(); - public final CommonPreference SAVE_GLOBAL_TRACK_INTERVAL = new IntPreference("save_global_track_interval", 5000).makeProfile().cache(); - public final CommonPreference SAVE_GLOBAL_TRACK_REMEMBER = new BooleanPreference("save_global_track_remember", false).makeProfile().cache(); - public final CommonPreference SHOW_SAVED_TRACK_REMEMBER = new BooleanPreference("show_saved_track_remember", true).makeGlobal(); + public final CommonPreference SAVE_GLOBAL_TRACK_TO_GPX = new BooleanPreference(this, "save_global_track_to_gpx", false).makeGlobal().cache(); + public final CommonPreference SAVE_GLOBAL_TRACK_INTERVAL = new IntPreference(this, "save_global_track_interval", 5000).makeProfile().cache(); + public final CommonPreference SAVE_GLOBAL_TRACK_REMEMBER = new BooleanPreference(this, "save_global_track_remember", false).makeProfile().cache(); + public final CommonPreference SHOW_SAVED_TRACK_REMEMBER = new BooleanPreference(this, "show_saved_track_remember", true).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference SAVE_TRACK_TO_GPX = new BooleanPreference("save_track_to_gpx", false).makeProfile().cache(); + public final CommonPreference SAVE_TRACK_TO_GPX = new BooleanPreference(this, "save_track_to_gpx", false).makeProfile().cache(); { SAVE_TRACK_TO_GPX.setModeDefaultValue(ApplicationMode.CAR, false); @@ -2059,66 +1209,66 @@ public class OsmandSettings { public static final Integer MONTHLY_DIRECTORY = 1; // public static final Integer DAILY_DIRECTORY = 2; - public final CommonPreference DISABLE_RECORDING_ONCE_APP_KILLED = new BooleanPreference("disable_recording_once_app_killed", false).makeProfile(); + public final CommonPreference DISABLE_RECORDING_ONCE_APP_KILLED = new BooleanPreference(this, "disable_recording_once_app_killed", false).makeProfile(); - public final CommonPreference SAVE_HEADING_TO_GPX = new BooleanPreference("save_heading_to_gpx", false).makeProfile(); + public final CommonPreference SAVE_HEADING_TO_GPX = new BooleanPreference(this, "save_heading_to_gpx", false).makeProfile(); - public final CommonPreference TRACK_STORAGE_DIRECTORY = new IntPreference("track_storage_directory", 0).makeProfile(); + public final CommonPreference TRACK_STORAGE_DIRECTORY = new IntPreference(this, "track_storage_directory", 0).makeProfile(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile(); + public final OsmandPreference FAST_ROUTE_MODE = new BooleanPreference(this, "fast_route_mode", true).makeProfile(); // dev version - public final CommonPreference DISABLE_COMPLEX_ROUTING = new BooleanPreference("disable_complex_routing", false).makeGlobal(); - public final CommonPreference ENABLE_TIME_CONDITIONAL_ROUTING = new BooleanPreference("enable_time_conditional_routing", true).makeProfile(); + public final CommonPreference DISABLE_COMPLEX_ROUTING = new BooleanPreference(this, "disable_complex_routing", false).makeGlobal(); + public final CommonPreference ENABLE_TIME_CONDITIONAL_ROUTING = new BooleanPreference(this, "enable_time_conditional_routing", true).makeProfile(); public boolean simulateNavigation = false; - public final CommonPreference SHOW_ROUTING_ALARMS = new BooleanPreference("show_routing_alarms", true).makeProfile().cache(); + public final CommonPreference SHOW_ROUTING_ALARMS = new BooleanPreference(this, "show_routing_alarms", true).makeProfile().cache(); - public final CommonPreference SHOW_TRAFFIC_WARNINGS = new BooleanPreference("show_traffic_warnings", false).makeProfile().cache(); + public final CommonPreference SHOW_TRAFFIC_WARNINGS = new BooleanPreference(this, "show_traffic_warnings", false).makeProfile().cache(); { SHOW_TRAFFIC_WARNINGS.setModeDefaultValue(ApplicationMode.CAR, true); } - public final CommonPreference SHOW_PEDESTRIAN = new BooleanPreference("show_pedestrian", false).makeProfile().cache(); + public final CommonPreference SHOW_PEDESTRIAN = new BooleanPreference(this, "show_pedestrian", false).makeProfile().cache(); { SHOW_PEDESTRIAN.setModeDefaultValue(ApplicationMode.CAR, true); } - public final CommonPreference SHOW_TUNNELS = new BooleanPreference("show_tunnels", false).makeProfile().cache(); + public final CommonPreference SHOW_TUNNELS = new BooleanPreference(this, "show_tunnels", false).makeProfile().cache(); { SHOW_TUNNELS.setModeDefaultValue(ApplicationMode.CAR, true); } - public final OsmandPreference SHOW_CAMERAS = new BooleanPreference("show_cameras", false).makeProfile().cache(); - public final CommonPreference SHOW_LANES = new BooleanPreference("show_lanes", false).makeProfile().cache(); + public final OsmandPreference SHOW_CAMERAS = new BooleanPreference(this, "show_cameras", false).makeProfile().cache(); + public final CommonPreference SHOW_LANES = new BooleanPreference(this, "show_lanes", false).makeProfile().cache(); { SHOW_LANES.setModeDefaultValue(ApplicationMode.CAR, true); SHOW_LANES.setModeDefaultValue(ApplicationMode.BICYCLE, true); } - public final OsmandPreference SHOW_WPT = new BooleanPreference("show_gpx_wpt", true).makeGlobal().cache(); - public final OsmandPreference SHOW_NEARBY_FAVORITES = new BooleanPreference("show_nearby_favorites", false).makeProfile().cache(); - public final OsmandPreference SHOW_NEARBY_POI = new BooleanPreference("show_nearby_poi", false).makeProfile().cache(); + public final OsmandPreference SHOW_WPT = new BooleanPreference(this, "show_gpx_wpt", true).makeGlobal().cache(); + public final OsmandPreference SHOW_NEARBY_FAVORITES = new BooleanPreference(this, "show_nearby_favorites", false).makeProfile().cache(); + public final OsmandPreference SHOW_NEARBY_POI = new BooleanPreference(this, "show_nearby_poi", false).makeProfile().cache(); - public final OsmandPreference SPEAK_STREET_NAMES = new BooleanPreference("speak_street_names", true).makeProfile().cache(); - public final CommonPreference SPEAK_TRAFFIC_WARNINGS = new BooleanPreference("speak_traffic_warnings", true).makeProfile().cache(); + public final OsmandPreference SPEAK_STREET_NAMES = new BooleanPreference(this, "speak_street_names", true).makeProfile().cache(); + public final CommonPreference SPEAK_TRAFFIC_WARNINGS = new BooleanPreference(this, "speak_traffic_warnings", true).makeProfile().cache(); { SPEAK_TRAFFIC_WARNINGS.setModeDefaultValue(ApplicationMode.CAR, true); } - public final CommonPreference SPEAK_PEDESTRIAN = new BooleanPreference("speak_pedestrian", false).makeProfile().cache(); + public final CommonPreference SPEAK_PEDESTRIAN = new BooleanPreference(this, "speak_pedestrian", false).makeProfile().cache(); { SPEAK_PEDESTRIAN.setModeDefaultValue(ApplicationMode.CAR, true); } - public final OsmandPreference SPEAK_SPEED_LIMIT = new BooleanPreference("speak_speed_limit", false).makeProfile().cache(); - public final OsmandPreference SPEAK_SPEED_CAMERA = new BooleanPreference("speak_cameras", false).makeProfile().cache(); - public final OsmandPreference SPEAK_TUNNELS = new BooleanPreference("speak_tunnels", false).makeProfile().cache(); + public final OsmandPreference SPEAK_SPEED_LIMIT = new BooleanPreference(this, "speak_speed_limit", false).makeProfile().cache(); + public final OsmandPreference SPEAK_SPEED_CAMERA = new BooleanPreference(this, "speak_cameras", false).makeProfile().cache(); + public final OsmandPreference SPEAK_TUNNELS = new BooleanPreference(this, "speak_tunnels", false).makeProfile().cache(); - public final OsmandPreference ANNOUNCE_WPT = new BooleanPreference("announce_wpt", true) { + public final OsmandPreference ANNOUNCE_WPT = new BooleanPreference(this, "announce_wpt", true) { @Override protected boolean setValue(Object prefs, Boolean val) { boolean valueSaved = super.setValue(prefs, val); @@ -2130,7 +1280,7 @@ public class OsmandSettings { } }.makeProfile().cache(); - public final OsmandPreference ANNOUNCE_NEARBY_FAVORITES = new BooleanPreference("announce_nearby_favorites", false) { + public final OsmandPreference ANNOUNCE_NEARBY_FAVORITES = new BooleanPreference(this, "announce_nearby_favorites", false) { @Override protected boolean setValue(Object prefs, Boolean val) { boolean valueSaved = super.setValue(prefs, val); @@ -2142,7 +1292,7 @@ public class OsmandSettings { } }.makeProfile().cache(); - public final OsmandPreference ANNOUNCE_NEARBY_POI = new BooleanPreference("announce_nearby_poi", false) { + public final OsmandPreference ANNOUNCE_NEARBY_POI = new BooleanPreference(this, "announce_nearby_poi", false) { @Override protected boolean setValue(Object prefs, Boolean val) { boolean valueSaved = super.setValue(prefs, val); @@ -2154,23 +1304,23 @@ public class OsmandSettings { } }.makeProfile().cache(); - public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); - public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache(); - public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference(this, "gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); + public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference(this, "gpx_routing_calculate_rtept", true).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference(this, "calc_gpx_route", false).makeGlobal().cache(); - public final OsmandPreference AVOID_TOLL_ROADS = new BooleanPreference("avoid_toll_roads", false).makeProfile().cache(); - public final OsmandPreference AVOID_MOTORWAY = new BooleanPreference("avoid_motorway", false).makeProfile().cache(); - public final OsmandPreference AVOID_UNPAVED_ROADS = new BooleanPreference("avoid_unpaved_roads", false).makeProfile().cache(); - public final OsmandPreference AVOID_FERRIES = new BooleanPreference("avoid_ferries", false).makeProfile().cache(); + public final OsmandPreference AVOID_TOLL_ROADS = new BooleanPreference(this, "avoid_toll_roads", false).makeProfile().cache(); + public final OsmandPreference AVOID_MOTORWAY = new BooleanPreference(this, "avoid_motorway", false).makeProfile().cache(); + public final OsmandPreference AVOID_UNPAVED_ROADS = new BooleanPreference(this, "avoid_unpaved_roads", false).makeProfile().cache(); + public final OsmandPreference AVOID_FERRIES = new BooleanPreference(this, "avoid_ferries", false).makeProfile().cache(); - public final OsmandPreference PREFER_MOTORWAYS = new BooleanPreference("prefer_motorways", false).makeProfile().cache(); + public final OsmandPreference PREFER_MOTORWAYS = new BooleanPreference(this, "prefer_motorways", false).makeProfile().cache(); - public final OsmandPreference LAST_UPDATES_CARD_REFRESH = new LongPreference("last_updates_card_refresh", 0).makeGlobal(); + public final OsmandPreference LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal(); - public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference("current_track_color", 0).makeGlobal().cache(); + public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().cache(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference SAVE_TRACK_INTERVAL = new IntPreference("save_track_interval", 5000).makeProfile(); + public final CommonPreference SAVE_TRACK_INTERVAL = new IntPreference(this, "save_track_interval", 5000).makeProfile(); { SAVE_TRACK_INTERVAL.setModeDefaultValue(ApplicationMode.CAR, 3000); @@ -2179,52 +1329,52 @@ public class OsmandSettings { } // Please note that SAVE_TRACK_MIN_DISTANCE, SAVE_TRACK_PRECISION, SAVE_TRACK_MIN_SPEED should all be "0" for the default profile, as we have no interface to change them - public final CommonPreference SAVE_TRACK_MIN_DISTANCE = new FloatPreference("save_track_min_distance", 0).makeProfile(); + public final CommonPreference SAVE_TRACK_MIN_DISTANCE = new FloatPreference(this, "save_track_min_distance", 0).makeProfile(); //{ // SAVE_TRACK_MIN_DISTANCE.setModeDefaultValue(ApplicationMode.CAR, 5.f); // SAVE_TRACK_MIN_DISTANCE.setModeDefaultValue(ApplicationMode.BICYCLE, 5.f); // SAVE_TRACK_MIN_DISTANCE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 5.f); //} - public final CommonPreference SAVE_TRACK_PRECISION = new FloatPreference("save_track_precision", 50.0f).makeProfile(); + public final CommonPreference SAVE_TRACK_PRECISION = new FloatPreference(this, "save_track_precision", 50.0f).makeProfile(); //{ // SAVE_TRACK_PRECISION.setModeDefaultValue(ApplicationMode.CAR, 50.f); // SAVE_TRACK_PRECISION.setModeDefaultValue(ApplicationMode.BICYCLE, 50.f); // SAVE_TRACK_PRECISION.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 50.f); //} - public final CommonPreference SAVE_TRACK_MIN_SPEED = new FloatPreference("save_track_min_speed", 0.f).makeProfile(); + public final CommonPreference SAVE_TRACK_MIN_SPEED = new FloatPreference(this, "save_track_min_speed", 0.f).makeProfile(); //{ // SAVE_TRACK_MIN_SPEED.setModeDefaultValue(ApplicationMode.CAR, 2.f); // SAVE_TRACK_MIN_SPEED.setModeDefaultValue(ApplicationMode.BICYCLE, 1.f); // SAVE_TRACK_MIN_SPEED.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 0.f); //} - public final CommonPreference AUTO_SPLIT_RECORDING = new BooleanPreference("auto_split_recording", true).makeProfile(); + public final CommonPreference AUTO_SPLIT_RECORDING = new BooleanPreference(this, "auto_split_recording", true).makeProfile(); - public final CommonPreference SHOW_TRIP_REC_NOTIFICATION = new BooleanPreference("show_trip_recording_notification", true).makeProfile(); + public final CommonPreference SHOW_TRIP_REC_NOTIFICATION = new BooleanPreference(this, "show_trip_recording_notification", true).makeProfile(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference LIVE_MONITORING = new BooleanPreference("live_monitoring", false).makeProfile(); + public final CommonPreference LIVE_MONITORING = new BooleanPreference(this, "live_monitoring", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference LIVE_MONITORING_INTERVAL = new IntPreference("live_monitoring_interval", 5000).makeProfile(); + public final CommonPreference LIVE_MONITORING_INTERVAL = new IntPreference(this, "live_monitoring_interval", 5000).makeProfile(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference LIVE_MONITORING_MAX_INTERVAL_TO_SEND = new IntPreference("live_monitoring_maximum_interval_to_send", 900000).makeProfile(); + public final CommonPreference LIVE_MONITORING_MAX_INTERVAL_TO_SEND = new IntPreference(this, "live_monitoring_maximum_interval_to_send", 900000).makeProfile(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference LIVE_MONITORING_URL = new StringPreference("live_monitoring_url", + public final CommonPreference LIVE_MONITORING_URL = new StringPreference(this, "live_monitoring_url", "https://example.com?lat={0}&lon={1}×tamp={2}&hdop={3}&altitude={4}&speed={5}").makeProfile(); - public final CommonPreference GPS_STATUS_APP = new StringPreference("gps_status_app", "").makeGlobal(); + public final CommonPreference GPS_STATUS_APP = new StringPreference(this, "gps_status_app", "").makeGlobal(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference SHOW_OSM_BUGS = new BooleanPreference("show_osm_bugs", false).makeProfile().cache(); + public final OsmandPreference SHOW_OSM_BUGS = new BooleanPreference(this, "show_osm_bugs", false).makeProfile().cache(); - public final OsmandPreference SHOW_OSM_EDITS = new BooleanPreference("show_osm_edits", true).makeProfile().cache(); + public final OsmandPreference SHOW_OSM_EDITS = new BooleanPreference(this, "show_osm_edits", true).makeProfile().cache(); - public final CommonPreference SHOW_CLOSED_OSM_BUGS = new BooleanPreference("show_closed_osm_bugs", false).makeProfile().cache(); - public final CommonPreference SHOW_OSM_BUGS_MIN_ZOOM = new IntPreference("show_osm_bugs_min_zoom", 8).makeProfile().cache(); + public final CommonPreference SHOW_CLOSED_OSM_BUGS = new BooleanPreference(this, "show_closed_osm_bugs", false).makeProfile().cache(); + public final CommonPreference SHOW_OSM_BUGS_MIN_ZOOM = new IntPreference(this, "show_osm_bugs_min_zoom", 8).makeProfile().cache(); - public final CommonPreference MAP_INFO_CONTROLS = new StringPreference("map_info_controls", "").makeProfile(); + public final CommonPreference MAP_INFO_CONTROLS = new StringPreference(this, "map_info_controls", "").makeProfile(); { for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { MAP_INFO_CONTROLS.setModeDefaultValue(mode, ""); @@ -2233,23 +1383,23 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference DEBUG_RENDERING_INFO = new BooleanPreference("debug_rendering", false).makeGlobal(); + public final OsmandPreference DEBUG_RENDERING_INFO = new BooleanPreference(this, "debug_rendering", false).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference SHOW_FAVORITES = new BooleanPreference("show_favorites", true).makeProfile().cache(); + public final OsmandPreference SHOW_FAVORITES = new BooleanPreference(this, "show_favorites", true).makeProfile().cache(); - public final CommonPreference SHOW_ZOOM_BUTTONS_NAVIGATION = new BooleanPreference("show_zoom_buttons_navigation", false).makeProfile().cache(); + public final CommonPreference SHOW_ZOOM_BUTTONS_NAVIGATION = new BooleanPreference(this, "show_zoom_buttons_navigation", false).makeProfile().cache(); { SHOW_ZOOM_BUTTONS_NAVIGATION.setModeDefaultValue(ApplicationMode.PEDESTRIAN, true); } // Json - public final OsmandPreference SELECTED_GPX = new StringPreference("selected_gpx", "").makeGlobal(); + public final OsmandPreference SELECTED_GPX = new StringPreference(this, "selected_gpx", "").makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference MAP_SCREEN_ORIENTATION = - new IntPreference("map_screen_orientation", -1/*ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED*/).makeProfile(); + new IntPreference(this, "map_screen_orientation", -1/*ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED*/).makeProfile(); // this value string is synchronized with settings_pref.xml preference name // public final CommonPreference SHOW_VIEW_ANGLE = new BooleanPreference("show_view_angle", false).makeProfile().cache(); @@ -2261,7 +1411,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name // seconds to auto_follow - public final CommonPreference AUTO_FOLLOW_ROUTE = new IntPreference("auto_follow_route", 0).makeProfile(); + public final CommonPreference AUTO_FOLLOW_ROUTE = new IntPreference(this, "auto_follow_route", 0).makeProfile(); { AUTO_FOLLOW_ROUTE.setModeDefaultValue(ApplicationMode.CAR, 15); @@ -2271,7 +1421,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name // seconds to auto_follow - public final CommonPreference KEEP_INFORMING = new IntPreference("keep_informing", 0).makeProfile(); + public final CommonPreference KEEP_INFORMING = new IntPreference(this, "keep_informing", 0).makeProfile(); { KEEP_INFORMING.setModeDefaultValue(ApplicationMode.CAR, 0); @@ -2279,9 +1429,9 @@ public class OsmandSettings { KEEP_INFORMING.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 0); } - public final CommonPreference TURN_SCREEN_ON_ENABLED = new BooleanPreference("turn_screen_on_enabled", false).makeProfile(); + public final CommonPreference TURN_SCREEN_ON_ENABLED = new BooleanPreference(this, "turn_screen_on_enabled", false).makeProfile(); - public final CommonPreference TURN_SCREEN_ON_TIME_INT = new IntPreference("turn_screen_on_time_int", 0).makeProfile(); + public final CommonPreference TURN_SCREEN_ON_TIME_INT = new IntPreference(this, "turn_screen_on_time_int", 0).makeProfile(); { TURN_SCREEN_ON_TIME_INT.setModeDefaultValue(ApplicationMode.CAR, 0); @@ -2289,7 +1439,7 @@ public class OsmandSettings { TURN_SCREEN_ON_TIME_INT.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 0); } - public final CommonPreference TURN_SCREEN_ON_SENSOR = new BooleanPreference("turn_screen_on_sensor", false).makeProfile(); + public final CommonPreference TURN_SCREEN_ON_SENSOR = new BooleanPreference(this, "turn_screen_on_sensor", false).makeProfile(); { TURN_SCREEN_ON_SENSOR.setModeDefaultValue(ApplicationMode.CAR, false); @@ -2306,7 +1456,7 @@ public class OsmandSettings { public static final int ROTATE_MAP_BEARING = 1; public static final int ROTATE_MAP_COMPASS = 2; public final CommonPreference ROTATE_MAP = - new IntPreference("rotate_map", ROTATE_MAP_NONE).makeProfile().cache(); + new IntPreference(this, "rotate_map", ROTATE_MAP_NONE).makeProfile().cache(); { ROTATE_MAP.setModeDefaultValue(ApplicationMode.CAR, ROTATE_MAP_BEARING); @@ -2320,16 +1470,16 @@ public class OsmandSettings { public static final int MIDDLE_BOTTOM_CONSTANT = 2; public static final int MIDDLE_TOP_CONSTANT = 3; public static final int LANDSCAPE_MIDDLE_RIGHT_CONSTANT = 4; - public final CommonPreference CENTER_POSITION_ON_MAP = new BooleanPreference("center_position_on_map", false).makeProfile(); + public final CommonPreference CENTER_POSITION_ON_MAP = new BooleanPreference(this, "center_position_on_map", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference MAX_LEVEL_TO_DOWNLOAD_TILE = new IntPreference("max_level_download_tile", 20).makeProfile().cache(); + public final OsmandPreference MAX_LEVEL_TO_DOWNLOAD_TILE = new IntPreference(this, "max_level_download_tile", 20).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference LEVEL_TO_SWITCH_VECTOR_RASTER = new IntPreference("level_to_switch_vector_raster", 1).makeGlobal().cache(); + public final OsmandPreference LEVEL_TO_SWITCH_VECTOR_RASTER = new IntPreference(this, "level_to_switch_vector_raster", 1).makeGlobal().cache(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference AUDIO_MANAGER_STREAM = new IntPreference("audio_stream", 3/*AudioManager.STREAM_MUSIC*/) { + public final OsmandPreference AUDIO_MANAGER_STREAM = new IntPreference(this, "audio_stream", 3/*AudioManager.STREAM_MUSIC*/) { @Override protected boolean setValue(Object prefs, Integer stream) { boolean valueSaved = super.setValue(prefs, stream); @@ -2355,7 +1505,7 @@ public class OsmandSettings { }.makeProfile(); // Corresponding USAGE value for AudioAttributes - public final OsmandPreference AUDIO_USAGE = new IntPreference("audio_usage", + public final OsmandPreference AUDIO_USAGE = new IntPreference(this, "audio_usage", 12/*AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE*/).makeProfile(); // For now this can be changed only in TestVoiceActivity @@ -2363,66 +1513,66 @@ public class OsmandSettings { { // 1500 ms delay works for most configurations to establish a BT SCO link - VOICE_PROMPT_DELAY[0] = new IntPreference("voice_prompt_delay_0", 1500).makeGlobal().cache(); /*AudioManager.STREAM_VOICE_CALL*/ + VOICE_PROMPT_DELAY[0] = new IntPreference(this, "voice_prompt_delay_0", 1500).makeGlobal().cache(); /*AudioManager.STREAM_VOICE_CALL*/ // On most devices sound output works pomptly so usually no voice prompt delay needed - VOICE_PROMPT_DELAY[3] = new IntPreference("voice_prompt_delay_3", 0).makeGlobal().cache(); /*AudioManager.STREAM_MUSIC*/ - VOICE_PROMPT_DELAY[5] = new IntPreference("voice_prompt_delay_5", 0).makeGlobal().cache(); /*AudioManager.STREAM_NOTIFICATION*/ + VOICE_PROMPT_DELAY[3] = new IntPreference(this, "voice_prompt_delay_3", 0).makeGlobal().cache(); /*AudioManager.STREAM_MUSIC*/ + VOICE_PROMPT_DELAY[5] = new IntPreference(this, "voice_prompt_delay_5", 0).makeGlobal().cache(); /*AudioManager.STREAM_NOTIFICATION*/ } // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference MAP_ONLINE_DATA = new BooleanPreference("map_online_data", false).makeProfile(); + public final CommonPreference MAP_ONLINE_DATA = new BooleanPreference(this, "map_online_data", false).makeProfile(); - public final CommonPreference TERRAIN_MODE = new EnumStringPreference<>("terrain_mode", TerrainMode.HILLSHADE, TerrainMode.values()).makeProfile(); + public final CommonPreference TERRAIN_MODE = new EnumStringPreference<>(this, "terrain_mode", TerrainMode.HILLSHADE, TerrainMode.values()).makeProfile(); - public final CommonPreference HILLSHADE_MIN_ZOOM = new IntPreference("hillshade_min_zoom", 3).makeProfile(); + public final CommonPreference HILLSHADE_MIN_ZOOM = new IntPreference(this, "hillshade_min_zoom", 3).makeProfile(); - public final CommonPreference HILLSHADE_MAX_ZOOM = new IntPreference("hillshade_max_zoom", 17).makeProfile(); + public final CommonPreference HILLSHADE_MAX_ZOOM = new IntPreference(this, "hillshade_max_zoom", 17).makeProfile(); - public final CommonPreference HILLSHADE_TRANSPARENCY = new IntPreference("hillshade_transparency", 100).makeProfile(); + public final CommonPreference HILLSHADE_TRANSPARENCY = new IntPreference(this, "hillshade_transparency", 100).makeProfile(); - public final CommonPreference SLOPE_MIN_ZOOM = new IntPreference("slope_min_zoom", 3).makeProfile(); + public final CommonPreference SLOPE_MIN_ZOOM = new IntPreference(this, "slope_min_zoom", 3).makeProfile(); - public final CommonPreference SLOPE_MAX_ZOOM = new IntPreference("slope_max_zoom", 17).makeProfile(); + public final CommonPreference SLOPE_MAX_ZOOM = new IntPreference(this, "slope_max_zoom", 17).makeProfile(); - public final CommonPreference SLOPE_TRANSPARENCY = new IntPreference("slope_transparency", 80).makeProfile(); + public final CommonPreference SLOPE_TRANSPARENCY = new IntPreference(this, "slope_transparency", 80).makeProfile(); - public final CommonPreference TERRAIN = new BooleanPreference("terrain_layer", true).makeProfile(); + public final CommonPreference TERRAIN = new BooleanPreference(this, "terrain_layer", true).makeProfile(); - public final CommonPreference CONTOUR_LINES_ZOOM = new StringPreference("contour_lines_zoom", null).makeProfile().cache(); + public final CommonPreference CONTOUR_LINES_ZOOM = new StringPreference(this, "contour_lines_zoom", null).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference MAP_OVERLAY = new StringPreference("map_overlay", null).makeProfile().cache(); + public final CommonPreference MAP_OVERLAY = new StringPreference(this, "map_overlay", null).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference MAP_UNDERLAY = new StringPreference("map_underlay", null).makeProfile().cache(); + public final CommonPreference MAP_UNDERLAY = new StringPreference(this, "map_underlay", null).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference MAP_OVERLAY_TRANSPARENCY = new IntPreference("overlay_transparency", 100).makeProfile().cache(); + public final CommonPreference MAP_OVERLAY_TRANSPARENCY = new IntPreference(this, "overlay_transparency", 100).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference MAP_TRANSPARENCY = new IntPreference("map_transparency", 255).makeProfile().cache(); + public final CommonPreference MAP_TRANSPARENCY = new IntPreference(this, "map_transparency", 255).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference MAP_TILE_SOURCES = new StringPreference("map_tile_sources", + public final CommonPreference MAP_TILE_SOURCES = new StringPreference(this, "map_tile_sources", TileSourceManager.getMapnikSource().getName()).makeProfile(); public final CommonPreference LAYER_TRANSPARENCY_SEEKBAR_MODE = - new EnumStringPreference<>("layer_transparency_seekbar_mode", LayerTransparencySeekbarMode.UNDEFINED, LayerTransparencySeekbarMode.values()); + new EnumStringPreference<>(this, "layer_transparency_seekbar_mode", LayerTransparencySeekbarMode.UNDEFINED, LayerTransparencySeekbarMode.values()); - public final CommonPreference MAP_OVERLAY_PREVIOUS = new StringPreference("map_overlay_previous", null).makeGlobal().cache(); + public final CommonPreference MAP_OVERLAY_PREVIOUS = new StringPreference(this, "map_overlay_previous", null).makeGlobal().cache(); - public final CommonPreference MAP_UNDERLAY_PREVIOUS = new StringPreference("map_underlay_previous", null).makeGlobal().cache(); + public final CommonPreference MAP_UNDERLAY_PREVIOUS = new StringPreference(this, "map_underlay_previous", null).makeGlobal().cache(); - public CommonPreference PREVIOUS_INSTALLED_VERSION = new StringPreference("previous_installed_version", "").makeGlobal(); + public CommonPreference PREVIOUS_INSTALLED_VERSION = new StringPreference(this, "previous_installed_version", "").makeGlobal(); - public final OsmandPreference SHOULD_SHOW_FREE_VERSION_BANNER = new BooleanPreference("should_show_free_version_banner", false).makeGlobal().cache(); + public final OsmandPreference SHOULD_SHOW_FREE_VERSION_BANNER = new BooleanPreference(this, "should_show_free_version_banner", false).makeGlobal().cache(); - public final OsmandPreference MARKERS_DISTANCE_INDICATION_ENABLED = new BooleanPreference("markers_distance_indication_enabled", true).makeProfile(); + public final OsmandPreference MARKERS_DISTANCE_INDICATION_ENABLED = new BooleanPreference(this, "markers_distance_indication_enabled", true).makeProfile(); - public final OsmandPreference DISPLAYED_MARKERS_WIDGETS_COUNT = new IntPreference("displayed_markers_widgets_count", 1).makeProfile(); + public final OsmandPreference DISPLAYED_MARKERS_WIDGETS_COUNT = new IntPreference(this, "displayed_markers_widgets_count", 1).makeProfile(); public final CommonPreference MAP_MARKERS_MODE = - new EnumStringPreference<>("map_markers_mode", MapMarkersMode.TOOLBAR, MapMarkersMode.values()); + new EnumStringPreference<>(this, "map_markers_mode", MapMarkersMode.TOOLBAR, MapMarkersMode.values()); { MAP_MARKERS_MODE.makeProfile().cache(); @@ -2432,18 +1582,18 @@ public class OsmandSettings { MAP_MARKERS_MODE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, MapMarkersMode.TOOLBAR); } - public final OsmandPreference SHOW_MAP_MARKERS = new BooleanPreference("show_map_markers", true).makeProfile(); + public final OsmandPreference SHOW_MAP_MARKERS = new BooleanPreference(this, "show_map_markers", true).makeProfile(); - public final OsmandPreference SHOW_COORDINATES_WIDGET = new BooleanPreference("show_coordinates_widget", false).makeProfile().cache(); + public final OsmandPreference SHOW_COORDINATES_WIDGET = new BooleanPreference(this, "show_coordinates_widget", false).makeProfile().cache(); - public final CommonPreference NOTES_SORT_BY_MODE = new EnumStringPreference<>("notes_sort_by_mode", NotesSortByMode.BY_DATE, NotesSortByMode.values()); + public final CommonPreference NOTES_SORT_BY_MODE = new EnumStringPreference<>(this, "notes_sort_by_mode", NotesSortByMode.BY_DATE, NotesSortByMode.values()); - public final OsmandPreference ANIMATE_MY_LOCATION = new BooleanPreference("animate_my_location", true).makeProfile().cache(); + public final OsmandPreference ANIMATE_MY_LOCATION = new BooleanPreference(this, "animate_my_location", true).makeProfile().cache(); - public final OsmandPreference EXTERNAL_INPUT_DEVICE = new IntPreference("external_input_device", 0).makeProfile(); + public final OsmandPreference EXTERNAL_INPUT_DEVICE = new IntPreference(this, "external_input_device", 0).makeProfile(); - public final OsmandPreference ROUTE_MAP_MARKERS_START_MY_LOC = new BooleanPreference("route_map_markers_start_my_loc", false).makeGlobal().cache(); - public final OsmandPreference ROUTE_MAP_MARKERS_ROUND_TRIP = new BooleanPreference("route_map_markers_round_trip", false).makeGlobal().cache(); + public final OsmandPreference ROUTE_MAP_MARKERS_START_MY_LOC = new BooleanPreference(this, "route_map_markers_start_my_loc", false).makeGlobal().cache(); + public final OsmandPreference ROUTE_MAP_MARKERS_ROUND_TRIP = new BooleanPreference(this, "route_map_markers_round_trip", false).makeGlobal().cache(); public ITileSource getMapTileSource(boolean warnWhenSelected) { String tileName = MAP_TILE_SOURCES.get(); @@ -2571,7 +1721,7 @@ public class OsmandSettings { public static final int EXTERNAL_STORAGE_TYPE_INTERNAL_FILE = 2; // ctx.getFilesDir() public static final int EXTERNAL_STORAGE_TYPE_OBB = 3; // ctx.getObbDirs public static final int EXTERNAL_STORAGE_TYPE_SPECIFIED = 4; - public final OsmandPreference OSMAND_USAGE_SPACE = new LongPreference("osmand_usage_space", 0).makeGlobal(); + public final OsmandPreference OSMAND_USAGE_SPACE = new LongPreference(this, "osmand_usage_space", 0).makeGlobal(); public void freezeExternalStorageDirectory() { @@ -2807,10 +1957,6 @@ public class OsmandSettings { } } - private Object objectToShow; - private boolean editObjectToShow; - private String searchRequestToShow; - public void setSearchRequestToShow(String request) { this.searchRequestToShow = request; } @@ -2902,10 +2048,10 @@ public class OsmandSettings { public final static String INTERMEDIATE_POINTS = "intermediate_points"; //$NON-NLS-1$ public final static String INTERMEDIATE_POINTS_DESCRIPTION = "intermediate_points_description"; //$NON-NLS-1$ - private IntermediatePointsStorage intermediatePointsStorage = new IntermediatePointsStorage(); - public final static String POINT_NAVIGATE_LAT_BACKUP = "point_navigate_lat_backup"; //$NON-NLS-1$ - public final static String POINT_NAVIGATE_LON_BACKUP = "point_navigate_lon_backup"; //$NON-NLS-1$ + + final static String POINT_NAVIGATE_LAT_BACKUP = "point_navigate_lat_backup"; //$NON-NLS-1$ + final static String POINT_NAVIGATE_LON_BACKUP = "point_navigate_lon_backup"; //$NON-NLS-1$ public final static String POINT_NAVIGATE_DESCRIPTION_BACKUP = "point_navigate_description_backup"; //$NON-NLS-1$ public final static String START_POINT_LAT_BACKUP = "start_point_lat_backup"; //$NON-NLS-1$ public final static String START_POINT_LON_BACKUP = "start_point_lon_backup"; //$NON-NLS-1$ @@ -2920,7 +2066,6 @@ public class OsmandSettings { private static final String IMPASSABLE_ROADS_DESCRIPTIONS = "impassable_roads_descriptions"; private static final String IMPASSABLE_ROADS_IDS = "impassable_roads_ids"; private static final String IMPASSABLE_ROADS_APP_MODE_KEYS = "impassable_roads_app_mode_keys"; - private ImpassableRoadsStorage mImpassableRoadsStorage = new ImpassableRoadsStorage(); public void backupPointToStart() { settingsAPI.edit(globalPreferences) @@ -3070,334 +2215,7 @@ public class OsmandSettings { } public final CommonPreference USE_INTERMEDIATE_POINTS_NAVIGATION = - new BooleanPreference("use_intermediate_points_navigation", false).makeGlobal().cache(); - - - private class IntermediatePointsStorage extends MapPointsStorage { - - public IntermediatePointsStorage() { - pointsKey = INTERMEDIATE_POINTS; - descriptionsKey = INTERMEDIATE_POINTS_DESCRIPTION; - } - - @Override - public boolean savePoints(List ps, List ds) { - boolean res = super.savePoints(ps, ds); - backupTargetPoints(); - return res; - } - } - - private class ImpassableRoadsStorage extends MapPointsStorage { - - protected String roadsIdsKey; - protected String appModeKey; - - public ImpassableRoadsStorage() { - pointsKey = IMPASSABLE_ROAD_POINTS; - descriptionsKey = IMPASSABLE_ROADS_DESCRIPTIONS; - roadsIdsKey = IMPASSABLE_ROADS_IDS; - appModeKey = IMPASSABLE_ROADS_APP_MODE_KEYS; - } - - public List getRoadIds(int size) { - List list = new ArrayList<>(); - String roadIds = settingsAPI.getString(globalPreferences, roadsIdsKey, ""); - if (roadIds.trim().length() > 0) { - StringTokenizer tok = new StringTokenizer(roadIds, ","); - while (tok.hasMoreTokens() && list.size() <= size) { - list.add(Long.parseLong(tok.nextToken())); - } - } - while (list.size() < size) { - list.add(0L); - } - return list; - } - - public List getAppModeKeys(int size) { - List list = new ArrayList<>(); - String roadIds = settingsAPI.getString(globalPreferences, appModeKey, ""); - if (roadIds.trim().length() > 0) { - StringTokenizer tok = new StringTokenizer(roadIds, ","); - while (tok.hasMoreTokens() && list.size() <= size) { - list.add(tok.nextToken()); - } - } - while (list.size() < size) { - list.add(""); - } - return list; - } - - public List getImpassableRoadsInfo() { - List points = getPoints(); - List roadIds = getRoadIds(points.size()); - List appModeKeys = getAppModeKeys(points.size()); - List descriptions = getPointDescriptions(points.size()); - - List avoidRoadsInfo = new ArrayList<>(); - - for (int i = 0; i < points.size(); i++) { - LatLon latLon = points.get(i); - PointDescription description = PointDescription.deserializeFromString(descriptions.get(i), null); - - AvoidRoadInfo avoidRoadInfo = new AvoidRoadInfo(); - avoidRoadInfo.id = roadIds.get(i); - avoidRoadInfo.latitude = latLon.getLatitude(); - avoidRoadInfo.longitude = latLon.getLongitude(); - avoidRoadInfo.name = description.getName(); - avoidRoadInfo.appModeKey = appModeKeys.get(i); - avoidRoadsInfo.add(avoidRoadInfo); - } - - return avoidRoadsInfo; - } - - public boolean addImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) { - List points = getPoints(); - List roadIds = getRoadIds(points.size()); - List appModeKeys = getAppModeKeys(points.size()); - List descriptions = getPointDescriptions(points.size()); - - roadIds.add(0, avoidRoadInfo.id); - points.add(0, new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude)); - appModeKeys.add(0, avoidRoadInfo.appModeKey); - descriptions.add(0, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name))); - - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); - } - - public boolean updateImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) { - List points = getPoints(); - - int index = points.indexOf(new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude)); - if (index != -1) { - List roadIds = getRoadIds(points.size()); - List appModeKeys = getAppModeKeys(points.size()); - List descriptions = getPointDescriptions(points.size()); - - roadIds.set(index, avoidRoadInfo.id); - appModeKeys.set(index, avoidRoadInfo.appModeKey); - descriptions.set(index, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name))); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); - } - return false; - } - - @Override - public boolean deletePoint(int index) { - List points = getPoints(); - List roadIds = getRoadIds(points.size()); - List appModeKeys = getAppModeKeys(points.size()); - List descriptions = getPointDescriptions(points.size()); - - if (index < points.size()) { - points.remove(index); - roadIds.remove(index); - appModeKeys.remove(index); - descriptions.remove(index); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); - } - return false; - } - - @Override - public boolean deletePoint(LatLon latLon) { - List points = getPoints(); - List roadIds = getRoadIds(points.size()); - List appModeKeys = getAppModeKeys(points.size()); - List descriptions = getPointDescriptions(points.size()); - - int index = points.indexOf(latLon); - if (index != -1) { - points.remove(index); - roadIds.remove(index); - appModeKeys.remove(index); - descriptions.remove(index); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); - } - return false; - } - - @Override - public boolean movePoint(LatLon latLonEx, LatLon latLonNew) { - List points = getPoints(); - List roadIds = getRoadIds(points.size()); - List appModeKeys = getAppModeKeys(points.size()); - List descriptions = getPointDescriptions(points.size()); - - int i = points.indexOf(latLonEx); - if (i != -1) { - points.set(i, latLonNew); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); - } else { - return false; - } - } - - public boolean saveAvoidRoadData(List points, List descriptions, - List roadIds, List appModeKeys) { - return savePoints(points, descriptions) && saveRoadIds(roadIds) && saveAppModeKeys(appModeKeys); - } - - public boolean saveRoadIds(List roadIds) { - StringBuilder stringBuilder = new StringBuilder(); - Iterator iterator = roadIds.iterator(); - while (iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - return settingsAPI.edit(globalPreferences) - .putString(roadsIdsKey, stringBuilder.toString()) - .commit(); - } - - public boolean saveAppModeKeys(List appModeKeys) { - StringBuilder stringBuilder = new StringBuilder(); - Iterator iterator = appModeKeys.iterator(); - while (iterator.hasNext()) { - stringBuilder.append(iterator.next()); - if (iterator.hasNext()) { - stringBuilder.append(","); - } - } - return settingsAPI.edit(globalPreferences) - .putString(appModeKey, stringBuilder.toString()) - .commit(); - } - } - - private abstract class MapPointsStorage { - - protected String pointsKey; - protected String descriptionsKey; - - public MapPointsStorage() { - } - - public List getPointDescriptions(int sz) { - List list = new ArrayList<>(); - String ip = settingsAPI.getString(globalPreferences, descriptionsKey, ""); - if (ip.trim().length() > 0) { - list.addAll(Arrays.asList(ip.split("--"))); - } - while (list.size() > sz) { - list.remove(list.size() - 1); - } - while (list.size() < sz) { - list.add(""); - } - return list; - } - - public List getPoints() { - List list = new ArrayList<>(); - String ip = settingsAPI.getString(globalPreferences, pointsKey, ""); - if (ip.trim().length() > 0) { - StringTokenizer tok = new StringTokenizer(ip, ","); - while (tok.hasMoreTokens()) { - String lat = tok.nextToken(); - if (!tok.hasMoreTokens()) { - break; - } - String lon = tok.nextToken(); - list.add(new LatLon(Float.parseFloat(lat), Float.parseFloat(lon))); - } - } - return list; - } - - public boolean insertPoint(double latitude, double longitude, PointDescription historyDescription, int index) { - List ps = getPoints(); - List ds = getPointDescriptions(ps.size()); - ps.add(index, new LatLon(latitude, longitude)); - ds.add(index, PointDescription.serializeToString(historyDescription)); - if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) { - SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription); - } - return savePoints(ps, ds); - } - - public boolean updatePoint(double latitude, double longitude, PointDescription historyDescription) { - List ps = getPoints(); - List ds = getPointDescriptions(ps.size()); - int i = ps.indexOf(new LatLon(latitude, longitude)); - if (i != -1) { - ds.set(i, PointDescription.serializeToString(historyDescription)); - if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) { - SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription); - } - return savePoints(ps, ds); - } else { - return false; - } - } - - public boolean deletePoint(int index) { - List ps = getPoints(); - List ds = getPointDescriptions(ps.size()); - if (index < ps.size()) { - ps.remove(index); - ds.remove(index); - return savePoints(ps, ds); - } else { - return false; - } - } - - public boolean deletePoint(LatLon latLon) { - List ps = getPoints(); - List ds = getPointDescriptions(ps.size()); - int index = ps.indexOf(latLon); - if (index != -1) { - ps.remove(index); - ds.remove(index); - return savePoints(ps, ds); - } else { - return false; - } - } - - public boolean savePoints(List ps, List ds) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ps.size(); i++) { - if (i > 0) { - sb.append(","); - } - sb.append(((float) ps.get(i).getLatitude() + "")).append(",").append(((float) ps.get(i).getLongitude() + "")); - } - StringBuilder tb = new StringBuilder(); - for (int i = 0; i < ds.size(); i++) { - if (i > 0) { - tb.append("--"); - } - if (ds.get(i) == null) { - tb.append(""); - } else { - tb.append(ds.get(i)); - } - } - return settingsAPI.edit(globalPreferences) - .putString(pointsKey, sb.toString()) - .putString(descriptionsKey, tb.toString()) - .commit(); - } - - public boolean movePoint(LatLon latLonEx, LatLon latLonNew) { - List ps = getPoints(); - List ds = getPointDescriptions(ps.size()); - int i = ps.indexOf(latLonEx); - if (i != -1) { - ps.set(i, latLonNew); - return savePoints(ps, ds); - } else { - return false; - } - } - } + new BooleanPreference(this, "use_intermediate_points_navigation", false).makeGlobal().cache(); public List getIntermediatePointDescriptions(int sz) { @@ -3490,16 +2308,16 @@ public class OsmandSettings { public static final String QUICK_FAB_MARGIN_X_LANDSCAPE_MARGIN = "quick_fab_margin_x_landscape_margin"; public static final String QUICK_FAB_MARGIN_Y_LANDSCAPE_MARGIN = "quick_fab_margin_y_landscape_margin"; - public final CommonPreference QUICK_ACTION = new StringPreference("quick_action_new", "").makeGlobal(); + public final CommonPreference QUICK_ACTION = new StringPreference(this, "quick_action_new", "").makeGlobal(); - public final CommonPreference QUICK_ACTION_LIST = new StringPreference("quick_action_list", "").makeGlobal(); + public final CommonPreference QUICK_ACTION_LIST = new StringPreference(this, "quick_action_list", "").makeGlobal(); - public final CommonPreference IS_QUICK_ACTION_TUTORIAL_SHOWN = new BooleanPreference("quick_action_tutorial", false).makeGlobal(); + public final CommonPreference IS_QUICK_ACTION_TUTORIAL_SHOWN = new BooleanPreference(this, "quick_action_tutorial", false).makeGlobal(); - private final CommonPreference QUICK_ACTION_FAB_MARGIN_X_PORTRAIT = new IntPreference(QUICK_FAB_MARGIN_X_PORTRAIT_MARGIN, 0).makeProfile(); - private final CommonPreference QUICK_ACTION_FAB_MARGIN_Y_PORTRAIT = new IntPreference(QUICK_FAB_MARGIN_Y_PORTRAIT_MARGIN, 0).makeProfile(); - private final CommonPreference QUICK_ACTION_FAB_MARGIN_X_LANDSCAPE_MARGIN = new IntPreference(QUICK_FAB_MARGIN_X_LANDSCAPE_MARGIN, 0).makeProfile(); - private final CommonPreference QUICK_ACTION_FAB_MARGIN_Y_LANDSCAPE_MARGIN = new IntPreference(QUICK_FAB_MARGIN_Y_LANDSCAPE_MARGIN, 0).makeProfile(); + private final CommonPreference QUICK_ACTION_FAB_MARGIN_X_PORTRAIT = new IntPreference(this, QUICK_FAB_MARGIN_X_PORTRAIT_MARGIN, 0).makeProfile(); + private final CommonPreference QUICK_ACTION_FAB_MARGIN_Y_PORTRAIT = new IntPreference(this, QUICK_FAB_MARGIN_Y_PORTRAIT_MARGIN, 0).makeProfile(); + private final CommonPreference QUICK_ACTION_FAB_MARGIN_X_LANDSCAPE_MARGIN = new IntPreference(this, QUICK_FAB_MARGIN_X_LANDSCAPE_MARGIN, 0).makeProfile(); + private final CommonPreference QUICK_ACTION_FAB_MARGIN_Y_LANDSCAPE_MARGIN = new IntPreference(this, QUICK_FAB_MARGIN_Y_LANDSCAPE_MARGIN, 0).makeProfile(); public boolean setPortraitFabMargin(int x, int y) { return QUICK_ACTION_FAB_MARGIN_X_PORTRAIT.set(x) && QUICK_ACTION_FAB_MARGIN_Y_PORTRAIT.set(y); @@ -3645,10 +2463,10 @@ public class OsmandSettings { return settingsAPI.edit(globalPreferences).putString(LAST_SEARCHED_INTERSECTED_STREET, street).commit(); } - public final OsmandPreference LAST_SELECTED_GPX_TRACK_FOR_NEW_POINT = new StringPreference("last_selected_gpx_track_for_new_point", null).makeGlobal().cache(); + public final OsmandPreference LAST_SELECTED_GPX_TRACK_FOR_NEW_POINT = new StringPreference(this, "last_selected_gpx_track_for_new_point", null).makeGlobal().cache(); // Avoid using this property, probably you need to use PoiFiltersHelper.getSelectedPoiFilters() - public final OsmandPreference SELECTED_POI_FILTER_FOR_MAP = new StringPreference("selected_poi_filter_for_map", null).makeProfile().cache(); + public final OsmandPreference SELECTED_POI_FILTER_FOR_MAP = new StringPreference(this, "selected_poi_filter_for_map", null).makeProfile().cache(); public Set getSelectedPoiFilters() { Set result = new LinkedHashSet<>(); @@ -3664,21 +2482,21 @@ public class OsmandSettings { } public final ListStringPreference POI_FILTERS_ORDER = (ListStringPreference) - new ListStringPreference("poi_filters_order", null, ",,").makeProfile().cache(); + new ListStringPreference(this, "poi_filters_order", null, ",,").makeProfile().cache(); public final ListStringPreference INACTIVE_POI_FILTERS = (ListStringPreference) - new ListStringPreference("inactive_poi_filters", null, ",,").makeProfile().cache(); + new ListStringPreference(this, "inactive_poi_filters", null, ",,").makeProfile().cache(); public final ContextMenuItemsPreference DRAWER_ITEMS = - (ContextMenuItemsPreference) new ContextMenuItemsPreference("drawer_items", DRAWER_ITEM_ID_SCHEME, new ContextMenuItemsSettings()) + (ContextMenuItemsPreference) new ContextMenuItemsPreference(this, "drawer_items", DRAWER_ITEM_ID_SCHEME, new ContextMenuItemsSettings()) .makeProfile().cache(); public final ContextMenuItemsPreference CONFIGURE_MAP_ITEMS = - (ContextMenuItemsPreference) new ContextMenuItemsPreference("configure_map_items", CONFIGURE_MAP_ITEM_ID_SCHEME, new ContextMenuItemsSettings()) + (ContextMenuItemsPreference) new ContextMenuItemsPreference(this, "configure_map_items", CONFIGURE_MAP_ITEM_ID_SCHEME, new ContextMenuItemsSettings()) .makeProfile().cache(); public final ContextMenuItemsPreference CONTEXT_MENU_ACTIONS_ITEMS = - (ContextMenuItemsPreference) new ContextMenuItemsPreference("context_menu_items", MAP_CONTEXT_MENU_ACTIONS, new MainContextMenuItemsSettings()) + (ContextMenuItemsPreference) new ContextMenuItemsPreference(this, "context_menu_items", MAP_CONTEXT_MENU_ACTIONS, new MainContextMenuItemsSettings()) .makeProfile().cache(); public final List CONTEXT_MENU_ITEMS_PREFERENCES = Arrays.asList(DRAWER_ITEMS, CONFIGURE_MAP_ITEMS, CONTEXT_MENU_ACTIONS_ITEMS); @@ -3700,7 +2518,7 @@ public class OsmandSettings { }; // this value string is synchronized with settings_pref.xml preference name // this value could localized - public final OsmandPreference VOICE_PROVIDER = new StringPreference("voice_provider", null) { + public final OsmandPreference VOICE_PROVIDER = new StringPreference(this, "voice_provider", null) { protected String getDefaultValue() { Configuration config = ctx.getResources().getConfiguration(); @@ -3715,7 +2533,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name - public final CommonPreference RENDERER = new StringPreference("renderer", RendererRegistry.DEFAULT_RENDER) { + public final CommonPreference RENDERER = new StringPreference(this, "renderer", RendererRegistry.DEFAULT_RENDER) { @Override protected boolean setValue(Object prefs, String val) { @@ -3736,11 +2554,9 @@ public class OsmandSettings { RENDERER.setModeDefaultValue(ApplicationMode.SKI, RendererRegistry.WINTER_SKI_RENDER); } - Map> customRendersProps = new LinkedHashMap>(); - public CommonPreference getCustomRenderProperty(String attrName) { if (!customRendersProps.containsKey(attrName)) { - customRendersProps.put(attrName, new StringPreference("nrenderer_" + attrName, "").makeProfile()); + customRendersProps.put(attrName, new StringPreference(this, "nrenderer_" + attrName, "").makeProfile()); } return customRendersProps.get(attrName); } @@ -3750,20 +2566,19 @@ public class OsmandSettings { getCustomRenderProperty("defAppMode"); } - Map> customBooleanRendersProps = new LinkedHashMap>(); public CommonPreference getCustomRenderBooleanProperty(String attrName) { if (!customBooleanRendersProps.containsKey(attrName)) { - customBooleanRendersProps.put(attrName, new BooleanPreference("nrenderer_" + attrName, false).makeProfile()); + customBooleanRendersProps.put(attrName, new BooleanPreference(this, "nrenderer_" + attrName, false).makeProfile()); } return customBooleanRendersProps.get(attrName); } - Map> customRoutingProps = new LinkedHashMap>(); + public CommonPreference getCustomRoutingProperty(String attrName, String defValue) { if (!customRoutingProps.containsKey(attrName)) { - customRoutingProps.put(attrName, new StringPreference("prouting_" + attrName, defValue).makeProfile()); + customRoutingProps.put(attrName, new StringPreference(this, "prouting_" + attrName, defValue).makeProfile()); } return customRoutingProps.get(attrName); } @@ -3773,73 +2588,73 @@ public class OsmandSettings { // pref.setModeDefaultValue(ApplicationMode.CAR, "car"); } - Map> customBooleanRoutingProps = new LinkedHashMap>(); + public CommonPreference getCustomRoutingBooleanProperty(String attrName, boolean defaulfValue) { if (!customBooleanRoutingProps.containsKey(attrName)) { - customBooleanRoutingProps.put(attrName, new BooleanPreference("prouting_" + attrName, defaulfValue).makeProfile()); + customBooleanRoutingProps.put(attrName, new BooleanPreference(this, "prouting_" + attrName, defaulfValue).makeProfile()); } return customBooleanRoutingProps.get(attrName); } - public final CommonPreference ROUTE_RECALCULATION_DISTANCE = new FloatPreference("routing_recalc_distance", 0.f).makeProfile(); - public final CommonPreference ROUTE_STRAIGHT_ANGLE = new FloatPreference("routing_straight_angle", 30.f).makeProfile(); + public final CommonPreference ROUTE_RECALCULATION_DISTANCE = new FloatPreference(this, "routing_recalc_distance", 0.f).makeProfile(); + public final CommonPreference ROUTE_STRAIGHT_ANGLE = new FloatPreference(this, "routing_straight_angle", 30.f).makeProfile(); - public final OsmandPreference USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference("enable_osmc_routing", true).makeGlobal(); + public final OsmandPreference USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference(this, "enable_osmc_routing", true).makeGlobal(); - public final OsmandPreference USE_OSM_LIVE_FOR_PUBLIC_TRANSPORT = new BooleanPreference("enable_osmc_public_transport", false).makeGlobal(); + public final OsmandPreference USE_OSM_LIVE_FOR_PUBLIC_TRANSPORT = new BooleanPreference(this, "enable_osmc_public_transport", false).makeGlobal(); - public final OsmandPreference VOICE_MUTE = new BooleanPreference("voice_mute", false).makeProfile().cache(); + public final OsmandPreference VOICE_MUTE = new BooleanPreference(this, "voice_mute", false).makeProfile().cache(); // for background service - public final OsmandPreference MAP_ACTIVITY_ENABLED = new BooleanPreference("map_activity_enabled", false).makeGlobal(); + public final OsmandPreference MAP_ACTIVITY_ENABLED = new BooleanPreference(this, "map_activity_enabled", false).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference SAFE_MODE = new BooleanPreference("safe_mode", false).makeGlobal(); - public final OsmandPreference PT_SAFE_MODE = new BooleanPreference("pt_safe_mode", true).makeGlobal(); - public final OsmandPreference NATIVE_RENDERING_FAILED = new BooleanPreference("native_rendering_failed_init", false).makeGlobal(); + public final OsmandPreference SAFE_MODE = new BooleanPreference(this, "safe_mode", false).makeGlobal(); + public final OsmandPreference PT_SAFE_MODE = new BooleanPreference(this, "pt_safe_mode", true).makeGlobal(); + public final OsmandPreference NATIVE_RENDERING_FAILED = new BooleanPreference(this, "native_rendering_failed_init", false).makeGlobal(); - public final OsmandPreference USE_OPENGL_RENDER = new BooleanPreference("use_opengl_render", + public final OsmandPreference USE_OPENGL_RENDER = new BooleanPreference(this, "use_opengl_render", false /*Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH*/ ).makeGlobal().cache(); - public final OsmandPreference OPENGL_RENDER_FAILED = new BooleanPreference("opengl_render_failed", false).makeGlobal().cache(); + public final OsmandPreference OPENGL_RENDER_FAILED = new BooleanPreference(this, "opengl_render_failed", false).makeGlobal().cache(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference CONTRIBUTION_INSTALL_APP_DATE = new StringPreference("CONTRIBUTION_INSTALL_APP_DATE", null).makeGlobal(); + public final OsmandPreference CONTRIBUTION_INSTALL_APP_DATE = new StringPreference(this, "CONTRIBUTION_INSTALL_APP_DATE", null).makeGlobal(); - public final OsmandPreference COORDINATES_FORMAT = new IntPreference("coordinates_format", PointDescription.FORMAT_DEGREES).makeProfile(); + public final OsmandPreference COORDINATES_FORMAT = new IntPreference(this, "coordinates_format", PointDescription.FORMAT_DEGREES).makeProfile(); - public final OsmandPreference FOLLOW_THE_ROUTE = new BooleanPreference("follow_to_route", false).makeGlobal(); - public final OsmandPreference FOLLOW_THE_GPX_ROUTE = new StringPreference("follow_gpx", null).makeGlobal(); + public final OsmandPreference FOLLOW_THE_ROUTE = new BooleanPreference(this, "follow_to_route", false).makeGlobal(); + public final OsmandPreference FOLLOW_THE_GPX_ROUTE = new StringPreference(this, "follow_gpx", null).makeGlobal(); - public final OsmandPreference SELECTED_TRAVEL_BOOK = new StringPreference("selected_travel_book", "").makeGlobal(); + public final OsmandPreference SELECTED_TRAVEL_BOOK = new StringPreference(this, "selected_travel_book", "").makeGlobal(); public final ListStringPreference DISPLAYED_TRANSPORT_SETTINGS = (ListStringPreference) - new ListStringPreference("displayed_transport_settings", null, ",").makeProfile(); + new ListStringPreference(this, "displayed_transport_settings", null, ",").makeProfile(); public final OsmandPreference SHOW_ARRIVAL_TIME_OTHERWISE_EXPECTED_TIME = - new BooleanPreference("show_arrival_time", true).makeProfile(); + new BooleanPreference(this, "show_arrival_time", true).makeProfile(); public final OsmandPreference SHOW_INTERMEDIATE_ARRIVAL_TIME_OTHERWISE_EXPECTED_TIME = - new BooleanPreference("show_intermediate_arrival_time", true).makeProfile(); + new BooleanPreference(this, "show_intermediate_arrival_time", true).makeProfile(); public final OsmandPreference SHOW_RELATIVE_BEARING_OTHERWISE_REGULAR_BEARING = - new BooleanPreference("show_relative_bearing", true).makeProfile(); + new BooleanPreference(this, "show_relative_bearing", true).makeProfile(); public final OsmandPreference AGPS_DATA_LAST_TIME_DOWNLOADED = - new LongPreference("agps_data_downloaded", 0).makeGlobal(); + new LongPreference(this, "agps_data_downloaded", 0).makeGlobal(); // Live Updates public final OsmandPreference IS_LIVE_UPDATES_ON = - new BooleanPreference("is_live_updates_on", false).makeGlobal(); + new BooleanPreference(this, "is_live_updates_on", false).makeGlobal(); public final OsmandPreference LIVE_UPDATES_RETRIES = - new IntPreference("live_updates_retryes", 2).makeGlobal(); + new IntPreference(this, "live_updates_retryes", 2).makeGlobal(); // UI boxes public final CommonPreference TRANSPARENT_MAP_THEME = - new BooleanPreference("transparent_map_theme", true).makeProfile(); + new BooleanPreference(this, "transparent_map_theme", true).makeProfile(); { TRANSPARENT_MAP_THEME.setModeDefaultValue(ApplicationMode.CAR, false); @@ -3848,7 +2663,7 @@ public class OsmandSettings { } public final CommonPreference SHOW_STREET_NAME = - new BooleanPreference("show_street_name", false).makeProfile(); + new BooleanPreference(this, "show_street_name", false).makeProfile(); { SHOW_STREET_NAME.setModeDefaultValue(ApplicationMode.DEFAULT, false); @@ -3866,16 +2681,16 @@ public class OsmandSettings { public static final int PARROT_EXTERNAL_DEVICE = 3; public final CommonPreference SEARCH_TAB = - new IntPreference("SEARCH_TAB", 0).makeGlobal().cache(); + new IntPreference(this, "SEARCH_TAB", 0).makeGlobal().cache(); public final CommonPreference FAVORITES_TAB = - new IntPreference("FAVORITES_TAB", 0).makeGlobal().cache(); + new IntPreference(this, "FAVORITES_TAB", 0).makeGlobal().cache(); public final CommonPreference OSMAND_THEME = - new IntPreference("osmand_theme", OSMAND_LIGHT_THEME).makeProfile().cache(); + new IntPreference(this, "osmand_theme", OSMAND_LIGHT_THEME).makeProfile().cache(); public final OsmandPreference OPEN_ONLY_HEADER_STATE_ROUTE_CALCULATED = - new BooleanPreference("open_only_header_route_calculated", false).makeProfile(); + new BooleanPreference(this, "open_only_header_route_calculated", false).makeProfile(); public boolean isLightActionBar() { return isLightContent(); @@ -3891,29 +2706,29 @@ public class OsmandSettings { } public final CommonPreference FLUORESCENT_OVERLAYS = - new BooleanPreference("fluorescent_overlays", false).makeGlobal().cache(); + new BooleanPreference(this, "fluorescent_overlays", false).makeGlobal().cache(); // public final OsmandPreference NUMBER_OF_FREE_DOWNLOADS_V2 = new IntPreference("free_downloads_v2", 0).makeGlobal(); - public final OsmandPreference NUMBER_OF_FREE_DOWNLOADS = new IntPreference(NUMBER_OF_FREE_DOWNLOADS_ID, 0).makeGlobal(); + public final OsmandPreference NUMBER_OF_FREE_DOWNLOADS = new IntPreference(this, NUMBER_OF_FREE_DOWNLOADS_ID, 0).makeGlobal(); // For RateUsDialog public final OsmandPreference LAST_DISPLAY_TIME = - new LongPreference("last_display_time", 0).makeGlobal().cache(); + new LongPreference(this, "last_display_time", 0).makeGlobal().cache(); public final OsmandPreference LAST_CHECKED_UPDATES = - new LongPreference("last_checked_updates", 0).makeGlobal(); + new LongPreference(this, "last_checked_updates", 0).makeGlobal(); public final OsmandPreference NUMBER_OF_APP_STARTS_ON_DISLIKE_MOMENT = - new IntPreference("number_of_app_starts_on_dislike_moment", 0).makeGlobal().cache(); + new IntPreference(this, "number_of_app_starts_on_dislike_moment", 0).makeGlobal().cache(); public final OsmandPreference RATE_US_STATE = - new EnumStringPreference<>("rate_us_state", RateUsState.INITIAL_STATE, RateUsState.values()).makeGlobal(); + new EnumStringPreference<>(this, "rate_us_state", RateUsState.INITIAL_STATE, RateUsState.values()).makeGlobal(); public final CommonPreference CUSTOM_APP_MODES_KEYS = - new StringPreference("custom_app_modes_keys", "").makeGlobal().cache(); + new StringPreference(this, "custom_app_modes_keys", "").makeGlobal().cache(); public Set getCustomAppModesKeys() { String appModesKeys = CUSTOM_APP_MODES_KEYS.get(); @@ -4189,158 +3004,4 @@ public class OsmandSettings { SLOPE } - private OsmandPreference[] generalPrefs = new OsmandPreference[]{ - EXTERNAL_INPUT_DEVICE, - CENTER_POSITION_ON_MAP, - ROTATE_MAP, - MAP_SCREEN_ORIENTATION, - LIVE_MONITORING_URL, - LIVE_MONITORING_MAX_INTERVAL_TO_SEND, - LIVE_MONITORING_INTERVAL, - LIVE_MONITORING, - SHOW_TRIP_REC_NOTIFICATION, - AUTO_SPLIT_RECORDING, - SAVE_TRACK_MIN_SPEED, - SAVE_TRACK_PRECISION, - SAVE_TRACK_MIN_DISTANCE, - SAVE_TRACK_INTERVAL, - TRACK_STORAGE_DIRECTORY, - SAVE_HEADING_TO_GPX, - DISABLE_RECORDING_ONCE_APP_KILLED, - SAVE_TRACK_TO_GPX, - SAVE_GLOBAL_TRACK_REMEMBER, - SAVE_GLOBAL_TRACK_INTERVAL, - MAP_EMPTY_STATE_ALLOWED, - DO_NOT_USE_ANIMATIONS, - USE_KALMAN_FILTER_FOR_COMPASS, - USE_MAGNETIC_FIELD_SENSOR_COMPASS, - USE_TRACKBALL_FOR_MOVEMENTS, - SPEED_SYSTEM, - ANGULAR_UNITS, - METRIC_SYSTEM, - DRIVING_REGION, - DRIVING_REGION_AUTOMATIC - }; - - String[] - appModeBeanPrefsIds = new String[] { - ICON_COLOR.getId(), - ICON_RES_NAME.getId(), - PARENT_APP_MODE.getId(), - ROUTING_PROFILE.getId(), - ROUTE_SERVICE.getId(), - USER_PROFILE_NAME.getId(), - LOCATION_ICON.getId(), - NAVIGATION_ICON.getId(), - APP_MODE_ORDER.getId() - }; - - public class PreferencesDataStore extends PreferenceDataStore { - - private ApplicationMode appMode; - - public PreferencesDataStore(@NonNull ApplicationMode appMode) { - this.appMode = appMode; - } - - @Override - public void putString(String key, @Nullable String value) { - setPreference(key, value, appMode); - } - - @Override - public void putStringSet(String key, @Nullable Set values) { - setPreference(key, values, appMode); - } - - @Override - public void putInt(String key, int value) { - setPreference(key, value, appMode); - } - - @Override - public void putLong(String key, long value) { - setPreference(key, value, appMode); - } - - @Override - public void putFloat(String key, float value) { - setPreference(key, value, appMode); - } - - @Override - public void putBoolean(String key, boolean value) { - setPreference(key, value, appMode); - } - - public void putValue(String key, Object value) { - setPreference(key, value, appMode); - } - - @Nullable - @Override - public String getString(String key, @Nullable String defValue) { - OsmandPreference preference = getPreference(key); - if (preference instanceof StringPreference) { - return ((StringPreference) preference).getModeValue(appMode); - } else { - Object value = preference.getModeValue(appMode); - if (value != null) { - return value.toString(); - } - } - return defValue; - } - - @Nullable - @Override - public Set getStringSet(String key, @Nullable Set defValues) { - return super.getStringSet(key, defValues); - } - - @Override - public int getInt(String key, int defValue) { - OsmandPreference preference = getPreference(key); - if (preference instanceof IntPreference) { - return ((IntPreference) preference).getModeValue(appMode); - } - return defValue; - } - - @Override - public long getLong(String key, long defValue) { - OsmandPreference preference = getPreference(key); - if (preference instanceof LongPreference) { - return ((LongPreference) preference).getModeValue(appMode); - } - return defValue; - } - - @Override - public float getFloat(String key, float defValue) { - OsmandPreference preference = getPreference(key); - if (preference instanceof FloatPreference) { - return ((FloatPreference) preference).getModeValue(appMode); - } - return defValue; - } - - @Override - public boolean getBoolean(String key, boolean defValue) { - OsmandPreference preference = getPreference(key); - if (preference instanceof BooleanPreference) { - return ((BooleanPreference) preference).getModeValue(appMode); - } - return defValue; - } - - @Nullable - public Object getValue(String key, Object defValue) { - OsmandPreference preference = getPreference(key); - if (preference != null) { - return preference.getModeValue(appMode); - } - return defValue; - } - } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/PreferenceWithListener.java b/OsmAnd/src/net/osmand/plus/settings/backend/PreferenceWithListener.java new file mode 100644 index 0000000000..082febfe90 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/PreferenceWithListener.java @@ -0,0 +1,49 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.StateChangedListener; + +import java.lang.ref.WeakReference; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +abstract class PreferenceWithListener implements OsmandPreference { + private List>> l = null; + + @Override + public synchronized void addListener(StateChangedListener listener) { + if (l == null) { + l = new LinkedList>>(); + } + if (!l.contains(new WeakReference>(listener))) { + l.add(new WeakReference>(listener)); + } + } + + public synchronized void fireEvent(T value) { + if (l != null) { + Iterator>> it = l.iterator(); + while (it.hasNext()) { + StateChangedListener t = it.next().get(); + if (t == null) { + it.remove(); + } else { + t.stateChanged(value); + } + } + } + } + + @Override + public synchronized void removeListener(StateChangedListener listener) { + if (l != null) { + Iterator>> it = l.iterator(); + while (it.hasNext()) { + StateChangedListener t = it.next().get(); + if (t == listener) { + it.remove(); + } + } + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java index 6c053f9c08..50ee1c028e 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java @@ -30,7 +30,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.poi.PoiUIFilter; @@ -907,6 +906,19 @@ public class SettingsHelper { } } + String[] + appModeBeanPrefsIds = new String[] { + ICON_COLOR.getId(), + ICON_RES_NAME.getId(), + PARENT_APP_MODE.getId(), + ROUTING_PROFILE.getId(), + ROUTE_SERVICE.getId(), + USER_PROFILE_NAME.getId(), + LOCATION_ICON.getId(), + NAVIGATION_ICON.getId(), + APP_MODE_ORDER.getId() + }; + public static class ProfileSettingsItem extends OsmandSettingsItem { private ApplicationMode appMode; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java new file mode 100644 index 0000000000..cdb923ed23 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java @@ -0,0 +1,141 @@ +package net.osmand.plus.settings.backend; + +import net.osmand.data.LatLon; +import net.osmand.data.PointDescription; +import net.osmand.plus.helpers.SearchHistoryHelper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; + +abstract class SettingsMapPointsStorage { + + private OsmandSettings osmandSettings; + protected String pointsKey; + protected String descriptionsKey; + + public SettingsMapPointsStorage(OsmandSettings osmandSettings) { + this.osmandSettings = osmandSettings; + } + + public List getPointDescriptions(int sz) { + List list = new ArrayList<>(); + String ip = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, descriptionsKey, ""); + if (ip.trim().length() > 0) { + list.addAll(Arrays.asList(ip.split("--"))); + } + while (list.size() > sz) { + list.remove(list.size() - 1); + } + while (list.size() < sz) { + list.add(""); + } + return list; + } + + public List getPoints() { + List list = new ArrayList<>(); + String ip = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, pointsKey, ""); + if (ip.trim().length() > 0) { + StringTokenizer tok = new StringTokenizer(ip, ","); + while (tok.hasMoreTokens()) { + String lat = tok.nextToken(); + if (!tok.hasMoreTokens()) { + break; + } + String lon = tok.nextToken(); + list.add(new LatLon(Float.parseFloat(lat), Float.parseFloat(lon))); + } + } + return list; + } + + public boolean insertPoint(double latitude, double longitude, PointDescription historyDescription, int index) { + List ps = getPoints(); + List ds = getPointDescriptions(ps.size()); + ps.add(index, new LatLon(latitude, longitude)); + ds.add(index, PointDescription.serializeToString(historyDescription)); + if (historyDescription != null && !historyDescription.isSearchingAddress(osmandSettings.ctx)) { + SearchHistoryHelper.getInstance(osmandSettings.ctx).addNewItemToHistory(latitude, longitude, historyDescription); + } + return savePoints(ps, ds); + } + + public boolean updatePoint(double latitude, double longitude, PointDescription historyDescription) { + List ps = getPoints(); + List ds = getPointDescriptions(ps.size()); + int i = ps.indexOf(new LatLon(latitude, longitude)); + if (i != -1) { + ds.set(i, PointDescription.serializeToString(historyDescription)); + if (historyDescription != null && !historyDescription.isSearchingAddress(osmandSettings.ctx)) { + SearchHistoryHelper.getInstance(osmandSettings.ctx).addNewItemToHistory(latitude, longitude, historyDescription); + } + return savePoints(ps, ds); + } else { + return false; + } + } + + public boolean deletePoint(int index) { + List ps = getPoints(); + List ds = getPointDescriptions(ps.size()); + if (index < ps.size()) { + ps.remove(index); + ds.remove(index); + return savePoints(ps, ds); + } else { + return false; + } + } + + public boolean deletePoint(LatLon latLon) { + List ps = getPoints(); + List ds = getPointDescriptions(ps.size()); + int index = ps.indexOf(latLon); + if (index != -1) { + ps.remove(index); + ds.remove(index); + return savePoints(ps, ds); + } else { + return false; + } + } + + public boolean savePoints(List ps, List ds) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ps.size(); i++) { + if (i > 0) { + sb.append(","); + } + sb.append(((float) ps.get(i).getLatitude() + "")).append(",").append(((float) ps.get(i).getLongitude() + "")); + } + StringBuilder tb = new StringBuilder(); + for (int i = 0; i < ds.size(); i++) { + if (i > 0) { + tb.append("--"); + } + if (ds.get(i) == null) { + tb.append(""); + } else { + tb.append(ds.get(i)); + } + } + return osmandSettings.settingsAPI.edit(osmandSettings.globalPreferences) + .putString(pointsKey, sb.toString()) + .putString(descriptionsKey, tb.toString()) + .commit(); + } + + public boolean movePoint(LatLon latLonEx, LatLon latLonNew) { + List ps = getPoints(); + List ds = getPointDescriptions(ps.size()); + int i = ps.indexOf(latLonEx); + if (i != -1) { + ps.set(i, latLonNew); + return savePoints(ps, ds); + } else { + return false; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java new file mode 100644 index 0000000000..3ee07b43bd --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java @@ -0,0 +1,26 @@ +package net.osmand.plus.settings.backend; + +public class StringPreference extends CommonPreference { + + private OsmandSettings osmandSettings; + + StringPreference(OsmandSettings osmandSettings, String id, String defaultValue) { + super(id, defaultValue); + this.osmandSettings = osmandSettings; + } + + @Override + protected String getValue(Object prefs, String defaultValue) { + return osmandSettings.settingsAPI.getString(prefs, getId(), defaultValue); + } + + @Override + protected boolean setValue(Object prefs, String val) { + return osmandSettings.settingsAPI.edit(prefs).putString(getId(), (val != null) ? val.trim() : val).commit(); + } + + @Override + public String parseString(String s) { + return s; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index a68867e4c0..6b73dd69f0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -16,9 +16,8 @@ import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.BooleanPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.BooleanPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; @@ -57,7 +56,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { String title = switchPreference.getTitle().toString(); items.add(new TitleItem(title)); - final OsmandSettings.BooleanPreference pref = (BooleanPreference) preference; + final BooleanPreference pref = (BooleanPreference) preference; CharSequence summaryOn = switchPreference.getSummaryOn(); CharSequence summaryOff = switchPreference.getSummaryOff(); final String on = summaryOn == null || summaryOn.toString().equals("") diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java index d016a7fee5..2888603681 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java @@ -17,6 +17,7 @@ import net.osmand.AndroidUtils; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -43,7 +44,7 @@ public class RecalculateRouteInDeviationBottomSheet extends BooleanPreferenceBot private OsmandApplication app; private OsmandSettings settings; private ApplicationMode appMode; - private OsmandSettings.CommonPreference preference; + private CommonPreference preference; private Slider slider; private TextView tvSliderTitle; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java index 1148f23720..3162064aaa 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java @@ -54,8 +54,9 @@ import net.osmand.PlatformUtil; import net.osmand.access.AccessibilitySettingsFragment; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -833,11 +834,11 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl return icon; } - public SwitchPreferenceCompat createSwitchPreference(OsmandSettings.OsmandPreference b, int title, int summary, int layoutId) { + public SwitchPreferenceCompat createSwitchPreference(OsmandPreference b, int title, int summary, int layoutId) { return createSwitchPreference(b, getString(title), getString(summary), layoutId); } - public SwitchPreferenceCompat createSwitchPreference(OsmandSettings.OsmandPreference b, String title, String summary, int layoutId) { + public SwitchPreferenceCompat createSwitchPreference(OsmandPreference b, String title, String summary, int layoutId) { SwitchPreferenceCompat p = new SwitchPreferenceCompat(getContext()); p.setTitle(title); p.setKey(b.getId()); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java index c668564a6d..302b7f5a39 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java @@ -28,7 +28,9 @@ import net.osmand.plus.ApplicationMode; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.ContextMenuItemsPreference; +import net.osmand.plus.settings.backend.ContextMenuItemsSettings; +import net.osmand.plus.settings.backend.MainContextMenuItemsSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -163,9 +165,9 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment private void initMainActionsIds(ApplicationMode appMode) { List defItems = getCustomizableDefaultItems(contextMenuAdapter.getDefaultItems()); - OsmandSettings.ContextMenuItemsSettings pref = getSettingForScreen(app, screenType).getModeValue(appMode); - if (pref instanceof OsmandSettings.MainContextMenuItemsSettings) { - mainActionItems = new ArrayList<>(((OsmandSettings.MainContextMenuItemsSettings) pref).getMainIds()); + ContextMenuItemsSettings pref = getSettingForScreen(app, screenType).getModeValue(appMode); + if (pref instanceof MainContextMenuItemsSettings) { + mainActionItems = new ArrayList<>(((MainContextMenuItemsSettings) pref).getMainIds()); if (mainActionItems.isEmpty()) { for (int i = 0; i < MAIN_BUTTONS_QUANTITY; i++) { mainActionItems.add(defItems.get(i).getId()); @@ -255,11 +257,11 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment } } FragmentManager fm = getFragmentManager(); - final OsmandSettings.ContextMenuItemsSettings prefToSave; + final ContextMenuItemsSettings prefToSave; if (screenType == ScreenType.CONTEXT_MENU_ACTIONS) { - prefToSave = new OsmandSettings.MainContextMenuItemsSettings(mainActionItems, hiddenMenuItems, ids); + prefToSave = new MainContextMenuItemsSettings(mainActionItems, hiddenMenuItems, ids); } else { - prefToSave = new OsmandSettings.ContextMenuItemsSettings(hiddenMenuItems, ids); + prefToSave = new ContextMenuItemsSettings(hiddenMenuItems, ids); } if (fm != null) { ChangeGeneralProfilesPrefBottomSheet.showInstance(fm, @@ -523,7 +525,7 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment } } - public static OsmandSettings.ContextMenuItemsPreference getSettingForScreen(OsmandApplication app, ScreenType screenType) throws IllegalArgumentException { + public static ContextMenuItemsPreference getSettingForScreen(OsmandApplication app, ScreenType screenType) throws IllegalArgumentException { switch (screenType) { case DRAWER: return app.getSettings().DRAWER_ITEMS; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java index 10cfd2adcc..d15e0f644f 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java @@ -25,8 +25,9 @@ import net.osmand.StateChangedListener; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.BooleanPreference; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandPreference; +import net.osmand.plus.settings.backend.BooleanPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.SettingsBaseActivity; @@ -218,7 +219,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP String description = SettingsBaseActivity.getRoutingStringPropertyDescription(app, p.getId(), p.getDescription()); if (p.getType() == RoutingParameterType.BOOLEAN) { - OsmandSettings.OsmandPreference pref = settings.getCustomRoutingBooleanProperty(p.getId(), p.getDefaultBoolean()); + OsmandPreference pref = settings.getCustomRoutingBooleanProperty(p.getId(), p.getDefaultBoolean()); SwitchPreferenceEx switchPreferenceEx = (SwitchPreferenceEx) createSwitchPreferenceEx(pref.getId(), title, description, R.layout.preference_with_descr_dialog_and_switch); switchPreferenceEx.setDescription(description); @@ -234,7 +235,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP for (Object o : vls) { svlss[i++] = o.toString(); } - OsmandSettings.OsmandPreference pref = settings.getCustomRoutingProperty(p.getId(), p.getType() == RoutingParameterType.NUMERIC ? "0.0" : "-"); + OsmandPreference pref = settings.getCustomRoutingProperty(p.getId(), p.getType() == RoutingParameterType.NUMERIC ? "0.0" : "-"); ListPreferenceEx listPreferenceEx = (ListPreferenceEx) createListPreferenceEx(pref.getId(), p.getPossibleValueDescriptions(), svlss, title, R.layout.preference_with_descr); listPreferenceEx.setDescription(description); @@ -381,10 +382,10 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP for (RoutingParameter parameter : otherRoutingParameters) { if (parameter.getType() == RoutingParameterType.BOOLEAN) { - OsmandSettings.CommonPreference pref = settings.getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); + CommonPreference pref = settings.getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); pref.addListener(booleanRoutingPrefListener); } else { - OsmandSettings.CommonPreference pref = settings.getCustomRoutingProperty(parameter.getId(), parameter.getType() == RoutingParameterType.NUMERIC ? "0.0" : "-"); + CommonPreference pref = settings.getCustomRoutingProperty(parameter.getId(), parameter.getType() == RoutingParameterType.NUMERIC ? "0.0" : "-"); pref.addListener(customRoutingPrefListener); } } @@ -396,10 +397,10 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP for (RoutingParameter parameter : otherRoutingParameters) { if (parameter.getType() == RoutingParameterType.BOOLEAN) { - OsmandSettings.CommonPreference pref = settings.getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); + CommonPreference pref = settings.getCustomRoutingBooleanProperty(parameter.getId(), parameter.getDefaultBoolean()); pref.removeListener(booleanRoutingPrefListener); } else { - OsmandSettings.CommonPreference pref = settings.getCustomRoutingProperty(parameter.getId(), parameter.getType() == RoutingParameterType.NUMERIC ? "0.0" : "-"); + CommonPreference pref = settings.getCustomRoutingProperty(parameter.getId(), parameter.getType() == RoutingParameterType.NUMERIC ? "0.0" : "-"); pref.removeListener(customRoutingPrefListener); } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java index b38fffa8e1..9a8c8dcd3d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java @@ -9,11 +9,11 @@ import androidx.preference.PreferenceViewHolder; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.settings.backend.StringPreference; import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.router.GeneralRouter; @@ -77,7 +77,7 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O String description = SettingsBaseActivity.getRoutingStringPropertyDescription(app, parameterId, parameter.getDescription()); String defValue = parameter.getType() == GeneralRouter.RoutingParameterType.NUMERIC ? ROUTING_PARAMETER_NUMERIC_DEFAULT : ROUTING_PARAMETER_SYMBOLIC_DEFAULT; - OsmandSettings.StringPreference pref = (OsmandSettings.StringPreference) app.getSettings().getCustomRoutingProperty(parameterId, defValue); + StringPreference pref = (StringPreference) app.getSettings().getCustomRoutingProperty(parameterId, defValue); Object[] values = parameter.getPossibleValues(); String[] valuesStr = new String[values.length]; diff --git a/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java b/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java index e6bdd34f07..60511eadb4 100644 --- a/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java +++ b/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java @@ -8,7 +8,7 @@ import androidx.preference.DialogPreference; import androidx.preference.PreferenceDataStore; import net.osmand.plus.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings.PreferencesDataStore; +import net.osmand.plus.settings.backend.OsmAndPreferencesDataStore; public class ListPreferenceEx extends DialogPreference { @@ -126,8 +126,8 @@ public class ListPreferenceEx extends DialogPreference { private Object getPersistedValue(Object defaultValue) { PreferenceDataStore dataStore = getPreferenceDataStore(); - if (dataStore instanceof PreferencesDataStore) { - Object value = ((PreferencesDataStore) dataStore).getValue(getKey(), defaultValue); + if (dataStore instanceof OsmAndPreferencesDataStore) { + Object value = ((OsmAndPreferencesDataStore) dataStore).getValue(getKey(), defaultValue); if (value instanceof Enum) { return ((Enum) value).ordinal(); } else if (value instanceof ApplicationMode) { @@ -144,8 +144,8 @@ public class ListPreferenceEx extends DialogPreference { return; } PreferenceDataStore dataStore = getPreferenceDataStore(); - if (dataStore instanceof PreferencesDataStore) { - ((PreferencesDataStore) dataStore).putValue(getKey(), value); + if (dataStore instanceof OsmAndPreferencesDataStore) { + ((OsmAndPreferencesDataStore) dataStore).putValue(getKey(), value); } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/preferences/MultiSelectBooleanPreference.java b/OsmAnd/src/net/osmand/plus/settings/preferences/MultiSelectBooleanPreference.java index 896e1864d1..1f69cd0989 100644 --- a/OsmAnd/src/net/osmand/plus/settings/preferences/MultiSelectBooleanPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/preferences/MultiSelectBooleanPreference.java @@ -6,7 +6,7 @@ import android.util.AttributeSet; import androidx.preference.MultiSelectListPreference; import androidx.preference.PreferenceDataStore; -import net.osmand.plus.settings.backend.OsmandSettings.PreferencesDataStore; +import net.osmand.plus.settings.backend.OsmAndPreferencesDataStore; import java.util.HashSet; import java.util.Set; @@ -79,8 +79,8 @@ public class MultiSelectBooleanPreference extends MultiSelectListPreference { return; } PreferenceDataStore dataStore = getPreferenceDataStore(); - if (dataStore instanceof PreferencesDataStore) { - PreferencesDataStore preferencesDataStore = (PreferencesDataStore) dataStore; + if (dataStore instanceof OsmAndPreferencesDataStore) { + OsmAndPreferencesDataStore preferencesDataStore = (OsmAndPreferencesDataStore) dataStore; for (String prefId : getPrefsIds()) { preferencesDataStore.putBoolean(prefId, getValues().contains(prefId)); @@ -96,8 +96,8 @@ public class MultiSelectBooleanPreference extends MultiSelectListPreference { Set enabledPrefs = new HashSet<>(); PreferenceDataStore dataStore = getPreferenceDataStore(); - if (dataStore instanceof PreferencesDataStore && getEntryValues() != null) { - PreferencesDataStore preferencesDataStore = (PreferencesDataStore) dataStore; + if (dataStore instanceof OsmAndPreferencesDataStore && getEntryValues() != null) { + OsmAndPreferencesDataStore preferencesDataStore = (OsmAndPreferencesDataStore) dataStore; for (String prefId : getPrefsIds()) { boolean enabled = preferencesDataStore.getBoolean(prefId, false); diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesAction.java b/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesAction.java index 9c4ae901f7..bcbd80ff92 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesAction.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesAction.java @@ -8,7 +8,7 @@ import android.widget.TextView; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.quickaction.QuickAction; @@ -46,7 +46,7 @@ public class ContourLinesAction extends QuickAction { OsmandApplication app = activity.getMyApplication(); RenderingRuleProperty contourLinesProp = app.getRendererRegistry().getCustomRenderingRuleProperty(CONTOUR_LINES_ATTR); if (contourLinesProp != null) { - final OsmandSettings.CommonPreference pref = app.getSettings().getCustomRenderProperty(contourLinesProp.getAttrName()); + final CommonPreference pref = app.getSettings().getCustomRenderProperty(contourLinesProp.getAttrName()); boolean selected = !pref.get().equals(CONTOUR_LINES_DISABLED_VALUE); if (selected && !plugin.isActive() && !plugin.needsInstallation()) { diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java b/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java index 94a33cf6a8..be2631dc04 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java @@ -7,6 +7,7 @@ import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -61,8 +62,8 @@ public class ContourLinesMenu { final String contourWidthName; final String contourDensityName; - final OsmandSettings.CommonPreference widthPref; - final OsmandSettings.CommonPreference densityPref; + final CommonPreference widthPref; + final CommonPreference densityPref; final RenderingRuleProperty contourWidthProp = app.getRendererRegistry().getCustomRenderingRuleProperty(CONTOUR_WIDTH_ATTR); if (contourWidthProp != null) { contourWidthName = SettingsActivity.getStringPropertyName(app, contourWidthProp.getAttrName(), @@ -82,8 +83,8 @@ public class ContourLinesMenu { densityPref = null; } - final OsmandSettings.CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); - final OsmandSettings.CommonPreference colorPref = settings.getCustomRenderProperty(colorSchemeProp.getAttrName()); + final CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); + final CommonPreference colorPref = settings.getCustomRenderProperty(colorSchemeProp.getAttrName()); final boolean selected = !pref.get().equals(CONTOUR_LINES_DISABLED_VALUE); final int toggleActionStringId = selected ? R.string.shared_string_on : R.string.shared_string_off; diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index 00ce824d6e..715d86443c 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -22,7 +22,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.TerrainMode; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SettingsActivity; @@ -234,7 +234,7 @@ public class SRTMPlugin extends OsmandPlugin { RenderingRuleProperty contourLinesProp = app.getRendererRegistry().getCustomRenderingRuleProperty(CONTOUR_LINES_ATTR); if (contourLinesProp != null) { - final OsmandSettings.CommonPreference pref = app.getSettings().getCustomRenderProperty(contourLinesProp.getAttrName()); + final CommonPreference pref = app.getSettings().getCustomRenderProperty(contourLinesProp.getAttrName()); if (!Algorithms.isEmpty(pref.get())) { contourLinesEnabled = !pref.get().equals(CONTOUR_LINES_DISABLED_VALUE); } else { @@ -291,7 +291,7 @@ public class SRTMPlugin extends OsmandPlugin { public void run() { RenderingRuleProperty contourLinesProp = app.getRendererRegistry().getCustomRenderingRuleProperty(CONTOUR_LINES_ATTR); if (contourLinesProp != null) { - final OsmandSettings.CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); + final CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); boolean selected = !pref.get().equals(CONTOUR_LINES_DISABLED_VALUE); SRTMPlugin plugin = OsmandPlugin.getPlugin(SRTMPlugin.class); @@ -338,7 +338,7 @@ public class SRTMPlugin extends OsmandPlugin { RenderingRuleProperty contourLinesProp = app.getRendererRegistry().getCustomRenderingRuleProperty(CONTOUR_LINES_ATTR); if (contourLinesProp != null) { - final OsmandSettings.CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); + final CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); boolean contourLinesSelected = isContourLinesLayerEnabled(app); String descr = getPrefDescription(app, contourLinesProp, pref); adapter.addItem(new ContextMenuItem.ItemBuilder() @@ -407,7 +407,7 @@ public class SRTMPlugin extends OsmandPlugin { final Runnable callback) { RenderingRuleProperty contourLinesProp = app.getRendererRegistry().getCustomRenderingRuleProperty(CONTOUR_LINES_ATTR); if (contourLinesProp != null) { - final OsmandSettings.CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); + final CommonPreference pref = settings.getCustomRenderProperty(contourLinesProp.getAttrName()); CommonPreference zoomSetting = settings.CONTOUR_LINES_ZOOM; if (!isChecked) { zoomSetting.set(pref.get()); @@ -435,7 +435,7 @@ public class SRTMPlugin extends OsmandPlugin { } } - public String getPrefDescription(final Context ctx, final RenderingRuleProperty p, final OsmandSettings.CommonPreference pref) { + public String getPrefDescription(final Context ctx, final RenderingRuleProperty p, final CommonPreference pref) { if (!Algorithms.isEmpty(pref.get())) { return SettingsActivity.getStringPropertyValue(ctx, pref.get()); } else { @@ -445,7 +445,7 @@ public class SRTMPlugin extends OsmandPlugin { public void selectPropertyValue(final MapActivity activity, final RenderingRuleProperty p, - final OsmandSettings.CommonPreference pref, + final CommonPreference pref, final Runnable callback) { final String propertyDescr = SettingsActivity.getStringPropertyDescription(activity, p.getAttrName(), p.getName()); diff --git a/OsmAnd/src/net/osmand/plus/transport/TransportLinesMenu.java b/OsmAnd/src/net/osmand/plus/transport/TransportLinesMenu.java index 76d3969e1d..4d304979ac 100644 --- a/OsmAnd/src/net/osmand/plus/transport/TransportLinesMenu.java +++ b/OsmAnd/src/net/osmand/plus/transport/TransportLinesMenu.java @@ -20,7 +20,7 @@ import net.osmand.CallbackWithObject; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/views/AidlMapLayer.java b/OsmAnd/src/net/osmand/plus/views/AidlMapLayer.java index 58a38d40b0..b0ccde211a 100644 --- a/OsmAnd/src/net/osmand/plus/views/AidlMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/AidlMapLayer.java @@ -24,7 +24,7 @@ import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.RotatedTileBox; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MapContextMenu; diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index cb9dfbf04b..0431e3a4cf 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -41,7 +41,7 @@ import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarkersGroup; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.base.FavoriteImageDrawable; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu.TrackChartPoints; diff --git a/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java index f6643e7902..84c0af503f 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java @@ -43,8 +43,9 @@ import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; @@ -1225,7 +1226,7 @@ public class MapControlsLayer extends OsmandMapLayer { @Override public boolean onLongClick(View notUseCouldBeNull) { - final OsmandSettings.OsmandPreference mapDensity = view.getSettings().MAP_DENSITY; + final OsmandPreference mapDensity = view.getSettings().MAP_DENSITY; final AlertDialog.Builder bld = new AlertDialog.Builder(view.getContext()); int p = (int) (mapDensity.get() * 100); final TIntArrayList tlist = new TIntArrayList(new int[]{25, 33, 50, 75, 100, 125, 150, 200, 300, 400}); diff --git a/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java b/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java index 43131febe2..f733cc972b 100644 --- a/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RulerControlLayer.java @@ -29,6 +29,7 @@ import net.osmand.data.QuadPoint; import net.osmand.data.RotatedTileBox; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.AngularConstants; import net.osmand.plus.settings.backend.OsmandSettings.RulerMode; @@ -67,7 +68,7 @@ public class RulerControlLayer extends OsmandMapLayer { private QuadPoint cacheCenter; private float cacheMapDensity; - private OsmandSettings.OsmandPreference mapDensity; + private OsmandPreference mapDensity; private OsmandSettings.MetricsConstants cacheMetricSystem; private int cacheIntZoom; private LatLon cacheCenterLatLon; diff --git a/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java b/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java index 4160328bcd..a5ba754002 100644 --- a/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java @@ -25,6 +25,7 @@ import net.osmand.data.RotatedTileBox; import net.osmand.data.TransportStop; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.Way; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -60,7 +61,7 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa private MapLayerData> data; private TransportStopRoute stopRoute = null; - private OsmandSettings.CommonPreference showTransportStops; + private CommonPreference showTransportStops; private Path path; private float backgroundIconHalfWidth; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index 61fffdb814..6350e957ac 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -48,6 +48,7 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndLocationProvider.GPSInfo; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.RulerMode; import net.osmand.plus.R; @@ -167,7 +168,7 @@ public class MapInfoWidgetsFactory { public static final int COMPASS_CONTROL_WIDGET_STATE_SHOW = R.id.compass_ruler_control_widget_state_show; public static final int COMPASS_CONTROL_WIDGET_STATE_HIDE = R.id.compass_ruler_control_widget_state_hide; - private final OsmandSettings.OsmandPreference showCompass; + private final OsmandPreference showCompass; public CompassRulerControlWidgetState(OsmandApplication ctx) { super(ctx); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java index e5fa0daca8..0e91dcfe6c 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java @@ -17,7 +17,7 @@ import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java index aa9a8d09cc..5eb78bd2b4 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java @@ -35,7 +35,7 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; @@ -1178,7 +1178,7 @@ public class RouteInfoWidgetsFactory { private String cacheRulerText; private int maxWidth; private float cacheMapDensity; - private OsmandSettings.OsmandPreference mapDensity; + private OsmandPreference mapDensity; private int cacheRulerZoom; private double cacheRulerTileX; private double cacheRulerTileY; diff --git a/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java b/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java index f3c9734a82..368dc2dc4a 100644 --- a/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java +++ b/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java @@ -8,7 +8,7 @@ import android.os.Build; import net.osmand.PlatformUtil; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.routing.VoiceRouter; import org.apache.commons.logging.Log; @@ -91,7 +91,7 @@ public class MediaCommandPlayerImpl extends AbstractPrologCommandPlayer implemen // Delay first prompt of each batch to allow BT SCO link being established, or when VOICE_PROMPT_DELAY is set >0 for the other stream types if (ctx != null) { Integer stream = ctx.getSettings().AUDIO_MANAGER_STREAM.getModeValue(getApplicationMode()); - OsmandSettings.OsmandPreference pref = ctx.getSettings().VOICE_PROMPT_DELAY[stream]; + OsmandPreference pref = ctx.getSettings().VOICE_PROMPT_DELAY[stream]; if (pref.getModeValue(getApplicationMode()) > 0) { try { Thread.sleep(pref.getModeValue(getApplicationMode())); diff --git a/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java b/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java index 4c2559dbf3..2e3340d859 100644 --- a/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java +++ b/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java @@ -17,7 +17,7 @@ import androidx.appcompat.app.AlertDialog; import net.osmand.PlatformUtil; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.routing.VoiceRouter; @@ -127,7 +127,7 @@ public class TTSCommandPlayerImpl extends AbstractPrologCommandPlayer { // Delay first prompt of each batch to allow BT SCO link being established, or when VOICE_PROMPT_DELAY is set >0 for the other stream types if (ctx != null) { Integer streamModeValue = ctx.getSettings().AUDIO_MANAGER_STREAM.getModeValue(getApplicationMode()); - OsmandSettings.OsmandPreference pref = ctx.getSettings().VOICE_PROMPT_DELAY[streamModeValue]; + OsmandPreference pref = ctx.getSettings().VOICE_PROMPT_DELAY[streamModeValue]; int vpd = pref == null ? 0 : pref.getModeValue(getApplicationMode()); if (vpd > 0) { ttsRequests++; diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java index 41edcb0a02..f05bb9273f 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java @@ -9,7 +9,7 @@ import androidx.appcompat.widget.PopupMenu; import androidx.fragment.app.Fragment; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings.WikiArticleShowImages; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; @@ -28,7 +28,7 @@ public class WikipediaOptionsBottomSheetDialogFragment extends MenuBottomSheetDi @Override public void createMenuItems(Bundle savedInstanceState) { final OsmandApplication app = getMyApplication(); - final OsmandSettings.CommonPreference showImagesPref = app.getSettings().WIKI_ARTICLE_SHOW_IMAGES; + final CommonPreference showImagesPref = app.getSettings().WIKI_ARTICLE_SHOW_IMAGES; items.add(new TitleItem(getString(R.string.shared_string_options))); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java index 3b67249cf7..ea09a79314 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java @@ -15,7 +15,7 @@ import androidx.appcompat.widget.PopupMenu; import net.osmand.PicassoUtils; import net.osmand.plus.OnDialogFragmentResultListener; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings.WikiArticleShowImages; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; @@ -44,7 +44,7 @@ public class WikivoyageOptionsBottomSheetDialogFragment extends MenuBottomSheetD if (app == null) { return; } - final OsmandSettings.CommonPreference showImagesPref = app.getSettings().WIKI_ARTICLE_SHOW_IMAGES; + final CommonPreference showImagesPref = app.getSettings().WIKI_ARTICLE_SHOW_IMAGES; final TravelDbHelper dbHelper = app.getTravelDbHelper(); items.add(new TitleItem(getString(R.string.shared_string_options))); From c8ed464125104a7f5e1f06f20d1d730aa85bda25 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 19 May 2020 15:26:29 +0200 Subject: [PATCH 0002/1366] Add todos --- .../src/net/osmand/plus/settings/backend/OsmandSettings.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 93705e3c69..523caf7866 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -186,10 +186,12 @@ public class OsmandSettings { + // TODO doesn't look correct package visibility public Object getProfilePreferences(ApplicationMode mode) { return settingsAPI.getPreferenceObject(getSharedPreferencesName(mode)); } + // TODO doesn't look correct package visibility public Object getProfilePreferences(String modeKey) { return settingsAPI.getPreferenceObject(getSharedPreferencesNameForKey(modeKey)); } @@ -198,16 +200,19 @@ public class OsmandSettings { return registeredPreferences.get(key); } + // TODO doesn't look correct public void setPreferenceForAllModes(String key, Object value) { for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { setPreference(key, value, mode); } } + // TODO doesn't look correct public boolean setPreference(String key, Object value) { return setPreference(key, value, APPLICATION_MODE.get()); } + // TODO doesn't look correct @SuppressWarnings("unchecked") public boolean setPreference(String key, Object value, ApplicationMode mode) { OsmandPreference preference = registeredPreferences.get(key); From e2fb0992b7baa431ddaec2c684164bf7ee4799dc Mon Sep 17 00:00:00 2001 From: sonora Date: Mon, 8 Jun 2020 22:03:46 +0200 Subject: [PATCH 0003/1366] disable debug libraries --- OsmAnd/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 6bebf5f67b..fab8755326 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -217,6 +217,9 @@ android { buildTypes { debug { signingConfig signingConfigs.development + debuggable false + jniDebuggable false + buildConfigField "boolean", "USE_DEBUG_LIBRARIES", "false" } release { signingConfig signingConfigs.publishing From 1dc34d28aaa8d1b4f32fa93e2e2c6678a0ece841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sat, 22 Aug 2020 22:03:10 +0200 Subject: [PATCH 0004/1366] New strings reworked --- OsmAnd/res/values/strings.xml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a1195b8a20..44c8fca222 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -24,11 +24,11 @@ Point of the track to navigate Navigate from my location to the track Select another track - Choose track file to follow or import it from device. + Choose track file to follow or import it from your device. Choose track file to follow Follow track Save as track file - Trip recoridng + Trip recording Add track waypoint Add track waypoint Import or record track files @@ -42,22 +42,22 @@ Add to a track file Save as new track file In case of reverse direction - Are you sure you want to close Plan route without saving? You will lose all changes. + Are you sure you want discard all changes in the planned route by closing it? Street-level imagery - Select a track file for which a new segment will be added. + Select a track file to add the new segment to. Navigation profile Threshold distance - To use this option OsmAnd need to snap your track to the map roads. \n\n On the next step you will need to select navigation profile to detect allowed roads and threshold distance to approximate you track with roads. + Next, snap your track to the nearest allowed road with one of your navigation profiles to use this option. Next segment Whole track Select how to connect points, with a straight line, or calculate a route between them with selected profile. - Only next segment will be recalculated using selected profile. - Whole track will be recalculated using selected profile. + Only the next segment will be recalculated using selected profile. + The whole track will be recalculated using the selected profile. Reverse route - Save as new Track + Save as new track Overwrite track Done - Select a track file for open. + Select a track file to open. Create new route Open existing track Import track @@ -68,29 +68,29 @@ Select the desired splitting option: by time or by distance. Select the interval at which marks with distance or time on the track will be displayed. Select width - Show start finish icons - Add to a Track + Show start and finish icons + Add to a track Plan a route Route between points - You need to set working days to continue - Closed OSM Note + Set working days to continue + Closed OSM note Go-cart Wheelchair forward Wheelchair Motor scooter Enduro motorcycle The added point will not be visible on the map, since the selected group is hidden, you can find it in \"%s\". - Get information about points of interest from Wikipedia. It is your pocket offline guide - just enable Wikipedia plugin and enjoy articles about objects around you. + Get info about points of interest from Wikipedia. It is your pocket offline guide - just turn on the Wikipedia plugin and enjoy articles about objects around you. Download Wikipedia maps The current destination point on the route will be deleted. If it will be the Destination, navigation will stop. Please provide a name for the point Volume buttons as zoom - Enable to control the map zoom level with device volume buttons. - Delete next destination point + Control the map-zoom level using the volume buttons on the device. + Delete nearest destination point Inline skates This device doesn\'t have speed cameras. Uninstall and Restart - Restart is needed to completely delete speed camera data. + Restart the app to delete all speed camera data. %1$s deleted Bearing Length limit From 053c4701ffadf02b7c4b822f4959e518fbe9afe0 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 1 Sep 2020 02:06:22 +0300 Subject: [PATCH 0005/1366] UI fixes first part --- OsmAnd/res/layout/track_appearance.xml | 2 +- OsmAnd/res/layout/track_width_card.xml | 3 +- .../plus/track/TrackAppearanceFragment.java | 48 +++++++++++-------- .../osmand/plus/track/TrackColoringCard.java | 1 + .../osmand/plus/views/layers/GPXLayer.java | 4 +- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/OsmAnd/res/layout/track_appearance.xml b/OsmAnd/res/layout/track_appearance.xml index 089e1f174d..0be92d2bb0 100644 --- a/OsmAnd/res/layout/track_appearance.xml +++ b/OsmAnd/res/layout/track_appearance.xml @@ -37,7 +37,7 @@ android:layout_height="wrap_content"> + android:orientation="vertical" + android:paddingBottom="@dimen/content_padding"> 0 && bottomContainer.getForeground() == null) { bottomContainer.setForeground(shadowIcon); } + updateButtonsShadow(); } }); } + private void updateButtonsShadow() { + boolean scrollToBottomAvailable = getBottomScrollView().canScrollVertically(1); + AndroidUiHelper.updateVisibility(buttonsShadow, scrollToBottomAvailable); + } + + private void updateColorItems() { + updateAppearanceIcon(); + if (trackWidthCard != null) { + trackWidthCard.updateItems(); + } + } + private void saveTrackInfo() { GPXFile gpxFile = selectedGpxFile.getGpxFile(); @@ -537,19 +559,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } private void saveGpx(final GPXFile gpxFile) { - new SaveGpxAsyncTask(gpxFile, new SaveGpxAsyncTask.SaveGpxListener() { - @Override - public void gpxSavingStarted() { - - } - - @Override - public void gpxSavingFinished(Exception errorMessage) { - if (errorMessage == null) { - app.showShortToastMessage(R.string.shared_string_track_is_saved, Algorithms.getFileWithoutDirs(gpxFile.path)); - } - } - }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new SaveGpxAsyncTask(gpxFile, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private void setupCards() { diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index ff21fa3f18..79a7107ca8 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -281,6 +281,7 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { public void onColorSelected(int prevColor, int newColor) { if (prevColor == INVALID_VALUE && customColors.size() < 6) { customColors.add(newColor); + trackDrawInfo.setColor(newColor); } else if (!Algorithms.isEmpty(customColors)) { int index = customColors.indexOf(prevColor); if (index != INVALID_VALUE) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 2f7cf6cb5f..59a249000a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -887,12 +887,12 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM @Override public boolean disableSingleTap() { - return false; + return isInTrackAppearanceMode(); } @Override public boolean disableLongPressOnMap() { - return false; + return isInTrackAppearanceMode(); } @Override From ee6e283d03ea0f8d5261ee1b4e9eb386ac6707a2 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 1 Sep 2020 12:38:53 +0300 Subject: [PATCH 0006/1366] Track appearance UI fixes second part --- OsmAnd/src/net/osmand/plus/UiUtilities.java | 8 +++++-- .../plus/track/CustomColorBottomSheet.java | 8 +++++-- .../plus/track/TrackAppearanceFragment.java | 22 +++++++++++++++++-- .../osmand/plus/track/TrackColoringCard.java | 15 +++++++++++-- .../osmand/plus/views/layers/GPXLayer.java | 12 ++++++---- 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 24ffd9c6f7..8dc59eccc9 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -230,8 +230,12 @@ public class UiUtilities { } @ColorInt - public static int mixTwoColors(@ColorInt int color1, @ColorInt int color2, float amount ) - { + public static int removeAlpha(@ColorInt int color) { + return Color.rgb(Color.red(color), Color.green(color), Color.blue(color)); + } + + @ColorInt + public static int mixTwoColors(@ColorInt int color1, @ColorInt int color2, float amount) { final byte ALPHA_CHANNEL = 24; final byte RED_CHANNEL = 16; final byte GREEN_CHANNEL = 8; diff --git a/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java b/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java index a5db15c147..dad9831f9c 100644 --- a/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java @@ -58,8 +58,12 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem } else { Bundle args = getArguments(); if (args != null) { - prevColor = args.getInt(PREV_SELECTED_COLOR); - newColor = prevColor != -1 ? prevColor : Color.RED; + if (args.containsKey(PREV_SELECTED_COLOR)) { + prevColor = args.getInt(PREV_SELECTED_COLOR); + } else { + prevColor = Color.RED; + } + newColor = prevColor; } } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index aa8a1ac395..c0d6b42741 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -390,13 +390,21 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement int strokeColor = UiUtilities.getColorWithAlpha(Color.BLACK, 0.7f); Drawable strokeIcon = app.getUIUtilities().getPaintedIcon(strokeIconId, strokeColor); + Drawable transparencyIcon = getTransparencyIcon(app, widthAttr, color); if (showArrows) { int arrowsIconId = getArrowsIconId(widthAttr); int contrastColor = UiUtilities.getContrastColor(app, color, false); Drawable arrows = app.getUIUtilities().getPaintedIcon(arrowsIconId, contrastColor); - return UiUtilities.getLayeredIcon(widthIcon, strokeIcon, arrows); + return UiUtilities.getLayeredIcon(transparencyIcon, widthIcon, strokeIcon, arrows); } - return UiUtilities.getLayeredIcon(widthIcon, strokeIcon); + return UiUtilities.getLayeredIcon(transparencyIcon, widthIcon, strokeIcon); + } + + private Drawable getTransparencyIcon(OsmandApplication app, String widthAttr, @ColorInt int color) { + int transparencyIconId = getTransparencyIconId(widthAttr); + int colorWithoutAlpha = UiUtilities.removeAlpha(color); + int transparencyColor = UiUtilities.getColorWithAlpha(colorWithoutAlpha, 0.8f); + return app.getUIUtilities().getPaintedIcon(transparencyIconId, transparencyColor); } private void updateCardsLayout() { @@ -638,6 +646,16 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } } + public static int getTransparencyIconId(String widthAttr) { + if (TRACK_WIDTH_BOLD.equals(widthAttr)) { + return R.drawable.ic_action_track_line_bold_transparency; + } else if (TRACK_WIDTH_MEDIUM.equals(widthAttr)) { + return R.drawable.ic_action_track_line_medium_transparency; + } else { + return R.drawable.ic_action_track_line_thin_transparency; + } + } + public static int getWidthIconId(String widthAttr) { if (TRACK_WIDTH_BOLD.equals(widthAttr)) { return R.drawable.ic_action_track_line_bold_color; diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index 79a7107ca8..5883c0dd73 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -26,6 +26,7 @@ import net.osmand.PlatformUtil; import net.osmand.plus.GPXDatabase; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -143,7 +144,11 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { private View createColorItemView(@ColorInt final int color, final FlowLayout rootView, boolean customColor) { View colorItemView = createCircleView(rootView); ImageView backgroundCircle = colorItemView.findViewById(R.id.background); - backgroundCircle.setImageDrawable(UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, R.drawable.bg_point_circle), color)); + + Drawable transparencyIcon = getTransparencyIcon(app, color); + Drawable colorIcon = app.getUIUtilities().getPaintedIcon(R.drawable.bg_point_circle, color); + Drawable layeredIcon = UiUtilities.getLayeredIcon(transparencyIcon, colorIcon); + backgroundCircle.setImageDrawable(layeredIcon); backgroundCircle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -173,6 +178,12 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { return colorItemView; } + private Drawable getTransparencyIcon(OsmandApplication app, @ColorInt int color) { + int colorWithoutAlpha = UiUtilities.removeAlpha(color); + int transparencyColor = UiUtilities.getColorWithAlpha(colorWithoutAlpha, 0.8f); + return app.getUIUtilities().getPaintedIcon(R.drawable.ic_bg_transparency, transparencyColor); + } + private View createAddCustomColorItemView(FlowLayout rootView) { View colorItemView = createCircleView(rootView); ImageView backgroundCircle = colorItemView.findViewById(R.id.background); @@ -183,7 +194,7 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { ImageView icon = colorItemView.findViewById(R.id.icon); icon.setVisibility(View.VISIBLE); int activeColorResId = nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light; - icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_add, activeColorResId)); + icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_plus, activeColorResId)); backgroundCircle.setImageDrawable(backgroundIcon); backgroundCircle.setOnClickListener(new View.OnClickListener() { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 59a249000a..1b5052f800 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -456,12 +456,16 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM int endX = (int) tileBox.getPixXFromLatLon(end.lat, end.lon); int endY = (int) tileBox.getPixYFromLatLon(end.lat, end.lon); - QuadRect startRect = calculateRect(startX, startY, startPointIcon.getIntrinsicWidth(), startPointIcon.getIntrinsicHeight()); - QuadRect endRect = calculateRect(endX, endY, finishPointIcon.getIntrinsicWidth(), finishPointIcon.getIntrinsicHeight()); + int iconSize = AndroidUtils.dpToPx(view.getContext(), 14); + QuadRect startRectWithoutShadow = calculateRect(startX, startY, iconSize, iconSize); + QuadRect endRectWithoutShadow = calculateRect(endX, endY, iconSize, iconSize); - if (QuadRect.intersects(startRect, endRect)) { - drawPoint(canvas, startRect, startAndFinishIcon); + if (QuadRect.intersects(startRectWithoutShadow, endRectWithoutShadow)) { + QuadRect startAndFinishRect = calculateRect(startX, startY, startAndFinishIcon.getIntrinsicWidth(), startAndFinishIcon.getIntrinsicHeight()); + drawPoint(canvas, startAndFinishRect, startAndFinishIcon); } else { + QuadRect startRect = calculateRect(startX, startY, startPointIcon.getIntrinsicWidth(), startPointIcon.getIntrinsicHeight()); + QuadRect endRect = calculateRect(endX, endY, finishPointIcon.getIntrinsicWidth(), finishPointIcon.getIntrinsicHeight()); drawPoint(canvas, startRect, startPointIcon); drawPoint(canvas, endRect, finishPointIcon); } From 6029bb4fea370bea0e3b7b649fd851aedfeb289d Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 1 Sep 2020 14:11:00 +0300 Subject: [PATCH 0007/1366] Fix custom color editing --- .../plus/track/CustomColorBottomSheet.java | 19 +++++---- .../plus/track/TrackAppearanceFragment.java | 9 +---- .../osmand/plus/track/TrackColoringCard.java | 40 +++---------------- 3 files changed, 18 insertions(+), 50 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java b/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java index dad9831f9c..a2015693a0 100644 --- a/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java @@ -11,6 +11,7 @@ import android.widget.EditText; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -46,7 +47,7 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem private boolean fromEditText; @ColorInt - private int prevColor; + private Integer prevColor; @ColorInt private int newColor; @@ -60,10 +61,10 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem if (args != null) { if (args.containsKey(PREV_SELECTED_COLOR)) { prevColor = args.getInt(PREV_SELECTED_COLOR); + newColor = prevColor; } else { - prevColor = Color.RED; + newColor = Color.RED; } - newColor = prevColor; } } @@ -78,7 +79,9 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem @Override public void onSaveInstanceState(Bundle outState) { outState.putInt(NEW_SELECTED_COLOR, newColor); - outState.putInt(PREV_SELECTED_COLOR, prevColor); + if (prevColor != null) { + outState.putInt(PREV_SELECTED_COLOR, prevColor); + } super.onSaveInstanceState(outState); } @@ -161,11 +164,13 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem dismiss(); } - public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, int prevColor) { + public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, @Nullable Integer prevColor) { try { if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(CustomColorBottomSheet.TAG) == null) { Bundle args = new Bundle(); - args.putInt(PREV_SELECTED_COLOR, prevColor); + if (prevColor != null) { + args.putInt(PREV_SELECTED_COLOR, prevColor); + } CustomColorBottomSheet customColorBottomSheet = new CustomColorBottomSheet(); customColorBottomSheet.setArguments(args); @@ -179,7 +184,7 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem public interface ColorPickerListener { - void onColorSelected(@ColorInt int prevColor, @ColorInt int newColor); + void onColorSelected(@ColorInt Integer prevColor, @ColorInt int newColor); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index c0d6b42741..4c6b80e539 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -180,13 +180,6 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement trackIcon = view.findViewById(R.id.track_icon); buttonsShadow = view.findViewById(R.id.buttons_shadow); - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - openMenuHeaderOnly(); - } - }); - if (isPortrait()) { updateCardsLayout(); } @@ -341,7 +334,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } @Override - public void onColorSelected(int prevColor, int newColor) { + public void onColorSelected(Integer prevColor, int newColor) { trackColoringCard.onColorSelected(prevColor, newColor); updateColorItems(); } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index 5883c0dd73..75029746db 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -23,9 +23,6 @@ import com.google.android.material.internal.FlowLayout; import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; -import net.osmand.plus.GPXDatabase; -import net.osmand.plus.GPXDatabase.GpxDataItem; -import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -46,9 +43,8 @@ import static net.osmand.plus.dialogs.GpxAppearanceAdapter.getAppearanceItems; public class TrackColoringCard extends BaseCard implements ColorPickerListener { - public static final int INVALID_VALUE = -1; - - private final static String SOLID_COLOR = "solid_color"; + private static final int INVALID_VALUE = -1; + private static final String SOLID_COLOR = "solid_color"; private static final Log log = PlatformUtil.getLog(TrackColoringCard.class); private TrackDrawInfo trackDrawInfo; @@ -202,7 +198,7 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { public void onClick(View v) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { - CustomColorBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), target, TrackColoringCard.INVALID_VALUE); + CustomColorBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), target, null); } } }); @@ -289,8 +285,8 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { } @Override - public void onColorSelected(int prevColor, int newColor) { - if (prevColor == INVALID_VALUE && customColors.size() < 6) { + public void onColorSelected(Integer prevColor, int newColor) { + if (prevColor == null && customColors.size() < 6) { customColors.add(newColor); trackDrawInfo.setColor(newColor); } else if (!Algorithms.isEmpty(customColors)) { @@ -299,35 +295,9 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { customColors.set(index, newColor); } } - saveCustomColors(); - saveCustomColorsToTracks(prevColor, newColor); updateContent(); } - private void saveCustomColorsToTracks(int prevColor, int newColor) { - List gpxDataItems = app.getGpxDbHelper().getItems(); - for (GPXDatabase.GpxDataItem dataItem : gpxDataItems) { - if (prevColor == dataItem.getColor()) { - app.getGpxDbHelper().updateColor(dataItem, newColor); - } - } - List files = app.getSelectedGpxHelper().getSelectedGPXFiles(); - for (SelectedGpxFile selectedGpxFile : files) { - if (prevColor == selectedGpxFile.getGpxFile().getColor(0)) { - selectedGpxFile.getGpxFile().setColor(newColor); - } - } - } - - private void saveCustomColors() { - List colorNames = new ArrayList<>(); - for (Integer color : customColors) { - String colorHex = Algorithms.colorToString(color); - colorNames.add(colorHex); - } - app.getSettings().CUSTOM_TRACK_COLORS.setStringsList(colorNames); - } - private class TrackColoringAdapter extends RecyclerView.Adapter { private List items; From 943f00a018afe046bad97cefcf204e2939260f53 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 2 Sep 2020 13:36:24 +0300 Subject: [PATCH 0008/1366] ui fixes started --- OsmAnd/res/layout/point_editor_fragment_new.xml | 9 +++++++-- OsmAnd/res/values/dimens.xml | 1 + .../mapcontextmenu/editors/PointEditorFragmentNew.java | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml index e39a1dbf44..8ac753afc0 100644 --- a/OsmAnd/res/layout/point_editor_fragment_new.xml +++ b/OsmAnd/res/layout/point_editor_fragment_new.xml @@ -150,7 +150,7 @@ + + 1.2 5dp + 42dp \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java index 4cf98456be..fd1e47e5b2 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java @@ -38,6 +38,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; import net.osmand.AndroidUtils; @@ -273,8 +274,9 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment { if (addressCaption.getVisibility() != View.VISIBLE) { addressCaption.setVisibility(View.VISIBLE); addAddressBtn.setText(view.getResources().getString(R.string.delete_address)); - View addressEdit = view.findViewById(R.id.address_edit); + TextInputEditText addressEdit = view.findViewById(R.id.address_edit); addressEdit.requestFocus(); + addressEdit.setSelection(addressEdit.getText().length()); AndroidUtils.softKeyboardDelayed(requireActivity(),addressEdit); } else { addressCaption.setVisibility(View.GONE); From 4b77cf7aedc470b68cb4ace8a33cb069b15800d4 Mon Sep 17 00:00:00 2001 From: sergosm Date: Tue, 8 Sep 2020 20:32:19 +0300 Subject: [PATCH 0009/1366] context_menu --- .../res/layout/map_context_menu_fragment.xml | 58 ++++++++++--------- .../plus/mapcontextmenu/MapContextMenu.java | 2 +- .../MapContextMenuFragment.java | 2 +- .../plus/mapcontextmenu/MenuController.java | 2 +- .../controllers/AMapPointMenuController.java | 2 +- .../FavouritePointMenuController.java | 19 +++--- .../editors/PointEditorFragmentNew.java | 12 ++-- 7 files changed, 52 insertions(+), 45 deletions(-) diff --git a/OsmAnd/res/layout/map_context_menu_fragment.xml b/OsmAnd/res/layout/map_context_menu_fragment.xml index 837a03a781..49c5bc6e32 100644 --- a/OsmAnd/res/layout/map_context_menu_fragment.xml +++ b/OsmAnd/res/layout/map_context_menu_fragment.xml @@ -174,6 +174,38 @@ android:paddingEnd="@dimen/context_menu_padding_margin_default" android:paddingTop="3dp"> + + + + + + + + + + - - - - - - - diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java index a554d06a4d..226216be06 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java @@ -1473,7 +1473,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL return menuController != null && menuController.displayDistanceDirection(); } - public String getSubtypeStr() { + public CharSequence getSubtypeStr() { MenuController menuController = getMenuController(); if (menuController != null) { return menuController.getSubtypeStr(); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java index 5721885ab6..44748e36bb 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java @@ -1835,7 +1835,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo } TextView line3 = (TextView) view.findViewById(R.id.context_menu_line3); - String subtypeStr = menu.getSubtypeStr(); + CharSequence subtypeStr = menu.getSubtypeStr(); if (TextUtils.isEmpty(subtypeStr)) { line3.setVisibility(View.GONE); } else { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java index 23f9393f22..55fc56b3b8 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java @@ -534,7 +534,7 @@ public abstract class MenuController extends BaseMenuController implements Colla } @NonNull - public String getSubtypeStr() { + public CharSequence getSubtypeStr() { return ""; } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AMapPointMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AMapPointMenuController.java index 73a43404a7..93c46908aa 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AMapPointMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AMapPointMenuController.java @@ -148,7 +148,7 @@ public class AMapPointMenuController extends MenuController { @NonNull @Override - public String getSubtypeStr() { + public CharSequence getSubtypeStr() { MapActivity activity = getMapActivity(); if (activity != null) { float bearing = getPointBearing(); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java index 65a7fa469e..d8459a2ca0 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java @@ -1,6 +1,8 @@ package net.osmand.plus.mapcontextmenu.controllers; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.text.SpannableString; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; @@ -18,14 +20,15 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.PointImageDrawable; +import net.osmand.plus.helpers.FontCache; import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapcontextmenu.builders.FavouritePointMenuBuilder; import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor; import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragment; import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragmentNew; import net.osmand.plus.transport.TransportStopRoute; +import net.osmand.plus.widgets.style.CustomTypefaceSpan; import net.osmand.util.OpeningHoursParser; -import net.osmand.view.GravityDrawable; import java.util.List; @@ -155,8 +158,12 @@ public class FavouritePointMenuController extends MenuController { @NonNull @Override - public String getSubtypeStr() { - return fav.getAddress(); + public CharSequence getSubtypeStr() { + Typeface typeface = FontCache.getRobotoRegular(getMapActivity()); + SpannableString addressSpannable = new SpannableString(fav.getAddress()); + addressSpannable.setSpan(new CustomTypefaceSpan(typeface), 0, addressSpannable.length(), 0); + + return addressSpannable; } @Override @@ -167,10 +174,8 @@ public class FavouritePointMenuController extends MenuController { FavouritesDbHelper helper = app.getFavorites(); String group = fav.getCategory(); if (helper.getGroup(group) != null) { - Drawable line2icon = helper.getColoredIconForGroup(group); - GravityDrawable gravityIcon = new GravityDrawable(line2icon); - gravityIcon.setBoundsFrom(line2icon); - return gravityIcon; + int colorId = R.color.color_favorite; + return getIcon(R.drawable.ic_action_group_name_16, colorId); } else { int colorId = isLight() ? R.color.icon_color_default_light : R.color.ctx_menu_bottom_view_icon_dark; return getIcon(R.drawable.ic_action_group_name_16, colorId); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java index 813aa9a0de..918afaae29 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java @@ -268,6 +268,8 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment { } } }); + AndroidUiHelper.updateVisibility(addressCaption, false); + addAddressBtn.setText(getAddressInitValue()); addAddressBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -279,7 +281,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment { AndroidUtils.softKeyboardDelayed(requireActivity(),addressEdit); } else { addressCaption.setVisibility(View.GONE); - addAddressBtn.setText(view.getResources().getString(R.string.add_address)); + addAddressBtn.setText(getAddressTextValue()); AndroidUtils.hideSoftKeyboard(requireActivity(), addressEdit); addressEdit.clearFocus(); } @@ -388,13 +390,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment { descriptionCaption.setVisibility(View.GONE); addDelDescription.setText(app.getString(R.string.add_description)); } - if (!addressEdit.getText().toString().isEmpty() || addressEdit.hasFocus()) { - addressCaption.setVisibility(View.VISIBLE); - addAddressBtn.setText(app.getString(R.string.delete_address)); - } else { - addressCaption.setVisibility(View.GONE); - addAddressBtn.setText(app.getString(R.string.add_address)); - } + } private void createGroupSelector() { From b703536bfecd9fd0984cd70e9efea26fd655e22f Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 9 Sep 2020 12:13:46 +0300 Subject: [PATCH 0010/1366] Fix route between points scroll --- ...ute_between_points_bottom_sheet_dialog.xml | 104 +++++++++--------- ...etweenPointsBottomSheetDialogFragment.java | 7 ++ 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml b/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml index 99b4cf41ff..cb7cca0488 100644 --- a/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml +++ b/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml @@ -1,70 +1,64 @@ - + android:layout_height="wrap_content" + android:background="?attr/bg_color" + android:orientation="vertical"> + android:orientation="vertical" + android:paddingBottom="@dimen/bottom_sheet_content_padding_small"> - + android:gravity="center_vertical" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingTop="@dimen/measurement_tool_menu_title_padding_top" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" + android:paddingBottom="@dimen/measurement_tool_menu_title_padding_bottom" + android:text="@string/route_between_points" + android:textAppearance="@style/TextAppearance.ListItemTitle" + osmand:typeface="@string/font_roboto_medium" /> - + - - - - - - + + - \ No newline at end of file + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java index f57cbd4e04..d611bf83be 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java @@ -13,6 +13,7 @@ import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -29,6 +30,7 @@ import java.util.List; import static net.osmand.plus.UiUtilities.CustomRadioButtonType.LEFT; import static net.osmand.plus.UiUtilities.CustomRadioButtonType.RIGHT; import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE; +import static net.osmand.plus.measurementtool.SelectFileBottomSheet.BOTTOM_SHEET_HEIGHT_DP; public class RouteBetweenPointsBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { @@ -225,6 +227,11 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends MenuBottomSheet items.add(new BaseBottomSheetItem.Builder().setCustomView(mainView).create()); } + @Override + protected int getCustomHeight() { + return AndroidUtils.dpToPx(getContext(), BOTTOM_SHEET_HEIGHT_DP); + } + @Override protected int getDismissButtonTextId() { return R.string.shared_string_close; From 240e532bde31f6bb4d4e0a821d50cf3572651330 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 9 Sep 2020 14:55:47 +0300 Subject: [PATCH 0011/1366] Fix plan road map control button bug and disable ability to add new points --- OsmAnd/res/layout/map_hud_bottom.xml | 19 +++++-- .../MeasurementToolFragment.java | 56 +++++++++++++------ .../measurementtool/MeasurementToolLayer.java | 4 ++ .../plus/views/layers/MapControlsLayer.java | 26 ++++++--- 4 files changed, 74 insertions(+), 31 deletions(-) diff --git a/OsmAnd/res/layout/map_hud_bottom.xml b/OsmAnd/res/layout/map_hud_bottom.xml index 81dc6fbd28..dc4be05d64 100644 --- a/OsmAnd/res/layout/map_hud_bottom.xml +++ b/OsmAnd/res/layout/map_hud_bottom.xml @@ -116,13 +116,20 @@ tools:src="@drawable/ic_action_remove_dark" android:contentDescription="@string/snap_to_road" /> - + android:layout_gravity="bottom"> + + + diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 3bbc3214d1..1ea7b54f1d 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -117,6 +117,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route SaveAsNewTrackFragmentListener { public static final String TAG = MeasurementToolFragment.class.getSimpleName(); + public static final String TAPS_DISABLED_KEY = "taps_disabled_key"; private RecyclerView pointsRv; private String previousToolBarTitle = ""; @@ -459,19 +460,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } else if (!editingCtx.isNewData() && !editingCtx.hasRoutePoints() && !editingCtx.hasRoute() && editingCtx.getPointsCount() > 1) { enterApproximationMode(mapActivity); } + } else { + measurementLayer.setTapsDisabled(savedInstanceState.getBoolean(TAPS_DISABLED_KEY)); } return view; } - private void enterApproximationMode(MapActivity mapActivity) { - MeasurementToolLayer layer = getMeasurementLayer(); - if (layer != null) { - layer.setTapsDisabled(true); - SnapTrackWarningBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), this); - } - } - public boolean isInEditMode() { return !planRouteMode && !editingCtx.isNewData() && !directionMode; } @@ -912,7 +907,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route @Override public void onChangeApplicationMode(ApplicationMode mode, RouteBetweenPointsDialogType dialogType, - RouteBetweenPointsDialogMode dialogMode) { + RouteBetweenPointsDialogMode dialogMode) { MeasurementToolLayer measurementLayer = getMeasurementLayer(); if (measurementLayer != null) { ChangeRouteType changeRouteType = ChangeRouteType.NEXT_SEGMENT; @@ -939,6 +934,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + MeasurementToolLayer measurementLayer = getMeasurementLayer(); + if (measurementLayer != null) { + outState.putBoolean(TAPS_DISABLED_KEY, measurementLayer.isTapsDisabled()); + } + } + private StartPlanRouteListener createStartPlanRouteListener() { return new StartPlanRouteListener() { @Override @@ -1050,13 +1054,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route @Override public void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack) { - File dir = getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR); - if (folderName != null) { - dir = new File(dir, folderName); + OsmandApplication app = getMyApplication(); + if (app != null) { + File dir = getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR); + if (folderName != null) { + dir = new File(dir, folderName); + } + fileName = fileName + GPX_FILE_EXT; + SaveType saveType = simplifiedTrack ? SaveType.LINE : SaveType.ROUTE_POINT; + saveNewGpx(dir, fileName, showOnMap, saveType, SaveAction.SHOW_IS_SAVED_FRAGMENT); } - fileName = fileName + GPX_FILE_EXT; - SaveType saveType = simplifiedTrack ? SaveType.LINE : SaveType.ROUTE_POINT; - saveNewGpx(dir, fileName, showOnMap, saveType, SaveAction.SHOW_IS_SAVED_FRAGMENT); } private MeasurementAdapterListener createMeasurementAdapterListener(final ItemTouchHelper touchHelper) { @@ -2112,11 +2119,28 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route updateToolbar(); } + private void enterApproximationMode(MapActivity mapActivity) { + MeasurementToolLayer layer = getMeasurementLayer(); + if (layer != null) { + FragmentManager manager = mapActivity.getSupportFragmentManager(); + manager.beginTransaction() + .hide(this).commit(); + layer.setTapsDisabled(true); + SnapTrackWarningBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), this); + AndroidUiHelper.setVisibility(mapActivity, View.GONE, R.id.map_ruler_container); + } + } + private void exitApproximationMode() { editingCtx.setInApproximationMode(false); MeasurementToolLayer layer = getMeasurementLayer(); - if (layer != null) { + MapActivity mapActivity = getMapActivity(); + if (layer != null && mapActivity != null) { + FragmentManager manager = mapActivity.getSupportFragmentManager(); + manager.beginTransaction() + .show(this).commit(); layer.setTapsDisabled(false); + AndroidUiHelper.setVisibility(mapActivity, View.VISIBLE, R.id.map_ruler_container); } } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 63d10688dc..fdb8dc8887 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -107,6 +107,10 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL this.tapsDisabled = tapsDisabled; } + public boolean isTapsDisabled() { + return tapsDisabled; + } + @Override public boolean onSingleTap(PointF point, RotatedTileBox tileBox) { if (inMeasurementMode && !tapsDisabled && editingCtx.getSelectedPointPosition() == -1) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index cd6bf62ced..a1e529cd91 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -433,7 +433,7 @@ public class MapControlsLayer extends OsmandMapLayer { } } else { ActivityCompat.requestPermissions(mapActivity, - new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, + new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, OsmAndLocationProvider.REQUEST_LOCATION_PERMISSION); } } @@ -478,7 +478,7 @@ public class MapControlsLayer extends OsmandMapLayer { public void navigateButton() { if (!OsmAndLocationProvider.isLocationPermissionAvailable(mapActivity)) { ActivityCompat.requestPermissions(mapActivity, - new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, + new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_FOR_NAVIGATION_FAB_PERMISSION); } else { final MapContextMenu menu = mapActivity.getContextMenu(); @@ -504,8 +504,8 @@ public class MapControlsLayer extends OsmandMapLayer { } else { AlertDialog.Builder bld = new AlertDialog.Builder(mapActivity); bld.setTitle(R.string.new_directions_point_dialog); - final int[] defaultVls = new int[] {0}; - bld.setSingleChoiceItems(new String[] { + final int[] defaultVls = new int[]{0}; + bld.setSingleChoiceItems(new String[]{ mapActivity.getString(R.string.clear_intermediate_points), mapActivity.getString(R.string.keep_intermediate_points) }, 0, new DialogInterface.OnClickListener() { @@ -883,8 +883,12 @@ public class MapControlsLayer extends OsmandMapLayer { menuControl.updateVisibility(showButtons); - mapZoomIn.updateVisibility(!routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait)); - mapZoomOut.updateVisibility(!routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait)); + mapZoomIn.updateVisibility(!routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() + && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait) + && (!isInGpxApproximationMode() || !isPotrait())); + mapZoomOut.updateVisibility(!routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() + && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait) + && (!isInGpxApproximationMode() || !isPotrait())); boolean forceHideCompass = routeDialogOpened || trackDialogOpened || isInMeasurementToolMode() || isInPlanRouteMode() || contextMenuOpened || isInChoosingRoutesMode() || isInTrackAppearanceMode() || isInWaypointsChoosingMode(); compassHud.forceHideCompass = forceHideCompass; @@ -985,7 +989,7 @@ public class MapControlsLayer extends OsmandMapLayer { public void updateMyLocationVisibility(MapHudButton backToLocationControl, RoutingHelper rh, boolean dialogOpened) { boolean tracked = mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); - boolean visible = !(tracked && rh.isFollowingMode()); + boolean visible = !(tracked && rh.isFollowingMode()) && (!isInGpxApproximationMode() || !isPotrait()); backToLocationControl.updateVisibility(visible && !dialogOpened && !isInPlanRouteMode() && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !isPotrait())); } @@ -1036,7 +1040,7 @@ public class MapControlsLayer extends OsmandMapLayer { } public void showTransparencyBar(CommonPreference transparenPreference, - boolean isTransparencyBarEnabled) { + boolean isTransparencyBarEnabled) { this.isTransparencyBarEnabled = isTransparencyBarEnabled; ApplicationMode appMode = app.getSettings().getApplicationMode(); if (MapControlsLayer.transparencySetting != transparenPreference) { @@ -1295,12 +1299,16 @@ public class MapControlsLayer extends OsmandMapLayer { return mapActivity.getMapLayers().getGpxLayer().isInTrackAppearanceMode(); } + private boolean isInGpxApproximationMode() { + return mapActivity.getMapLayers().getMeasurementToolLayer().isTapsDisabled(); + } + private boolean isInChoosingRoutesMode() { return MapRouteInfoMenu.chooseRoutesVisible; } private boolean isInWaypointsChoosingMode() { - return MapRouteInfoMenu.waypointsVisible; + return MapRouteInfoMenu.waypointsVisible; } public static View.OnLongClickListener getOnClickMagnifierListener(final OsmandMapTileView view) { From f2d64a746454e5a36e896f15341462c7c0a4b05a Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 9 Sep 2020 18:47:02 +0300 Subject: [PATCH 0012/1366] Fix widgets showing up after route between points dialog --- .../GpxApproximationFragment.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java index 4217faf1c9..4698b00d86 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java @@ -165,7 +165,6 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment params.gravity = Gravity.BOTTOM | Gravity.START; mainView.findViewById(R.id.control_buttons).setLayoutParams(params); } - enterGpxApproximationMode(); runLayoutListener(); calculateGpxApproximation(); @@ -193,7 +192,6 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment if (gpxApproximator != null) { gpxApproximator.cancelApproximation(); } - exitGpxApproximationMode(); if (!applyApproximation) { Fragment fragment = getTargetFragment(); if (fragment instanceof GpxApproximationFragmentListener) { @@ -276,28 +274,6 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment } } - private void enterGpxApproximationMode() { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - boolean portrait = AndroidUiHelper.isOrientationPortrait(mapActivity); - AndroidUiHelper.setVisibility(mapActivity, portrait ? View.INVISIBLE : View.GONE, - R.id.map_left_widgets_panel, - R.id.map_right_widgets_panel, - R.id.map_center_info); - } - } - - private void exitGpxApproximationMode() { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - AndroidUiHelper.setVisibility(mapActivity, View.VISIBLE, - R.id.map_left_widgets_panel, - R.id.map_right_widgets_panel, - R.id.map_center_info, - R.id.map_search_button); - } - } - @Override public boolean shouldShowMapControls(int menuState) { return (menuState & (MenuState.HEADER_ONLY | MenuState.HALF_SCREEN)) != 0; From 029b5556673172d29cb9b788cf0b2fd62cda6d8e Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 10 Sep 2020 13:23:20 +0300 Subject: [PATCH 0013/1366] Add bottom sheet behaviour dialog --- .../drawable/bottom_sheet_buttons_bg_dark.xml | 11 + .../bottom_sheet_buttons_bg_light.xml | 11 + .../layout/bottom_sheet_behaviour_base.xml | 50 ++++ .../layout/bottom_sheet_plan_route_start.xml | 59 ++-- .../BottomSheetBehaviourDialogFragment.java | 282 ++++++++++++++++++ .../StartPlanRouteBottomSheet.java | 8 +- 6 files changed, 384 insertions(+), 37 deletions(-) create mode 100644 OsmAnd/res/drawable/bottom_sheet_buttons_bg_dark.xml create mode 100644 OsmAnd/res/drawable/bottom_sheet_buttons_bg_light.xml create mode 100644 OsmAnd/res/layout/bottom_sheet_behaviour_base.xml create mode 100644 OsmAnd/src/net/osmand/plus/base/BottomSheetBehaviourDialogFragment.java diff --git a/OsmAnd/res/drawable/bottom_sheet_buttons_bg_dark.xml b/OsmAnd/res/drawable/bottom_sheet_buttons_bg_dark.xml new file mode 100644 index 0000000000..1322edb6cb --- /dev/null +++ b/OsmAnd/res/drawable/bottom_sheet_buttons_bg_dark.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable/bottom_sheet_buttons_bg_light.xml b/OsmAnd/res/drawable/bottom_sheet_buttons_bg_light.xml new file mode 100644 index 0000000000..cfc0b32c50 --- /dev/null +++ b/OsmAnd/res/drawable/bottom_sheet_buttons_bg_light.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_behaviour_base.xml b/OsmAnd/res/layout/bottom_sheet_behaviour_base.xml new file mode 100644 index 0000000000..1f54a2b8d1 --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_behaviour_base.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_plan_route_start.xml b/OsmAnd/res/layout/bottom_sheet_plan_route_start.xml index a4aa9f312e..d43c589a9d 100644 --- a/OsmAnd/res/layout/bottom_sheet_plan_route_start.xml +++ b/OsmAnd/res/layout/bottom_sheet_plan_route_start.xml @@ -1,47 +1,40 @@ - + android:orientation="horizontal" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingTop="@dimen/bottom_sheet_title_padding_top" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" + android:paddingBottom="@dimen/bottom_sheet_title_padding_bottom"> - - - - - - - + android:letterSpacing="@dimen/description_letter_spacing" + android:text="@string/plan_route_last_edited" + android:textColor="?attr/active_color_basic" + android:textSize="@dimen/default_desc_text_size" + osmand:typeface="@string/font_roboto_medium" /> - \ No newline at end of file + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/base/BottomSheetBehaviourDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/BottomSheetBehaviourDialogFragment.java new file mode 100644 index 0000000000..332fb5be0e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/base/BottomSheetBehaviourDialogFragment.java @@ -0,0 +1,282 @@ +package net.osmand.plus.base; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.LinearLayout; + +import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.helpers.AndroidUiHelper; + +import java.util.ArrayList; +import java.util.List; + +public abstract class BottomSheetBehaviourDialogFragment extends BottomSheetDialogFragment { + + private static final String USED_ON_MAP_KEY = "used_on_map"; + private static final int DEFAULT_VALUE = -1; + + protected List items = new ArrayList<>(); + + protected boolean usedOnMap = true; + protected boolean nightMode; + protected boolean portrait; + + protected View dismissButton; + protected View rightButton; + + private LinearLayout itemsContainer; + + public void setUsedOnMap(boolean usedOnMap) { + this.usedOnMap = usedOnMap; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState != null) { + usedOnMap = savedInstanceState.getBoolean(USED_ON_MAP_KEY); + } + nightMode = isNightMode(requiredMyApplication()); + portrait = AndroidUiHelper.isOrientationPortrait(requireActivity()); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + LayoutInflater themedInflater = UiUtilities.getInflater(requireContext(), nightMode); + View mainView = themedInflater.inflate(R.layout.bottom_sheet_behaviour_base, parent, false); + itemsContainer = (LinearLayout) mainView.findViewById(R.id.items_container); + + View scrollView = mainView.findViewById(R.id.bottom_sheet_scroll_view); + final BottomSheetBehavior behavior = BottomSheetBehavior.from(scrollView); + behavior.setPeekHeight(getPeekHeight()); + + LinearLayout buttonsContainer = (LinearLayout) mainView.findViewById(R.id.buttons_container); + buttonsContainer.setBackgroundResource(getButtonsContainerBg()); + + if (!portrait) { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialog) { + behavior.setState(BottomSheetBehavior.STATE_EXPANDED); + } + }); + } + } + + createMenuItems(savedInstanceState); + inflateMenuItems(); + + dismissButton = mainView.findViewById(R.id.dismiss_button); + UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), getDismissButtonTextId()); + dismissButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onDismissButtonClickAction(); + dismiss(); + } + }); + if (hideButtonsContainer()) { + mainView.findViewById(R.id.buttons_container).setVisibility(View.GONE); + } else { + int rightBottomButtonTextId = getRightBottomButtonTextId(); + if (rightBottomButtonTextId != DEFAULT_VALUE) { + mainView.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); + rightButton = mainView.findViewById(R.id.right_bottom_button); + UiUtilities.setupDialogButton(nightMode, rightButton, getRightBottomButtonType(), rightBottomButtonTextId); + rightButton.setVisibility(View.VISIBLE); + rightButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onRightBottomButtonClick(); + } + }); + } + } + updateBackground(); + updateBottomButtons(); + return mainView; + } + + @Override + public void onStart() { + super.onStart(); + FragmentActivity activity = requireActivity(); + if (!AndroidUiHelper.isOrientationPortrait(activity)) { + Dialog dialog = getDialog(); + Window window = dialog != null ? dialog.getWindow() : null; + if (window != null) { + WindowManager.LayoutParams params = window.getAttributes(); + params.width = activity.getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width); + window.setAttributes(params); + } + } + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(USED_ON_MAP_KEY, usedOnMap); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + items.clear(); + if (itemsContainer != null) { + itemsContainer.removeAllViews(); + } + } + + public abstract void createMenuItems(Bundle savedInstanceState); + + protected void inflateMenuItems() { + Activity activity = requireActivity(); + for (BaseBottomSheetItem item : items) { + item.inflate(activity, itemsContainer, nightMode); + } + } + + @Override + protected Drawable getContentIcon(@DrawableRes int id) { + return getIcon(id, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); + } + + protected Drawable getActiveIcon(@DrawableRes int id) { + return getIcon(id, getActiveColorId()); + } + + @ColorRes + protected int getActiveColorId() { + return nightMode ? R.color.osmand_orange : R.color.color_myloc_distance; + } + + @ColorInt + protected int getResolvedColor(@ColorRes int colorId) { + Context ctx = getContext(); + return ctx != null ? ContextCompat.getColor(ctx, colorId) : 0; + } + + private void updateBackground() { + if (portrait) { + itemsContainer.setBackgroundResource(getPortraitBgResId()); + } else { + itemsContainer.setBackgroundResource(getLandscapeTopsidesBgResId()); + } + } + + protected int getPeekHeight() { + return DEFAULT_VALUE; + } + + protected boolean hideButtonsContainer() { + return false; + } + + @StringRes + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + protected DialogButtonType getDismissButtonType() { + return DialogButtonType.SECONDARY; + } + + protected void onDismissButtonClickAction() { + + } + + @StringRes + protected int getRightBottomButtonTextId() { + return DEFAULT_VALUE; + } + + protected DialogButtonType getRightBottomButtonType() { + return DialogButtonType.PRIMARY; + } + + protected void onRightBottomButtonClick() { + + } + + protected boolean isDismissButtonEnabled() { + return true; + } + + protected boolean isRightBottomButtonEnabled() { + return true; + } + + protected void updateBottomButtons() { + if (dismissButton != null) { + boolean enabled = isDismissButtonEnabled(); + dismissButton.setEnabled(enabled); + dismissButton.findViewById(R.id.button_text).setEnabled(enabled); + } + if (rightButton != null) { + boolean enabled = isRightBottomButtonEnabled(); + rightButton.setEnabled(enabled); + rightButton.findViewById(R.id.button_text).setEnabled(enabled); + } + } + + @ColorRes + protected int getBgColorId() { + return nightMode ? R.color.list_background_color_dark : R.color.list_background_color_light; + } + + @DrawableRes + protected int getPortraitBgResId() { + return nightMode ? R.drawable.bg_bottom_menu_dark : R.drawable.bg_bottom_menu_light; + } + + @DrawableRes + protected int getLandscapeTopsidesBgResId() { + return nightMode ? R.drawable.bg_bottom_sheet_topsides_landscape_dark : R.drawable.bg_bottom_sheet_topsides_landscape_light; + } + + @DrawableRes + protected int getLandscapeSidesBgResId() { + return nightMode ? R.drawable.bg_bottom_sheet_sides_landscape_dark : R.drawable.bg_bottom_sheet_sides_landscape_light; + } + + private int getButtonsContainerBg() { + if (portrait) { + return getBgColorId(); + } + return nightMode ? R.drawable.bottom_sheet_buttons_bg_dark : R.drawable.bottom_sheet_buttons_bg_light; + } + + protected boolean isNightMode(@NonNull OsmandApplication app) { + if (usedOnMap) { + return app.getDaynightHelper().isNightModeForMapControls(); + } + return !app.getSettings().isLightContent(); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java index de235b0dc5..aedb65ee72 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java @@ -19,7 +19,7 @@ import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.BottomSheetBehaviourDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; @@ -38,7 +38,7 @@ import java.util.List; import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo; -public class StartPlanRouteBottomSheet extends MenuBottomSheetDialogFragment { +public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragment { public static final String TAG = StartPlanRouteBottomSheet.class.getSimpleName(); private static final Log LOG = PlatformUtil.getLog(StartPlanRouteBottomSheet.class); @@ -136,8 +136,8 @@ public class StartPlanRouteBottomSheet extends MenuBottomSheetDialogFragment { } @Override - protected int getCustomHeight() { - return AndroidUtils.dpToPx(mainView.getContext(), BOTTOM_SHEET_HEIGHT_DP); + protected int getPeekHeight() { + return AndroidUtils.dpToPx(getContext(), BOTTOM_SHEET_HEIGHT_DP); } private void onItemClick(int position, List gpxInfoList) { From 463972f8a547388495c74fd0b96d1015b079624b Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 10 Sep 2020 14:07:05 +0300 Subject: [PATCH 0014/1366] Use bottom sheet behaviour for plan route dialogs --- .../bottom_sheet_plan_route_select_file.xml | 103 ++++++++---------- ...etweenPointsBottomSheetDialogFragment.java | 6 +- .../SelectFileBottomSheet.java | 8 +- 3 files changed, 55 insertions(+), 62 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml b/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml index da5f1dff61..362dacf2c6 100644 --- a/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml +++ b/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml @@ -1,66 +1,59 @@ - - + + + + + android:clipToPadding="false" + android:orientation="horizontal" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" + tools:itemCount="3" + tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/point_editor_icon_category_item" + tools:orientation="horizontal" /> - + - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java index d611bf83be..b1ab024ea9 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java @@ -18,7 +18,7 @@ import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.BottomSheetBehaviourDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.settings.backend.ApplicationMode; @@ -32,7 +32,7 @@ import static net.osmand.plus.UiUtilities.CustomRadioButtonType.RIGHT; import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.BOTTOM_SHEET_HEIGHT_DP; -public class RouteBetweenPointsBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { +public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetBehaviourDialogFragment { private static final Log LOG = PlatformUtil.getLog(RouteBetweenPointsBottomSheetDialogFragment.class); public static final String TAG = RouteBetweenPointsBottomSheetDialogFragment.class.getSimpleName(); @@ -228,7 +228,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends MenuBottomSheet } @Override - protected int getCustomHeight() { + protected int getPeekHeight() { return AndroidUtils.dpToPx(getContext(), BOTTOM_SHEET_HEIGHT_DP); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index d9619de9d1..0f1920c7e6 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -15,7 +15,7 @@ import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.BottomSheetBehaviourDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.GpxTrackAdapter.OnItemClickListener; @@ -32,7 +32,7 @@ import java.util.Map; import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo; import static net.osmand.util.Algorithms.collectDirs; -public class SelectFileBottomSheet extends MenuBottomSheetDialogFragment { +public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { enum Mode { OPEN_TRACK(R.string.plan_route_open_existing_track, R.string.plan_route_select_track_file_for_open), @@ -173,8 +173,8 @@ public class SelectFileBottomSheet extends MenuBottomSheetDialogFragment { } @Override - protected int getCustomHeight() { - return AndroidUtils.dpToPx(mainView.getContext(), BOTTOM_SHEET_HEIGHT_DP); + protected int getPeekHeight() { + return AndroidUtils.dpToPx(getContext(), BOTTOM_SHEET_HEIGHT_DP); } public static void showInstance(FragmentManager fragmentManager, SelectFileListener listener, Mode mode) { From 0fcc660a348caab7c1de2654fafbb4dfc95143a5 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 10 Sep 2020 15:44:13 +0300 Subject: [PATCH 0015/1366] Add lower state for gpx approximation and disable swipe to dismiss --- .../net/osmand/plus/base/ContextMenuFragment.java | 10 +++++++--- .../measurementtool/GpxApproximationFragment.java | 14 +++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java index 57928eac50..5cb595f0ff 100644 --- a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java @@ -612,6 +612,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment { } } + protected boolean isHideable() { + return true; + } + private void processScreenHeight(ViewParent parent) { View container = (View) parent; MapActivity mapActivity = getMapActivity(); @@ -783,7 +787,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment { private int getPosY(final int currentY, boolean needCloseMenu, int previousState) { - if (needCloseMenu) { + if (needCloseMenu && isHideable()) { return screenHeight; } MapActivity mapActivity = getMapActivity(); @@ -858,7 +862,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment { @Override public void onAnimationEnd(Animator animation) { if (!canceled) { - if (needCloseMenu) { + if (needCloseMenu && isHideable()) { dismiss(); } else { updateMainViewLayout(posY); @@ -870,7 +874,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment { } }).start(); } else { - if (needCloseMenu) { + if (needCloseMenu && isHideable()) { dismiss(); } else { mainView.setY(posY); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java index 4217faf1c9..c2cdaf0ec1 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java @@ -56,6 +56,8 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment private View cancelButton; private View applyButton; + private SliderCard sliderCard; + @Override public int getMainLayoutId() { return R.layout.fragment_gpx_approximation_bottom_sheet_dialog; @@ -87,7 +89,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment @Override public int getSupportedMenuStatesPortrait() { - return MenuState.HALF_SCREEN | MenuState.FULL_SCREEN; + return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN; } @Override @@ -175,11 +177,17 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment @Override protected void calculateLayout(View view, boolean initLayout) { + int sliderHeight = sliderCard != null ? sliderCard.getViewHeight() : 0; menuTitleHeight = view.findViewById(R.id.control_buttons).getHeight() - - view.findViewById(R.id.buttons_shadow).getHeight(); + - view.findViewById(R.id.buttons_shadow).getHeight() + sliderHeight; super.calculateLayout(view, initLayout); } + @Override + protected boolean isHideable() { + return false; + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -265,7 +273,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment cardsContainer.removeAllViews(); if (getTopView() != null) { - SliderCard sliderCard = new SliderCard(mapActivity, distanceThreshold); + sliderCard = new SliderCard(mapActivity, distanceThreshold); sliderCard.setListener(this); getTopView().addView(sliderCard.build(mapActivity)); } From 3c177d9a6cd5c3a7fb6f94dfbc3525b4597fe6fb Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 10 Sep 2020 16:26:16 +0300 Subject: [PATCH 0016/1366] Fix difference in distance calculation for multiple segments --- .../plus/measurementtool/MeasurementEditingContext.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 88ec9f7975..e365348586 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -43,7 +43,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.WHOLE_TRACK; -import static net.osmand.plus.measurementtool.command.MeasurementModeCommand.MeasurementCommandType.*; +import static net.osmand.plus.measurementtool.command.MeasurementModeCommand.MeasurementCommandType.APPROXIMATE_POINTS; public class MeasurementEditingContext { @@ -249,8 +249,10 @@ public class MeasurementEditingContext { Pair pair = new Pair<>(points.get(i), points.get(i + 1)); RoadSegmentData data = this.roadSegmentData.get(pair); if (data == null) { - distance += MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(), - pair.second.getLatitude(), pair.second.getLongitude()); + if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE || !pair.first.lastPoint || !pair.second.firstPoint) { + distance += MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(), + pair.second.getLatitude(), pair.second.getLongitude()); + } } else { distance += data.getDistance(); } From 2248d47941f5e51dc8f2566cff562bb51c437530 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 10 Sep 2020 16:53:19 +0300 Subject: [PATCH 0017/1366] Fix bug with wrong height when few ContextMenuFragment fragments are displayed simultaneously --- .../layout/fragment_plan_route_warning.xml | 119 +++++++++++ .../osmand/plus/activities/MapActivity.java | 12 +- .../MeasurementToolFragment.java | 21 +- .../SnapTrackWarningBottomSheet.java | 95 --------- .../SnapTrackWarningFragment.java | 190 ++++++++++++++++++ 5 files changed, 331 insertions(+), 106 deletions(-) create mode 100644 OsmAnd/res/layout/fragment_plan_route_warning.xml delete mode 100644 OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java create mode 100644 OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java diff --git a/OsmAnd/res/layout/fragment_plan_route_warning.xml b/OsmAnd/res/layout/fragment_plan_route_warning.xml new file mode 100644 index 0000000000..83eeb281e5 --- /dev/null +++ b/OsmAnd/res/layout/fragment_plan_route_warning.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index f71a6c0fb6..efe26164d2 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -122,7 +122,7 @@ import net.osmand.plus.measurementtool.GpxApproximationFragment; import net.osmand.plus.measurementtool.GpxData; import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementToolFragment; -import net.osmand.plus.measurementtool.SnapTrackWarningBottomSheet; +import net.osmand.plus.measurementtool.SnapTrackWarningFragment; import net.osmand.plus.quickaction.QuickActionListFragment; import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.resources.ResourceManager; @@ -692,9 +692,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return; } - SnapTrackWarningBottomSheet snapTrackWarningBottomSheet = getSnapTrackWarningBottomSheet(); - if (snapTrackWarningBottomSheet != null) { - snapTrackWarningBottomSheet.dismiss(); + SnapTrackWarningFragment snapTrackWarningFragment = getSnapTrackWarningBottomSheet(); + if (snapTrackWarningFragment != null) { + snapTrackWarningFragment.dismissImmediate(); return; } @@ -2329,8 +2329,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return getFragment(GpxApproximationFragment.TAG); } - private SnapTrackWarningBottomSheet getSnapTrackWarningBottomSheet() { - return getFragment(SnapTrackWarningBottomSheet.TAG); + public SnapTrackWarningFragment getSnapTrackWarningBottomSheet() { + return getFragment(SnapTrackWarningFragment.TAG); } public PointEditorFragmentNew getPointEditorFragmentNew() { diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 1ea7b54f1d..9788db1f35 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -414,7 +414,18 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route toolBarController.setOnBackButtonClickListener(new OnClickListener() { @Override public void onClick(View v) { - quit(false); + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + GpxApproximationFragment gpxApproximationFragment = mapActivity.getGpxApproximationFragment(); + SnapTrackWarningFragment snapTrackWarningFragment = mapActivity.getSnapTrackWarningBottomSheet(); + if (gpxApproximationFragment != null) { + gpxApproximationFragment.dismissImmediate(); + } else if (snapTrackWarningFragment != null) { + snapTrackWarningFragment.dismissImmediate(); + } else { + quit(false); + } + } } }); toolBarController.setOnSaveViewClickListener(new OnClickListener() { @@ -640,15 +651,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { - case SnapTrackWarningBottomSheet.REQUEST_CODE: + case SnapTrackWarningFragment.REQUEST_CODE: switch (resultCode) { - case SnapTrackWarningBottomSheet.CANCEL_RESULT_CODE: + case SnapTrackWarningFragment.CANCEL_RESULT_CODE: toolBarController.setSaveViewVisible(true); directionMode = false; exitApproximationMode(); updateToolbar(); break; - case SnapTrackWarningBottomSheet.CONTINUE_RESULT_CODE: + case SnapTrackWarningFragment.CONTINUE_RESULT_CODE: MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { GpxApproximationFragment.showInstance(mapActivity.getSupportFragmentManager(), @@ -2126,7 +2137,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route manager.beginTransaction() .hide(this).commit(); layer.setTapsDisabled(true); - SnapTrackWarningBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), this); + SnapTrackWarningFragment.showInstance(mapActivity.getSupportFragmentManager(), this); AndroidUiHelper.setVisibility(mapActivity, View.GONE, R.id.map_ruler_container); } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java deleted file mode 100644 index 42d051bb8c..0000000000 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java +++ /dev/null @@ -1,95 +0,0 @@ -package net.osmand.plus.measurementtool; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; - -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -import net.osmand.PlatformUtil; -import net.osmand.plus.R; -import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; -import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; -import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; -import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; -import net.osmand.plus.helpers.GpxTrackAdapter; - -import org.apache.commons.logging.Log; - -public class SnapTrackWarningBottomSheet extends MenuBottomSheetDialogFragment { - - public static final int REQUEST_CODE = 1000; - public static final int CANCEL_RESULT_CODE = 2; - public static final int CONTINUE_RESULT_CODE = 3; - - public static final String TAG = SnapTrackWarningBottomSheet.class.getSimpleName(); - private static final Log LOG = PlatformUtil.getLog(SnapTrackWarningBottomSheet.class); - - protected View mainView; - protected GpxTrackAdapter adapter; - private boolean continued = false; - - @Override - public void createMenuItems(Bundle savedInstanceState) { - Activity activity = getActivity(); - if (activity instanceof MapActivity) { - activity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.GONE); - } - BaseBottomSheetItem description = new BottomSheetItemWithDescription.Builder() - .setDescription(getString(R.string.rourte_between_points_warning_desc)) - .setTitle(getString(R.string.route_between_points)) - .setLayoutId(R.layout.bottom_sheet_item_list_title_with_descr) - .create(); - items.add(description); - items.add(new DividerSpaceItem(getContext(), getResources().getDimensionPixelSize(R.dimen.content_padding_half))); - } - - @Override - protected int getRightBottomButtonTextId() { - return R.string.shared_string_continue; - } - - @Override - protected void onRightBottomButtonClick() { - Fragment fragment = getTargetFragment(); - if (fragment != null) { - continued = true; - fragment.onActivityResult(REQUEST_CODE, CONTINUE_RESULT_CODE, null); - } - dismiss(); - } - - @Override - protected int getDismissButtonTextId() { - return R.string.shared_string_cancel; - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - Activity activity = getActivity(); - if (activity instanceof MapActivity) { - activity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.VISIBLE); - } - Fragment fragment = getTargetFragment(); - if (fragment != null && !continued) { - fragment.onActivityResult(REQUEST_CODE, CANCEL_RESULT_CODE, null); - } - } - - public static void showInstance(FragmentManager fm, Fragment targetFragment) { - try { - if (!fm.isStateSaved()) { - SnapTrackWarningBottomSheet fragment = new SnapTrackWarningBottomSheet(); - fragment.setTargetFragment(targetFragment, REQUEST_CODE); - fm.beginTransaction() - .add(R.id.bottomFragmentContainer, fragment, TAG) - .commitAllowingStateLoss(); - } - } catch (RuntimeException e) { - LOG.error("showInstance", e); - } - } -} diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java new file mode 100644 index 0000000000..6730e4d923 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java @@ -0,0 +1,190 @@ +package net.osmand.plus.measurementtool; + +import android.app.Activity; +import android.os.Bundle; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.LinearLayout; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.MapActivityLayers; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.views.OsmandMapTileView; +import net.osmand.plus.views.layers.MapControlsLayer; +import net.osmand.plus.views.layers.MapInfoLayer; + +import org.apache.commons.logging.Log; + +import static android.view.Gravity.TOP; +import static android.view.ViewGroup.LayoutParams.*; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.BACK_TO_LOC_HUD_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_IN_HUD_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_OUT_HUD_ID; +import static net.osmand.plus.UiUtilities.DialogButtonType.*; + +public class SnapTrackWarningFragment extends BaseOsmAndFragment { + + public static final int REQUEST_CODE = 1000; + public static final int CANCEL_RESULT_CODE = 2; + public static final int CONTINUE_RESULT_CODE = 3; + + public static final String TAG = SnapTrackWarningFragment.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(SnapTrackWarningFragment.class); + + private static final String ZOOM_IN_BUTTON_ID = ZOOM_IN_HUD_ID + TAG; + private static final String ZOOM_OUT_BUTTON_ID = ZOOM_OUT_HUD_ID + TAG; + private static final String BACK_TO_LOC_BUTTON_ID = BACK_TO_LOC_HUD_ID + TAG; + + protected View mainView; + private boolean continued = false; + private View cancelButton; + private View applyButton; + private boolean nightMode; + private boolean portrait; + + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + OsmandApplication app = getMyApplication(); + if (app != null) { + nightMode = app.getDaynightHelper().isNightModeForMapControls(); + portrait = AndroidUiHelper.isOrientationPortrait(getMapActivity()); + } + View rootView = UiUtilities.getInflater(getContext(), nightMode) + .inflate(R.layout.fragment_plan_route_warning, container, false); + if (rootView == null) { + return null; + } + applyButton = rootView.findViewById(R.id.right_bottom_button); + cancelButton = rootView.findViewById(R.id.dismiss_button); + View mapControlsContainer = rootView.findViewById(R.id.map_controls_container); + updateButtons(rootView); + if (portrait) { + setupControlButtons(rootView); + mapControlsContainer.setVisibility(View.VISIBLE); + } else { + mapControlsContainer.setVisibility(View.GONE); + final TypedValue typedValueAttr = new TypedValue(); + int bgAttrId = AndroidUtils.isLayoutRtl(app) ? R.attr.right_menu_view_bg : R.attr.left_menu_view_bg; + getMapActivity().getTheme().resolveAttribute(bgAttrId, typedValueAttr, true); + rootView.setBackgroundResource(typedValueAttr.resourceId); + LinearLayout mainView = rootView.findViewById(R.id.main_view); + FrameLayout.LayoutParams params; + params = (FrameLayout.LayoutParams) mainView.getLayoutParams(); + params.gravity = TOP; + int landscapeWidth = getResources().getDimensionPixelSize(R.dimen.dashboard_land_width); + rootView.setLayoutParams(new FrameLayout.LayoutParams(landscapeWidth, MATCH_PARENT)); + } + return rootView; + } + + private void setupControlButtons(@NonNull View view) { + MapActivity mapActivity = getMapActivity(); + View zoomInButtonView = view.findViewById(R.id.map_zoom_in_button); + View zoomOutButtonView = view.findViewById(R.id.map_zoom_out_button); + View myLocButtonView = view.findViewById(R.id.map_my_location_button); + View mapRulerView = view.findViewById(R.id.map_ruler_layout); + + MapActivityLayers mapLayers = mapActivity.getMapLayers(); + + OsmandMapTileView mapTileView = mapActivity.getMapView(); + View.OnLongClickListener longClickListener = MapControlsLayer.getOnClickMagnifierListener(mapTileView); + + MapControlsLayer mapControlsLayer = mapLayers.getMapControlsLayer(); + mapControlsLayer.setupZoomInButton(zoomInButtonView, longClickListener, ZOOM_IN_BUTTON_ID); + mapControlsLayer.setupZoomOutButton(zoomOutButtonView, longClickListener, ZOOM_OUT_BUTTON_ID); + mapControlsLayer.setupBackToLocationButton(myLocButtonView, false, BACK_TO_LOC_BUTTON_ID); + + MapInfoLayer mapInfoLayer = mapLayers.getMapInfoLayer(); + mapInfoLayer.setupRulerWidget(mapRulerView); + } + + private void updateButtons(View view) { + View buttonsContainer = view.findViewById(R.id.buttons_container); + buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.list_background_color)); + applyButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Fragment fragment = getTargetFragment(); + if (fragment != null) { + continued = true; + dismissImmediate(); + fragment.onActivityResult(REQUEST_CODE, CONTINUE_RESULT_CODE, null); + } + } + }); + cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.onBackPressed(); + } + } + }); + UiUtilities.setupDialogButton(nightMode, cancelButton, SECONDARY, R.string.shared_string_cancel); + UiUtilities.setupDialogButton(nightMode, applyButton, PRIMARY, R.string.shared_string_apply); + AndroidUiHelper.updateVisibility(applyButton, true); + AndroidUiHelper.updateVisibility(view.findViewById(R.id.buttons_divider), true); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + Activity activity = getActivity(); + if (activity instanceof MapActivity) { + activity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.VISIBLE); + } + Fragment fragment = getTargetFragment(); + if (fragment != null && !continued) { + fragment.onActivityResult(REQUEST_CODE, CANCEL_RESULT_CODE, null); + } + } + + public MapActivity getMapActivity() { + FragmentActivity activity = getActivity(); + if (activity instanceof MapActivity) { + return (MapActivity) activity; + } else { + return null; + } + } + + public static void showInstance(FragmentManager fm, Fragment targetFragment) { + try { + if (!fm.isStateSaved()) { + SnapTrackWarningFragment fragment = new SnapTrackWarningFragment(); + fragment.setTargetFragment(targetFragment, REQUEST_CODE); + fm.beginTransaction() + .replace(R.id.fragmentContainer, fragment, TAG) + .addToBackStack(TAG) + .commitAllowingStateLoss(); + } + } catch (RuntimeException e) { + LOG.error("showInstance", e); + } + } + + public void dismissImmediate() { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + try { + mapActivity.getSupportFragmentManager().popBackStackImmediate(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); + } catch (Exception e) { + LOG.error(e); + } + } + } +} From 8ef458826fbd7ad127e7a2b4ebf5821618e617d0 Mon Sep 17 00:00:00 2001 From: Lukas <35879422+Lukas458@users.noreply.github.com> Date: Thu, 10 Sep 2020 21:14:03 +0200 Subject: [PATCH 0018/1366] added trecycling:small_electrical_appliances recycling:small_electrical_applicances is documented in https://wiki.openstreetmap.org/wiki/Tag:amenity%3Drecycling and it's a bit more precise than just recycling:small_appliances. recycling:small_electrical_applicances gets more and more used when people want to add the information that there is the possibility to recycle these things. --- OsmAnd/res/values/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 1858dec24a..fe274284d9 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -498,6 +498,7 @@ Magazines Paper packaging Small appliances + Small electrical appliances Wood Books Shoes From ceb2825b4f608914588b2df9cc4af9748dcf1f3c Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 9 Sep 2020 18:44:36 +0000 Subject: [PATCH 0019/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3483 of 3483 strings) --- OsmAnd/res/values-pt/strings.xml | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index bba5a6aa8b..568f398f0b 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -650,7 +650,7 @@ Linguagem Próximo Anterior - Alterar unidade de medida de distância. + Alterar a unidade de medida de distância. Unidades de comprimento Milhas/pés Milhas/jardas @@ -1908,7 +1908,7 @@ Widget Mapillary Permite contribuir rapidamente para Mapillary. Fotos on-line ao nível da rua para todos. Descubra locais, colabore, capture o mundo. - Imagens de nível de rua + Mapillary Fotos ao nível da rua para todos. Descubra locais, colabore, capture o mundo. O seu destino está localizado numa área de acesso privado. Permitir uso de estradas privadas para esta viagem\? Reiniciar pesquisa @@ -2042,8 +2042,8 @@ Use a saída %1$d e continue Enviar Pontos de Interesse (POI) Cálculo da rota - Ainda não tem nenhum percurso - Também pode adicionar ficheiros GPX ao diretório + Ainda não tem nenhuns ficheiros de trilhos + Também pode adicionar ficheiros ao diretório Adicionar mais… Aparência Ativar gravação rápida @@ -2100,7 +2100,7 @@ Necessário para descarregar mapas. À procura de localização… Espaço livre - Armazenamento de dados de OsmAnd (para mapas, ficheiros GPX, etc.): %1$s. + Armazenamento de dados de OsmAnd (para mapas, ficheiros de trilhos, etc.): %1$s. Conceder permissão Permitir acesso à localização Encontrar a minha posição @@ -2961,9 +2961,9 @@ Trocar Mostrar mais Trilhos mostrados - Mostrar/ocultar trajetos GPX - Um botão para mostrar ou ocultar trajetos GPX selecionados no mapa. - Ocultar trajetos GPX + Mostrar/ocultar trilhos + Um botão para mostrar ou ocultar trilhos selecionados no mapa. + Ocultar trilhos Sem elétricos Evita elétricos Sem autocarros @@ -2989,7 +2989,7 @@ Paralelos Seixos Caminho para cavaleiros - Mostrar trajetos GPX + Mostrar trilhos Por favor defina primeiro o destino Rota anterior Adicionar casa @@ -3239,7 +3239,7 @@ Alertas mostrados no canto inferior esquerdo durante a navegação. Mudar de perfil Idioma e saída - Redefinir para o padrão + Redefinir para a predefinição Criar, importar, editar perfis Gerir perfis de app… Afeta toda a app @@ -3840,7 +3840,7 @@ Selecione um ficheiro de faixa para o qual um novo segmento será adicionado. Seguir a trilha Escolha o ficheiro de trilha a seguir - Escolha o ficheiro de trilha a seguir ou importe-o do aparelho. + Escolha o ficheiro de trilho a seguir ou importe um. Selecionar outra trilha Navegue de minha localização até a trilha Ponto da trilha para navegar @@ -3870,7 +3870,7 @@ Trilhas Adicionar ponto de passagem de trilha Gravação de viagem - GPX + REC Especifique o intervalo de registo para a gravação geral da faixa (ativado através do widget de gravação Trip no mapa). Pausar a gravação da viagem Retomar a gravação da viagem @@ -3885,4 +3885,9 @@ está gravado Adicione pelo menos dois pontos. Refazer + Trilho simplificado + Apenas a linha da rota será gravada, os pontos de passagem serão apagados. + Nome do ficheiro + %s ficheiros de faixa selecionados + Vai pausar o registo de faixas quando a aplicação for morta (através de aplicações recentes). (indicação de fundo de OsmAnd desaparece da barra de notificação do Android.) \ No newline at end of file From 504a372200795229962971781573e3f238e154c9 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 10 Sep 2020 12:34:20 +0000 Subject: [PATCH 0020/1366] Translated using Weblate (German) Currently translated at 99.9% (3482 of 3483 strings) --- OsmAnd/res/values-de/strings.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 296430c488..8e10c01079 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -2015,7 +2015,7 @@ Erforderlich, um Karten herunterzuladen. Standort wird gesucht … Freier Speicherplatz - OsmAnd speichert Daten (Karten, GPX-Dateien usw.) in \'%1$s\'. + OsmAnd speichert Daten (Karten, Track-Dateien usw.) in \'%1$s\'. Berechtigung erteilen Standortbestimmung zulassen Erhalten Sie Wegbeschreibungen und entdecken Sie neue Orte ohne Internetverbindung @@ -2072,8 +2072,8 @@ Benachrichtigungen Aussehen Routenberechnung - Sie haben noch keine GPX-Dateien - GPX-Dateien können dem Ordner hinzugefügt werden + Sie haben noch keine Track-Dateien + Track-Dateien können dem Ordner hinzugefügt werden Weitere hinzufügen … POI hochladen Nehmen Sie die %1$d Ausfahrt @@ -2901,10 +2901,10 @@ Von %1$s Schritt für Schritt Straßentypen - GPX-Tracks ein-/ausblenden - Eine Schaltfläche zum Ein- oder Ausblenden ausgewählter GPX-Tracks auf der Karte. - GPX-Tracks ausblenden - GPX-Tracks einblenden + Tracks ein-/ausblenden + Eine Schaltfläche zum Ein- oder Ausblenden ausgewählter Tracks auf der Karte. + Tracks ausblenden + Tracks einblenden Aussteigen bei Zusteigen an Haltestelle Aktivierung von OsmAnd Live für Änderungen bei öffentlichen Verkehrsmitteln. @@ -3891,4 +3891,5 @@ Anderen Track wählen Track-Punkt, zu dem navigiert werden soll Nächstgelegener Punkt + Wiederholen \ No newline at end of file From 745d84c129cb62bbf5c32ee2834abcc4a8088279 Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Thu, 10 Sep 2020 19:12:12 +0000 Subject: [PATCH 0021/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3483 of 3483 strings) --- OsmAnd/res/values-ru/strings.xml | 96 ++++++++++++++++---------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 1058b2e316..c3460fabc0 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -35,7 +35,7 @@ Файл GPX с координатами и данными выбранных заметок. Файл GPX с координатами и данными всех заметок. Место - Ваш пункт назначения находится на частной территории. Разрешить использование частных дорог для этой поездки\? + Пункт назначения находится на частной территории. Разрешить использование частных дорог на этом маршруте\? Искать снова Увеличить радиус поиска Ничего не найдено @@ -99,12 +99,12 @@ Кнопка переключения автомасштабирования на основе скорости. Включение автомасштаба Выключение автомасштаба - Установить пункт назначения + Добавить точку маршрута Заменить пункт назначения Добавить первую промежуточную точку Кнопка для установки центра экрана пунктом назначения маршрута, любой ранее выбранный пункт назначения станет последним промежуточным пунктом. Кнопка для установки центра экрана пунктом отправления. Затем будет предложено установить пункт назначения или запустить расчёт маршрута. - Кнопка для установки центра экрана пунктом назначения, заменив ранее выбранный пункт назначения (если такой был задан). + Кнопка для установки центра экрана пунктом назначения с заменой предыдущего (если был задан). Кнопка для установки центра экрана первой промежуточной точкой маршрута. Нет покрытия Нет подложки @@ -143,7 +143,7 @@ Выберите пересечённость местности Использовать данные о высотах Фактор рельефа местности (по данным SRTM, ASTER и EU-DEM). - Название быстрого действия было изменено на %1$s, чтобы избежать дублирования. + Действие переименовано в %1$s, чтобы избежать дублирования. Обнаружен дубликат имени Переключатель, чтобы показать или скрыть избранные точки на карте. Переключатель, чтобы показать или скрыть POI на карте. @@ -801,7 +801,7 @@ Только показать Запуск сопровождения Вид транспорта: - Сначала выберите пункт назначения + Сначала задайте пункт назначения Маршрут Приложение «Статус GPS» не найдено. Искать в магазине приложений\? Рабочие часы @@ -1181,9 +1181,9 @@ Добавить последним промежуточным пунктом Добавить первым промежуточным пунктом Заменить пункт назначения - Пункт назначения уже установлен: + Пункт назначения уже задан: Пункт %1$s - Пункты назначения + Точки маршрута Промежуточный пункт %1$s Удалить пункт Службы мониторинга @@ -1267,7 +1267,7 @@ Имя файла GPX Файл GPX сохранён в {0} Инструмент расчёта дистанции и планирования - Промежуточные пункты выстроены в оптимальный маршрут от текущего местоположения до пункта назначения. + Оптимальный порядок точек по пути к месту назначения. Не удалось выполнить резервное копирование изменений OSM. Резервное копирование как правка OSM высота @@ -1281,7 +1281,7 @@ Контурные линии Загрузка… Создание маршрутов по нажатию на карте, а также использование или изменение существующих файлов GPX, планирование поездки и измерение расстояния между точками. Результаты могут быть сохранены в виде файла GPX, который впоследствии может быть использован для навигации. - Установить как пункт назначения + Сделать пунктом назначения Сначала установите город или улицу Пункт назначения %1$s Тип фокусировки камеры @@ -1348,7 +1348,7 @@ Ближний план Средний план Дальний план - Избегать автомагистрали + Избегать автомагистралей Без автомагистралей Предпочитать автомагистрали Предпочитать автомагистрали @@ -1357,7 +1357,7 @@ Без грунтовых дорог Избегать грунтовых дорог Без паромов - Избегать паромные переправы + Исключить паромные переправы Максимальная масса Укажите допустимый предел массы автомобиля для учёта при построении маршрута. Отображение карты @@ -1383,7 +1383,7 @@ Быстрое построение маршрута не удалось (%s), отмените для возврата к медленному построению. Масштаб Выберите GPX… - Установить пункт назначения + Задать пункт назначения Предпочтения маршрута Информация про маршрут Добавить следующим пунктом назначения @@ -1483,7 +1483,7 @@ Интервал разбиения Старт навигации автоматически Сохранить как группу избранных - Установить пункты назначения + Задать точки маршрута Метки точек " \n @@ -1594,7 +1594,7 @@ Анонимному пользователю недоступно:\n- создание групп;\n- синхронизация групп и устройств с сервером;\n- управление группами и устройствами в личном кабинете. Вы вошли как %1$s Маршруты - Подробности + Детали Транспорт Другие атрибуты карты Настройки карты @@ -1815,11 +1815,11 @@ Переместить файлы данных Osmand в новое место назначения\? Напечатайте для поиска Номера домов - Избегать пересечение национальных границ + Избегать перехода границы Максимальная высота Укажите высоту транспортного средства для учёта при построении маршрута. - Умный перерасчёт маршрута - Перерасчёт только начальной части маршрута для длительных поездок. + Умный пересчёт маршрута + Для больших маршрутов пересчитывать только начало. Удалить правки OSM Выключено Раскраска по сетевой принадлежности @@ -2029,7 +2029,7 @@ Удалить путевую точку GPX\? Редактировать путевую точку GPX Без лестниц - Избегать лестницы и ступеньки + Избегать ступеней и лестниц Без пересечений границ Обновлять Загружать только по Wi-Fi @@ -2112,7 +2112,7 @@ Автообновления Выберите или скачайте голосовые оповещения для вашего языка. Полный отчёт - Пересчитать маршрут + Пересчёт маршрута Имя пользователя и пароль OSM Количество получателей Активные @@ -2205,7 +2205,7 @@ Не показывать новые версии Обновить все карты сейчас? Очистить всю плитку - Топливно-эффективный способ + Снижать расход топлива Использование топливо-сберегающего пути (обычно короче). Вы уверены, что хотите заменить избранные %1$s\? Изменить @@ -2670,7 +2670,7 @@ Текущий Добавляет промежуточную остановку Добавляет первую остановку - Перемещает пункт назначения и создаёт промежуточную остановку + Перемещает пункт назначения и создаёт промежуточную точку Показать закрытые заметки Показать/скрыть заметки OSM на карте. GPX — подходит для экспорта в JOSM и другие OSM редакторы. @@ -2884,7 +2884,7 @@ Гуарани Вы используете {0} карту, которая поставляется OsmAnd. Хотите запустить полную версию Osmand\? Запустить OsmAnd\? - Установить пункт назначения + Добавить точку маршрута Добавить промежуточный пункт Установить отправную точку Путь @@ -2915,7 +2915,7 @@ Работа Ровность Предыдущий маршрут - Пожалуйста, сначала установите пункт назначения + Сначала задайте пункт назначения Поменять Показать больше Отображаемые треки @@ -2998,28 +2998,28 @@ Государственная дорога Пешком Сократите длину тега «%s» до менее чем 255 символов. - Выберите виды общественного транспорта, которые следует избегать при навигации: - Избегать виды транспорта… + Выберите виды транспорта, которых следует избегать при навигации: + Исключить виды транспорта… Длина значения «%s» Режим %s Без булыжников или брусчатки - Избегать булыжники и брусчатку + Избегать мощёных улиц и брусчатки Миллирадианы Угловые единицы Изменить, в чём измеряется азимут. Градусы Без трамваев - Избегать трамваи + Исключить трамваи Без автобусов - Избегать автобусы и троллейбусы + Исключить автобусы и троллейбусы Без маршрутных такси - Избегать маршрутные такси + Исключить маршрутные такси Без поездов - Избегать поезда + Исключить поезда Без метро - Избегать метро и лёгкий железнодорожный транспорт + Исключить метро и рельсовый транспорт Без паромов - Избегать паромы + Исключить паромы • Отображение времени между пересадками в общественном транспорте \n \n• Исправлен пользовательский интерфейс для \"Детали маршрута\" @@ -3112,7 +3112,7 @@ Лыжные туры Сани Склоны для катания на санях. - Более сложные маршруты с крутыми участками. Возможны препятствия, которых следует избегать. + Более сложные маршруты с крутыми участками дороги. В целом, препятствия, которых следует избегать. Сложные маршруты, с опасными препятствиями и крутыми участками. Предпочитаемая сложность Служба скачивания OsmAnd @@ -3162,7 +3162,7 @@ Выбор настроек навигации для профиля Выбор верхней границы изменений Использовать бесконтактный датчик (сенсорный выключатель) - Пожалуйста, включите хотя бы один профиль приложения, чтобы использовать эту настройку. + Включите хотя бы один профиль, чтобы использовать эту настройку. %s сохранено Навигация OsmAnd Пользовательский профиль навигации @@ -3254,7 +3254,7 @@ Переместить в новое место назначения Внутреннее хранилище, скрытое от пользователя и других приложений. Изменение папки хранилища - Избегать определённых маршрутов и типов дорог + Исключить определённые маршруты и типы дорог Использовано %1$s ТБ Использовано %1$s ГБ Использовано %1$s МБ @@ -3454,9 +3454,9 @@ Укажите имя профиля Открыть настройки Плагин отключён - Этот плагин представляет собой отдельное приложение, вам нужно будет удалить его отдельно, если вы больше не планируете его использовать. + Плагин является отдельным приложением, удалите его отдельно, если больше не собираетесь использовать. \n -\nПлагин останется на устройстве после удаления OsmAnd. +\nПосле удаления OsmAnd плагин останется на устройстве. Меню %1$s — %2$s — %3$s Маршрутизация @@ -3464,8 +3464,8 @@ Импортируемый профиль содержит дополнительные данные. Нажмите «Импорт», чтобы импортировать только данные профиля, или выберите дополнительные данные. Вы можете выбрать дополнительные данные для экспорта вместе с профилем. Приложение по умолчанию (%s) - Отключить перерасчёт - Минимальное расстояние для перерасчёта маршрута + Не перестраивать + Минимальное отклонение для перестроения маршрута Маршрут будет пересчитан, если расстояние до него больше заданного параметра Пользовательский профиль Угол: %s° @@ -3501,7 +3501,7 @@ Ваши заметки OSM находятся в %1$s. Видеозаметки Фотозаметки - Перерасчёт маршрута + Пересчёт маршрута Имя пользователя и пароль Эти настройки применяются ко всем профилям. Редактирование OSM @@ -3537,7 +3537,7 @@ Побочный эффект: в записи трека будут отсутствовать все участки, где критерий минимальной скорости не был соблюдён (например, когда вы толкаете велосипед вверх по крутому склону). Также не будет информации о периодах покоя, например, во время отдыха. Это влияет на любой анализ или последующую обработку, например, при попытке определить общую продолжительность поездки, время в движении или среднюю скорость. Побочный эффект: в результате фильтрации по точности, точки могут быть полностью пропущены, например, под мостами, под деревьями, между высокими зданиями или при определённых погодных условиях. Примечание: при включении GPS непосредственно перед записью точность определения первой точки может быть снижена, поэтому мы рассматриваем добавление секундной задержки перед записью точки (либо записи лучшей из трёх последовательных точек и т. д.), но пока это не реализовано. - Этот фильтр позволяет избежать записи повторяющихся точек, между которыми могло произойти очень малое фактическое перемещение, и создаёт более приятный визуальный вид треков без последующей обработки. + Фильтр предотвращает запись точек при отсутствии фактического перемещения и улучшает вид треков без обработки. Побочные эффекты: периоды в состоянии покоя не записываются вообще или только по одной точке каждый. Небольшие (в реальности) перемещения (например, в сторону, указывающие возможное изменение направления движения) могут быть отфильтрованы. Файл содержит меньше информации для последующей обработки и имеет худшую статистику, отфильтровывая явно избыточные точки во время записи, при этом потенциально сохраняя артефакты, вызванные плохим приёмом или эффектами модуля GPS. Рекомендация: настройка 5 метров может должна вас устроить, если нет необходимости учитывать более короткие перемещения, и вы точное не хотите записывать данные в состоянии покоя. Указанные %1$s уже существуют в OsmAnd. @@ -3598,9 +3598,9 @@ Язык Все языки Для просмотра POI Википедии на карте необходимы дополнительные карты. - Настройка количества элементов в разделах «Панель», «Настройка карты» и контекстном меню. -\n -\nМожно отключить неиспользуемые плагины, чтобы скрыть их элементы управления. %1$s. + Настройка элементов в разделах «Панель», «Настройка карты» и контекстном меню. +\n +\nОтключите неиспользуемые плагины, чтобы скрыть их элементы управления. %1$s. Элементы панели, контекстное меню Боковое меню Элементы ниже разделённые делителем. @@ -3790,9 +3790,9 @@ Масштабирование кнопками громкости Укажите длину автомобиля, для длинных транспортных средств могут применяться ограничения на маршруте. Удалить следующий пункт - Пожалуйста, укажите название точки - Текущий пункт назначения на маршруте будет удалён. Если это пункт назначения, навигация остановится. - Информация о достопримечательностях из Википедии. Это ваш карманный автономный гид — просто включите плагин Википедии и наслаждайтесь статьями об объектах вокруг вас. + Задайте название точки + Следующая точка маршрута будет удалена. Если это конечный пункт, навигация завершится. + Информация о достопримечательностях из Википедии. Ваш карманный офлайн-гид — просто включите плагин и читайте об объектах вокруг вас. Скачать карты Википедии Эндуро мотоцикл Мотороллер @@ -3832,7 +3832,7 @@ \n \nДалее вам следует выбрать профиль для построения маршрута с учётом ограничений этого профиля. Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем. - В случае обратного направления + При обратном направлении Закрыть план маршрута без сохранения\? Все изменения будут потеряны. Изображения на уровне улиц Сохранить как новый файл трека From 2f5eea011a6621b2979a1b27b8a6876cea5e048d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Wed, 9 Sep 2020 23:25:28 +0000 Subject: [PATCH 0022/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 14.9% (522 of 3483 strings) --- OsmAnd/res/values-nb/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index aa1ff19745..34941f6d26 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -3719,4 +3719,5 @@ Ferdig Terskeldistanse Navigeringsprofil + Lukket OSM-notat \ No newline at end of file From 1ee3a3ecfb54dc2e7bf16c505d870f0922eb7484 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 10 Sep 2020 13:02:26 +0000 Subject: [PATCH 0023/1366] Translated using Weblate (German) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-de/phrases.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml index 92384a6b2a..53f9e13926 100644 --- a/OsmAnd/res/values-de/phrases.xml +++ b/OsmAnd/res/values-de/phrases.xml @@ -3817,7 +3817,7 @@ Wasserstand: über dem mittleren Wasserstand Wasserstand: unter dem mittleren Wasserstand Hindernis - Trinkwassernachfüllung: ja + ja Trinkwassernachfüllung: nein Trinkwasser-Nachfüllnetz Internetzugangsgebühr für Kunden @@ -3827,7 +3827,7 @@ Rohr Druck Pumpenzustand: fehlender Arm - Ja + ja ja kein Vibrieren Pfeil @@ -3836,4 +3836,12 @@ Stadtteil Bezirk Aufzug + Fahrplan + Echtzeit + Verspätung + ja + Anzeige der Abreisezeiten: nein + Abbiegepfeil: nein + Anzeige der Abreisezeiten + Nachfüllen von Trinkwasser \ No newline at end of file From 77eec6e222505b15f97965519b932e0dff95c439 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Wed, 9 Sep 2020 23:38:42 +0000 Subject: [PATCH 0024/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-uk/phrases.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml index 22b9d46dbc..0ceed5636b 100644 --- a/OsmAnd/res/values-uk/phrases.xml +++ b/OsmAnd/res/values-uk/phrases.xml @@ -3803,7 +3803,7 @@ Рівень води: вище середнього Рівень води: нижче середнього Завада - Поповнення питної води: так + Так Поповнення питної води: ні Мережа поповнення питної води Під тиском @@ -3822,4 +3822,11 @@ Подарункова коробка Ліфт Стрілка: ні + Розклад + Реальний час + Затримка + Так + Дошка відправлень: немає + Дошка відправлень + Поповнення питної води \ No newline at end of file From 71af148948755927937fcdfadc907201985c7ed0 Mon Sep 17 00:00:00 2001 From: Zmicer Turok Date: Thu, 10 Sep 2020 12:28:54 +0000 Subject: [PATCH 0025/1366] Translated using Weblate (Belarusian) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-be/phrases.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-be/phrases.xml b/OsmAnd/res/values-be/phrases.xml index 018f7cff3b..3227d98308 100644 --- a/OsmAnd/res/values-be/phrases.xml +++ b/OsmAnd/res/values-be/phrases.xml @@ -3838,4 +3838,7 @@ Так Расклад адпраўленняў: не Расклад адпраўленняў + Расклад + Рэальны час + Затрымка \ No newline at end of file From 1a9328caedc3acbce8d2104c5eede2a87b1a572e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 9 Sep 2020 14:58:40 +0000 Subject: [PATCH 0026/1366] Translated using Weblate (Estonian) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-et/phrases.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml index 629a0b4e08..9edfecd079 100644 --- a/OsmAnd/res/values-et/phrases.xml +++ b/OsmAnd/res/values-et/phrases.xml @@ -3792,7 +3792,7 @@ SMS Joogivee täitmise võrgustik Joogivee täitmine: ei - Joogivee täitmine: jah + Jah Takistus Veetase: alla keskmise veetaseme Veetase: üle keskmise veetaseme @@ -3816,4 +3816,11 @@ Surve Nool: ei Lift + Sõiduplaan + Reaalajas + Viivitus + Jah + Väljuvate reiside tabloo: ei + Väljuvate reiside tabloo + Joogivee täitmine \ No newline at end of file From c09ffc4e44a385deebeaece62fe653202d728798 Mon Sep 17 00:00:00 2001 From: Franco Date: Wed, 9 Sep 2020 18:14:25 +0000 Subject: [PATCH 0027/1366] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-es-rAR/phrases.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml index a90d059b97..5c24c258fb 100644 --- a/OsmAnd/res/values-es-rAR/phrases.xml +++ b/OsmAnd/res/values-es-rAR/phrases.xml @@ -3822,7 +3822,7 @@ Nivel del agua: por encima del nivel medio del agua Nivel del agua: por debajo del nivel medio del agua Obstrucción - Recarga de agua potable: sí + Recarga de agua potable: no Red de recarga de agua potable Succión @@ -3841,4 +3841,11 @@ Municipio Flecha: no Ascensor + A horario + En tiempo real + Con retraso + + Tablero de partidas: no + Tablero de partidas + Recarga de agua potable \ No newline at end of file From 69f8838676c6b07e75bc727bfd46c7ce2dd476d3 Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 9 Sep 2020 18:55:04 +0000 Subject: [PATCH 0028/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-pt/phrases.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index 84ebceecad..646845caf2 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -3771,7 +3771,7 @@ Quantidade de erupções Rede de reabastecimento de água potável Reabastecimento de água potável: não - Reabastecimento de água potável: sim + Sim Obstrução Nível da água: abaixo do nível médio da água Nível da água: acima do nível médio da água @@ -3819,4 +3819,11 @@ Give-box Seta: não Elevador + Calendário + Tempo real + Atraso + Sim + Quadro de partidas: não + Quadro de partidas + Reabastecimento de água potável \ No newline at end of file From a222ebe460fae0db6dee6d3ca39926778c01a175 Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 9 Sep 2020 18:43:19 +0000 Subject: [PATCH 0029/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (267 of 267 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/pt/ --- OsmAnd-telegram/res/values-pt/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OsmAnd-telegram/res/values-pt/strings.xml b/OsmAnd-telegram/res/values-pt/strings.xml index 8b114893d7..6076bfee91 100644 --- a/OsmAnd-telegram/res/values-pt/strings.xml +++ b/OsmAnd-telegram/res/values-pt/strings.xml @@ -163,7 +163,7 @@ Por favor, instale o Telegram e configure uma conta. Então pode usar esta app. Todos - Desativado + Desligado Precisa de uma conta e número de telefone registados no Telegram Não tenho uma conta do Telegram Digite o número de telefone @@ -204,7 +204,7 @@ A app não tem permissão para acessar os dados de localização. Por favor, ligue \"Localização\" nas configurações do sistema Selecione um dos provedores de localização para compartilhar sua localização. - Modo em segundo plano + Modo de fundo OsmAnd Tracker é executado em segundo plano com o ecrã desligado. Distância Compartilhar localização @@ -230,15 +230,15 @@ m/s km/h mph - Quilômetros por hora + Quilómetros por hora Milhas por hora Metros por segundo - Minutos por quilômetro + Minutos por quilómetro Minutos por milha Milhas náuticas por hora (nó) Milhas/pés Milhas/jardas - Quilômetros/metros + Quilómetros/metros Milhas náuticas Milhas/metros h @@ -252,7 +252,7 @@ Selecione o fuso horário a mostrar nas suas mensagens de localização. Fuso horário Unidades e formatos - Alterar unidade de distância. + Alterar a unidade de medida de distância. Unidades de comprimento Definir unidade de velocidade. Unidade de velocidade From ad015e51c64f78fcd197a167cf025c225ec0492e Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Wed, 9 Sep 2020 15:37:15 +0000 Subject: [PATCH 0030/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3821 of 3821 strings) --- OsmAnd/res/values-ru/phrases.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml index ffdab949ff..8ae4605c7c 100644 --- a/OsmAnd/res/values-ru/phrases.xml +++ b/OsmAnd/res/values-ru/phrases.xml @@ -3826,4 +3826,7 @@ Расписание отправлений: нет Расписание отправлений Заправка питьевой воды + Реальное время + Задержка + Расписание \ No newline at end of file From d7832f2a4a5f3257b65de95e32643bb9fe032f5b Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Fri, 11 Sep 2020 09:18:42 +0000 Subject: [PATCH 0031/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3484 of 3484 strings) --- OsmAnd/res/values-ru/strings.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index c3460fabc0..3d933c60cd 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3885,4 +3885,19 @@ сохраняется Добавьте как минимум два пункта. ПОВТОРИТЬ + • Обновленный режим планирования маршрута позволяет использовать разные типы навигации для каждого сегмента и прикрепляет любой трек к дорогам +\n +\n • Новые параметры внешнего вида для дорожек: выберите цвет, толщину, включите стрелки направления и отметки начала/окончания +\n +\n • Улучшена видимость велосипедных узлов +\n +\n • Контекстное меню для треков с основной информацией +\n +\n • Улучшенные алгоритмы поиска +\n +\n • Улучшены параметры следования по треку в навигации +\n +\n • Исправлены проблемы с импортом/экспортом настроек профиля +\n +\n \ No newline at end of file From 8cc8b6d19c1b37c1fe1da14bec28b1c71d5ddb60 Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Fri, 11 Sep 2020 02:30:58 +0000 Subject: [PATCH 0032/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3484 of 3484 strings) --- OsmAnd/res/values-ru/strings.xml | 176 +++++++++++++++---------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 3d933c60cd..68767b0cc6 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -57,8 +57,8 @@ Включить анимацию прокрутки карты с моим положением во время навигации. Масштаб: %1$s Имя группы - Изменить цвет - Изменить имя + Выбрать цвет + Задать имя Для больших расстояний: добавьте промежуточные пункты, если маршрут не построен в течение 10 минут. Разрешить частный доступ Разрешить доступ на частную территорию. @@ -139,15 +139,15 @@ Средняя высота Время Длина маршрута - Стиль вождения + Стиль езды Выберите пересечённость местности Использовать данные о высотах Фактор рельефа местности (по данным SRTM, ASTER и EU-DEM). Действие переименовано в %1$s, чтобы избежать дублирования. Обнаружен дубликат имени - Переключатель, чтобы показать или скрыть избранные точки на карте. + Переключатель, чтобы показать или скрыть сохранённые точки на карте. Переключатель, чтобы показать или скрыть POI на карте. - Показать/скрыть избранные + Показать/скрыть Мои места Добавить категорию Действия Если оставить это поле пустым, то оно будет автоматически заполнено адресом или названием места. @@ -233,7 +233,7 @@ Сохранить фильтр Удалить фильтр Новый фильтр - Изменить положение маркера + Изменить позицию Текущий путь Навигация OsmAnd Live Уровень заряда батареи @@ -261,7 +261,7 @@ Выберите качество видео. Подтвердить Поиск адреса - Пожалуйста, укажите корректный тип POI или оставьте его пустым. + Укажите правильный тип POI или пропустите его. Формат аудио Выберите формат аудио. Битрейт аудио @@ -390,7 +390,7 @@ Видимость Теги Описание - Пожалуйста, укажите имя и пароль пользователя OSM для отправки файлов GPX. + Укажите ваши имя пользователя OSM и пароль для отправки файлов GPX. Поддержка Поддержать разработку новых функций Показывать масштаб @@ -434,7 +434,7 @@ Голосовые подсказки (TTS, предпочтительно) Википедия (локально) Пользовательские - Файл, содержащий ранее экспортированные избранные, уже существует. Заменить его? + Файл экспорта сохранённых точек уже существует. Заменить его\? Настройки профиля Профиль по умолчанию Вид карты и настройки навигации сохраняются для каждого отдельного профиля. Установите ваш профиль по умолчанию. @@ -446,7 +446,7 @@ Прозрачная тема Нативная библиотека не поддерживается на этом устройстве. Инициализация нативной библиотеки… - Центрировать карту автоматически + Автовозврат к позиции на карте Выберите время, через которое карта вернётся к текущей позиции. Автовозврат карты только при следовании по маршруту Возвращать карту в текущее положение только при следовании по маршруту. @@ -457,12 +457,12 @@ Данные POI «%1$s» устарели и могут быть удалены. Файл с обновляемыми POI не найден и не может быть создан. Обновить до OsmAnd+ - На сервере данных были найдены файлы, не совместимые с данной версией программы. Для их использования, пожалуйста, обновите приложение. + На сервере данных были найдены файлы, не совместимые с данной версией программы. Чтобы их использовать, обновите приложение. Nominatim (Интернет) Определение положения… Моё местоположение (найдено) Адрес… - Избранные… + Сохранённые… Неопределённо Текущий центр карты Начало: @@ -475,15 +475,15 @@ Отправить в OSM Детализированная карта Показывать детали (дороги и др.), начиная с мелких масштабов. - Избранные точки удалены. + Сохранённые места удалены. Вы уверены, что хотите удалить %1$d избранных и %2$d избранных групп\? Дом Друзья Места Другое Не нужно - Отсутствует базовая карта, покрывающая весь мир на мелком масштабе. Пожалуйста загрузите World_basemap_x.obf для полноценный работы приложения. - На устройстве отсутствуют локальные данные. Пожалуйста, загрузите их для того, чтобы использовать приложение без интернета. + Отсутствует базовая карта для обзора мира на мелком масштабе. Загрузите World_basemap_x.obf + На устройстве отсутствуют локальные данные. Загрузите их, чтобы использовать приложение без интернета. " \n \nУдерживайте для вызова настроек" @@ -565,7 +565,7 @@ Отправить местоположение Поделиться местоположением Путевая точка GPX «{0}» добавлена - Добавить путевую точку к записанному треку GPX + Добавить точку в записанный трек Административное Препятствие Образование @@ -610,7 +610,7 @@ \nНавигация временно переключена на онлайн-сервис CloudMade. Невозможно найти указанную папку. Папка хранилища данных - У вас имеется предыдущая версия OsmAnd. Все локальные данные поддерживаются новой версией. Однако избранные точки нужно выгрузить из предыдущей версии приложения и загрузить в новую. + У вас установлена предыдущая версия OsmAnd. Все локальные данные поддерживаются новой версией. Однако сохранённые точки нужно вручную экспортировать из старой версии и импортировать в новую. Сборка {0} успешно установлена ({1}). Загружается сборка… Установить OsmAnd — {0} из {1} {2} МБ\? @@ -675,9 +675,9 @@ Выравнивание карты: Ориентация карты Детали маршрута - Избранные точки успешно импортированы - Файл GPX, содержащий избранные точки, не был найден в {0} - Избранные точки сохранены в {0} + Сохранённые успешно импортированы + GPX-файл с сохранёнными точками отсутствует в {0} + Точки сохранены в {0} Нет избранных точек для сохранения Не удалось загрузить GPX. Отправить отчёт @@ -796,7 +796,7 @@ Загружается список доступных регионов… Не удалось получить список регионов с https://osmand.net. Отредактирована избранная точка - Избранные точки отсутствуют + Нет сохранённых точек Заменить Только показать Запуск сопровождения @@ -905,13 +905,13 @@ Да Отмена Нет - Введите имя избранной точки - Избранная - Точка «{0}» была успешно добавлена к избранным. - Редактировать точку - Удалить точку - Удалить точку «%s» из избранных\? - Точка {0} была успешно удалена из избранных. + Название точки + Сохранённая + Точка «{0}» сохранена. + Редактировать место + Удалить из моих + Удалить точку «%s» из сохранённых\? + Точка {0} удалена. Комментарий добавлен Не удалось добавить комментарий. Комментарий @@ -1051,7 +1051,7 @@ Запись места и времени парковки вашего авто. \nИ место, и время отображаются на панели управления или как виджет на карте. Можно добавить напоминание в календаре Android. Место парковки - Пометить место парковки + Отметить парковку Удалить метку места парковки Точка отправления слишком далеко от ближайшей дороги. Общие места @@ -1210,7 +1210,7 @@ \nГлобальные данные (между 70° на севере и 70° на юге) основываются на измерениях SRTM (Shuttle Radar Topography Mission) и ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer), инструментом визуализации Terra, флагманского спутника Земли системы наблюдения NASA. ASTER является результатом совместных усилий NASA, министерства экономики Японии, торговли и промышленности (METI), космических систем Японии (J-spacesystems). Фото %1$s %2$s Аудио/видеоданные - Вы уверены, что хотите остановить навигацию? + Остановить навигацию\? Вы уверены, что хотите удалить пункт назначения (и промежуточные пункты)? Точный маршрут (альфа) Пожертвуйте, чтобы увидеть новые функции реализованными в приложении. @@ -1261,7 +1261,7 @@ Сортировать от двери до двери Доступно %1$d файлов для скачивания осталось %1$d файлов - Пожалуйста, подождите, пока завершится текущая операция + Подождите, пока завершится текущая операция Открыть существующий файл GPX Начать новый подтрек Имя файла GPX @@ -1308,7 +1308,7 @@ Названия улиц (TTS) Объявлять… Настройки озвучивания названий улиц, предупреждений о дорожном движении (принудительные остановки, искусственные неровности), камер контроля скорости и ограничений скорости. - Пожалуйста, укажите в настройках пароль и имя пользователя OSM + Укажите в настройках пароль и имя пользователя OSM Карта: Пароль OSM (необязательно) Выберите регион вождения: США, Европа, Великобритания, Азия и другие. @@ -1341,7 +1341,7 @@ Пеший туризм Мотоцикл Вы уверены, что желаете удалить %1$d изменений OSM\? - Пожалуйста, сначала рассчитайте маршрут + Сначала постройте маршрут Симуляция использования рассчитанного маршрута Симуляция использования трека GPX Без автомасштаба @@ -1455,12 +1455,12 @@ Повторять навигационные инструкции Объявление прибытия Как скоро следует сообщать о прибытии? - Избранные точки, опубликованные через OsmAnd + Места, отправленные в OsmAnd Рассчитать маршрут между точками Мировые пункты обмена bitcoin дней Соединение - Сохранить данные как файл GPX или импортировать путевые точки в избранные\? + Сохранить данные в файл GPX или импортировать путевые точки в Мои места\? Розовый Коричневый Пустой файл GPX @@ -1556,8 +1556,8 @@ Скачать недостающие карты %1$s (%2$d МБ)\? Путевые точки Дорожные предупреждения - Избранные поблизости - POI поблизости + Мои места рядом + Ближайшие POI Туры Все Расстояние @@ -1579,7 +1579,7 @@ Платный проезд Знак остановки Снизьте скорость - Скоростной радар + Камера скорости Дорожные предупреждения Выберите допустимое значение превышения скорости выше которого вы получите голосовое предупреждение. Допустимое превышение скорости @@ -1701,7 +1701,7 @@ Переименовать Удалить Удалить все - Добавить + Сохранить Применить Старт Стоп @@ -1719,10 +1719,10 @@ Выход Показать Показать все - Показать на карте + Показывать на карте Карта - Избранные - Избранные + Сохранено + Сохранённые Добавить к избранным Аудио Видео @@ -1739,9 +1739,9 @@ Отменить выбор всех Поделиться Мои места - Избранные + Точки Треки - Текущий пишущийся трек + Текущий трек Поделиться заметкой Дата выпуска Настройки навигации @@ -1781,12 +1781,12 @@ \nВ случае активации этого вида, стиль карты меняется на «Зимний/лыжный», показывая все детали пейзажа так, как они выглядят зимой. Такой (зимний) вид может быть отменён либо путём деактивации здесь, либо если вы поменяете «Стиль карты» в меню «Настройки карты» на желаемый вид. Текущий маршрут Скачать карты - Для правильного отображения дорожных знаков и правил, пожалуйста, выберите свой регион вождения: + Для правильного отображения дорожных знаков и правил выберите свой регион вождения: Добро пожаловать Отметить для удаления OsmAnd обеспечивает глобальный локальный просмотр карт и локальную навигацию. OSM изменения добавлены в локальную базу данных - Во многих странах (Германия, Франция, Италия и другие) использование предупреждения о камерах контроля скорости не допускается законом. OsmAnd не несёт никакой ответственности, если вы нарушите закон. Пожалуйста, нажмите «Да» только если вы имеете право использовать эту функцию. + Во многих странах (Германия, Франция, Италия и другие) использование предупреждений о камерах контроля скорости незаконно. OsmAnd не несёт никакой ответственности, если вы нарушите закон. Нажимайте «Да» только если вы имеете право использовать эту функцию. Информация A-GPS Данные A-GPS загружены: %1$s Сообщение @@ -1889,8 +1889,8 @@ Для применения изменения требуется перезапуск. Нравится ли вам приложение? Оценить приложение - Пожалуйста, дайте оценку OsmAnd на Google Play - Пожалуйста, дайте нам знать о любых предложениях. + Пожалуйста, оцените OsmAnd в Google Play + Отправляйте нам любые предложения. Цвет трека GPX Толщина трека GPX Нет доступных обновлений @@ -1922,10 +1922,10 @@ Добавить часы работы Тип POI Количество строк на странице %1$s - Пожалуйста, укажите тип POI. + Укажите тип POI. Жирный контур Рабочие дни - Избранные + Сохранённые Успешно сохранён в: %1$s POI будут удалены после того как вы отправите ваши изменения удалить @@ -1936,7 +1936,7 @@ Все несохранённые изменения будут потеряны. Продолжить\? Моделировать ваше местоположение, используя рассчитанный маршрут или записанный трек GPX. Остановить моделирование своего местоположения. - Добавить новую + Создать новую Выберите категорию Выберите единицы измерения скорости. Единицы измерения скорости @@ -1958,11 +1958,11 @@ Опасность Регионы Карты мира - Добавить в избранные + Сохранить в Мои места Региональные карты - Пожалуйста, используйте название категории, которое ещё не существует. + Задайте название, которое ещё не используется. Название категории - Добавить новую категорию + Добавить категорию Слой рельефа местности выключен Контурные линии выключены Дороги @@ -1988,7 +1988,7 @@ Карта загружена QR-код Показать карту - Мировая обзорная карта (охватывающая весь мир при низком уровне масштабирования) отсутствует или устарела. Пожалуйста, загрузите её для глобального обзора. + Базовая карта мира (покрывающая весь мир с низким уровнем масштабирования) отсутствует или устарела. Загрузите её для глобального обзора. Карта %1$s готова к использованию. Имитировать первый запуск Устанавливает признак первого запуска приложения, не изменяет других настроек. @@ -2050,7 +2050,7 @@ Еженедельно Месяц и страна: Открыть повторно - Выберите дороги, которых следует избегать при навигации. + Укажите дороги, которых следует избегать при навигации. Отменить все Тип Правки OSM отправлены через OsmAnd @@ -2080,11 +2080,11 @@ Не показывать моё имя в отчётах Стоимость в месяц Ежемесячный платёж - Пожалуйста, введите действительный адрес электронной почты + Введите действительный адрес электронной почты Спасибо за поддержку OsmAnd! \nЧтобы активировать все новые возможности вам нужно перезапустить приложение. Параметры подписки - Пожалуйста, сначала приобретите подписку на OsmAnd Live + Сначала приобретите подписку на OsmAnd Live Эта подписка позволяет получать ежечасное обновление для всех карт мира. \nЧасть доходов переводится сообществу OSM и выплачивается за каждый вклад в OSM. \nЕсли вы любите OsmAnd и OSM и хотите поддержать их, данная подписка — отличный способ сделать это. @@ -2134,18 +2134,18 @@ Переместить ↑ Переместить ↓ Завершить навигацию - Избегать дорог + Исключить из маршрута Публичное имя Поддерживаемый регион Пожалуйста, введите публичное имя Предлагается выбрать, прежде всего, управление приложением через гибкую панель управления или статическое меню. Ваш выбор всегда может быть изменён в настройках панели управления. Просмотр - Пожалуйста, добавьте маркеры на карте + Добавьте маркеры на карте Путевых точек не найдено Добавить маркеры для всех точек? Добавить к маркерам Активирует функцию маркеров карты. - Переключено на внутреннее хранилище, так как выбранная папка хранения данных защищена от записи. Пожалуйста, выберите папку, доступную для записи. + Переключено на внутреннюю память, поскольку выбранная папка хранения данных защищена от записи. Выберите папку, доступную для записи. Общее хранилище Сортировать Перейти вверх @@ -2207,7 +2207,7 @@ Очистить всю плитку Снижать расход топлива Использование топливо-сберегающего пути (обычно короче). - Вы уверены, что хотите заменить избранные %1$s\? + Вы уверены, что хотите заменить %1$s\? Изменить Начать от @@ -2249,7 +2249,7 @@ Некорректный OLC \n Короткий OLC -\nПожалуйста, введите полный код +\nВведите полный код Корректный полный OLC \nОписывает область: %1$s x %2$s Начать новый сегмент после 6 минутного перерыва, новый трек после 2 часового перерыва, или новый файл после длительного перерыва (если изменилась дата). @@ -2261,15 +2261,15 @@ Добавить POI Изменить стиль карты Стиль карты изменён на «%s». - Добавить место парковки + Сохранить парковку Добавить действие Редактировать действие - Добавить в избранные + Сохранить место Добавить действие Удалить действие Вы уверены, что хотите удалить действие «%s»\? - Показать избранные - Скрыть избранные + Показать сохранённые + Скрыть сохранённые Показать/скрыть POI Показать %1$s Скрыть %1$s @@ -2297,10 +2297,10 @@ Mapillary Уличные фотографии для всех. Открывайте для себя места, сотрудничайте, снимайте мир. Название содержит слишком много заглавных букв. Вы хотите продолжить? - Переключатель, чтобы приостановить или возобновить навигацию. + Кнопка приостановки и возобновления навигации. Показывать диалог завершения навигации Запуск/остановка навигации - Переключатель, чтобы начать или остановить навигацию. + Кнопка запуска и остановки навигации. Сохранять записанные треки в папках помесячно Сохранять записанные треки в подпапках с записью месяца (например, 2018-01). Кеш тайлов @@ -2327,7 +2327,7 @@ От Перезагрузить Фильтровать фотографии по отправителю, дате или типу. Фильтры применяются только для больших масштабов. - Не удалось импортировать файл. Пожалуйста, убедитесь что OsmAnd имеет разрешение на его чтение. + Не удалось импортировать файл. Убедитесь, что OsmAnd имеет разрешение на его чтение. Откорректированное расстояние Установите Mapillary, чтобы добавить фотографии этого места. Высота маршрута @@ -2335,7 +2335,7 @@ Показать на карте после сохранения Просмотрите карту и добавьте точки Измерить расстояние - Необходимо добавить хотя бы одну точку. + Добавьте хотя бы одну точку. Фотография Mapillary Улучшить фотопокрытие через Mapillary Скрыть, начиная с уровня масштабирования @@ -2385,7 +2385,7 @@ Маркеры Изменить заметку Изменить заметку OSM - Добавить копию пункта отправления в качестве пункта назначения. + Добавить пункт отправления в качестве пункта назначения. Сделать маршрут круговым Использовать местоположение Добавлено @@ -2470,23 +2470,23 @@ Полноэкранный режим Отметить пройденным Файл %1$s не содержит путевых точек, импортировать его как трек? - Выберите трек, чтобы добавить свои путевые точки к маркерам. + Выберите трек, чтобы добавить в маркеры его точки. Трек путевых точек Направо Налево Показать цифровую панель Нажатие на карте переключает кнопки управления и виджеты. - могут быть импортированы как избранные точки или как файл GPX. + возможет импорт в сохранённые точки или как файл GPX. Больше Импортировать как файл GPX - Импортировать как избранные + Импортировать в Мои места Импорт файла Неправильный ввод Просмотр Путевые точки добавлены в маркеры карты Маршрут рассчитан Путешествие - Добавить ваше местоположение как точку отправления при планировании маршрута. + Добавьте свою позицию в качестве точки отправления, чтобы построить идеальный маршрут. Показать пройденные Скрыть пройденные Удалить из «Маркеров карты» @@ -2583,7 +2583,7 @@ Сохранить точку маршрута Путевая точка 1 Точка маршрута 1 - Добавить избранные + Добавить сохранённые Избранное можно импортировать или создать, отмечая точки на карте. Импортировать файл GPX Переместить точку @@ -3043,7 +3043,7 @@ %1$d файлов (%2$s) присутствуют в предыдущем местоположении «%3$s». Переместить карты Не перемещать - Маршрут пешком составляет около %1$s, и может быть быстрее общественного транспорта + Маршрут пешком составляет около %1$s и может быть быстрее общественного транспорта Политика конфиденциальности Помогите нам сделать OsmAnd лучше Разрешите OsmAnd собирать и обрабатывать анонимные данные об использовании приложения. Мы не собираем и не храним данные о вашем местоположении или о любых местах, которые вы просматриваете на карте. @@ -3072,7 +3072,7 @@ Тип: %s Базовый профиль Выберите тип навигации - Пожалуйста, выберите тип навигации для нового приложения + Выберите тип навигации для нового профиля Введите имя профиля Сначала необходимо указать имя профиля. Уже есть профиль с таким именем @@ -3405,14 +3405,14 @@ Все настройки профиля будут сброшены в значения по умолчанию после установки. Сбросить все настройки профиля\? %1$s: %2$s - Нет правил маршрутизации в «%1$s». Пожалуйста, выберите другой файл. + Нет правил маршрутизации в «%1$s». Выберите другой файл. Для использования этой функции требуется разрешение. Это низкоскоростной фильтр отсечки, чтобы не записывать точки ниже определённой скорости. Это может сделать записанные треки более гладкими при просмотре на карте. Упорядочить категории Изменяйте порядок сортировки списка, скрывайте категории. Вы можете импортировать или экспортировать все изменения с профилями. - Вы можете добавить новую пользовательскую категорию, выбрав одну или несколько категорий. + Вы можете создать свою категорию, выбрав одну или несколько категорий из списка. Сброс к настройкам по умолчанию приведёт к возврату порядка сортировки по умолчанию. - Добавить пользовательскую категорию + Создать свою категорию Показывать только ночью Все настройки плагина восстановлены до состояния по умолчанию. Все настройки профиля восстановлены до состояния по умолчанию. @@ -3691,10 +3691,10 @@ Скрыть общественный транспорт Показать общественный транспорт Показать/скрыть общественный транспорт - Добавить/редактировать избранные + Добавить/изменить место Создать/изменить POI Возврат к редактированию - Место стоянки + Парковки Переключатель, чтобы показать или скрыть общественный транспорт на карте. Восстановить исходный порядок Нажатие кнопки «Действия» переключает между выбранными профилями. @@ -3833,7 +3833,7 @@ \nДалее вам следует выбрать профиль для построения маршрута с учётом ограничений этого профиля. Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем. При обратном направлении - Закрыть план маршрута без сохранения\? Все изменения будут потеряны. + Закрыть план маршрута\? Все изменения будут утеряны. Изображения на уровне улиц Сохранить как новый файл трека Добавить в файл трека @@ -3846,14 +3846,14 @@ Добавить файлы треков Импортируйте или запишите файлы треков Добавить путевую точку - Добавить путевую точку + Добавить к маршруту Запись поездки Сохранить как файл трека Следовать по маршруту Выберите файл маршрута для следования Выберите или импортируйте файл маршрута. Выбрать другой трек - Перейдите от моего местоположения к треку + Ведение от моей позиции к треку Точка трека для навигации Начало трека Ближайшая точка @@ -3873,7 +3873,7 @@ Укажите интервал общей записи трека (включается через виджет «Запись GPX» на карте). Остановить запись Возобновить запись поездки - По умолчанию системы + По выбору системы Все последующие сегменты Предыдущий сегмент Все предыдущие сегменты From e3078577ac64700a8d3c4acd045061afc9136937 Mon Sep 17 00:00:00 2001 From: sergosm Date: Fri, 11 Sep 2020 12:36:56 +0300 Subject: [PATCH 0033/1366] Update MeasurementToolFragment.java --- .../plus/measurementtool/MeasurementToolFragment.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 3bbc3214d1..f762a2a16c 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -1132,10 +1132,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route final ApplicationMode appMode = editingCtx.getAppMode(); if (mapActivity != null) { Drawable icon; - if (appMode == MeasurementEditingContext.DEFAULT_APP_MODE) { - icon = getActiveIcon(R.drawable.ic_action_split_interval); + if (editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData()) { + if (appMode == MeasurementEditingContext.DEFAULT_APP_MODE) { + icon = getActiveIcon(R.drawable.ic_action_split_interval); + } else { + icon = getIcon(appMode.getIconRes(), appMode.getIconColorInfo().getColor(nightMode)); + } } else { - icon = getIcon(appMode.getIconRes(), appMode.getIconColorInfo().getColor(nightMode)); + icon = getContentIcon(R.drawable.ic_action_help); } ImageButton snapToRoadBtn = (ImageButton) mapActivity.findViewById(R.id.snap_to_road_image_button); snapToRoadBtn.setImageDrawable(icon); From 016c0732c35fc684e53a28085f3220ac5f786ad2 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 11 Sep 2020 13:20:41 +0300 Subject: [PATCH 0034/1366] Fix translation --- OsmAnd/res/values-ru/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 68767b0cc6..f29ccc01c4 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3828,9 +3828,9 @@ Только следующий сегмент будет перестроен с использованием выбранного профиля. Следующий сегмент Весь трек - Для использования данной возможности OsmAnd проложит ваш трек по дорогам. + Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам. \n -\nДалее вам следует выбрать профиль для построения маршрута с учётом ограничений этого профиля. +\nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам. Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем. При обратном направлении Закрыть план маршрута\? Все изменения будут утеряны. @@ -3882,12 +3882,12 @@ Все предыдущие сегменты будут пересчитаны с использованием выбранного профиля. Открыть сохранённый трек Остановка записи GPX при принудительном закрытии (через последние приложения). (Из панели уведомлений Android исчезнет значок фонового режима.) - сохраняется - Добавьте как минимум два пункта. + сохранен + Добавьте как минимум две точки. ПОВТОРИТЬ • Обновленный режим планирования маршрута позволяет использовать разные типы навигации для каждого сегмента и прикрепляет любой трек к дорогам \n -\n • Новые параметры внешнего вида для дорожек: выберите цвет, толщину, включите стрелки направления и отметки начала/окончания +\n • Новые параметры внешнего вида для треков: выберите цвет, толщину, включите стрелки направления и отметки начала/окончания \n \n • Улучшена видимость велосипедных узлов \n From 3ec438738527d1c816a4eb281307d9d5a2cafbc7 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 11 Sep 2020 13:26:27 +0300 Subject: [PATCH 0035/1366] Fix typo --- ...agment_route_between_points_bottom_sheet_dialog.xml | 4 ++-- OsmAnd/res/values-ar/strings.xml | 10 +++++----- OsmAnd/res/values-b+kab/strings.xml | 2 +- OsmAnd/res/values-be/strings.xml | 10 +++++----- OsmAnd/res/values-ca/strings.xml | 10 +++++----- OsmAnd/res/values-da/strings.xml | 4 ++-- OsmAnd/res/values-de/strings.xml | 10 +++++----- OsmAnd/res/values-el/strings.xml | 10 +++++----- OsmAnd/res/values-eo/strings.xml | 10 +++++----- OsmAnd/res/values-es-rAR/strings.xml | 10 +++++----- OsmAnd/res/values-es-rUS/strings.xml | 10 +++++----- OsmAnd/res/values-et/strings.xml | 4 ++-- OsmAnd/res/values-eu/strings.xml | 10 +++++----- OsmAnd/res/values-fr/strings.xml | 10 +++++----- OsmAnd/res/values-hu/strings.xml | 10 +++++----- OsmAnd/res/values-is/strings.xml | 10 +++++----- OsmAnd/res/values-it/strings.xml | 10 +++++----- OsmAnd/res/values-iw/strings.xml | 10 +++++----- OsmAnd/res/values-ja/strings.xml | 10 +++++----- OsmAnd/res/values-nb/strings.xml | 10 +++++----- OsmAnd/res/values-pl/strings.xml | 10 +++++----- OsmAnd/res/values-pt-rBR/strings.xml | 10 +++++----- OsmAnd/res/values-pt/strings.xml | 10 +++++----- OsmAnd/res/values-ru/strings.xml | 10 +++++----- OsmAnd/res/values-sc/strings.xml | 10 +++++----- OsmAnd/res/values-sk/strings.xml | 10 +++++----- OsmAnd/res/values-sr/strings.xml | 10 +++++----- OsmAnd/res/values-tr/strings.xml | 10 +++++----- OsmAnd/res/values-uk/strings.xml | 10 +++++----- OsmAnd/res/values-zh-rCN/strings.xml | 10 +++++----- OsmAnd/res/values-zh-rTW/strings.xml | 10 +++++----- OsmAnd/res/values/strings.xml | 10 +++++----- .../RouteBetweenPointsBottomSheetDialogFragment.java | 4 ++-- .../plus/measurementtool/SelectFileBottomSheet.java | 2 +- .../measurementtool/SnapTrackWarningBottomSheet.java | 2 +- 35 files changed, 151 insertions(+), 151 deletions(-) diff --git a/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml b/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml index 99b4cf41ff..8e159a161e 100644 --- a/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml +++ b/OsmAnd/res/layout/fragment_route_between_points_bottom_sheet_dialog.xml @@ -40,7 +40,7 @@ android:paddingRight="@dimen/content_padding" android:paddingStart="@dimen/content_padding" android:paddingBottom="@dimen/content_padding" - android:text="@string/rourte_between_points_desc" + android:text="@string/route_between_points_desc" android:textColor="?android:textColorPrimary" android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier" osmand:typeface="@string/font_roboto_regular" @@ -58,7 +58,7 @@ android:paddingStart="@dimen/content_padding" android:paddingTop="@dimen/measurement_tool_content_padding_medium" android:paddingBottom="@dimen/measurement_tool_content_padding_medium" - android:text="@string/rourte_between_points_next_segment_button_desc" + android:text="@string/route_between_points_next_segment_button_desc" android:textColor="?android:textColorPrimary" android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier" osmand:typeface="@string/font_roboto_regular" diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 2e0f9a51b6..44e3867f3c 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3810,15 +3810,15 @@ تم الكتابة فوق المسار ملف تعريف التنقل - حدد ملف المسار الذي سيتم إضافة مقطع جديد إليه. + حدد ملف المسار الذي سيتم إضافة مقطع جديد إليه. حفظ كمسار جديد عكس الطريق - سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد. - سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد. - حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها مع ملف التعريف المحدد. + سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد. + سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد. + حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها مع ملف التعريف المحدد. مسار كامل المقطع التالي - لاستخدام هذا الخيارتحتاج إلى محاذاة المسار الخاص بك إلى خريطة الطرق. + لاستخدام هذا الخيارتحتاج إلى محاذاة المسار الخاص بك إلى خريطة الطرق. \n \nفي الخطوة التالية ، ستحتاج إلى تحديد ملف تعريف الملاحة لاكتشاف الطرق المسموح بها وبداية المسافة لتقريب تتبعك بالطرق. بداية المسافة diff --git a/OsmAnd/res/values-b+kab/strings.xml b/OsmAnd/res/values-b+kab/strings.xml index 9023496916..43d88c80b1 100644 --- a/OsmAnd/res/values-b+kab/strings.xml +++ b/OsmAnd/res/values-b+kab/strings.xml @@ -1337,6 +1337,6 @@ Abrid yettin Aḥric i d-itteddun Amaɣnu n tunigin - Fren afaylu n uḍfar iɣer ara yernu uḥric amaynut. + Fren afaylu n uḍfar iɣer ara yernu uḥric amaynut. Tebɣiḍ s tidet ad tmedleḍ abrid n uɣawas war asekles\? Ad tesruḥeḍ akk ibeddilen. \ No newline at end of file diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index 3727aa2c06..36cf216c5c 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -3697,17 +3697,17 @@ Перазапісаць след Захаваць як новы след Зваротны маршрут - Увесь след будзе пералічаны з выкарыстаннем абранага профілю. - Толькі наступны сегмент будзе пералічаны паводле абранага профілю. - Абярыце спосаб злучэння пунктаў. Варыянты: прамая лінія; разлік маршруту паводле абранага профілю. + Увесь след будзе пералічаны з выкарыстаннем абранага профілю. + Толькі наступны сегмент будзе пералічаны паводле абранага профілю. + Абярыце спосаб злучэння пунктаў. Варыянты: прамая лінія; разлік маршруту паводле абранага профілю. Увесь след Наступны сегмент - Для выкарыстання гэтага параметру OsmAnd пракладзе ваш след па дарогах. + Для выкарыстання гэтага параметру OsmAnd пракладзе ваш след па дарогах. \n \n Пасля вам патрэбна абраць профіль навігацыі для вызначэння маршруту з улікам параметраў і абмежаванняў гэтага профілю. Максімальная дыстанцыя Профіль навігацыі - Абраць файл следу, да якога будзе дададзены новы сегмент. + Абраць файл следу, да якога будзе дададзены новы сегмент. Выявы на ўзроўні вуліц Сапраўды закрыць план маршруту без захавання\? Усе змены страцяцца. У выпадку адваротнага кірунку diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index 895b086078..b6944c01bf 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -3713,17 +3713,17 @@ Abasta l\'àrea: %1$s x %2$s Afegir a una ruta Mostrar icones d\'inici final Triar amplària - Trieu un arxiu de ruta al qual s\'afegirà un nou segment. - Per usar aquesta opció OsmAnd ha d\'ajustar la seua ruta a les vies del mapa. + Trieu un arxiu de ruta al qual s\'afegirà un nou segment. + Per usar aquesta opció OsmAnd ha d\'ajustar la seua ruta a les vies del mapa. \n \nEn el pas següent cal que elegiu el perfil de navegació per detectar vies permeses i el llindar de distància per aproximar la ruta a les vies. - Trieu com connectar els punts, amb una línia recta, o calcular la ruta entre ells d\'acord amb el perfil seleccionat. + Trieu com connectar els punts, amb una línia recta, o calcular la ruta entre ells d\'acord amb el perfil seleccionat. Trieu l\'interval a què les marques de distància o temps sobre la ruta es mostraran. Personalitzat Desar com a una ruta nova Ruta inversa - La ruta sencera serà recalculada fent ús del perfil seleccionat. - Només el següent segment serà recalculat fent ús del perfil seleccionat. + La ruta sencera serà recalculada fent ús del perfil seleccionat. + Només el següent segment serà recalculat fent ús del perfil seleccionat. Ruta sencera Següent segment Llindar de distància diff --git a/OsmAnd/res/values-da/strings.xml b/OsmAnd/res/values-da/strings.xml index 54fad8d47e..058b72d771 100644 --- a/OsmAnd/res/values-da/strings.xml +++ b/OsmAnd/res/values-da/strings.xml @@ -3731,8 +3731,8 @@ Overskriv spor Gem som nyt spor Omvendt rute - Hele sporet genberegnes ved hjælp af den valgte profil. - Kun det næste segment genberegnes ved hjælp af den valgte profil. + Hele sporet genberegnes ved hjælp af den valgte profil. + Kun det næste segment genberegnes ved hjælp af den valgte profil. Hele sporet Næste segment Tærskelafstand diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 8e10c01079..16672becc8 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3829,13 +3829,13 @@ Schwellenwert-Distanz Als neuen Track speichern Route umkehren - Der gesamte Track wird mit dem ausgewählten Profil neu berechnet. - Nur das nächste Segment wird mit dem ausgewählten Profil neu berechnet. - Wählen Sie, wie Punkte mit einer geraden Linie verbunden werden sollen, oder berechnen Sie eine Route zwischen ihnen mit dem ausgewählten Profil. + Der gesamte Track wird mit dem ausgewählten Profil neu berechnet. + Nur das nächste Segment wird mit dem ausgewählten Profil neu berechnet. + Wählen Sie, wie Punkte mit einer geraden Linie verbunden werden sollen, oder berechnen Sie eine Route zwischen ihnen mit dem ausgewählten Profil. Ganzer Track Nächstes Segment Navigationsprofil - Wählen Sie eine Trackdatei, für die ein neues Segment hinzugefügt werden soll. + Wählen Sie eine Trackdatei, für die ein neues Segment hinzugefügt werden soll. Track auswählen, der verfolgt werden soll Adresse löschen Adresse hinzufügen @@ -3876,7 +3876,7 @@ Track Datei zum Folgen auswählen, oder importieren. Die GPX-Aufzeichnung wird angehalten, wenn OsmAnd beendet wird (über „zuletzt verwendete Apps“). (Die Hintergrunddienst-Anzeige verschwindet aus der Android-Benachrichtigungsleiste.) Aufzeichnungsintervall für die generelle Track-Aufzeichnung festlegen (via Schaltfläche \'GPX\' auf dem Kartenbildschirm). - Um diese Option nutzen zu können, muss OsmAnd den Track auf die Straßen der Karte einrasten. + Um diese Option nutzen zu können, muss OsmAnd den Track auf die Straßen der Karte einrasten. \n \n Wählen Sie im nächsten Schritt ein Navigationsprofil um festzulegen, welche Straßentypen verwendet werden sollen, und wählen Sie einen Wert für die maximal zulässige Entfernung zwischen Track und Straße. Track-Wegpunkt hinzufügen diff --git a/OsmAnd/res/values-el/strings.xml b/OsmAnd/res/values-el/strings.xml index d97fabeee7..9ef59f2e76 100644 --- a/OsmAnd/res/values-el/strings.xml +++ b/OsmAnd/res/values-el/strings.xml @@ -3708,17 +3708,17 @@ Σημειώστε τις επιλογές αφύπνισης της οθόνης (εξασφαλίστε ότι το OsmAnd είναι στο προσκήνιο όταν η συσκευή κλειδώνεται): Αποθήκευση ως νέου ίχνους Αντιστροφή διαδρομής - Ολόκληρο το ίχνος θα επανυπολογιστεί χρησιμοποιώντας την επιλεγμένη κατατομή (προφίλ). - Μόνο το επόμενο τμήμα θα επανυπολογιστεί χρησιμοποιώντας την επιλεγμένη κατατομή (προφίλ). - Επιλέξτε πώς να συνδέσετε τα σημεία, με ευθεία γραμμή, ή να υπολογίσετε μια διαδρομή μεταξύ τους με την επιλεγμένη κατατομή (προφίλ). - Για να χρησιμοποιήσετε αυτήν την επιλογή το OsmAnd χρειάζεται να προσκολλήσει το ίχνος σας στους δρόμους του χάρτη. + Ολόκληρο το ίχνος θα επανυπολογιστεί χρησιμοποιώντας την επιλεγμένη κατατομή (προφίλ). + Μόνο το επόμενο τμήμα θα επανυπολογιστεί χρησιμοποιώντας την επιλεγμένη κατατομή (προφίλ). + Επιλέξτε πώς να συνδέσετε τα σημεία, με ευθεία γραμμή, ή να υπολογίσετε μια διαδρομή μεταξύ τους με την επιλεγμένη κατατομή (προφίλ). + Για να χρησιμοποιήσετε αυτήν την επιλογή το OsmAnd χρειάζεται να προσκολλήσει το ίχνος σας στους δρόμους του χάρτη. \n \nΣτο επόμενο βήμα θα χρειαστείτε να επιλέξετε κατατομή (προφίλ) πλοήγησης για να εντοπίσετε τους επιτρεπόμενους δρόμους και την απόσταση κατωφλίου για να προσεγγίσετε το ίχνος σας με τους δρόμους. Ολόκληρο το ίχνος Επόμενο τμήμα Απόσταση κατωφλίου Κατατομή (προφίλ) πλοήγησης - Επιλέξτε ένα αρχείο ίχνους στο οποίο θα προστεθεί νέο τμήμα. + Επιλέξτε ένα αρχείο ίχνους στο οποίο θα προστεθεί νέο τμήμα. Τατζίκικα Μερικά άρθρα της Wikipedia μπορεί να μην είναι διαθέσιμα στη γλώσσα σας. Καντονέζικα diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index e5480958a6..304dea0021 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -3821,17 +3821,17 @@ Superskribi kurson Konservi kiel novan spuron Inversigi kurson - Tuta kurso estos rekalkulita uzante la elektitan profilon. - Nur sekva segmento estos rekalkulita uzante la elektitan profilon. - Elektu kiel konekti punktojn: ĉu per rekta linio, ĉu kalkuli kurson inter ilin uzante la elektitan profilon. + Tuta kurso estos rekalkulita uzante la elektitan profilon. + Nur sekva segmento estos rekalkulita uzante la elektitan profilon. + Elektu kiel konekti punktojn: ĉu per rekta linio, ĉu kalkuli kurson inter ilin uzante la elektitan profilon. Tuta kurso Sekva segmento - Por uzi tiun ĉi agordon, OsmAnd postulas ĝustigi vian kurson al vojoj sur la mapo. + Por uzi tiun ĉi agordon, OsmAnd postulas ĝustigi vian kurson al vojoj sur la mapo. \n \n Sekve vi devos elekti profilon de navigo (por trovi permesatajn vojojn) kaj sojlan distancon (por alproksimigi vian kurson al vojoj). Sojla distanco Profilo de navigo - Elektu dosieron de spuro al kiu nova segmento estos aldonita. + Elektu dosieron de spuro al kiu nova segmento estos aldonita. Strat-nivela fotaro Ĉu vi certe volas fermi planadon de kurso sen konservi\? Ĉiuj viaj ŝanĝoj perdiĝos. Kiam en inversa direkto diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 53987c3a28..0b581eab94 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -3826,17 +3826,17 @@ Sobrescribir traza Guardar como nueva traza Ruta inversa - Recalcular sólo el siguiente segmento usando el perfil elegido. - Recalcular toda la traza usando el perfil elegido. - Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido. + Recalcular sólo el siguiente segmento usando el perfil elegido. + Recalcular toda la traza usando el perfil elegido. + Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido. Traza completa Siguiente segmento - Para utilizar esta opción, OsmAnd debe ajustar su traza a los caminos del mapa. + Para utilizar esta opción, OsmAnd debe ajustar su traza a los caminos del mapa. \n \n En el siguiente paso se debe elegir el perfil de navegación para detectar los caminos permitidos y el umbral de distancia para aproximar la traza a los caminos. Distancia de umbral Perfil de navegación - Elige un archivo de traza al que se añadirá un nuevo segmento. + Elige un archivo de traza al que se añadirá un nuevo segmento. Imágenes a nivel de calle ¿Cerrar el plan de ruta sin guardar\? Se perderán todos los cambios. En caso de dirección inversa diff --git a/OsmAnd/res/values-es-rUS/strings.xml b/OsmAnd/res/values-es-rUS/strings.xml index 608cb6e866..29da2f288d 100644 --- a/OsmAnd/res/values-es-rUS/strings.xml +++ b/OsmAnd/res/values-es-rUS/strings.xml @@ -3834,13 +3834,13 @@ Grabar la traza automáticamente al navegar Intervalo de registro para la grabación general de trazas (activar mediante el widget de grabación de viaje sobre el mapa). Guardar como nueva traza - Recalcular toda la traza usando el perfil elegido. - Para utilizar esta opción, OsmAnd debe ajustar su traza a los caminos del mapa. + Recalcular toda la traza usando el perfil elegido. + Para utilizar esta opción, OsmAnd debe ajustar su traza a los caminos del mapa. \n \n En el siguiente paso se debe elegir el perfil de navegación para detectar los caminos permitidos y el umbral de distancia para aproximar la traza a los caminos. - Recalcular sólo el siguiente segmento usando el perfil elegido. - Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido. - Elige un archivo de traza al que se añadirá un nuevo segmento. + Recalcular sólo el siguiente segmento usando el perfil elegido. + Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido. + Elige un archivo de traza al que se añadirá un nuevo segmento. Ruta inversa Añadir punto de referencia de la traza Segmento anterior diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index d3a43c153e..d058f6ca17 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -3644,7 +3644,7 @@ Terve rada Järgmine segment Navigeerimisprofiil - Vali rajafail, millele lisame uue segmendi. + Vali rajafail, millele lisame uue segmendi. Tänavataseme vaated Kas sa oled kindel et soovid sulgeda teekonna planeerija ilma seda salvestamata\? Kõik muudatused lähevad kaotsi. Vastupidise suuna korral @@ -3662,7 +3662,7 @@ „Lähtesta vaikeseadeteks“ taastab paigaldusjärgse vaikimisi sortimisjärjekorra. Lisaprogramm arendajale Toiming %1$s ei ole toetatud - Terve rada arvutatakse valitud profiili abil uuesti. + Terve rada arvutatakse valitud profiili abil uuesti. Salvesta uue rajana Kirjuta rada üle Veebipõhine OSM kaartide klassifikatsioon piltidega. diff --git a/OsmAnd/res/values-eu/strings.xml b/OsmAnd/res/values-eu/strings.xml index bd2cfbcd31..abd30d80ff 100644 --- a/OsmAnd/res/values-eu/strings.xml +++ b/OsmAnd/res/values-eu/strings.xml @@ -3781,7 +3781,7 @@ Area honi dagokio: %1$s x %2$s Norabideko geziak Sortu ibilbide berria Distantzia margena - Aukera hau erabiltzeko OsmAnd-ek zure arrastoak mapako errepideetara atxiki behar ditu. + Aukera hau erabiltzeko OsmAnd-ek zure arrastoak mapako errepideetara atxiki behar ditu. \n \nHurrengo urratsean, nabigazio profila hautatu beharko duzu baimendutako errepideak eta zure arrastoa errepideetara hurbiltzeko distantzia tartea atzemateko. Editatutako azkena @@ -3791,12 +3791,12 @@ Area honi dagokio: %1$s x %2$s Gainidatzi arrastoa Gorde arrasto berri gisa Alderantzizko ibilbidea - Arrasto osoa birkalkulatuko da hautatutako profilaren bidez. - Bakarrik hurrengo segmentua birkalkulatuko da hautatutako profilaren bidez. - Hautatu nola konektatu puntuak, lerro zuzen batez, edo kalkulatu horien arteko ibilbidea hautatutako profilarekin. + Arrasto osoa birkalkulatuko da hautatutako profilaren bidez. + Bakarrik hurrengo segmentua birkalkulatuko da hautatutako profilaren bidez. + Hautatu nola konektatu puntuak, lerro zuzen batez, edo kalkulatu horien arteko ibilbidea hautatutako profilarekin. Arrasto osoa Hurrengo segmentua Nabigazio profila - Hautatu zein arrasto fitxategiari gehituko zaion segmentu berria. + Hautatu zein arrasto fitxategiari gehituko zaion segmentu berria. Ezarri behar dituzu lanegunak jarraitzeko \ No newline at end of file diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 726ae2b57e..401ab1f460 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3801,13 +3801,13 @@ Sélectionnez un fichier de trace à ouvrir. Terminé Remplacer la trace - Sélectionnez comment relier les points : par une ligne droite ou en calculant un itinéraire avec le profil sélectionné. - Toute la trace sera recalculée en utilisant le profil sélectionné. - Seul le prochain segment sera recalculé en utilisant le profil sélectionné. - Pour utiliser cette option, OsmAnd doit aligner votre trace sur les routes de la carte. + Sélectionnez comment relier les points : par une ligne droite ou en calculant un itinéraire avec le profil sélectionné. + Toute la trace sera recalculée en utilisant le profil sélectionné. + Seul le prochain segment sera recalculé en utilisant le profil sélectionné. + Pour utiliser cette option, OsmAnd doit aligner votre trace sur les routes de la carte. \n \n À l\'étape suivante, vous devrez sélectionner le profil de navigation pour détecter les routes autorisées et le seuil de distance pour rapprocher votre trace des routes. - Sélectionnez un fichier de trace auquel ajouter un nouveau segment. + Sélectionnez un fichier de trace auquel ajouter un nouveau segment. Enregistrer comme nouvelle trace Inverser l\'itinéraire Trace entière diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index 25eab931cf..0be4073d8b 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -3834,7 +3834,7 @@ Egyszerűsített nyomvonal Kész elmentve - Jelölje ki, hogyan legyenek összekötve a pontok: egyenes vonallal vagy a kiválasztott profilnak megfelelően kiszámított útvonallal. + Jelölje ki, hogyan legyenek összekötve a pontok: egyenes vonallal vagy a kiválasztott profilnak megfelelően kiszámított útvonallal. Teljes nyomvonal Megjegyzés: Ha a GPS közvetlenül a felvétel előtt ki volt kapcsolva, akkor rosszabb lehet az első mért pont pontossága. A kódban ezért szeretnénk majd talán várni egy-két másodpercet egy pont rögzítése előtt (vagy a 3 egymást követő pont közül a legjobbat rögzíteni vagy valami hasonló), de ezt még nem programoztuk le. Cím törlése @@ -3847,8 +3847,8 @@ Meglévő nyomvonal megnyitása Tömör Adja meg a címet - Csak a következő szakasz lesz újraszámítva a kiválasztott profilnak megfelelően. - Ennek a beállításnak a használatához az OsmAndnak hozzá kell tördelnie a nyomvonalát a térképen található utakhoz. + Csak a következő szakasz lesz újraszámítva a kiválasztott profilnak megfelelően. + Ennek a beállításnak a használatához az OsmAndnak hozzá kell tördelnie a nyomvonalát a térképen található utakhoz. \n \n A következő lépésben ki kell választania a navigációs profilt az engedélyezett utak és a küszöbtávolság észleléséhez, hogy a nyomvonalát közelíteni lehessen az utakhoz. Egyedi @@ -3867,7 +3867,7 @@ Minden korábbi szakasz Válassza ki a megnyitni kívánt nyomvonalfájlt. Útvonaltípus módosítása ez előtt: - A teljes útvonal újra lesz számítva a kiválasztott profilnak megfelelően. + A teljes útvonal újra lesz számítva a kiválasztott profilnak megfelelően. Mentés új nyomvonalként Útvonal megfordítása Cím hozzáadása @@ -3877,7 +3877,7 @@ Mellékhatások: A nyugalmi periódusok egyáltalán nem vagy csak egy ponttal rögzülnek. Kiszűrhetők a kis (valós) mozgások (pl. az út során egy átvezető út jelzése céljából megtett kitérők). A fájl kevesebb információt tartalmaz az utófeldolgozáshoz és rosszabb a statisztikája, mivel a felvételkor kiszűri a nyilvánvalóan felesleges pontokat, miközben megtarthatja a rossz vétel vagy a GPS lapkakészlet által okozott hibás mintázatok. Minden későbbi szakasz %s nyomvonalfájl kijelölve - Jelölje ki azt a nyomvonalfájlt, amelyhez az új szakasz hozzáadódjék. + Jelölje ki azt a nyomvonalfájlt, amelyhez az új szakasz hozzáadódjék. Nyomvonalak Mégis \ No newline at end of file diff --git a/OsmAnd/res/values-is/strings.xml b/OsmAnd/res/values-is/strings.xml index 97a4c5bcf6..d2404aaba2 100644 --- a/OsmAnd/res/values-is/strings.xml +++ b/OsmAnd/res/values-is/strings.xml @@ -3776,9 +3776,9 @@ \nVeldu %1$s og þú munt fá aðvaranir og ábendingar um hraðamyndavélar. \n \nVeldu %2$s: öllum gögnum sem tengjast hraðamyndavélum; t.d. aðvaranir, tilkynningar, staðsetningar o.fl. verður eytt þar til OsmAnd er sett inn aftur frá grunni. - Veldu ferilskrá þar sem nýjum bút verður bætt inn. - Veldu hvernig eigi að tengja punkta; með beinni línu eða reikna leið milli þeirra með þessu sniði. - Allur ferillinn verður endurreiknaður með völdu sniði. + Veldu ferilskrá þar sem nýjum bút verður bætt inn. + Veldu hvernig eigi að tengja punkta; með beinni línu eða reikna leið milli þeirra með þessu sniði. + Allur ferillinn verður endurreiknaður með völdu sniði. Lokaður OSM-minnispunktur Allur ferillinn Sýna tákn fyrir upphaf/enda @@ -3792,7 +3792,7 @@ Virkja þetta til að hægt sé að stýra aðdráttarstigi korts með hljóðstyrkshnöppum. Tilgreindu lengd farartækis sem leyfð er á leiðum. Ef stefna er öfug - Aðeins næsti bútur verður endurreiknaður með völdu sniði. + Aðeins næsti bútur verður endurreiknaður með völdu sniði. Enduro-mótorhjól Leið milli punkta Næsti bútur @@ -3858,7 +3858,7 @@ Settu inn heimilisfang Veldu ferilskrá til að fylgja eða flyttu inn úr tæki. Bæta í ferilskrá - Til að nota þennan valkost þarf OsmAnd að festa ferilinn þinn við vegi á kortinu. + Til að nota þennan valkost þarf OsmAnd að festa ferilinn þinn við vegi á kortinu. \n \nÍ næsta skrefi þarftu að velja leiðsagnarsnið svo hægt sé að finna hvaða vegir séu leyfilegir og hvaða þolvik vegalengdar eigi að miða við til að nálga ferilinn þinn við fyrirliggjandi vegi. Bæta við ferilskrám diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 764e5959fe..6b8fad2f81 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -3823,19 +3823,19 @@ Scegli il file di una traccia da aprire. Fatto Profilo di navigazione - Per utilizzare questa opzione OsmAnd ha bisogno di bloccare la traccia alle strade della mappa. + Per utilizzare questa opzione OsmAnd ha bisogno di bloccare la traccia alle strade della mappa. \n \n Nel prossimo passaggio avrai bisogno di selezionare il profilo di navigazione per determinare le strade permesse e la soglia della distanza per approssimare la strada alle strade. - Scegli come collegare i punti, con una linea retta, o calcolando un percorso che li colleghi utilizzando il profilo scelto. + Scegli come collegare i punti, con una linea retta, o calcolando un percorso che li colleghi utilizzando il profilo scelto. Sovrascrivi traccia Salva come nuova Traccia Inverti il percorso - Solo il nuovo segmento sarà ricalcolato utilizzando il profilo scelto. - Tutta la traccia sarà ricalcolata utilizzando il profilo scelto. + Solo il nuovo segmento sarà ricalcolato utilizzando il profilo scelto. + Tutta la traccia sarà ricalcolata utilizzando il profilo scelto. Tutta la traccia Nuovo segmento Soglia distanza - Seleziona un file traccia a cui verrà aggiunto un nuovo segmento. + Seleziona un file traccia a cui verrà aggiunto un nuovo segmento. Immagini stradali Sei sicuro di voler chiudere la Pianificazione del percorso senza salvare\? Perderai tutti i cambiamenti. In caso di direzione inversa diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index e418440ed8..ce6cf4cb93 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -3834,11 +3834,11 @@ המקטע הבא סף מרחק פרופיל ניווט - נא לבחור קובץ מסלול שבו יתווסף המקטע החדש. - כל המסלול יחושב מחדש באמצעות הפרופיל הנבחר. - רק המקטע הבא יחושב מחודש באמצעות הפרופיל הנבחר. - נא לבחור כיצד לחבר נקודות, בקו ישר, או לחבר מסלול ביניהן עם הפרופיל הנבחר. - כדי להשתמש באפשרות זו על OsmAnd להצמיד את המסלול שלך לדרכים שעל המפה. + נא לבחור קובץ מסלול שבו יתווסף המקטע החדש. + כל המסלול יחושב מחדש באמצעות הפרופיל הנבחר. + רק המקטע הבא יחושב מחודש באמצעות הפרופיל הנבחר. + נא לבחור כיצד לחבר נקודות, בקו ישר, או לחבר מסלול ביניהן עם הפרופיל הנבחר. + כדי להשתמש באפשרות זו על OsmAnd להצמיד את המסלול שלך לדרכים שעל המפה. \n \n בשלב הבא יהיה עליך לבחור בפרופיל ניווט כדי לזהות את הדרכים המורשות ואת סף המרחק כדי להעריך את המסלול שלך ביחס לדרכים. תמונות ברמת רחוב diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 3f0cdf866d..b3d6ea7d20 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -3733,17 +3733,17 @@ POIの更新は利用できません 経路を上書き 新しい経路として保存 ルート反転 - 選択したプロファイルを使用して、次のセグメントのみ再計算します。 - 選択したプロファイルを使用して、経路全体が再計算されます。 - 直線で地点間をつなげる方法をとるか、選択したプロファイルで地点間のルートを計算します。 + 選択したプロファイルを使用して、次のセグメントのみ再計算します。 + 選択したプロファイルを使用して、経路全体が再計算されます。 + 直線で地点間をつなげる方法をとるか、選択したプロファイルで地点間のルートを計算します。 全経路 次のセグメント - このオプションを使用するには、OsmAndで経路をマップ上の道路にスナップする必要があります。 + このオプションを使用するには、OsmAndで経路をマップ上の道路にスナップする必要があります。 \n \n次にナビゲーションプロファイルを選択して、利用予定の道路(一般道、高速道路)と、道路を追跡するおおよその距離を検出する必要があります。 限界距離 ナビゲーションプロファイル - 新しいセグメントを追加するための経路ファイルを選択します。 + 新しいセグメントを追加するための経路ファイルを選択します。 ストリート画像 保存せずにルート計画を終了した場合すべての変更が失われます。よろしいですか? エンデューロバイク diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index 34941f6d26..f3c79269cd 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -3705,15 +3705,15 @@ Velg en sporfil for åpning. Snu rute Overskriv spor - Hele sporet vil bli omregnet ved bruk av valgt profil. - Velg hvordan punkter skal knyttes sammen, i rett linje, eller utregnet rute mellom dem med valgt profil. - Kun neste segment vil bli omregnet ved bruk av valgt profil. + Hele sporet vil bli omregnet ved bruk av valgt profil. + Velg hvordan punkter skal knyttes sammen, i rett linje, eller utregnet rute mellom dem med valgt profil. + Kun neste segment vil bli omregnet ved bruk av valgt profil. Hele sporet Neste segment - For å bruke dette valget må OsmAnd rute sporet ditt til kartveiene. + For å bruke dette valget må OsmAnd rute sporet ditt til kartveiene. \n \n På neste steg vil du måtte velge navigasjonsprofil for oppdagelse av tillatte veier, og terskeldistanse for å anslå sporet ditt til veier. - Velg en sporfil å legge til det nye segmentet i. + Velg en sporfil å legge til det nye segmentet i. Lagre som nytt spor Opprett ny rute Ferdig diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index 7ec21316d4..5250a19bc4 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -3833,11 +3833,11 @@ Nowy segment Odległość graniczna Profil nawigacji - Wybierz plik śladu do którego zostanie dodany nowy segment. - Cała trasa zostanie ponownie wyznaczona przy użyciu wybranego profilu. - Tylko następny segment zostanie ponownie obliczony przy użyciu wybranego profilu. - Wybierz sposób łączenia punktów linią prostą lub obliczania trasy między nimi z wybranym profilem. - Aby skorzystać z tej opcji, OsmAnd musi przyciągnąć ślad do dróg mapy. + Wybierz plik śladu do którego zostanie dodany nowy segment. + Cała trasa zostanie ponownie wyznaczona przy użyciu wybranego profilu. + Tylko następny segment zostanie ponownie obliczony przy użyciu wybranego profilu. + Wybierz sposób łączenia punktów linią prostą lub obliczania trasy między nimi z wybranym profilem. + Aby skorzystać z tej opcji, OsmAnd musi przyciągnąć ślad do dróg mapy. \n \nW następnym kroku należy wybrać profil nawigacji w celu wykrycia dozwolonych dróg i odległości progowej w celu przybliżenia śledzenia drogi. Zdjęcia z poziomu ulicy diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 5e320024f5..9c22577d6c 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -3817,17 +3817,17 @@ Substituir trilha Salvar como nova trilha Rota reversa - A trilha inteira será recalculada usando o perfil selecionado. - Apenas o próximo segmento será recalculado usando o perfil selecionado. - Selecione como conectar pontos, com uma linha reta, ou calcular uma rota entre eles com o perfil selecionado. + A trilha inteira será recalculada usando o perfil selecionado. + Apenas o próximo segmento será recalculado usando o perfil selecionado. + Selecione como conectar pontos, com uma linha reta, ou calcular uma rota entre eles com o perfil selecionado. Trilha inteira Próximo segmento - Para usar esta opção, OsmAnd precisa ajustar sua trilha para as estradas do mapa. + Para usar esta opção, OsmAnd precisa ajustar sua trilha para as estradas do mapa. \n \n Na próxima etapa, você precisará selecionar o perfil de navegação para detectar as estradas permitidas e a distância limite para aproximar o rastreamento das estradas. Distância limite Perfil de navegação - Selecione um arquivo de trilha para o qual um novo segmento será adicionado. + Selecione um arquivo de trilha para o qual um novo segmento será adicionado. Imagens de rua Tem certeza de que deseja fechar plano de rota sem salvar\? Você perderá todas as alterações. Em caso de direção reversa diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index 568f398f0b..3e6ec03ab5 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -3827,17 +3827,17 @@ Sobrescrever trilho Gravar como novo trilho Rota inversa - O trilho inteiro será recalculado a usar o perfil selecionado. - Somente o próximo segmento será recalculado a usar o perfil selecionado. - Selecione como ligar pontos, com uma linha reta ou calcule uma rota entre eles com o perfil selecionado. + O trilho inteiro será recalculado a usar o perfil selecionado. + Somente o próximo segmento será recalculado a usar o perfil selecionado. + Selecione como ligar pontos, com uma linha reta ou calcule uma rota entre eles com o perfil selecionado. Trilho inteiro Próximo segmento - Para usar esta opção o OsmAnd precisa de encaixar o seu trilho nas estradas do mapa. + Para usar esta opção o OsmAnd precisa de encaixar o seu trilho nas estradas do mapa. \n \n No passo seguinte, terá de selecionar o perfil de navegação para detetar estradas permitidas e a distância limiar para se aproximar do seu trilho com as estradas. Distância limiar Perfil de navegação - Selecione um ficheiro de faixa para o qual um novo segmento será adicionado. + Selecione um ficheiro de faixa para o qual um novo segmento será adicionado. Seguir a trilha Escolha o ficheiro de trilha a seguir Escolha o ficheiro de trilho a seguir ou importe um. diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index f29ccc01c4..82814f988c 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3819,19 +3819,19 @@ Выберите файл трека для открытия. Готово Перезаписать трек - Выбрать трек, к которому будет добавлен новый сегмент. + Выбрать трек, к которому будет добавлен новый сегмент. Профиль Предельная дистанция Сохранить как новый трек Обратный маршрут - Весь трек будет перестроен с использованием выбранного профиля. - Только следующий сегмент будет перестроен с использованием выбранного профиля. + Весь трек будет перестроен с использованием выбранного профиля. + Только следующий сегмент будет перестроен с использованием выбранного профиля. Следующий сегмент Весь трек - Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам. + Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам. \n \nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам. - Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем. + Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем. При обратном направлении Закрыть план маршрута\? Все изменения будут утеряны. Изображения на уровне улиц diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index e6308e5cb2..facff58683 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3824,17 +3824,17 @@ Subraiscrie sa rasta Sarva comente una rasta noa Fùrria s\'àndala - Sa rasta intrea at a èssere torrada a calculare impreende su profilu ischertadu. - Petzi su segmentu imbeniente at a èssere torradu a calculare impreende su profilu ischertadu. - Ischerta comente connètere sos puntos: cun una lìnia reta o calculende un\'àndala intre issos cun su profilu ischertadu. + Sa rasta intrea at a èssere torrada a calculare impreende su profilu ischertadu. + Petzi su segmentu imbeniente at a èssere torradu a calculare impreende su profilu ischertadu. + Ischerta comente connètere sos puntos: cun una lìnia reta o calculende un\'àndala intre issos cun su profilu ischertadu. Rasta intrea Segmentu imbeniente - Pro impreare custa optzione OsmAnd tenet bisòngiu de alliniare sa rasta tua a sos caminos de sa mapa. + Pro impreare custa optzione OsmAnd tenet bisòngiu de alliniare sa rasta tua a sos caminos de sa mapa. \n \n In su passu chi benit as a dèpere ischertare su profilu de navigatzione pro rilevare sos caminos permìtidos e su lìmite de distàntzia pro aprossimare sa rasta tua cun sos caminos. Lìmite de distàntzia Profilu de navigatzione - Ischerta unu documentu de rasta in ue annànghere su segmentu nou. + Ischerta unu documentu de rasta in ue annànghere su segmentu nou. Fotografias a livellu de sas carreras Ses seguru de chèrrere serrare sa pianificatzione de s\'àndala chene sarvare\? As a pèrdere totu sas modìficas. In casu de diretzione furriada diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 883aec744d..cc7c2f013a 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -3822,17 +3822,17 @@ Prepísať stopu Uložiť ako novú stopu Otočiť trasu - Celá stopa bude prepočítaná pomocou zvoleného profilu. - Len nasledujúci úsek bude prepočítaný pomocou zvoleného profilu. - Zvoľte ako spojiť body, priamou čiarou alebo vypočítať trasu medzi nimi pomocou zvoleného profilu. + Celá stopa bude prepočítaná pomocou zvoleného profilu. + Len nasledujúci úsek bude prepočítaný pomocou zvoleného profilu. + Zvoľte ako spojiť body, priamou čiarou alebo vypočítať trasu medzi nimi pomocou zvoleného profilu. Celá stopa Ďalší úsek - Pre použitie tejto možnosti musí OsmAnd prichytiť vašu stopu na cesty v mape. + Pre použitie tejto možnosti musí OsmAnd prichytiť vašu stopu na cesty v mape. \n \n V ďalšom kroku budete musieť zvoliť navigačný profil pre detekciu povolených ciest a hraničnú vzdialenosť pre aproximovanie vašej stopy cestami. Hraničná vzdialenosť Navigačný profil - Zvoľte súbor stopy, pre ktorú bude pridaný nový úsek. + Zvoľte súbor stopy, pre ktorú bude pridaný nový úsek. Snímky z úrovne ulice Naozaj chcete zatvoriť plánovanie trasy bez uloženia\? Všetky zmeny sa stratia. V prípade opačného smeru diff --git a/OsmAnd/res/values-sr/strings.xml b/OsmAnd/res/values-sr/strings.xml index 98d62e33e4..fb598f330b 100644 --- a/OsmAnd/res/values-sr/strings.xml +++ b/OsmAnd/res/values-sr/strings.xml @@ -3819,17 +3819,17 @@ Замени стазу Сачувај као нову стазу Обрнута рута - Читава стаза ће се прерачунати користећи одабрани профил. - Само ће се следећи сегмент прерачунати користећи одабрани профил. - Изаберите како повезати тачке, са правом линијом, или израчунајте руту између њих са одабраним профилом. + Читава стаза ће се прерачунати користећи одабрани профил. + Само ће се следећи сегмент прерачунати користећи одабрани профил. + Изаберите како повезати тачке, са правом линијом, или израчунајте руту између њих са одабраним профилом. Цела стаза Следећи сегмент - Да бисте користили ову опцију, ОсмАнд мора да прилагоди вашу стазу путевима на мапи. + Да бисте користили ову опцију, ОсмАнд мора да прилагоди вашу стазу путевима на мапи. \n \n На следећем кораку мора ћете одабрати навигацијски профил како бисте открили дозвољене путеве и праг удаљености и тиме приближили вашу стазу путевима. Праг удаљености Навигацијски профил - Изаберите датотеку записа којој ће се додати нови сегмент. + Изаберите датотеку записа којој ће се додати нови сегмент. Слике на нивоу улице Јесте ли сигурни да желите затворити План руте без чувања\? Изгуби ћете све промене. У случају обрнутог правца diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index b5c6b9300e..58e5c1f7cc 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3778,19 +3778,19 @@ Açmak için bir yol dosyası seçin. Bitti Yolun üzerine yaz - Bu seçeneği kullanmak için OsmAnd\'ın izlediğiniz yolu harita yollarına eşleştirmesi gereklidir. + Bu seçeneği kullanmak için OsmAnd\'ın izlediğiniz yolu harita yollarına eşleştirmesi gereklidir. \n \n Sonraki adımda, izin verilen yolları tespit etmek için navigasyon profilini ve izlediğiniz yolu yaklaşık olarak belirlemek için eşik mesafesini seçmeniz gerekecektir. Yeni bir Yol olarak kaydet Ters güzergah - Tüm yol, seçilen profil kullanılarak yeniden hesaplanacaktır. - Sadece sonraki bölüm, seçilen profil kullanılarak yeniden hesaplanacaktır. - Düz bir çizgi ile noktaları nasıl birleştireceğinizi veya seçili profille aralarında nasıl güzergah hesaplayacağınızı seçin. + Tüm yol, seçilen profil kullanılarak yeniden hesaplanacaktır. + Sadece sonraki bölüm, seçilen profil kullanılarak yeniden hesaplanacaktır. + Düz bir çizgi ile noktaları nasıl birleştireceğinizi veya seçili profille aralarında nasıl güzergah hesaplayacağınızı seçin. Tüm yol Sonraki bölüm Eşik mesafesi Navigasyon profili - Kendisine yeni bir bölümün ekleneceği bir yol dosyası seçin. + Kendisine yeni bir bölümün ekleneceği bir yol dosyası seçin. Sokak seviyesi görüntüleri Kaydetmeden güzergah planlamayı kapatmak istediğinize emin misiniz\? Tüm değişiklikleri kaybedeceksiniz. Ters yön durumunda diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 7a2df33e4d..891dfd9680 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -3818,7 +3818,7 @@ Оберіть файл з треком для перегляду. Готово Перезаписати трек - Для користування цією функцією, OsmAnd необхідно прив\'язати цей трек до мапи доріг. + Для користування цією функцією, OsmAnd необхідно прив\'язати цей трек до мапи доріг. \n \nДалі вам потрібно вибрати профіль навігації для виявлення дозволених доріг та обмеження відстані наближення вашого треку до доріг. Зворотний маршрут @@ -3826,11 +3826,11 @@ Наступний сегмент Обмеження відстані Профіль навігації - Виберіть файл треку, до якого буде додано новий сегмент. + Виберіть файл треку, до якого буде додано новий сегмент. Зберегти як новий трек - Весь трек буде перераховано за допомогою вибраного профілю. - Лише наступний сегмент буде перераховано за допомогою обраного профілю. - Виберіть спосіб з\'єднання точок: прямою лінією чи розраховувати маршрут між ними за допомогою вибраного профілю. + Весь трек буде перераховано за допомогою вибраного профілю. + Лише наступний сегмент буде перераховано за допомогою обраного профілю. + Виберіть спосіб з\'єднання точок: прямою лінією чи розраховувати маршрут між ними за допомогою вибраного профілю. Зображення вулиць Ви дійсно бажаєте закрити планування маршруту без збереження\? Внесені зміни буде втрачено. Для зворотного напрямку diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index 962d8cc4fe..6de13e20e3 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -3121,7 +3121,7 @@ 添加的点在地图上不可见,因为选定的组是隐藏的,您可以在\"%s\"中找到它。 选择显示轨迹上带有距离或时间标记的间隔。 选择所需的拆分选项:“按时间”或“按距离”。 - 新的配置文件将在下一段路线计算时生效。 + 新的配置文件将在下一段路线计算时生效。 整个轨迹 最后更改 导入轨迹 @@ -3133,15 +3133,15 @@ 保存为新的轨迹 你确定在不保存的情况下退出计划路线吗?所有的更改均会丢失。 反转路线 - 全部路线会以选择的配置文件进行重新计算。 - 选择以直线或以选择的导航文件来计算路线的方式去连接导航点。 + 全部路线会以选择的配置文件进行重新计算。 + 选择以直线或以选择的导航文件来计算路线的方式去连接导航点。 下一段 - 要使用这个选项,OsmAnd 会跟踪你在地图道路上的轨迹。 + 要使用这个选项,OsmAnd 会跟踪你在地图道路上的轨迹。 \n \n在进行下一步时,你需要选择导航文件来检测与你的起始点相近的道路。 起始距离 导航文件 - 选择一个要添加新片段的跟踪文件。 + 选择一个要添加新片段的跟踪文件。 街道等级图像 防止相反的方向 删除地址 diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index bbc2ef6d57..f5ab8c7db4 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3819,17 +3819,17 @@ 覆寫軌跡 儲存為新軌跡 反向路線 - 整個軌跡都會使用選定的設定檔重新計算。 - 僅下一個片段會使用選定的設定檔重新計算。 - 選取如何連接點,用直線或以選定的設定檔計算其間的路徑。 + 整個軌跡都會使用選定的設定檔重新計算。 + 僅下一個片段會使用選定的設定檔重新計算。 + 選取如何連接點,用直線或以選定的設定檔計算其間的路徑。 整個軌道 下一段 - 要使用此選項,OsmAnd 必須將您的軌跡捕捉到地圖道路上。 + 要使用此選項,OsmAnd 必須將您的軌跡捕捉到地圖道路上。 \n \n在下一步,您只需要選取設定檔以偵測允許的道路與距離門檻以追蹤道路。 門檻距離 導航設定檔 - 選取要加入新片段的軌道檔案。 + 選取要加入新片段的軌道檔案。 街道級照片 您確定要不儲存就關閉計劃錄線嗎?您將會失去所有變更。 反向時 diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 5a7f1cf925..a3a8913a16 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -72,15 +72,15 @@ In case of reverse direction Are you sure you want to close Plan route without saving? You will lose all changes. Street-level imagery - Select a track file for which a new segment will be added. + Select a track file for which a new segment will be added. Navigation profile Threshold distance - To use this option OsmAnd need to snap your track to the map roads. \n\n On the next step you will need to select navigation profile to detect allowed roads and threshold distance to approximate you track with roads. + To use this option OsmAnd need to snap your track to the map roads. \n\n On the next step you will need to select navigation profile to detect allowed roads and threshold distance to approximate you track with roads. Next segment Whole track - Select how to connect points, with a straight line, or calculate a route between them with selected profile. - Only next segment will be recalculated using selected profile. - Whole track will be recalculated using selected profile. + Select how to connect points, with a straight line, or calculate a route between them with selected profile. + Only next segment will be recalculated using selected profile. + Whole track will be recalculated using selected profile. Reverse route Save as new Track Overwrite track diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java index f57cbd4e04..abccad0131 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java @@ -93,9 +93,9 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends MenuBottomSheet case WHOLE_ROUTE_CALCULATION: switch (dialogMode) { case SINGLE: - return getString(R.string.rourte_between_points_next_segment_button_desc); + return getString(R.string.route_between_points_next_segment_button_desc); case ALL: - return getString(R.string.rourte_between_points_whole_track_button_desc); + return getString(R.string.route_between_points_whole_track_button_desc); } break; case NEXT_ROUTE_CALCULATION: diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index 6ff4374bad..b71ef4e267 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -36,7 +36,7 @@ public class SelectFileBottomSheet extends MenuBottomSheetDialogFragment { enum Mode { OPEN_TRACK(R.string.plan_route_open_existing_track, R.string.plan_route_select_track_file_for_open), - ADD_TO_TRACK(R.string.add_to_a_track, R.string.rourte_between_points_add_track_desc); + ADD_TO_TRACK(R.string.add_to_a_track, R.string.route_between_points_add_track_desc); int title; int description; diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java index 42d051bb8c..aa75f1dd70 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningBottomSheet.java @@ -38,7 +38,7 @@ public class SnapTrackWarningBottomSheet extends MenuBottomSheetDialogFragment { activity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.GONE); } BaseBottomSheetItem description = new BottomSheetItemWithDescription.Builder() - .setDescription(getString(R.string.rourte_between_points_warning_desc)) + .setDescription(getString(R.string.route_between_points_warning_desc)) .setTitle(getString(R.string.route_between_points)) .setLayoutId(R.layout.bottom_sheet_item_list_title_with_descr) .create(); From 450cc2d68726c0a34da3921d2448257bf4ca414c Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 11 Sep 2020 14:08:54 +0300 Subject: [PATCH 0036/1366] Fix string name --- OsmAnd/res/layout/fragment_plan_route_warning.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/layout/fragment_plan_route_warning.xml b/OsmAnd/res/layout/fragment_plan_route_warning.xml index 83eeb281e5..3b7019dd9e 100644 --- a/OsmAnd/res/layout/fragment_plan_route_warning.xml +++ b/OsmAnd/res/layout/fragment_plan_route_warning.xml @@ -90,8 +90,8 @@ android:textColor="?android:textColorPrimary" android:textSize="@dimen/default_desc_text_size" osmand:typeface="@string/font_roboto_regular" - android:text="@string/rourte_between_points_warning_desc" - tools:text="@string/rourte_between_points_warning_desc" /> + android:text="@string/route_between_points_warning_desc" + tools:text="@string/route_between_points_warning_desc" /> From f48d962ede7a446d82f139a267831958b22b1892 Mon Sep 17 00:00:00 2001 From: sergosm Date: Fri, 11 Sep 2020 14:57:50 +0300 Subject: [PATCH 0037/1366] Update map_context_menu_fragment.xml --- OsmAnd/res/layout/map_context_menu_fragment.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/layout/map_context_menu_fragment.xml b/OsmAnd/res/layout/map_context_menu_fragment.xml index 49c5bc6e32..cc24c22ac5 100644 --- a/OsmAnd/res/layout/map_context_menu_fragment.xml +++ b/OsmAnd/res/layout/map_context_menu_fragment.xml @@ -220,7 +220,7 @@ android:layout_marginRight="@dimen/context_menu_padding_margin_small" android:layout_weight="1" android:ellipsize="end" - android:maxLines="1" + android:maxLines="2" osmand:typeface="@string/font_roboto_medium" tools:text="Some really long string"/> From a5942627627bb7b6b9eb9c43e05b6c3ed3ee000c Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 11 Sep 2020 15:19:52 +0300 Subject: [PATCH 0038/1366] Fix translation --- OsmAnd/res/values-ru/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 82814f988c..438fc2f8e9 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -1739,7 +1739,7 @@ Отменить выбор всех Поделиться Мои места - Точки + Избранные Треки Текущий трек Поделиться заметкой @@ -1925,7 +1925,7 @@ Укажите тип POI. Жирный контур Рабочие дни - Сохранённые + Избранные Успешно сохранён в: %1$s POI будут удалены после того как вы отправите ваши изменения удалить @@ -1958,7 +1958,7 @@ Опасность Регионы Карты мира - Сохранить в Мои места + Добавить в избранное Региональные карты Задайте название, которое ещё не используется. Название категории @@ -2261,10 +2261,10 @@ Добавить POI Изменить стиль карты Стиль карты изменён на «%s». - Сохранить парковку + Добавить место парковки Добавить действие Редактировать действие - Сохранить место + Добавить в избранное Добавить действие Удалить действие Вы уверены, что хотите удалить действие «%s»\? From df452989d1e713ccc3ccdb2c280b7532b2684c67 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 11 Sep 2020 15:24:52 +0300 Subject: [PATCH 0039/1366] Fix show Plan route UI after user selection from bottom sheet or choose different animation --- .../plus/activities/MapActivityActions.java | 3 +- .../net/osmand/plus/helpers/ImportHelper.java | 6 +- .../MeasurementToolFragment.java | 53 ++--------- .../StartPlanRouteBottomSheet.java | 87 ++++++++++++------- 4 files changed, 66 insertions(+), 83 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index d1096c74c4..ab05b2e2f3 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -59,6 +59,7 @@ import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment import net.osmand.plus.mapmarkers.MapMarkersDialogFragment; import net.osmand.plus.mapmarkers.MarkersPlanRouteContext; import net.osmand.plus.measurementtool.MeasurementToolFragment; +import net.osmand.plus.measurementtool.StartPlanRouteBottomSheet; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.WaypointsFragment; @@ -929,7 +930,7 @@ public class MapActivityActions implements DialogProvider { .setListener(new ItemClickListener() { @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) { - MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager()); + StartPlanRouteBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); return true; } }).createItem()); diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index 3d63266db9..9be5fa7277 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -1108,11 +1108,7 @@ public class ImportHelper { } private void showPlanRouteFragment() { - MeasurementToolFragment fragment = (MeasurementToolFragment) activity.getSupportFragmentManager() - .findFragmentByTag(MeasurementToolFragment.TAG); - if (fragment != null && !fragment.isDetached() && !fragment.isRemoving()) { - fragment.addNewGpxData(result); - } + MeasurementToolFragment.showInstance(activity.getSupportFragmentManager(), result); } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 8007470ba6..33d4f5cf5c 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -97,9 +97,7 @@ import static net.osmand.plus.measurementtool.MeasurementEditingContext.Calculat import static net.osmand.plus.measurementtool.MeasurementEditingContext.SnapToRoadProgressListener; import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.ADD_TO_TRACK; -import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.SelectFileListener; -import static net.osmand.plus.measurementtool.StartPlanRouteBottomSheet.StartPlanRouteListener; import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode; import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.AFTER; import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.ALL; @@ -458,9 +456,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route if (savedInstanceState == null) { if (fileName != null) { addNewGpxData(getGpxFile(fileName)); - } else if (editingCtx.isNewData() && planRouteMode && initialPoint == null) { - StartPlanRouteBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), - createStartPlanRouteListener()); } else if (!editingCtx.isNewData() && !editingCtx.hasRoutePoints() && !editingCtx.hasRoute() && editingCtx.getPointsCount() > 1) { enterApproximationMode(mapActivity); } @@ -949,47 +944,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } } - private StartPlanRouteListener createStartPlanRouteListener() { - return new StartPlanRouteListener() { - @Override - public void openExistingTrackOnClick() { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - SelectFileBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), - createSelectFileListener(), OPEN_TRACK); - } - } - - @Override - public void openLastEditTrackOnClick(String gpxFileName) { - addNewGpxData(getGpxFile(gpxFileName)); - } - - @Override - public void dismissButtonOnClick() { - quit(true); - } - }; - } - - private SelectFileListener createSelectFileListener() { - return new SelectFileListener() { - @Override - public void selectFileOnCLick(String gpxFileName) { - addNewGpxData(getGpxFile(gpxFileName)); - } - - @Override - public void dismissButtonOnClick() { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - StartPlanRouteBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), - createStartPlanRouteListener()); - } - } - }; - } - private GPXFile getGpxFile(String gpxFileName) { OsmandApplication app = getMyApplication(); GPXFile gpxFile = null; @@ -1933,6 +1887,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route return showFragment(fragment, fragmentManager); } + public static boolean showInstance(FragmentManager fragmentManager, GPXFile gpxFile) { + MeasurementToolFragment fragment = new MeasurementToolFragment(); + fragment.addNewGpxData(gpxFile); + fragment.setPlanRouteMode(true); + return showFragment(fragment, fragmentManager); + } + public static boolean showInstance(FragmentManager fragmentManager, MeasurementEditingContext editingCtx, boolean planRoute) { MeasurementToolFragment fragment = new MeasurementToolFragment(); fragment.setEditingCtx(editingCtx); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java index aedb65ee72..666fe4f0a6 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java @@ -9,6 +9,7 @@ import android.view.View; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.view.ContextThemeWrapper; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -19,6 +20,7 @@ import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BottomSheetBehaviourDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; @@ -37,6 +39,7 @@ import java.util.Comparator; import java.util.List; import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo; +import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK; public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragment { @@ -47,13 +50,8 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen protected View mainView; protected GpxTrackAdapter adapter; - private StartPlanRouteListener listener; private ImportHelper importHelper; - public void setListener(StartPlanRouteListener listener) { - this.listener = listener; - } - @Override public void createMenuItems(Bundle savedInstanceState) { importHelper = new ImportHelper((AppCompatActivity) getActivity(), getMyApplication(), null); @@ -70,6 +68,10 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + FragmentActivity activity = getActivity(); + if (activity != null) { + MeasurementToolFragment.showInstance(activity.getSupportFragmentManager()); + } dismiss(); } }) @@ -83,10 +85,12 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (listener != null) { - listener.openExistingTrackOnClick(); + MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null) { + hideBottomSheet(); + SelectFileBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), + createSelectFileListener(), OPEN_TRACK); } - dismiss(); } }) .create(); @@ -137,14 +141,15 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen @Override protected int getPeekHeight() { - return AndroidUtils.dpToPx(getContext(), BOTTOM_SHEET_HEIGHT_DP); + return AndroidUtils.dpToPx(requiredMyApplication(), BOTTOM_SHEET_HEIGHT_DP); } private void onItemClick(int position, List gpxInfoList) { if (position != RecyclerView.NO_POSITION && position < gpxInfoList.size()) { String fileName = gpxInfoList.get(position).getFileName(); - if (listener != null) { - listener.openLastEditTrackOnClick(fileName); + FragmentActivity activity = getActivity(); + if (activity != null) { + MeasurementToolFragment.showInstance(activity.getSupportFragmentManager(), fileName); } } dismiss(); @@ -189,35 +194,55 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen } } - public static void showInstance(FragmentManager fragmentManager, StartPlanRouteListener listener) { + private SelectFileBottomSheet.SelectFileListener createSelectFileListener() { + return new SelectFileBottomSheet.SelectFileListener() { + @Override + public void selectFileOnCLick(String gpxFileName) { + dismiss(); + MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null) { + MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), gpxFileName); + } + } + + @Override + public void dismissButtonOnClick() { + MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null) { + showBottomSheet(); + } + } + }; + } + + public static void showInstance(FragmentManager fragmentManager) { if (!fragmentManager.isStateSaved()) { StartPlanRouteBottomSheet fragment = new StartPlanRouteBottomSheet(); - fragment.setUsedOnMap(true); fragment.setRetainInstance(true); - fragment.setListener(listener); fragment.show(fragmentManager, TAG); } } + protected void hideBottomSheet() { + MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null) { + FragmentManager manager = mapActivity.getSupportFragmentManager(); + manager.beginTransaction() + .hide(this).commit(); + } + } + + protected void showBottomSheet() { + MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null) { + FragmentManager manager = mapActivity.getSupportFragmentManager(); + manager.beginTransaction() + .show(this).commit(); + } + } + @Override protected int getDismissButtonTextId() { return R.string.shared_string_cancel; } - - @Override - protected void onDismissButtonClickAction() { - if (listener != null) { - listener.dismissButtonOnClick(); - } - } - - interface StartPlanRouteListener { - - void openExistingTrackOnClick(); - - void openLastEditTrackOnClick(String fileName); - - void dismissButtonOnClick(); - - } } From afbb7902ac4c55050ea5650e0fcab4c6b7c77473 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 11 Sep 2020 16:12:42 +0300 Subject: [PATCH 0040/1366] Fix #9775 --- .../plus/measurementtool/MeasurementToolFragment.java | 8 +++++++- .../plus/routepreparationmenu/FollowTrackFragment.java | 6 ++++-- .../plus/routepreparationmenu/MapRouteInfoMenu.java | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 8007470ba6..7aee988d21 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -168,6 +168,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route this.planRouteMode = planRouteMode; } + private void setDirectionMode(boolean directionMode) { + this.directionMode = directionMode; + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @@ -1933,10 +1937,12 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route return showFragment(fragment, fragmentManager); } - public static boolean showInstance(FragmentManager fragmentManager, MeasurementEditingContext editingCtx, boolean planRoute) { + public static boolean showInstance(FragmentManager fragmentManager, MeasurementEditingContext editingCtx, + boolean planRoute, boolean directionMode) { MeasurementToolFragment fragment = new MeasurementToolFragment(); fragment.setEditingCtx(editingCtx); fragment.setPlanRouteMode(planRoute); + fragment.setDirectionMode(directionMode); return showFragment(fragment, fragmentManager); } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index 12346bcf12..4f9214438e 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -82,6 +82,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca private GPXFile gpxFile; + private boolean editingTrack; private boolean selectingTrack; private int menuTitleHeight; @@ -529,6 +530,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca public void openPlanRoute(boolean useAppMode) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null && gpxFile != null) { + editingTrack = true; QuadRect rect = gpxFile.getRect(); TrkSegment segment = gpxFile.getNonEmptyTrkSegment(); ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT; @@ -538,7 +540,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca if (useAppMode) { editingContext.setAppMode(app.getRoutingHelper().getAppMode()); } - MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), editingContext, true); + MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), editingContext, true, true); } } @@ -609,7 +611,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca private void onDismiss() { try { MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { + if (mapActivity != null && !editingTrack) { if (!mapActivity.isChangingConfigurations()) { mapActivity.getMapRouteInfoMenu().cancelSelectionFromTracks(); } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java index 876804b945..f3576af790 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java @@ -1566,6 +1566,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener if (mapActivity != null) { GPXRouteParamsBuilder routeParams = mapActivity.getRoutingHelper().getCurrentGPXRoute(); if (routeParams != null) { + hide(); selectTrack(); } } From 0c42601620724a11ec7f9c58e10ca1ebf9fe0f47 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 11 Sep 2020 16:57:09 +0300 Subject: [PATCH 0041/1366] Remove unnecessary dimen resource --- OsmAnd/res/layout/point_editor_fragment_new.xml | 4 ++-- OsmAnd/res/values/dimens.xml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml index 8ac753afc0..7dc6929004 100644 --- a/OsmAnd/res/layout/point_editor_fragment_new.xml +++ b/OsmAnd/res/layout/point_editor_fragment_new.xml @@ -150,7 +150,7 @@ 1.2 5dp - 42dp \ No newline at end of file From 7161a08a66b606df0515ca91ea6bc029cd52ca2c Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 11 Sep 2020 17:04:26 +0300 Subject: [PATCH 0042/1366] Fix divider padding --- OsmAnd/res/layout/point_editor_fragment_new.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml index 7dc6929004..95d1feb56b 100644 --- a/OsmAnd/res/layout/point_editor_fragment_new.xml +++ b/OsmAnd/res/layout/point_editor_fragment_new.xml @@ -167,9 +167,11 @@ tools:text="@string/add_address" /> + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginLeft="@dimen/content_padding" + android:layout_marginRight="@dimen/content_padding" + android:background="?attr/dashboard_divider" /> Date: Fri, 11 Sep 2020 17:51:36 +0300 Subject: [PATCH 0043/1366] Fix #9772 --- .../osmand/plus/measurementtool/MeasurementEditingContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index e365348586..105c947ddc 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -743,7 +743,7 @@ public class MeasurementEditingContext { locations.add(l); } pair.second.setTrkPtIndex(locations.size() - 1); - if (i < size - 2) { + if (i < size - 2 && !locations.isEmpty()) { locations.remove(locations.size() - 1); } route.addAll(data.segments); From b0e3cc99cbd5b7b5651dcb34e6a70481a122fc41 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 11 Sep 2020 18:28:06 +0300 Subject: [PATCH 0044/1366] Fix #9777 --- OsmAnd/AndroidManifest.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index f2d870080b..9adf3b6482 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -484,11 +484,17 @@ - + + + + + + + From 0173e3c8818c9e18ae582399c293a7482579f583 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Fri, 11 Sep 2020 18:12:41 +0200 Subject: [PATCH 0045/1366] Fix xml --- OsmAnd/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index aaf33c5e36..0084a20c5a 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -80,7 +80,7 @@ Whole track Select how to connect points, with a straight line, or calculate a route between them with selected profile. Only the next segment will be recalculated using selected profile. - The whole track will be recalculated using the selected profile. + The whole track will be recalculated using the selected profile. Reverse route Save as new track Overwrite track From 45700f4ad906b87ead228855f31c9a283d0bee9e Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Fri, 11 Sep 2020 18:18:04 +0200 Subject: [PATCH 0046/1366] Fix xml --- OsmAnd/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 0084a20c5a..50c8ed0079 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -78,9 +78,9 @@ Next, snap your track to the nearest allowed road with one of your navigation profiles to use this option. Next segment Whole track - Select how to connect points, with a straight line, or calculate a route between them with selected profile. - Only the next segment will be recalculated using selected profile. - The whole track will be recalculated using the selected profile. + Select how to connect points, with a straight line, or calculate a route between them with selected profile. + Only the next segment will be recalculated using selected profile. + The whole track will be recalculated using the selected profile. Reverse route Save as new track Overwrite track From 843a86bc5ab4aeeae223aab04a72bf2f28ae0ae6 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 11 Sep 2020 19:31:15 +0300 Subject: [PATCH 0047/1366] Fix compilation --- OsmAnd/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 50c8ed0079..7f95db8cd1 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -72,10 +72,10 @@ In case of reverse direction Are you sure you want discard all changes in the planned route by closing it? Street-level imagery - Select a track file to add the new segment to. + Select a track file to add the new segment to. Navigation profile Threshold distance - Next, snap your track to the nearest allowed road with one of your navigation profiles to use this option. + Next, snap your track to the nearest allowed road with one of your navigation profiles to use this option. Next segment Whole track Select how to connect points, with a straight line, or calculate a route between them with selected profile. From 1509301779c508d975f193881ad64ec8d9cdb3e5 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 11 Sep 2020 23:03:07 +0200 Subject: [PATCH 0048/1366] Improve bug templates --- .github/ISSUE_TEMPLATE/2-faq-report.md | 2 +- .github/ISSUE_TEMPLATE/3-bug-report.md | 18 ++++++++++-------- .github/ISSUE_TEMPLATE/4-routing-report.md | 14 ++++++++++---- .github/ISSUE_TEMPLATE/5-feature-request.md | 9 +++++---- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/2-faq-report.md b/.github/ISSUE_TEMPLATE/2-faq-report.md index fbc18c4381..531d263d7f 100644 --- a/.github/ISSUE_TEMPLATE/2-faq-report.md +++ b/.github/ISSUE_TEMPLATE/2-faq-report.md @@ -1,8 +1,8 @@ --- name: "📚 Outdated FAQ" about: Report an issue in FAQ - --- + 🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑 Please do not file FAQ issues on the GitHub issues tracker. diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md index d12ea14578..ecf870be10 100644 --- a/.github/ISSUE_TEMPLATE/3-bug-report.md +++ b/.github/ISSUE_TEMPLATE/3-bug-report.md @@ -2,6 +2,7 @@ name: "\U0001F41E Bug report" about: Report a bug in OsmAnd --- + Yes, the previous version in which this bug was not present was: .... - ### Description - A clear and concise description of the problem... - + ## 🔬 Minimal Reproduction + 1. Open app, and click on ... ## 🔥 Exception or Error +

 
 
 
 
- -## 🌍 Your Environment +## 🌍 Your Environment **OsmAnd Version:** +

 
 
@@ -60,10 +61,11 @@ If the bug is reproducible, please describe steps below:
 **Device and Android/iOS version:**
 
 **Maps used (online or offline):**
+
 
-- [ ] Offline maps offered within the OsmAnd app for download. 
-  
+
+- [ ] Offline maps offered within the OsmAnd app for download.
+
 - [ ] Online (tile / raster) maps 
 
-
 **Anything else relevant?**
diff --git a/.github/ISSUE_TEMPLATE/4-routing-report.md b/.github/ISSUE_TEMPLATE/4-routing-report.md
index 4c1e68c11a..216cd4b402 100644
--- a/.github/ISSUE_TEMPLATE/4-routing-report.md
+++ b/.github/ISSUE_TEMPLATE/4-routing-report.md
@@ -2,6 +2,7 @@
 name: "\U0001F6A9 Routing report"
 about: Report a routing issue in OsmAnd
 ---
+
 
+
 - [ ] OsmAnd's in-app offline routing
 - [ ] Any online routing provider (YOURS, OpenRouteService, OSRM, etc.)
 
 ### Routing Profile
+
 
 
 ### Start and end points
@@ -38,6 +41,7 @@ Please give us the following information so that we can try to **reproduce** you
 Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can be helpful. -->
 
 ### Actual and expected routes
+
 
 
 ### Is this a regression?
@@ -45,9 +49,10 @@ Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can b
 
  Yes, the previous version in which this bug was not present was: ....
 
-## 🌍  Your Environment
+## 🌍 Your Environment
 
 **OsmAnd Version:**
+
 

 
 
@@ -57,10 +62,11 @@ Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can b
 **Device and Android/iOS version:**
 
 **Maps used (online or offline):**
+
 
-- [ ] Offline maps offered within the OsmAnd app for download. 
-  
+
+- [ ] Offline maps offered within the OsmAnd app for download.
+
 - [ ] Online (tile / raster) maps 
 
-
 **Anything else relevant?**
diff --git a/.github/ISSUE_TEMPLATE/5-feature-request.md b/.github/ISSUE_TEMPLATE/5-feature-request.md
index 046fb3a90f..9c46069f8c 100644
--- a/.github/ISSUE_TEMPLATE/5-feature-request.md
+++ b/.github/ISSUE_TEMPLATE/5-feature-request.md
@@ -1,11 +1,11 @@
 ---
 name: "\U0001F680 Feature request"
 about: Suggest a feature for OsmAnd
-
 ---
+
  A clear and concise description of the problem or missing capability...
 
+
 
 ### Describe the solution you'd like
+
  If you have a solution in mind, please describe it.
 
-
 ### Describe alternatives you've considered
+
  Have you considered any alternative solutions or workarounds?

From 5fa7f47cda678d7e282511e57aeaea531798c33a Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Fri, 11 Sep 2020 15:12:56 +0000
Subject: [PATCH 0049/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml
index 568f398f0b..c60ed23da3 100644
--- a/OsmAnd/res/values-pt/strings.xml
+++ b/OsmAnd/res/values-pt/strings.xml
@@ -3890,4 +3890,19 @@
     Nome do ficheiro
     %s ficheiros de faixa selecionados
     Vai pausar o registo de faixas quando a aplicação for morta (através de aplicações recentes). (indicação de fundo de OsmAnd desaparece da barra de notificação do Android.)
+    - O modo Rota do Plano Atualizado permite usar diferentes tipos de navegação para cada segmento e anexa qualquer pista às estradas
+\n
+\n - Novas opções de aparência para pistas: selecionar cor, espessura, rodar nas setas de direcção e marcas de início/fim
+\n
+\n - Melhoria da visibilidade dos nós da bicicleta
+\n
+\n - Menu de contexto para faixas com informações básicas
+\n
+\n - Algoritmos de pesquisa melhorados
+\n
+\n - Opções de faixa de acompanhamento melhoradas na navegação
+\n
+\n - Problemas fixos com as configurações de importação/exportação de perfis
+\n
+\n
 
\ No newline at end of file

From f439a3c2fdae1f4968c744f955c83a2e8c28d344 Mon Sep 17 00:00:00 2001
From: Ldm Public 
Date: Thu, 10 Sep 2020 21:56:35 +0000
Subject: [PATCH 0050/1366] Translated using Weblate (French)

Currently translated at 99.7% (3476 of 3484 strings)
---
 OsmAnd/res/values-fr/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml
index 726ae2b57e..573c593af2 100644
--- a/OsmAnd/res/values-fr/strings.xml
+++ b/OsmAnd/res/values-fr/strings.xml
@@ -3231,7 +3231,7 @@
     Apparence de la carte
     Apparence de la carte
     Thème de l\'application, unités, région
-    Restaurer les valeurs par défaut
+    Rétablir les paramètres par défaut
     Alertes visuelles
     Définir les paramètres de l\'itinéraire
     Paramètres de l\'itinéraire

From 0155e7a09b5e8bd43d9eb65d7b634e9b5433254f Mon Sep 17 00:00:00 2001
From: Nikita Epifanov 
Date: Fri, 11 Sep 2020 09:20:06 +0000
Subject: [PATCH 0051/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 68767b0cc6..1b4c82d601 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -482,7 +482,7 @@
     Места
     Другое
     Не нужно
-    Отсутствует базовая карта для обзора мира на мелком масштабе. Загрузите World_basemap_x.obf
+    Загрузите базовую карту мира, чтобы получить обзор всего мира с низким уровнем масштабирования.
     На устройстве отсутствуют локальные данные. Загрузите их, чтобы использовать приложение без интернета.
     "
 \n

From 478fb7fc8a0f67939aba50e1001b3aa73b424120 Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Thu, 10 Sep 2020 21:50:53 +0000
Subject: [PATCH 0052/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-uk/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml
index 7a2df33e4d..47088f053c 100644
--- a/OsmAnd/res/values-uk/strings.xml
+++ b/OsmAnd/res/values-uk/strings.xml
@@ -3883,4 +3883,19 @@
     Буде збережено лише лінію маршруту, а проміжні точки буде видалено.
     Назва файлу
     Повторити
+    • Оновлений режим планування маршруту дозволяє застосувати різні типи переходів для кожного сегмента і прив\'язує будь-який трек до доріг
+\n
+\n• Нові параметри вигляду треків: вибір кольору, товщина стрілки напрямку та позначки початку/завершення
+\n
+\n• Покращено оглядовість велосипедних вузлів
+\n
+\n• Контекстне меню для треків з основною інформацією
+\n
+\n• Вдосконалено алгоритми пошуку
+\n
+\n• Вдосконалено параметри стеження за треками в навігації
+\n
+\n• Виправлено вади перенесення налаштувань профілю
+\n
+\n
 
\ No newline at end of file

From 6937da7f42345a8f87eef019d8f5f1cfe140343c Mon Sep 17 00:00:00 2001
From: Mirco Zorzo 
Date: Fri, 11 Sep 2020 17:30:23 +0000
Subject: [PATCH 0053/1366] Translated using Weblate (Italian)

Currently translated at 89.9% (3133 of 3484 strings)
---
 OsmAnd/res/values-it/strings.xml | 35 +++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml
index 764e5959fe..f108b3b501 100644
--- a/OsmAnd/res/values-it/strings.xml
+++ b/OsmAnd/res/values-it/strings.xml
@@ -3845,7 +3845,7 @@
     Tracce
     Tracce
     Tracce
-    GPX
+    REG
     Registra la traccia in un file GPX
     Traccia di un percorso
     Aggiungi dei file traccia
@@ -3870,4 +3870,37 @@
     Taglia dopo
     Cambia il tipo di percorso prima
     Cambia il tipo di percorso dopo
+    Solo la linea del percorso verrà salvato, i punti intermedi saranno cancellati.
+    Nome del file
+    %s file traccia selezionati
+    Metterà in pausa la registrazione della traccia quando l\'applicazione viene terminata (attraverso le app recenti). (L\'indicazione di OsmAnd in background scomparirà dalla barra delle notifiche di Android.)
+    Specifica l\'intervallo di registrazione per la registrazione delle tracce (abilitata attraverso il pulsante di Registrazione del viaggio sulla mappa).
+    Sospendi la registrazione del viaggio
+    Riprendi la registrazione del viaggio
+    Preimpostazioni di sistema
+    Tutti i segmenti successivi
+    Segmento precedente
+    Tutti i segmenti precedenti
+    Solo il segmento selezionato verrà ricalcolato con il profilo selezionato.
+    Tutti i segmenti successivi verranno ricalcolati con il profilo selezionato.
+    Tutti i segmenti precedenti verranno ricalcolati con il profilo selezionato.
+    Apri una traccia salvata
+    è stato salvato
+    Per favore aggiungi gli ultimi due punti.
+    Ripeti
+    • Aggiornata la modalità Pianificazione dell\'Itinerario che permette l\'utilizzo di diversi profili di navigazione per ogni segmento e incolla le tracce alle strade
+\n
+\n •Nuove opzioni per l\'Aspetto delle tracce: scegli il colore, lo spessore, la visualizzazione delle frecce di direzione, e i marcatori di inizio e fine
+\n
+\n • Migliorata la visibilità dei nodi ciclistici
+\n
+\n • Menù contestuale con informazioni di base
+\n
+\n • Migliorato l\'algoritmo di ricerca
+\n
+\n • Migliorate le opzioni Segui traccia in Navigazione
+\n
+\n • Corretto il problema all\'importa/esporta le impostazioni dei profili
+\n
+\n
 
\ No newline at end of file

From c4a6639dc0172472dcf844ad0e6b1bc28fb5346f Mon Sep 17 00:00:00 2001
From: Zmicer Turok 
Date: Fri, 11 Sep 2020 09:41:04 +0000
Subject: [PATCH 0054/1366] Translated using Weblate (Belarusian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-be/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml
index 3727aa2c06..b880739cfb 100644
--- a/OsmAnd/res/values-be/strings.xml
+++ b/OsmAnd/res/values-be/strings.xml
@@ -3941,4 +3941,19 @@
 \nАдзін месяц - 43 829 хвілін.
     Абярыце спосаб захоўвання спампаваных фрагментаў.
     Вярнуць
+    • Абноўлены рэжым планавання маршруту дазваляе выкарыстоўваць розныя тыпы навігацыі для кожнага сегмента і прымацоўвае любы шлях да дарог
+\n
+\n • Новыя варыянты выгляду для дарожак: абраць колер, таўшчыню, уключыць стрэлкі кірунку і адзнакі старту/фінішу
+\n
+\n • Палепшаная бачнасць роварных вузлоў
+\n
+\n • Кантэкстнае меню для слядоў з асноўнай інфармацыяй
+\n
+\n • Палепшаны алгарытмы пошуку
+\n
+\n • Палепшаны параметры адсочвання ў навігацыі
+\n
+\n • Выпраўлены праблемы з імпартам / экспартам налад профілю
+\n
+\n
 
\ No newline at end of file

From ca6efce34879069c552081249b817e26e3d9e9db Mon Sep 17 00:00:00 2001
From: Softmap 
Date: Fri, 11 Sep 2020 12:13:37 +0000
Subject: [PATCH 0055/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index 2e0f9a51b6..3416a49692 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -3875,4 +3875,19 @@
     اسم الملف
     الرجاء إضافة نقطتين على الأقل.
     إعادة
+    • وضع مخطط المسار المحدث يسمح باستخدام أنواع الملاحة المختلفة لكل جزء ويربط أي مسار بالطرق
+\n
+\n• خيارات المظهر الجديدة للمسارات: تحديد اللون، السماكة ستقوم بتفعيل أسهم التوجيه و علامات البداية والنهاية
+\n
+\n• تحسين رؤية عقد الدراجات
+\n
+\n• قائمة السياق للمسارات بمعلومات أساسية
+\n
+\n• تحسين خوارزميات البحث
+\n
+\n• تم تحسين خيارات متابعة المسار أثناء الملاحة
+\n
+\n• تم إصلاح المشكلات المتعلقة باستيراد/تصدير إعدادات الملف الشخصي
+\n
+\n
 
\ No newline at end of file

From a175f93a7d58814ad0bf6fa41b8ffd4bae38be70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= 
Date: Thu, 10 Sep 2020 23:18:48 +0000
Subject: [PATCH 0056/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?=
 =?UTF-8?q?gian=20Bokm=C3=A5l)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Currently translated at 15.6% (544 of 3484 strings)
---
 OsmAnd/res/values-nb/strings.xml | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml
index 34941f6d26..5b55a1c545 100644
--- a/OsmAnd/res/values-nb/strings.xml
+++ b/OsmAnd/res/values-nb/strings.xml
@@ -3720,4 +3720,30 @@
     Terskeldistanse
     Navigeringsprofil
     Lukket OSM-notat
+    Legg til sporfiler
+    Importer eller ta opp sporfiler
+    Følg spor
+    Velg sporfil å følge
+    Velg sporfil å følge, eller importer en.
+    Velg et annet spor
+    Starten av sporet
+    Nærmeste punkt
+    Slett adresse
+    Legg til adresse
+    Skriv inn adresse
+    Endre rutetype før
+    Endre rutetype etter
+    Forenklet spor
+    Filnavn
+    Systemforvalg
+    Alle påfølgende segmenter
+    Alle foregående segmenter
+    Forrige segment
+    Kun valgt segment vil bli utregnet på ny i valgt profil.
+    Alle påfølgende segmenter vil bli utregnet på ny i valgt profil.
+    Alle tidligere segmenter vil bli utregnet på ny i valgt profil.
+    Åpne lagret spor
+    har blitt lagret
+    Legg til minst to punkter.
+    Gjenta
 
\ No newline at end of file

From 4384777b77d27810186c5369b480f82c0ed0a655 Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Thu, 10 Sep 2020 21:44:56 +0000
Subject: [PATCH 0057/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-uk/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml
index 0ceed5636b..086eba5d78 100644
--- a/OsmAnd/res/values-uk/phrases.xml
+++ b/OsmAnd/res/values-uk/phrases.xml
@@ -3829,4 +3829,5 @@
     Дошка відправлень: немає
     Дошка відправлень
     Поповнення питної води
+    Невеликі електроприлади
 
\ No newline at end of file

From d360fd0d4ec10ad0c22139885f11446873ec1c14 Mon Sep 17 00:00:00 2001
From: Zmicer Turok 
Date: Fri, 11 Sep 2020 09:39:06 +0000
Subject: [PATCH 0058/1366] Translated using Weblate (Belarusian)

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-be/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-be/phrases.xml b/OsmAnd/res/values-be/phrases.xml
index 3227d98308..c1811632b4 100644
--- a/OsmAnd/res/values-be/phrases.xml
+++ b/OsmAnd/res/values-be/phrases.xml
@@ -3841,4 +3841,5 @@
     Расклад
     Рэальны час
     Затрымка
+    Маленькія электрапрыборы
 
\ No newline at end of file

From 49a39c306e6acd15e0e94b30672f82883b4fb6f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Thu, 10 Sep 2020 21:08:14 +0000
Subject: [PATCH 0059/1366] Translated using Weblate (Estonian)

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-et/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml
index 9edfecd079..5ea981e678 100644
--- a/OsmAnd/res/values-et/phrases.xml
+++ b/OsmAnd/res/values-et/phrases.xml
@@ -3823,4 +3823,5 @@
     Väljuvate reiside tabloo: ei
     Väljuvate reiside tabloo
     Joogivee täitmine
+    Väikesed elektriseadmed
 
\ No newline at end of file

From 8843c21b358b63284dcca24d420f772f107f3d18 Mon Sep 17 00:00:00 2001
From: Franco 
Date: Fri, 11 Sep 2020 11:56:56 +0000
Subject: [PATCH 0060/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-es-rAR/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml
index 53987c3a28..3c36653855 100644
--- a/OsmAnd/res/values-es-rAR/strings.xml
+++ b/OsmAnd/res/values-es-rAR/strings.xml
@@ -3890,4 +3890,19 @@
     %s archivo(s) de trazas marcado(s)
     Añade al menos dos puntos.
     Rehacer
+    • Se ha actualizado el modo «Planificar ruta»: ahora permite usar diferentes tipos de navegación para cada segmento y adjunta cualquier traza a los caminos
+\n
+\n • Nuevas opciones en el aspecto de las trazas: elegir el color, cambiar el grosor de las flechas de dirección y las marcas de inicio/fin.
+\n
+\n • Mejoras en la visibilidad de los nodos de bicicleta
+\n
+\n • Menú contextual con información básica para las trazas
+\n
+\n • Algoritmos de búsqueda mejorados
+\n
+\n • Mejoras en las opciones de seguimiento de la navegación
+\n
+\n • Se han solucionado los problemas de la importación y exportación en los ajustes de los perfiles
+\n
+\n
 
\ No newline at end of file

From 54d23d007e532a300d20a3777287b1d5db12514d Mon Sep 17 00:00:00 2001
From: Franco 
Date: Fri, 11 Sep 2020 11:57:14 +0000
Subject: [PATCH 0061/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-es-rAR/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml
index 5c24c258fb..cfe9475d1e 100644
--- a/OsmAnd/res/values-es-rAR/phrases.xml
+++ b/OsmAnd/res/values-es-rAR/phrases.xml
@@ -3848,4 +3848,5 @@
     Tablero de partidas: no
     Tablero de partidas
     Recarga de agua potable
+    Pequeños electrodomésticos
 
\ No newline at end of file

From 7876cf7253b95b2740bafd55ba9412095812a38a Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Fri, 11 Sep 2020 15:02:01 +0000
Subject: [PATCH 0062/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-pt/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml
index 646845caf2..744b9de0ca 100644
--- a/OsmAnd/res/values-pt/phrases.xml
+++ b/OsmAnd/res/values-pt/phrases.xml
@@ -3826,4 +3826,5 @@
     Quadro de partidas: não
     Quadro de partidas
     Reabastecimento de água potável
+    Pequenos aparelhos elétricos
 
\ No newline at end of file

From 7ab6d825e86d972df7d09cce8f70d09180d12e17 Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Fri, 11 Sep 2020 13:25:12 +0000
Subject: [PATCH 0063/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-zh-rTW/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml
index bbc2ef6d57..cfd0c15548 100644
--- a/OsmAnd/res/values-zh-rTW/strings.xml
+++ b/OsmAnd/res/values-zh-rTW/strings.xml
@@ -3883,4 +3883,19 @@
     已儲存
     請至少新增兩個點。
     重做
+    • 更新的規劃路線模式允許對不同路段使用不同的導航類型,並可將任何軌跡附加到道路上
+\n
+\n • 新的軌跡外觀選項:選取顏色、厚度、開啟方向箭頭與開始/結束標記
+\n
+\n • 改善自行車節點的能見度
+\n
+\n • 有基本資訊的軌跡情境選單
+\n
+\n • 改進了搜尋演算法
+\n
+\n • 改進了導航中的「跟隨軌跡」選項
+\n
+\n • 修復設定檔的匯入/匯出問題
+\n
+\n
 
\ No newline at end of file

From 5e51a4a4983f05f76124a9a4556906b551e94292 Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Fri, 11 Sep 2020 13:26:27 +0000
Subject: [PATCH 0064/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-zh-rTW/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml
index f65ebd2d68..c078b2c6e7 100644
--- a/OsmAnd/res/values-zh-rTW/phrases.xml
+++ b/OsmAnd/res/values-zh-rTW/phrases.xml
@@ -3840,4 +3840,5 @@
     時刻表:否
     時刻表
     飲用水補充
+    小電器
 
\ No newline at end of file

From 596d6750198f567b56be89c964119e2ce27facae Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Thu, 10 Sep 2020 23:21:50 +0000
Subject: [PATCH 0065/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (267 of 267 strings)

Translation: OsmAnd/Telegram
Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/ru/
---
 OsmAnd-telegram/res/values-ru/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd-telegram/res/values-ru/strings.xml b/OsmAnd-telegram/res/values-ru/strings.xml
index daff0e950b..b76aa52417 100644
--- a/OsmAnd-telegram/res/values-ru/strings.xml
+++ b/OsmAnd-telegram/res/values-ru/strings.xml
@@ -63,7 +63,7 @@
     У меня нет учетной записи Telegram
     Введите номер телефона
     Введите код аутентификации
-    Добавить
+    Сохранить
     Назовите новое устройство макс. 200 символов.
     Расстояние
     Моя локация

From b00481ff065dd7e5f7562e185e4f95b6c8370504 Mon Sep 17 00:00:00 2001
From: Nikita Epifanov 
Date: Fri, 11 Sep 2020 20:30:16 +0000
Subject: [PATCH 0066/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-ru/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml
index 8ae4605c7c..2f7dba711d 100644
--- a/OsmAnd/res/values-ru/phrases.xml
+++ b/OsmAnd/res/values-ru/phrases.xml
@@ -3829,4 +3829,5 @@
     Реальное время
     Задержка
     Расписание
+    Малые электроприборы
 
\ No newline at end of file

From 7d55b00fece42d193a85d5dae10eb6b9536e5a0e Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Sat, 12 Sep 2020 02:10:18 +0000
Subject: [PATCH 0067/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-uk/strings.xml | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml
index 41c421b907..1b1ca18e75 100644
--- a/OsmAnd/res/values-uk/strings.xml
+++ b/OsmAnd/res/values-uk/strings.xml
@@ -3779,33 +3779,33 @@
     Попередження про камери контролю швидкості в деяких країнах заборонено законом.
     Орієнтація
     %1$s видалено
-    Для вилучення даних про камери контролю швидкості потрібен перезапуск.
+    Перезапустіть застосунок для видалення даних про камери контролю швидкості.
     Видалити та перезапустити
     Вкажіть довжину транспортного засобу для розрахунку маршрутів.
     Обмеження довжини
     На цьому пристрої немає камер контролю швидкості.
     Роликові ковзани
-    Увімкнути для зміни масштабу мапи кнопками гучності пристрою.
+    Зміна масштабу мапи кнопками гучності пристрою.
     Масштабування кнопками гучності
     Вкажіть довжину вашого автомобіля, для довгих транспортних засобів можуть застосовуватися деякі обмеження на маршрутах.
-    Видалити наступну точку призначення
+    Видалити найближчу точку призначення
     Вкажіть назву пункту
     Поточну точку призначення на маршруті буде видалено. Якщо це буде місце призначення, навігація припиниться.
     Завантажити мапи Вікіпедії
-    Отримайте відомості про визначні місця у Вікіпедії. Це ваш автономний кишеньковий посібник - просто ввімкніть втулок \"Вікіпедія\" і насолоджуйтеся статтями про об\'єкти навколо вас.
+    Отримайте відомості про визначні місця у Вікіпедії. Це ваш автономний кишеньковий посібник - просто ввімкніть втулок \"Вікіпедія\" і насолоджуйтеся статтями про об\'єкти довкола вас.
     Моторолер
     Спортивний мотоцикл
     Інвалідне крісло
     Інвалідне крісло попереду
     Картинг
-    Закрита нотатка OSM
+    Закрита примітка OSM
     Власне
     Додану точку не буде показано на мапі, вся вибрана група є прихованою, ви можете побачити її в \"%s\".
     Зазначте робочі дні, щоб продовжити
     Маршрут між точками
     Планування маршруту
     Додати до треку
-    Показувати старт та фініш
+    Показувати піктограми старт та фініш
     Встановити ширину
     Виберіть інтервал показу міток часу або відстані для показу поверх треку.
     Виберіть власний варіант поділу: за часом чи відстанню.
@@ -3815,12 +3815,10 @@
     Імпортувати трек
     Переглянути наявний трек
     Створити новий маршрут
-    Оберіть файл з треком для перегляду.
+    Виберіть який файл з треком відкрити.
     Готово
     Перезаписати трек
-    Для користування цією функцією, OsmAnd необхідно прив\'язати цей трек до мапи доріг.
-\n
-\nДалі вам потрібно вибрати профіль навігації для виявлення дозволених доріг та обмеження відстані наближення вашого треку до доріг.
+    Далі, пов\'яжіть трек до найближчої дозволеної дороги з одним із профілів навігації, щоб скористатися цим параметром.
     Зворотний маршрут
     Весь трек
     Наступний сегмент
@@ -3832,7 +3830,7 @@
     Лише наступний сегмент буде перераховано за допомогою обраного профілю.
     Виберіть спосіб з\'єднання точок: прямою лінією чи розраховувати маршрут між ними за допомогою вибраного профілю.
     Зображення вулиць
-    Ви дійсно бажаєте закрити планування маршруту без збереження\? Внесені зміни буде втрачено.
+    Ви дійсно бажаєте відхилити всі зміни у запланованому маршруті, закривши його\?
     Для зворотного напрямку
     Зберегти як новий файл треку
     Додати у файл треку
@@ -3850,7 +3848,7 @@
     Зберегти як файл треку
     Стежити за треком
     Виберіть файл треку для перегляду
-    Виберіть файл треку для його перегляду або імпортуйте його.
+    Виберіть файл треку для перегляду або імпортуйте його з пристрою.
     Обрати інший трек
     Перехід від мого розташування до треку
     Точка треку для навігації

From d8bd5f936eb114e108b8b7c86aa8259efaeb5da3 Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Sat, 12 Sep 2020 12:39:25 +0300
Subject: [PATCH 0068/1366] Add_favorite_Screen

1. Skip first direction, then coma - address: "1.22 km, Bohdana Khmelnytskogo 1" (it destroy some fragmnet menu);
2. After the user tap on the text field, place the cursor at the end of the text;
3. Allign drawable icon.
---
 .../res/layout/map_context_menu_fragment.xml  | 59 +++++++++----------
 .../FavouritePointMenuController.java         |  7 ++-
 .../editors/PointEditorFragmentNew.java       |  1 +
 .../src/net/osmand/view/GravityDrawable.java  |  5 +-
 4 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/OsmAnd/res/layout/map_context_menu_fragment.xml b/OsmAnd/res/layout/map_context_menu_fragment.xml
index cc24c22ac5..7a57679825 100644
--- a/OsmAnd/res/layout/map_context_menu_fragment.xml
+++ b/OsmAnd/res/layout/map_context_menu_fragment.xml
@@ -174,38 +174,6 @@
                     android:paddingEnd="@dimen/context_menu_padding_margin_default"
                     android:paddingTop="3dp">
 
-                    
-
-                        
-
-                        
-
-                        
-
-                    
-
                     
 
+                        
+
+                            
+
+                            
+
+                        
+
                     
 
                 
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
index d8459a2ca0..c1420b7d24 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
@@ -29,6 +29,7 @@ import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragmentNew;
 import net.osmand.plus.transport.TransportStopRoute;
 import net.osmand.plus.widgets.style.CustomTypefaceSpan;
 import net.osmand.util.OpeningHoursParser;
+import net.osmand.view.GravityDrawable;
 
 import java.util.List;
 
@@ -174,8 +175,10 @@ public class FavouritePointMenuController extends MenuController {
 			FavouritesDbHelper helper = app.getFavorites();
 			String group = fav.getCategory();
 			if (helper.getGroup(group) != null) {
-				int colorId = R.color.color_favorite;
-				return getIcon(R.drawable.ic_action_group_name_16, colorId);
+				Drawable line2icon = helper.getColoredIconForGroup(group);
+				GravityDrawable gravityIcon = new GravityDrawable(line2icon);
+				gravityIcon.setBoundsFrom(line2icon);
+				return gravityIcon;
 			} else {
 				int colorId = isLight() ? R.color.icon_color_default_light : R.color.ctx_menu_bottom_view_icon_dark;
 				return getIcon(R.drawable.ic_action_group_name_16, colorId);
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
index 918afaae29..d56733ae45 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
@@ -233,6 +233,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 		}
 		if (getAddressInitValue() != null){
 			addressEdit.setText(getAddressInitValue());
+			addressEdit.setSelection(addressEdit.getText().length());
 		}
 
 		descriptionCaption = view.findViewById(R.id.description);
diff --git a/OsmAnd/src/net/osmand/view/GravityDrawable.java b/OsmAnd/src/net/osmand/view/GravityDrawable.java
index 20d2b6776c..019d23bfac 100644
--- a/OsmAnd/src/net/osmand/view/GravityDrawable.java
+++ b/OsmAnd/src/net/osmand/view/GravityDrawable.java
@@ -64,10 +64,9 @@ public class GravityDrawable extends Drawable {
 
 	@Override
 	public void draw(Canvas canvas) {
-		int halfCanvas = canvas.getHeight() / 2;
-		int halfDrawable = original.getIntrinsicHeight() / 2;
+		int halfCanvas = getBounds().height() / 3;
+		int halfDrawable = original.getIntrinsicHeight() / 3;
 
-		// align to top
 		canvas.save();
 		canvas.translate(0, -halfCanvas + halfDrawable);
 		original.draw(canvas);

From bb65803201def12695efe5188ff58f4f91134471 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Sat, 12 Sep 2020 14:20:31 +0300
Subject: [PATCH 0069/1366] Added .wpt.chart and .3d.chart support

---
 .../main/java/net/osmand/IndexConstants.java  |  3 +
 OsmAnd/AndroidManifest.xml                    | 66 +++++++++++++++++++
 .../net/osmand/plus/helpers/ImportHelper.java | 47 ++++++++-----
 3 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java
index 0dea2d42fb..93569dfddd 100644
--- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java
+++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java
@@ -45,6 +45,9 @@ public class IndexConstants {
 
 	public static final String GPX_FILE_EXT = ".gpx"; //$NON-NLS-1$
 
+	public static final String WPT_CHART_FILE_EXT = ".wpt.chart";
+	public static final String SQLITE_CHART_FILE_EXT = ".3d.chart";
+
 	public final static String POI_TABLE = "poi"; //$NON-NLS-1$
 	
 	public static final String INDEX_DOWNLOAD_DOMAIN = "download.osmand.net";
diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml
index 9adf3b6482..2c6d6b6463 100644
--- a/OsmAnd/AndroidManifest.xml
+++ b/OsmAnd/AndroidManifest.xml
@@ -371,6 +371,72 @@
 				
 			
 
+			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+			
+
+			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+			
+
+			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+			
+
+			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+			
+
 			
 			
 				
diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
index 9be5fa7277..2308774602 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
@@ -74,10 +74,13 @@ import java.util.Locale;
 import java.util.zip.ZipInputStream;
 
 import static android.app.Activity.RESULT_OK;
+import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT;
 import static net.osmand.IndexConstants.GPX_FILE_EXT;
 import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT;
 import static net.osmand.IndexConstants.RENDERER_INDEX_EXT;
 import static net.osmand.IndexConstants.ROUTING_FILE_EXT;
+import static net.osmand.IndexConstants.SQLITE_CHART_FILE_EXT;
+import static net.osmand.IndexConstants.SQLITE_EXT;
 import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE;
 import static net.osmand.plus.AppInitializer.loadRoutingFiles;
 import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB;
@@ -181,7 +184,7 @@ public class ImportHelper {
 		} else if (isContentIntent) {
 			fileName = getNameFromContentUri(app, uri);
 		}
-		handleGpxOrFavouritesImport(uri, fileName, saveFile, false, true);
+		handleGpxOrFavouritesImport(uri, fileName, saveFile, false, true, false);
 	}
 
 	public void handleFileImport(Uri intentUri, String fileName, Bundle extras, boolean useImportDir) {
@@ -191,7 +194,7 @@ public class ImportHelper {
 		final boolean saveFile = !isFileIntent || !isOsmandSubdir;
 
 		if (fileName == null) {
-			handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false);
+			handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false);
 		} else  if (fileName.endsWith(KML_SUFFIX)) {
 			handleKmlImport(intentUri, fileName, saveFile, useImportDir);
 		} else if (fileName.endsWith(KMZ_SUFFIX)) {
@@ -204,8 +207,12 @@ public class ImportHelper {
 			handleOsmAndSettingsImport(intentUri, fileName, extras, null);
 		} else if (fileName.endsWith(ROUTING_FILE_EXT)) {
 			handleXmlFileImport(intentUri, fileName, null);
+		} else if (fileName.endsWith(WPT_CHART_FILE_EXT)) {
+			handleGpxOrFavouritesImport(intentUri, fileName.replace(WPT_CHART_FILE_EXT, GPX_FILE_EXT), saveFile, useImportDir, false, true);
+		} else if (fileName.endsWith(SQLITE_CHART_FILE_EXT)) {
+			handleSqliteTileImport(intentUri, fileName.replace(SQLITE_CHART_FILE_EXT, SQLITE_EXT));
 		} else {
-			handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false);
+			handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false);
 		}
 	}
 
@@ -277,7 +284,9 @@ public class ImportHelper {
 	}
 
 	@SuppressLint("StaticFieldLeak")
-	private void handleGpxOrFavouritesImport(final Uri fileUri, final String fileName, final boolean save, final boolean useImportDir, final boolean forceImportFavourites) {
+	private void handleGpxOrFavouritesImport(final Uri fileUri, final String fileName, final boolean save,
+											 final boolean useImportDir, final boolean forceImportFavourites,
+											 final boolean forceImportGpx) {
 		new AsyncTask() {
 			ProgressDialog progress = null;
 
@@ -343,8 +352,7 @@ public class ImportHelper {
 				if (AndroidUtils.isActivityNotDestroyed(activity)) {
 					progress.dismiss();
 				}
-
-				importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites);
+				importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx);
 			}
 		}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 	}
@@ -1144,7 +1152,8 @@ public class ImportHelper {
 	}
 
 	private void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save,
-									   final boolean useImportDir, final boolean forceImportFavourites) {
+									   final boolean useImportDir, final boolean forceImportFavourites,
+									   final boolean forceImportGpx) {
 		if (gpxFile == null || gpxFile.isPointsEmpty()) {
 			if (forceImportFavourites) {
 				final DialogInterface.OnClickListener importAsTrackListener = new DialogInterface.OnClickListener() {
@@ -1177,16 +1186,20 @@ public class ImportHelper {
 		if (forceImportFavourites) {
 			importFavoritesImpl(gpxFile, fileName, true);
 		} else if (fileName != null) {
-			ImportGpxBottomSheetDialogFragment fragment = new ImportGpxBottomSheetDialogFragment();
-			fragment.setUsedOnMap(true);
-			fragment.setImportHelper(this);
-			fragment.setGpxFile(gpxFile);
-			fragment.setFileName(fileName);
-			fragment.setSave(save);
-			fragment.setUseImportDir(useImportDir);
-			activity.getSupportFragmentManager().beginTransaction()
-					.add(fragment, ImportGpxBottomSheetDialogFragment.TAG)
-					.commitAllowingStateLoss();
+			if (forceImportGpx) {
+				handleResult(gpxFile, fileName, save, useImportDir, false);
+			} else {
+				ImportGpxBottomSheetDialogFragment fragment = new ImportGpxBottomSheetDialogFragment();
+				fragment.setUsedOnMap(true);
+				fragment.setImportHelper(this);
+				fragment.setGpxFile(gpxFile);
+				fragment.setFileName(fileName);
+				fragment.setSave(save);
+				fragment.setUseImportDir(useImportDir);
+				activity.getSupportFragmentManager().beginTransaction()
+						.add(fragment, ImportGpxBottomSheetDialogFragment.TAG)
+						.commitAllowingStateLoss();
+			}
 		}
 	}
 

From ff5cc15a243d26b21affb9d68e8683fd1bab090d Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Sat, 12 Sep 2020 15:19:29 +0300
Subject: [PATCH 0070/1366] Address are not shown after importing file, but
 they contains in file.

---
 OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java | 1 +
 OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java             | 1 +
 2 files changed, 2 insertions(+)

diff --git a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java
index 6228d67569..91bf4ffbf9 100644
--- a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java
+++ b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java
@@ -128,6 +128,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
 
 				@Override
 				public void onFavoriteDataUpdated(@NonNull FavouritePoint favouritePoint) {
+					favouritesAdapter.notifyDataSetChanged();
 				}
 			});
 		}
diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
index 2308774602..c57f53a0fa 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
@@ -1221,6 +1221,7 @@ public class ImportHelper {
 				if (p.desc != null) {
 					fp.setDescription(p.desc);
 				}
+				fp.setAddress(p.getExtensionsToRead().get("address"));
 				fp.setColor(p.getColor(0));
 				fp.setIconIdFromName(app, p.getIconName());
 				fp.setBackgroundType(BackgroundType.getByTypeName(p.getBackgroundType(), DEFAULT_BACKGROUND_TYPE));

From a814e2120744068570e49689a62d48a8730873df Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Sat, 12 Sep 2020 16:32:07 +0300
Subject: [PATCH 0071/1366] Fix #9787

---
 .../net/osmand/plus/routing/RouteProvider.java    | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java
index c1aa605955..eb7765e9af 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java
@@ -469,7 +469,9 @@ public class RouteProvider {
 			List gpxRouteLocations = result.getImmutableAllLocations();
 			int gpxNextIndex = calcWholeRoute ? 0 : findStartIndexFromRoute(gpxRouteLocations, routeParams.start, calculateOsmAndRouteParts);
 			Location gpxNextLocation = null;
+			Location gpxLastLocation = !gpxRouteLocations.isEmpty() ? gpxRouteLocations.get(gpxRouteLocations.size() - 1) : null;
 			List firstSegmentRoute = null;
+			List lastSegmentRoute = null;
 			List gpxRoute;
 			if (gpxNextIndex > 0) {
 				gpxNextLocation = gpxRouteLocations.get(gpxNextIndex);
@@ -486,14 +488,25 @@ public class RouteProvider {
 			if (calculateOsmAndRouteParts
 					&& routeParams.start != null && gpxNextLocation != null
 					&& gpxNextLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
-				RouteCalculationResult firstSegmentResult = findOfflineRouteSegment(routeParams, routeParams.start, new LatLon(gpxNextLocation.getLatitude(), gpxNextLocation.getLongitude()));
+				RouteCalculationResult firstSegmentResult = findOfflineRouteSegment(
+						routeParams, routeParams.start, new LatLon(gpxNextLocation.getLatitude(), gpxNextLocation.getLongitude()));
 				firstSegmentRoute = firstSegmentResult.getOriginalRoute();
 			}
+			if (calculateOsmAndRouteParts
+					&& routeParams.end != null && gpxLastLocation != null
+					&& MapUtils.getDistance(gpxLastLocation.getLatitude(), gpxLastLocation.getLongitude(),
+					routeParams.end.getLatitude(), routeParams.end.getLongitude()) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
+				RouteCalculationResult lastSegmentResult = findOfflineRouteSegment(routeParams, gpxLastLocation, routeParams.end);
+				lastSegmentRoute = lastSegmentResult.getOriginalRoute();
+			}
 			List newGpxRoute = new ArrayList<>();
 			if (firstSegmentRoute != null && !firstSegmentRoute.isEmpty()) {
 				newGpxRoute.addAll(firstSegmentRoute);
 			}
 			newGpxRoute.addAll(gpxRoute);
+			if (lastSegmentRoute != null && !lastSegmentRoute.isEmpty()) {
+				newGpxRoute.addAll(lastSegmentRoute);
+			}
 			return new RouteCalculationResult(newGpxRoute, routeParams.start, routeParams.end,
 					routeParams.intermediates, routeParams.ctx, routeParams.leftSide, null, null, routeParams.mode, true);
 		}

From dae7f6c74bd03492f21214e341abafe6573b8c95 Mon Sep 17 00:00:00 2001
From: Ahmad Alfrhood 
Date: Sat, 12 Sep 2020 08:01:40 +0000
Subject: [PATCH 0072/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index 1cd03b7d07..02597df8e6 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -3806,7 +3806,7 @@
     استيراد المسار
     فتح المسار الموجود
     إنشاء مسار جديد
-    حدد ملف المسار للفتح.
+    حدد المسار للفتح.
     تم
     الكتابة فوق المسار
     ملف تعريف التنقل

From 61162b469369aefd4f7b08551c0e9e41b10212bf Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Sat, 12 Sep 2020 08:04:07 +0000
Subject: [PATCH 0073/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt/strings.xml | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml
index b8c19a6a45..9b348c9bbe 100644
--- a/OsmAnd/res/values-pt/strings.xml
+++ b/OsmAnd/res/values-pt/strings.xml
@@ -3754,15 +3754,15 @@
 \nSelecione %1$s e receberá alertas e avisos sobre radares de velocidade. 
 \n 
 \nSelecione %2$s. Todos os dados relacionados a radares de velocidade: alertas, notificações, POIs serão apagados até que o OsmAnd seja completamente reinstalado.
-    Obter informações sobre pontos de interesse da Wikipédia. É o seu guia de bolso off-line - falta só ativar o suplemento Wikipédia e desfrutar de artigos sobre os elementos ao seu redor.
+    Obter informações sobre pontos de interesse da Wikipédia. É o seu guia de bolso off-line - falta só ativar o suplemento de Wikipédia e desfrutar de artigos sobre os elementos ao seu redor.
     Motoneta
-    Apagar próximo ponto de destino
+    Apagar o ponto de destino mais próximo
     Descarregar mapas da Wikipédia
     Pode acessar essas ações tocando no botão “%1$s”.
     Desinstalar
     Forneça o comprimento do seu veículo. Algumas restrições de rotas podem ser aplicadas a veículos longos.
     Botões de volume como zoom
-    É necessário reiniciar para excluir completamente os dados da câmera de velocidade.
+    Reinicie a app para apagar os dados da câmara de velocidade.
     %1$s apagado
     Uma alternância para mostrar ou ocultar a camada Mapillary no mapa.
     Definir altura da embarcação
@@ -3796,7 +3796,7 @@
     Legal
     Pode definir a altura da embarcação para evitar pontes baixas. Lembre-se, se a ponte for móvel, usaremos sua altura no estado aberto.
     Cadeira de rodas para a frente
-    Ativar para controlar o nível de zoom do mapa com os botões de volume do aparelho.
+    Controlar o nível de ampliação do mapa pelos botões de volume do aparelho.
     Mostrar/ocultar Mapillary
     Desinstalar radares de velocidade
     Anotaçaõ OSM fechada
@@ -3806,7 +3806,7 @@
     POIs de radares de velocidade
     Retomar
     Rolamento
-    Precisa de definir dias úteis para continuar
+    Defina dias úteis para continuar
     Rota entre pontos
     Planejar uma rota
     Adicionar ao trilho
@@ -3832,15 +3832,13 @@
     Selecione como ligar pontos, com uma linha reta ou calcule uma rota entre eles com o perfil selecionado.
     Trilho inteiro
     Próximo segmento
-    Para usar esta opção o OsmAnd precisa de encaixar o seu trilho nas estradas do mapa.
-\n
-\n No passo seguinte, terá de selecionar o perfil de navegação para detetar estradas permitidas e a distância limiar para se aproximar do seu trilho com as estradas.
+    Em seguida, encaixe a sua pista na estrada mais próxima permitida com um dos seus perfis de navegação para usar esta opção.
     Distância limiar
     Perfil de navegação
     Selecione um ficheiro de faixa para o qual um novo segmento será adicionado.
     Seguir a trilha
     Escolha o ficheiro de trilha a seguir
-    Escolha o ficheiro de trilho a seguir ou importe um.
+    Escolha o ficheiro de trilho a seguir ou importe um do seu aparelho.
     Selecionar outra trilha
     Navegue de minha localização até a trilha
     Ponto da trilha para navegar
@@ -3855,7 +3853,7 @@
     Alterar o tipo de rota antes
     Alterar o tipo de rota após
     Imagens de rua
-    Tem certeza de que deseja fechar plano de rota sem gravar\? Perderá todas as alterações.
+    Tem certeza que quer descartar todas as mudanças na rota planeada a fecha-la\?
     Em caso de direção reversa
     Rota de trilha
     Trilhas

From a4bdfa8506d50987a9b5ab1184c7f45189e908c9 Mon Sep 17 00:00:00 2001
From: Hinagiku Zeppeki 
Date: Sat, 12 Sep 2020 08:23:57 +0000
Subject: [PATCH 0074/1366] Translated using Weblate (Japanese)

Currently translated at 97.6% (3401 of 3484 strings)
---
 OsmAnd/res/values-ja/strings.xml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml
index b3d6ea7d20..4e8391bc49 100644
--- a/OsmAnd/res/values-ja/strings.xml
+++ b/OsmAnd/res/values-ja/strings.xml
@@ -2703,7 +2703,7 @@ POIの更新は利用できません
     インターネットへ接続せずにOsmAnd上で地球上のあらゆる興味深いスポットのガイドを利用することができます。
     アプリ内課金
     1回払い
-    買いきり購入の場合、期限を気にせず利用できるようになります。
+    買いきりの場合、期限を問わず利用可能です。
     購入 - %1$s
     Wikivoyageオフライン
     等高線と陰影起伏図
@@ -3797,7 +3797,7 @@ POIの更新は利用できません
 \n%1$sを選択すると、スピードカメラに関するアラートと警告が表示されます。
 \n
 \n%2$sを選択すると、スピードカメラに関するすべてのデータ(警告、通知、POI)が、OsmAndの再インストールを行うまで削除されます。
-    アクティブを維持
+    機能を維持
     アンインストール
     一部の国では、スピードカメラの事前警告は法律で禁止されています。
     \"%1$s\"がオンの場合、設定された動作時間はそちらに依存します。
@@ -3860,4 +3860,7 @@ POIの更新は利用できません
     後でトリミング
     先にルートタイプを変更
     後でルートタイプを変更
+    次年度以降 %1$s
+    初%2$s度 %1$s
+    初%2$s度 %1$s
 
\ No newline at end of file

From 82b3848dd247869a75f20d7ca66ebf4bf71d1a07 Mon Sep 17 00:00:00 2001
From: Ldm Public 
Date: Sat, 12 Sep 2020 14:08:36 +0000
Subject: [PATCH 0075/1366] Translated using Weblate (French)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-fr/strings.xml | 39 ++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml
index dfaf9717f6..bd4408d069 100644
--- a/OsmAnd/res/values-fr/strings.xml
+++ b/OsmAnd/res/values-fr/strings.xml
@@ -3755,7 +3755,7 @@
 \n
 \nSélectionnez %2$s. Toutes les données relatives aux radars (alertes, notifications, PI) seront supprimées.
     Garder actif
-    Un redémarrage est nécessaire pour supprimer complètement les données des radars.
+    Redémarrez l\'application pour supprimer les données radars.
     Désinstaller les radars
     Légal
     PI radars
@@ -3769,12 +3769,12 @@
     Cet appareil n\'a pas de radars.
     Patins à roulettes en ligne
     Zoomer avec les boutons de volume
-    Activer pour contrôler le niveau de zoom de la carte avec les boutons de réglage du volume sonore.
+    Contrôler le niveau de zoom de la carte avec les boutons de réglage du volume sonore.
     Le prochain point sur la route va être supprimé. S\'il s\'agit de la destination finale, la navigation s\'arrêtera.
     Indiquez la longueur de votre véhicule, certaines restrictions d\'itinéraire peuvent s\'appliquer aux véhicules longs.
     Supprimer le prochain point
     Merci de renseigner un nom pour le point
-    Utilisez un guide de poche hors ligne grâce à Wikipédia. Activez le plugin Wikipédia : des points d\'intérêt seront affichés, ils vous permettrons d\'obtenir des informations sur les lieux qui vous entourent.
+    Utilisez le guide Wikipédia hors ligne. Activez le plugin Wikipédia : des points d\'intérêt seront affichés, ils vous permettrons d\'obtenir des informations sur les lieux qui vous entourent.
     Télécharger les cartes Wikipédia
     Scooter
     Moto enduro
@@ -3782,7 +3782,7 @@
     Note OSM fermée
     Fauteuil roulant
     Fauteuil roulant vers l\'avant
-    Vous devez définir les jours travaillés avant de poursuivre
+    Définissez les jours travaillés pour continuer
     Itinéraire entre points
     Planifier un itinéraire
     Ajouter à une trace
@@ -3804,9 +3804,7 @@
     Sélectionnez comment relier les points : par une ligne droite ou en calculant un itinéraire avec le profil sélectionné.
     Toute la trace sera recalculée en utilisant le profil sélectionné.
     Seul le prochain segment sera recalculé en utilisant le profil sélectionné.
-    Pour utiliser cette option, OsmAnd doit aligner votre trace sur les routes de la carte.
-\n
-\n À l\'étape suivante, vous devrez sélectionner le profil de navigation pour détecter les routes autorisées et le seuil de distance pour rapprocher votre trace des routes.
+    Ensuite, sélectionnez le profil de navigation pour détecter les routes autorisées et le seuil de distance afin de déplacer votre trace.
     Sélectionnez un fichier de trace auquel ajouter un nouveau segment.
     Enregistrer comme nouvelle trace
     Inverser l\'itinéraire
@@ -3815,7 +3813,7 @@
     Seuil de distance
     Profil de navigation
     Photos des rues
-    Voulez-vous vraiment fermer l\'itinéraire planifié sans enregistrer \? Vous perdrez toutes les modifications.
+    Voulez-vous vraiment fermer l\'itinéraire planifié sans enregistrer \? (vous perdrez vos modifications)
     Si inversion du sens
     Point de la trace vers lequel naviguer
     Enregistrer le parcours
@@ -3831,7 +3829,7 @@
     Traces
     Traces
     Traces
-    REC
+    ENR
     Enregistrer le parcours dans un fichier GPX
     Enregistrement du parcours
     Enregistrer comme fichier de trace
@@ -3850,7 +3848,7 @@
     Ouvrir une trace enregistrée
     a été enregistré
     Veuillez ajouter au moins deux points.
-    Sélectionnez le fichier de trace à suivre ou importez-en un.
+    Sélectionnez le fichier de trace à suivre ou importez-le depuis votre appareil.
     Reprendre l\'enregistrement du trajet
     Suspendre l\'enregistrement du trajet
     Définit la fréquence d’enregistrement du parcours (enregistrement activé depuis le gadget sur la carte).
@@ -3861,4 +3859,25 @@
     Segment précédent
     Tous les segments précédents
     Seul le segment sélectionné sera recalculé avec le profil sélectionné.
+    • Mise à jour du mode de planification d\'itinéraire autorisant différents types de navigation pour chaque segment et permettant de déplacer n\'importe quelle trace sur les routes
+\n
+\n• Nouvelles options pour l\'apparence des traces : choix de la couleur et de l\'épaisseur des flèches de direction et affichage des marques de départ et d\'arrivée
+\n
+\n• Amélioration de \"bicycle nodes visibility\"
+\n
+\n• Nouveau menu contextuel pour les traces affichant des informations basiques
+\n
+\n• Amélioration de l\'algorithme de recherche
+\n
+\n• Amélioration du suivi des traces lors de la Navigation
+\n
+\n• Correction de l\'import / export des profils
+\n
+\n
+    Couper avant
+    Couper après
+    Modifier le type d’itinéraire avant
+    Modifier le type d’itinéraire après
+    Seule la ligne d\'itinéraire sera enregistrée, les points de passage seront supprimés.
+    Rétablir
 
\ No newline at end of file

From b20a96788956694b3fe7d9037a970fb579d7d8f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Sat, 12 Sep 2020 10:37:04 +0000
Subject: [PATCH 0076/1366] Translated using Weblate (Turkish)

Currently translated at 99.1% (3456 of 3484 strings)
---
 OsmAnd/res/values-tr/strings.xml | 63 +++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 22 deletions(-)

diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml
index 58e5c1f7cc..fd9beef585 100644
--- a/OsmAnd/res/values-tr/strings.xml
+++ b/OsmAnd/res/values-tr/strings.xml
@@ -154,7 +154,7 @@
     Yollar-sadece haritalar
     Trafik uyarıları (hız sınırları, zorunlu duruşlar, hız tümsekleri, tüneller), hız kamerası uyarıları ve şerit bilgilerini ayarlayın.
     Başka bir başlık algılanmadığında pusulayı kullan.
-    Navigasyon sırasında konumu yola uydur.
+    Navigasyon sırasında konumu yola tuttur.
     Yola tuttur
     OsmAnd (OSM Automated Navigation Directions) 
 \n 
@@ -1238,8 +1238,8 @@
     Seçimini kaldırın
     Tüm Seçimleri Kaldır
     Daralt
-    Benim İzlerim
-    Mevcut kaydedilen izim
+    İzlenen yollar
+    Şu anda kaydedilen yol
     Rota noktaları
     İz bölümü
     İz noktası
@@ -1658,7 +1658,7 @@
     min/m
     min/km
     m/s
-    Seyahat kayıt
+    Seyahat kaydetme
     Navigasyon
     Arka planda çalıştır
     GPS uyanma aralığı
@@ -1960,7 +1960,7 @@
     Konum aranıyor…
     OsmAnd\'ın konumunuzu bulmasına ve o bölge için harita indirmeyi önermesine izin verin.
     Başka bölge seç
-    OsmAnd\'ın veri deposu (haritalar, GPX dosyaları vb. için): %1$s.
+    OsmAnd\'ın veri deposu (haritalar, yol dosyaları vb. için): %1$s.
     Değiştir
     Al
     Mil/metre
@@ -2317,8 +2317,8 @@
     Arazi kotunda faktör (SRTM, ASTER ve EU-DEM verileri aracılığıyla).
     Şehir veya bölge
     %1$d çıkışa gir ve ilerle
-    Henüz GPX dosyanız yok
-    Ayrıca klasöre GPX dosyaları ekleyebilirsiniz
+    Henüz yol dosyanız yok
+    Ayrıca klasöre yol dosyaları ekleyebilirsiniz
     Daha fazla ekle…
     Görünüm
     Hızlı kaydı aç
@@ -2450,9 +2450,9 @@
     Yol türleri
     Takas
     Daha fazla görüntüle
-    GPX yollarını göster/gizle
-    GPX Yollarını Gizle
-    GPX Yollarını Göster
+    Yolları göster/gizle
+    Yolları Gizle
+    Yolları Göster
     Ev ekle
     Iş ekle
     İş
@@ -2920,7 +2920,7 @@
     Adım adım
     Burada çık
     Durakta bin
-    Seçilen GPX yollarını haritada göstermek veya gizlemek için bir düğme.
+    Seçilen yolları haritada göstermek veya gizlemek için bir düğme.
     Lütfen önce hedefi ayarlayın
     • Yeni \'Yol Tarifleri\' ekranı: Ev ve İş hedefi düğmelerini, \'önceki rota\' kısayolunu, etkin GPX yol-izlerinin ve işaretleyicilerin listesini, arama geçmişini görüntüler
 \n
@@ -3739,7 +3739,7 @@
     Kaldır
     Kerteriz
     %1$s silindi
-    Hız kamerası verilerini tamamen silmek için yeniden başlatma gerekmektedir.
+    Tüm hız kamerası verilerini silmek için uygulamayı yeniden başlatın.
     Kaldır ve Yeniden Başlat
     Bu aygıtta hız kameraları yok.
     Paten
@@ -3748,8 +3748,8 @@
     Güzergahdaki geçerli hedef noktası silinecektir. Eğer bu varış noktası olacaksa, navigasyon duracaktır.
     Lütfen nokta için bir ad belirtin
     Aracınızın uzunluğunu belirtin, uzun araçlar için bazı güzergah kısıtlamaları geçerli olabilir.
-    Sonraki varış noktasını sil
-    Harita yakınlaştırma seviyesini cihaz ses seviyesi düğmeleriyle denetlemeyi etkinleştirin.
+    En yakın varış noktasını sil
+    Harita yakınlaştırma seviyesini cihaz ses seviyesi düğmelerini kullanarak denetleyin.
     Yakınlaştırma için ses seviyesi düğmeleri
     Wikipedia haritalarını indir
     Wikipedia\'dan ilgi çekici yerler hakkında bilgi alın. Bu sizin çevrim dışı cep rehberinizdir - sadece Wikipedia eklentisini etkinleştirin ve etrafınızdaki nesneler hakkında makalelerin tadını çıkarın.
@@ -3758,13 +3758,13 @@
     Tekerlekli sandalye
     İleri tekerlekli sandalye
     Go-kart
-    Kapatılmış OSM Notu
+    Kapatılmış OSM notu
     İzlemeye ekle
-    Devam etmek için çalışma günlerini ayarlamalısınız
+    Devam etmek için çalışma günlerini ayarla
     Noktalar arasındaki güzergah
     Güzergah planla
     Seçilen grup gizli olduğu için eklenen nokta haritada görünmeyecek, \"%s\" içinde bulabilirsiniz.
-    Başlangıç bitiş simgelerini göster
+    Başlangıç ve bitiş simgelerini göster
     Genişlik seç
     Yol üzerinde mesafe veya zaman işaretlerinin görüntüleneceği aralığı seçin.
     İstediğiniz bölme seçeneğini seçin: zamana veya mesafeye göre.
@@ -3778,10 +3778,8 @@
     Açmak için bir yol dosyası seçin.
     Bitti
     Yolun üzerine yaz
-    Bu seçeneği kullanmak için OsmAnd\'ın izlediğiniz yolu harita yollarına eşleştirmesi gereklidir.
-\n
-\n Sonraki adımda, izin verilen yolları tespit etmek için navigasyon profilini ve izlediğiniz yolu yaklaşık olarak belirlemek için eşik mesafesini seçmeniz gerekecektir.
-    Yeni bir Yol olarak kaydet
+    Ardından, bu seçeneği kullanmak için navigasyon profillerinizden biriyle izlenen yolunuzu izin verilen en yakın yola tutturun.
+    Yeni bir yol olarak kaydet
     Ters güzergah
     Tüm yol, seçilen profil kullanılarak yeniden hesaplanacaktır.
     Sadece sonraki bölüm, seçilen profil kullanılarak yeniden hesaplanacaktır.
@@ -3792,7 +3790,28 @@
     Navigasyon profili
     Kendisine yeni bir bölümün ekleneceği bir yol dosyası seçin.
     Sokak seviyesi görüntüleri
-    Kaydetmeden güzergah planlamayı kapatmak istediğinize emin misiniz\? Tüm değişiklikleri kaybedeceksiniz.
+    Planlanan güzergahtaki tüm değişiklikleri kapatarak atmak istediğinizden emin misiniz\?
     Ters yön durumunda
     REC
+    Kaydedilen yolu aç
+    kaydedildi
+    Lütfen en az iki nokta ekleyin.
+    Yeniden yap
+    İzlenen yollar
+    Yolu GPX dosyasına kaydet
+    Yol dosyalarını içe aktarın veya kaydedin
+    Yeni yol dosyası olarak kaydet
+    Bir yol dosyasına ekle
+    İzlenen yollar
+    İzlenen yollar
+    Yol dosyaları ekle
+    Yol ara noktası ekle
+    Yol ara noktası ekle
+    Seyahat kaydetme
+    Yol dosyası olarak kaydet
+    %s yol dosyası seçildi
+    (Son uygulamalar aracılığıyla) uygulama kapatıldığında yol kaydını duraklatacaktır. (OsmAnd arka plan göstergesi Android bildirim çubuğundan kaybolur.)
+    Genel yol kaydı için kayıt aralığını seçin (haritadaki seyahat kayıt widget\'ı aracılığıyla etkin).
+    Seyahat kaydetmeyi duraklat
+    Seyahat kaydetmeyi devam ettir
 
\ No newline at end of file

From 84456a2e0079a415e5ae634415cfd23dc89c82c0 Mon Sep 17 00:00:00 2001
From: Mirco Zorzo 
Date: Sat, 12 Sep 2020 09:55:37 +0000
Subject: [PATCH 0077/1366] Translated using Weblate (Italian)

Currently translated at 90.0% (3139 of 3484 strings)
---
 OsmAnd/res/values-it/strings.xml | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml
index 5c63764ec2..505d5ee27f 100644
--- a/OsmAnd/res/values-it/strings.xml
+++ b/OsmAnd/res/values-it/strings.xml
@@ -563,9 +563,7 @@
     Componenti aggiuntivi
     I plugin abilitano funzionalità aggiuntive e impostazioni avanzate.
     Componenti aggiuntivi
-    Realizza contributi OSM come la creazione o la modifica di PDI OSM, aprendo o commentando note OSM, 
-\ne contribuendo i file GPX registrati in OsmAnd inserendo il tuo nome utente e password.
-\nOpenStreetMap.org è un progetto collaborativo di mappatura globale di dominio pubblico.
+    Realizza contributi OSM come la creazione o la modifica di PDI OSM, aprendo o commentando note OSM, e contribuendo i file GPX registrati in OsmAnd inserendo il tuo nome utente e password. OpenStreetMap.org è un progetto collaborativo di mappatura globale di dominio pubblico.
     Le mappe vettoriali dovrebbero apparire più velocemente. Su certi dispositivi potrebbero non funzionare bene.
     Seleziona una voce e provane gli annunci vocali:
     Sviluppo di OsmAnd
@@ -3823,9 +3821,7 @@
     Scegli il file di una traccia da aprire.
     Fatto
     Profilo di navigazione
-    Per utilizzare questa opzione OsmAnd ha bisogno di bloccare la traccia alle strade della mappa.
-\n
-\n Nel prossimo passaggio avrai bisogno di selezionare il profilo di navigazione per determinare le strade permesse e la soglia della distanza per approssimare la strada alle strade.
+    Poi approssima la traccia alle strade più vicine permesse da uno dei tuoi profili di navigazione per utilizzare questa opzione.
     Scegli come collegare i punti, con una linea retta, o calcolando un percorso che li colleghi utilizzando il profilo scelto.
     Sovrascrivi traccia
     Salva come nuova Traccia
@@ -3837,7 +3833,7 @@
     Soglia distanza
     Seleziona un file traccia a cui verrà aggiunto un nuovo segmento.
     Immagini stradali
-    Sei sicuro di voler chiudere la Pianificazione del percorso senza salvare\? Perderai tutti i cambiamenti.
+    Sei sicuro di voler chiudere la Pianificazione del percorso perdendo così le modifiche effettuate\?
     In caso di direzione inversa
     Registra automaticamente la traccia durante la navigazione
     Salva come un nuovo file traccia
@@ -3852,11 +3848,11 @@
     Importa o registra dei file traccia
     Aggiungi un punto intermedio alla traccia
     Aggiungi un punto intermedio alla traccia
-    Registrazione viaggio
+    Registrazione percorso
     Salva come un file traccia
     Segui la traccia
     Scegli il file della traccia da seguire
-    Scegli il file della traccia da seguire o importala dal dispositivo.
+    Scegli il file della traccia da seguire o importare dal dispositivo.
     Seleziona un\'altra traccia
     Naviga dalla mia posizione alla traccia
     Punto della traccia da navigare
@@ -3868,9 +3864,9 @@
     Immetti un indirizzo
     Taglia prima
     Taglia dopo
-    Cambia il tipo di percorso prima
-    Cambia il tipo di percorso dopo
-    Solo la linea del percorso verrà salvato, i punti intermedi saranno cancellati.
+    Cambia il tipo di percorso precedente
+    Cambia il tipo di percorso seguente
+    Solo la linea del percorso verrà salvata, i punti intermedi saranno cancellati.
     Nome del file
     %s file traccia selezionati
     Metterà in pausa la registrazione della traccia quando l\'applicazione viene terminata (attraverso le app recenti). (L\'indicazione di OsmAnd in background scomparirà dalla barra delle notifiche di Android.)
@@ -3886,7 +3882,7 @@
     Tutti i segmenti precedenti verranno ricalcolati con il profilo selezionato.
     Apri una traccia salvata
     è stato salvato
-    Per favore aggiungi gli ultimi due punti.
+    Per favore aggiungi almeno due punti.
     Ripeti
     • Aggiornata la modalità Pianificazione dell\'Itinerario che permette l\'utilizzo di diversi profili di navigazione per ogni segmento e incolla le tracce alle strade
 \n
@@ -3903,4 +3899,5 @@
 \n • Corretto il problema all\'importa/esporta le impostazioni dei profili
 \n
 \n
+    Traccia semplificata
 
\ No newline at end of file

From 1696877e2c1a18b3d38b6cd5d3fb5e5ff3ef97f1 Mon Sep 17 00:00:00 2001
From: Yaron Shahrabani 
Date: Sat, 12 Sep 2020 06:57:53 +0000
Subject: [PATCH 0078/1366] Translated using Weblate (Hebrew)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-iw/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml
index ce6cf4cb93..1e25024941 100644
--- a/OsmAnd/res/values-iw/strings.xml
+++ b/OsmAnd/res/values-iw/strings.xml
@@ -3782,7 +3782,7 @@
     אזהרות מפני מצלמות מהירות אסורות על פי חוק בחלק מהמדינות.
     תכווין
     %1$s נמחקו
-    נדרשת הפעלה מחדש כדי למחוק לחלוטין את נתוני מצלמות המהירות.
+    הפעלת היישומון מחדש תמחק את כל נתוני מצלמות המהירות.
     הסרה והפעלה מחדש
     בחלק מהמדינות או האזורים השימוש ביישומוני אזהרה מפני מצלמות מהירות אסור על פי חוק.
 \n
@@ -3795,10 +3795,10 @@
     נא לציין את אורך כלי הרכב כדי לבדוק מסלולים מורשים.
     מגבלת אורך
     למכשיר הזה אין מצלמות מהירות.
-    מאפשר לשלוח ברמת התקריב של המפה עם כפתורי עצמת השמע של המכשיר.
+    ניתן לשלוט ברמת התקריב של המפה עם כפתורי עצמת השמע של המכשיר.
     כפתורי עצמת שמע כתקריב
     נא לספק את אורך כלי הרכב שלך, מגבלות מסלול מסוימות עשויות לחול על כלי רכב ארוכים.
-    מחיקת נקודת היעד הבאה
+    מחיקת נקודת היעד הקרובה ביותר
     נא לספק שם לנקודה
     נקודת היעד הנוכחית במסלול תימחק. אם זה יהיה היעד, הניווט ייעצר.
     הורדת מפות ויקיפדיה
@@ -3809,7 +3809,7 @@
     כסא גלגלים ספורטיבי
     קארטינג
     הערת OSM סגורה
-    עליך להגדיר ימי עבודה כדי להמשיך
+    יש להגדיר ימי עבודה כדי להמשיך
     מסלול בין נקודות
     תכנון מסלול
     הוספה למסלול
@@ -3842,7 +3842,7 @@
 \n
 \n בשלב הבא יהיה עליך לבחור בפרופיל ניווט כדי לזהות את הדרכים המורשות ואת סף המרחק כדי להעריך את המסלול שלך ביחס לדרכים.
     תמונות ברמת רחוב
-    לסגור את תכנון המסלול בלי לשמור\? כל השינויים שלך יאבדו.
+    להתעלם מהשינויים במסלול המתוכנן על ידי סגירתו\?
     במקרה של כיוון הפוך
     שמירה כקובץ מסלול חדש
     הוספה לקובץ מסלול
@@ -3860,7 +3860,7 @@
     שמירה כקובץ מסלול
     מעקב אחר מסלול
     בחירת קובץ מסלול למעקב
-    נא לבחור בקובץ מסלול לעקוב אחריו או לייבא אחד כזה.
+    נא לבחור בקובץ מסלול לעקוב אחריו או לייבא אותו מהמכשיר שלך.
     בחירת מסלול אחר
     לנווט מהמיקום שלי אל המסלול
     נקודה במסלול לניווט

From 8fc4a5f911dcd154b1d1fada44ed46194c7ffba7 Mon Sep 17 00:00:00 2001
From: Softmap 
Date: Sat, 12 Sep 2020 15:41:11 +0000
Subject: [PATCH 0079/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index 02597df8e6..1548c1dd0a 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -3823,7 +3823,7 @@
 \nفي الخطوة التالية ، ستحتاج إلى تحديد ملف تعريف الملاحة لاكتشاف الطرق المسموح بها وبداية المسافة لتقريب تتبعك بالطرق.
     بداية المسافة
     صور للشارع
-    هل أنت متأكد أنك تريد إغلاق مسار الخطة دون حفظ؟ سوف تفقد كل التغييرات.
+    هل أنت متأكد أنك تريد إغلاق مسار الخطة دون حفظ؟ سوف تفقد كل التغييرات؟
     في حالة الاتجاه المعاكس
     تسجيل المسار أثناء الملاحة
     حفظ كملف مسار جديد

From 875f6664ce8a23106feed59bcd7567accb346ba4 Mon Sep 17 00:00:00 2001
From: Eduardo Addad de Oliveira 
Date: Sat, 12 Sep 2020 14:59:22 +0000
Subject: [PATCH 0080/1366] Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt-rBR/strings.xml | 33 ++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml
index 9c22577d6c..ea83d5b1b6 100644
--- a/OsmAnd/res/values-pt-rBR/strings.xml
+++ b/OsmAnd/res/values-pt-rBR/strings.xml
@@ -3776,20 +3776,20 @@
     Os alertas de radares de velocidade em alguns países são proibidos por lei.
     Rolamento
     %1$s excluído
-    É necessário reiniciar para excluir completamente os dados da câmera de velocidade.
+    Reinicie o aplicativo para excluir todos os dados da câmera de velocidade.
     Desinstalar e reiniciar
     Especifique o comprimento do veículo a ser permitido nas rotas.
     Limite de comprimento
     Este dispositivo não possui câmeras de velocidade.
     Patins em linha
-    Ativar para controlar o nível de zoom do mapa com os botões de volume do dispositivo.
+    Controle o nível de zoom do mapa usando os botões de volume do dispositivo.
     Botões de volume como zoom
     Forneça o comprimento do seu veículo. Algumas restrições de rotas podem ser aplicadas a veículos longos.
-    Excluir próximo ponto de destino
+    Apagar o ponto de destino mais próximo
     Forneça um nome para o ponto
     O ponto de destino atual na rota será excluído. Se for o destino, a navegação será interrompida.
     Baixar mapas da Wikipédia
-    Obter informações sobre pontos de interesse da Wikipédia. É o seu guia de bolso off-line - só ativar o complemento Wikipédia e desfrutar de artigos sobre os elementos ao seu redor.
+    Obtenha informações sobre pontos de interesse na Wikipédia. É o seu guia offline de bolso - basta ativar o plug-in da Wikipédia e desfrutar dos artigos sobre os objetos ao seu redor.
     Motocicleta enduro
     Motoneta
     Cadeira de rodas
@@ -3797,11 +3797,11 @@
     Carrinho de compras
     Nota OSM fechada
     Adicionar a uma trilha
-    Você precisa definir dias úteis para continuar
+    Defina dias úteis para continuar
     Rota entre pontos
     Planejar uma rota
     O ponto adicionado não será visível no mapa, já que o grupo selecionado está oculto, você pode encontrá-lo em \"%s\".
-    Mostrar ícones de início e término
+    Mostrar ícones de início e fim
     Selecionar largura
     Selecione o intervalo no qual as marcas com distância ou tempo na pista serão exibidas.
     Selecione a opção de divisão desejada: por tempo ou por distância.
@@ -3812,7 +3812,7 @@
     Importar trilha
     Abrir trilha existente
     Criar nova rota
-    Selecione um arquivo de faixa para abrir.
+    Selecione um arquivo de trilha para abrir.
     Concluído
     Substituir trilha
     Salvar como nova trilha
@@ -3829,7 +3829,7 @@
     Perfil de navegação
     Selecione um arquivo de trilha para o qual um novo segmento será adicionado.
     Imagens de rua
-    Tem certeza de que deseja fechar plano de rota sem salvar\? Você perderá todas as alterações.
+    Tem certeza de que deseja descartar todas as alterações no percurso planejado, fechando-o\?
     Em caso de direção reversa
     Salvar como novo arquivo de trilha
     Trilhas
@@ -3847,7 +3847,7 @@
     Salvar como arquivo de trilha
     Seguir a trilha
     Escolha o arquivo de trilha a seguir
-    Escolha o arquivo de trilha a seguir ou importe um.
+    Escolha o arquivo de trilha a seguir ou importe-o de seu dispositivo.
     Selecionar outra trilha
     Navegue de minha localização até a trilha
     Ponto da trilha para navegar
@@ -3881,4 +3881,19 @@
     está salvo
     Adicione pelo menos dois pontos.
     Refazer
+    "• O modo de rota de plano atualizado permite o uso de diferentes tipos de navegação para cada segmento e anexa qualquer trilha às estradas
+\n
+\n • Novas opções de aparência para trilhas: selecione a cor, a espessura, ative as setas de direção e as marcas de início/fim
+\n
+\n  • Melhor visibilidade dos nós da bicicleta
+\n
+\n  • Menu de contexto para trilhas com informações básicas
+\n
+\n  • Algoritmos de pesquisa aprimorados
+\n
+\n  • Opções de acompanhamento de trilha aprimoradas na navegação
+\n
+\n  • Problemas corrigidos com importação/exportação de configurações de perfil
+\n
+\n"
 
\ No newline at end of file

From c91f2eec56e329b56951d553ab49f15580127511 Mon Sep 17 00:00:00 2001
From: Eduardo Addad de Oliveira 
Date: Sat, 12 Sep 2020 14:58:06 +0000
Subject: [PATCH 0081/1366] Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-pt-rBR/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml
index 4a969baf22..27475442c8 100644
--- a/OsmAnd/res/values-pt-rBR/phrases.xml
+++ b/OsmAnd/res/values-pt-rBR/phrases.xml
@@ -3841,4 +3841,5 @@
     Quadro de partidas: não
     Quadro de partidas
     Recarga de água potável
+    Pequenos aparelhos elétricos
 
\ No newline at end of file

From ca4f54f45c72d27b5383e2b35cfafded44b743a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Sat, 12 Sep 2020 11:53:09 +0000
Subject: [PATCH 0082/1366] Translated using Weblate (Estonian)

Currently translated at 97.9% (3414 of 3484 strings)
---
 OsmAnd/res/values-et/strings.xml | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml
index d058f6ca17..80fdecc6df 100644
--- a/OsmAnd/res/values-et/strings.xml
+++ b/OsmAnd/res/values-et/strings.xml
@@ -3646,7 +3646,7 @@
     Navigeerimisprofiil
     Vali rajafail, millele lisame uue segmendi.
     Tänavataseme vaated
-    Kas sa oled kindel et soovid sulgeda teekonna planeerija ilma seda salvestamata\? Kõik muudatused lähevad kaotsi.
+    Kas sa oled kindel et soovid sulgeda teekonna planeerija ilma seda salvestamata\?
     Vastupidise suuna korral
     Muuda järjekorda või peida kirjed %1$s\'st.
     Need kirjed on menüüs peidetuna, kuid tehtud valikud või lisaprogrammid on jätkuvalt kasutatavad.
@@ -3714,4 +3714,19 @@
     Korda tegevust
     Järjesta kategooriad ümber
     Visualiseerimise stiil
+    Mõnedes riikides või piirkondades on kiiruskaamerate eest hoiatavad rakendused seadusega keelatud,
+\n
+\nVastavalt oma maa seadustele pead sa otsuse tegema.
+\n
+\nValides %1$s sa saad kiiruskaamerate-kohaseid teateid ja hoiatusi.
+\n 
+\nValides %s$s kustutatakse kõik kiiruskaameratega seotud andmed, nagu hoiatused, teated ja huvipunktid seniks, kuni sa OsmAnd\'ile ei tee täiesti uut paigaldust.
+    Praegune teekonna vahepunkt saab kustutatud. Kui ta osutub sihtkohaks, siis navigatsioon lõppeb.
+    Muuda teekonna tüüpi pärast
+    Muuda teekonna tüüpi enne
+    Kärbi pärast
+    Kärbi enne
+    Kinnita teede külge
+    Selle valiku kasutamiseks mõne oma navigeerimisprofiili kasutamisel kinnita oma rada lähimale lubatud teele.
+    Valitud profiili alusel arvutatakse uus teekond vaid järgmise segmendi osas.
 
\ No newline at end of file

From 7fae800f432d21bd1d1fb43223f03e0da78cc693 Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Sat, 12 Sep 2020 22:04:45 +0000
Subject: [PATCH 0083/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 27afe56282..8825ffe15e 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -1033,7 +1033,7 @@
     Частный
     Забрать автомобиль со стоянки
     Предупреждение
-    Напоминание о необходимости забрать автомобиль добавлено в ваш календарь, где оно может быть изменено или удалено.
+    Напоминание забрать авто добавлено в календарь, там его можно изменить или удалить.
     Задайте максимальное время стоянки
     Удалить отметку места парковки?
     Удалить точку парковки
@@ -2342,7 +2342,7 @@
     Прозрачно-розовый
     Берберский
     Переместить все в историю
-    Сортировать по
+    Сортировка
     Без анимации
     Выключение анимации карты.
     Выйти без сохранения?
@@ -2357,7 +2357,7 @@
     Сохранить точки, как точки маршрута или как линию.
     Выберите профиль навигации
     %1$d из %2$d
-    Список
+    Списком
     Группы
     Использовано: %1$s
     Сделать активным
@@ -2678,7 +2678,7 @@
     Файл GPX
     OSC файл
     Выберите тип файла
-    Экспортировать как: заметки OSM, POI или оба.
+    Экспортировать в виде POI, заметок OSM или обоих вариантов.
     Все данные
     Заметки OSM
     Впереди туннель
@@ -2703,8 +2703,8 @@
     С
     Необязательное имя точки
     Спортивные сплавы
-    Сначала дальнее
-    Сначала ближнее
+    По удалённости (сначала дальние)
+    Удалённость (сначала ближние)
     Группа удалена
     Очистить все промежуточные точки
     Использовать двузначную долготу
@@ -2808,7 +2808,7 @@
     Редактировать точку
     Добавить точку
     Сохранить как трек
-    Добавлено вами точек — %1$s. Введите имя файла и нажмите «Сохранить».
+    Добавлено точек: %1$s. Введите имя файла и нажмите «Сохранить».
     Точка %1$s удалена
     Мир
     Ваш поисковый запрос будет отправлен: «%1$s», вместе с вашим местоположением.
@@ -3067,7 +3067,7 @@
     Лошадь
     Вертолёт
     Вы можете добавить собственную модифицированную версию routing.xml в ..osmand/routing
-    Выберите значок
+    Значок
     Лыжи
     Тип: %s
     Базовый профиль
@@ -3346,7 +3346,7 @@
     Положение значка в состоянии покоя
     После нажатия кнопки «Применить» удалённые профили будут полностью потеряны.
     Базовый профиль
-    Выберите цвет
+    Цвет
     Вы не можете удалить стандартные профили OsmAnd, но вы можете отключить их на предыдущем экране или переместить вниз.
     Редактировать профили
     «Тип навигации» определяет способ расчета маршрутов.
@@ -3571,9 +3571,9 @@
     Пользовательский плагин
     Удалить описание
     Добавить описание
-    Выберите группу
+    Категории
     Квадрат
-    Выберите фигуру
+    Форма
     Круг
     Восьмиугольник
     Сообщение о доступности
@@ -3588,7 +3588,7 @@
     Затенение рельефа использует тёмные оттенки для отображения склонов, вершин и низменностей.
     Для отображения склонов на карте необходимы дополнительные карты.
     Склоны
-    Заменить другую точку на эту.
+    Заменить этой точкой другую.
     Изменения применены к профилю «%1$s».
     Невозможно прочитать из «%1$s».
     Невозможно записать в «%1$s».
@@ -3805,7 +3805,7 @@
     Маршрут между точками
     План маршрута
     Выберите нужный вариант разбиения: по времени или по расстоянию.
-    Выберите интервал с которым будут отображаться метки с расстоянием или временем на треке.
+    Интервал между метками расстояния или времени на треке.
     Своё
     Добавленная точка не будет видна на карте, так как выбранная группа скрыта, найти её можно в «%s».
     Показывать значки старта и финиша

From e0bb089a6980663d4085082534f7ed13c81fbcdd Mon Sep 17 00:00:00 2001
From: Nikita Epifanov 
Date: Sat, 12 Sep 2020 20:18:10 +0000
Subject: [PATCH 0084/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 8825ffe15e..8252ed2138 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -3779,20 +3779,20 @@
     Оповещение о камерах контроля скорости в некоторых странах запрещено законом.
     Ориентация
     Удалено: %1$s
-    Перезапуск необходим для полного удаления данных камер контроля скорости.
+    Перезапустите приложение, чтобы удалить все данные о камерах контроля скорости.
     Удалить и перезапустить
     Удалить
     Укажите длину транспортного средства, разрешённую для движения по маршрутам.
     Предельная длина
     В этом устройстве нет камер контроля скорости.
     Роликовые коньки
-    Управление уровнем масштабирования карты с помощью кнопок регулировки громкости устройства.
+    Управляйте уровнем масштабирования карты с помощью кнопок громкости на устройстве.
     Масштабирование кнопками громкости
     Укажите длину автомобиля, для длинных транспортных средств могут применяться ограничения на маршруте.
-    Удалить следующий пункт
+    Удалить ближайшую точку назначения
     Задайте название точки
     Следующая точка маршрута будет удалена. Если это конечный пункт, навигация завершится.
-    Информация о достопримечательностях из Википедии. Ваш карманный офлайн-гид — просто включите плагин и читайте об объектах вокруг вас.
+    Получите информацию о достопримечательностях из Википедии. Это ваш карманный автономный путеводитель - просто включите плагин Википедии и наслаждайтесь статьями об объектах вокруг вас.
     Скачать карты Википедии
     Эндуро мотоцикл
     Мотороллер
@@ -3801,7 +3801,7 @@
     В карту
     Инвалидное кресло впереди
     Добавить к треку
-    Необходимо указать рабочие дни для продолжения
+    Установите рабочие дни, чтобы продолжить
     Маршрут между точками
     План маршрута
     Выберите нужный вариант разбиения: по времени или по расстоянию.
@@ -3833,7 +3833,7 @@
 \nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
     Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем.
     При обратном направлении
-    Закрыть план маршрута\? Все изменения будут утеряны.
+    Вы уверены, что хотите отменить все изменения в запланированном маршруте, закрыв его\?
     Изображения на уровне улиц
     Сохранить как новый файл трека
     Добавить в файл трека
@@ -3851,7 +3851,7 @@
     Сохранить как файл трека
     Следовать по маршруту
     Выберите файл маршрута для следования
-    Выберите или импортируйте файл маршрута.
+    Выберите файл трека или импортируйте его со своего устройства.
     Выбрать другой трек
     Ведение от моей позиции к треку
     Точка трека для навигации

From fda2bc90a93e53b4c05086da31f82fc8ee9a2110 Mon Sep 17 00:00:00 2001
From: Softmap 
Date: Sat, 12 Sep 2020 15:43:49 +0000
Subject: [PATCH 0085/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index 1548c1dd0a..57b4c76c7d 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -3818,9 +3818,7 @@
     حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها مع ملف التعريف المحدد.
     مسار كامل
     المقطع التالي
-    لاستخدام هذا الخيارتحتاج إلى محاذاة المسار الخاص بك إلى خريطة الطرق.
-\n
-\nفي الخطوة التالية ، ستحتاج إلى تحديد ملف تعريف الملاحة لاكتشاف الطرق المسموح بها وبداية المسافة لتقريب تتبعك بالطرق.
+    بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد ملفات تعريف التنقل الخاصة بك لاستخدام هذا الخيار.
     بداية المسافة
     صور للشارع
     هل أنت متأكد أنك تريد إغلاق مسار الخطة دون حفظ؟ سوف تفقد كل التغييرات؟

From 84b9825eb5255f9447ac885c82d1e7c602455bd4 Mon Sep 17 00:00:00 2001
From: Franco 
Date: Sat, 12 Sep 2020 17:25:07 +0000
Subject: [PATCH 0086/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-es-rAR/strings.xml | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml
index 532b57eb5c..4eed292de2 100644
--- a/OsmAnd/res/values-es-rAR/strings.xml
+++ b/OsmAnd/res/values-es-rAR/strings.xml
@@ -2337,7 +2337,8 @@
 \n • Medio Oriente: **
 \n • África: **
 \n • Antártida: *
-\n ¡Más países alrededor del globo están disponibles para descargar! Desde Afganistán a Zimbabue, desde Australia a Estados Unidos. Argentina, Brasil, Canadá, Francia, Alemania, México, Reino Unido, España, …
+\n ¡Más países alrededor del globo están disponibles para descargar!
+\nDesde Afganistán a Zimbabue, desde Australia a Estados Unidos. Argentina, Brasil, Canadá, Francia, Alemania, México, Reino Unido, España, …
 \n
     OsmAnd+ (OSM Automated Navigation Directions, y en español, Guía de Navegación Automatizada de OSM) es una aplicación de mapa y navegación con acceso a los datos libres de OSM, en todo el mundo y de alta calidad. 
 \n Disfruta del navegador por voz y óptico, la visualización de PDI (puntos de interés), la creación y gestión de trazas GPX, utiliza la información de visualización y la altitud de las curvas de nivel (mediante un complemento), elige entre modos de automóvil, bicicleta o peatón, edita en OSM y mucho más. 
@@ -3776,7 +3777,7 @@
 \nPulsa en «%2$s», para borrar todos los datos relacionados con los radares de velocidad (alertas, notificaciones y PDI) hasta reinstalar OsmAnd completamente.
     Desinstalar radares de velocidad
     PDI de los radares de velocidad
-    Se debe reiniciar para borrar completamente los datos de los radares de velocidad.
+    Reiniciar la aplicación para borrar todos los datos de los radares de velocidad.
     Legal
     Mantener
     Desinstalar
@@ -3791,10 +3792,10 @@
     Límite de longitud
     Este dispositivo no tiene radares de velocidad.
     Patines en línea
-    Permite controlar el nivel de zoom del mapa con los botones de volumen del dispositivo.
+    Controla el nivel de zoom del mapa usando los botones de volumen del dispositivo.
     Botones de volumen como zoom
     Proporciona la longitud del vehículo, se pueden aplicar algunas restricciones de rutas para vehículos largos.
-    Borrar el siguiente punto de destino
+    Borrar el punto de destino más cercano
     Proporciona un nombre para el punto
     El punto de destino actual de la ruta será borrado. Si será el destino, la navegación se detendrá.
     Descargar datos de Wikipedia
@@ -3805,7 +3806,7 @@
     Go-kart
     Nota de OSM cerrada
     Silla de ruedas (hacia adelante)
-    Debes definir los días laborales para continuar
+    Definir los días laborales para continuar
     Ruta entre puntos
     Crear una ruta
     Añadir a una traza
@@ -3821,7 +3822,7 @@
     Importar traza
     Abrir traza existente
     Crear nueva ruta
-    Marca un archivo de traza para abrir.
+    Marcar un archivo de traza para abrir.
     Listo
     Sobrescribir traza
     Guardar como nueva traza
@@ -3831,14 +3832,12 @@
     Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido.
     Traza completa
     Siguiente segmento
-    Para utilizar esta opción, OsmAnd debe ajustar su traza a los caminos del mapa.
-\n
-\n En el siguiente paso se debe elegir el perfil de navegación para detectar los caminos permitidos y el umbral de distancia para aproximar la traza a los caminos.
+    A continuación, ajusta la traza al camino permitido más cercano con un perfil de navegación.
     Distancia de umbral
     Perfil de navegación
     Elige un archivo de traza al que se añadirá un nuevo segmento.
     Imágenes a nivel de calle
-    ¿Cerrar el plan de ruta sin guardar\? Se perderán todos los cambios.
+    ¿Cerrar el plan de ruta sin guardar\?, se descartarán todos los cambios.
     En caso de dirección inversa
     Grabar la traza automáticamente al navegar
     Trazas
@@ -3856,7 +3855,7 @@
     Guardar como archivo de traza
     Seguir traza
     Elige el archivo de la traza a seguir
-    Elige el archivo de la traza a seguir o importa una.
+    Elige el archivo de la traza a seguir o impórtala desde el dispositivo.
     Elegir otra traza
     Navegar desde mi ubicación a la traza
     Punto de la traza para navegar
@@ -3872,7 +3871,7 @@
     Cambiar el tipo de ruta posterior
     Traza simplificada
     Nombre del archivo
-    GRABAR
+    Grabar
     La grabación de la traza se pausará al cerrar la aplicación (mediante aplicaciones recientes). (La indicación de fondo de OsmAnd, desaparecerá de la barra de notificaciones de Android.)
     Intervalo de registro para la grabación general de trazas (activar mediante el widget de grabación de viaje sobre el mapa).
     Pausar grabación del viaje

From 4b798ad7108554efc1a9a062de1ed79c8e07a421 Mon Sep 17 00:00:00 2001
From: Franco 
Date: Sat, 12 Sep 2020 17:32:32 +0000
Subject: [PATCH 0087/1366] Translated using Weblate (Spanish (American))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-es-rUS/strings.xml | 55 ++++++++++++++++++----------
 1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/OsmAnd/res/values-es-rUS/strings.xml b/OsmAnd/res/values-es-rUS/strings.xml
index 29da2f288d..bb6fe37c9e 100644
--- a/OsmAnd/res/values-es-rUS/strings.xml
+++ b/OsmAnd/res/values-es-rUS/strings.xml
@@ -2014,7 +2014,7 @@
     Necesario para descargar mapas.
     Buscando la ubicación…
     Espacio libre
-    Almacenamiento de datos de OsmAnd (para mapas, archivos GPX, etc.): %1$s.
+    Almacenamiento de datos de OsmAnd (para mapas, archivos de trazas, etc.): %1$s.
     Conceder permiso
     Permitir el acceso a la ubicación
     Obtén direcciones y descubre sitios nuevos sin una conexión a Internet
@@ -2066,8 +2066,8 @@
     Activar la grabación rápida
     Muestra una notificación del sistema que permite iniciar la grabación del viaje.
     Notificaciones
-    Sin archivos GPX aún
-    También puedes añadir archivos GPX a la carpeta
+    Sin archivos de trazas aún
+    También puedes añadir archivos de trazas a la carpeta
     Añadir GPX
     Aspecto
     Muy fino
@@ -2337,7 +2337,8 @@
 \n • Medio Oriente: **
 \n • África: **
 \n • Antártida: *
-\n ¡Más países alrededor del globo están disponibles para descargar! Desde Afganistán a Zimbabue, desde Australia a Estados Unidos. Argentina, Brasil, Canadá, Francia, Alemania, México, Reino Unido, España, …
+\n ¡Más países alrededor del globo están disponibles para descargar!
+\nDesde Afganistán a Zimbabue, desde Australia a Estados Unidos. Argentina, Brasil, Canadá, Francia, Alemania, México, Reino Unido, España, …
 \n
     OsmAnd+ (OSM Automated Navigation Directions, y en español, Guía de Navegación Automatizada de OSM) es una aplicación de mapa y navegación con acceso a los datos libres de OSM, en todo el mundo y de alta calidad. 
 \n Disfruta del navegador por voz y óptico, la visualización de PDI (puntos de interés), la creación y gestión de trazas GPX, utiliza la información de visualización y la altitud de las curvas de nivel (mediante un complemento), elige entre modos de automóvil, bicicleta o peatón, edita en OSM y mucho más. 
@@ -2625,7 +2626,7 @@
     Archivo GPX con coordenadas y datos de todas las notas.
     Acciones
     Marcador
-    \'%1$s ediciones, suman %2$s mBTC\'
+    %1$s ediciones, suman %2$s mBTC
     Destinatarios de OSM
     Total de donaciones
     Sin nombre
@@ -2897,10 +2898,10 @@
     Tipos de caminos
     Bajar en
     Esperar en la parada
-    Mostrar u ocultar trazas GPX
-    Un botón que muestra u oculta las trazas GPX elegidas en el mapa.
-    Ocultar trazas GPX
-    Mostrar trazas GPX
+    Mostrar u ocultar trazas
+    Un botón que muestra u oculta las trazas elegidas en el mapa.
+    Ocultar trazas
+    Mostrar trazas
     • Nueva pantalla «Direcciones»: Muestra los botones de destino «Casa» y «Trabajo», el atajo de la «ruta anterior», la lista de trazas, marcadores GPX activos y el historial de búsqueda.
 \n
 \n • Información adicional en «Detalles de la ruta»: Tipos de caminos, superficie, pendiente y suavidad
@@ -3782,17 +3783,17 @@
     Un botón que alterna la capa de Mapillary en el mapa.
     Rumbo
     %1$s borrado
-    Se debe reiniciar para borrar completamente los datos de los radares de velocidad.
+    Reiniciar la aplicación para borrar todos los datos de los radares de velocidad.
     Desinstalar y reiniciar
     Indica la longitud permitida del vehículo en rutas.
     Límite de longitud
     Este dispositivo no tiene radares de velocidad.
     Patines en línea
-    Permite controlar el nivel de zoom del mapa con los botones de volumen del dispositivo.
+    Controla el nivel de zoom del mapa usando los botones de volumen del dispositivo.
     Botones de volumen como zoom
     Descargar datos de Wikipedia
     El punto de destino actual de la ruta será borrado. Si será el destino, la navegación se detendrá.
-    Borrar el siguiente punto de destino
+    Borrar el punto de destino más cercano
     Obtén información sobre los puntos de interés de Wikipedia. Es tu guía de bolsillo sin conexión - sólo activa el complemento de Wikipedia y disfruta los artículos sobre los objetos de alrededor.
     Proporciona un nombre para el punto
     Proporciona la longitud del vehículo, se pueden aplicar algunas restricciones de rutas para vehículos largos.
@@ -3801,7 +3802,7 @@
     Mostrar los iconos de inicio y fin
     Sólido
     Personalizado
-    Debes definir los días laborales para continuar
+    Definir los días laborales para continuar
     Elegir la anchura
     Ruta entre puntos
     Crear una ruta
@@ -3835,9 +3836,7 @@
     Intervalo de registro para la grabación general de trazas (activar mediante el widget de grabación de viaje sobre el mapa).
     Guardar como nueva traza
     Recalcular toda la traza usando el perfil elegido.
-    Para utilizar esta opción, OsmAnd debe ajustar su traza a los caminos del mapa.
-\n
-\n En el siguiente paso se debe elegir el perfil de navegación para detectar los caminos permitidos y el umbral de distancia para aproximar la traza a los caminos.
+    A continuación, ajusta la traza al camino permitido más cercano con un perfil de navegación.
     Recalcular sólo el siguiente segmento usando el perfil elegido.
     Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido.
     Elige un archivo de traza al que se añadirá un nuevo segmento.
@@ -3846,11 +3845,11 @@
     Segmento anterior
     Recortar antes
     Recortar después
-    Marca un archivo de traza para abrir.
+    Marcar un archivo de traza para abrir.
     Abrir traza existente
     Última edición
     Importar traza
-    ¿Cerrar el plan de ruta sin guardar\? Se perderán todos los cambios.
+    ¿Cerrar el plan de ruta sin guardar\?, se descartarán todos los cambios.
     Crear nueva ruta
     Cambiar el tipo de ruta anterior
     Cambiar el tipo de ruta posterior
@@ -3863,12 +3862,12 @@
     Punto más cercano
     Perfil de navegación
     Navegar desde mi ubicación a la traza
-    GRABAR
+    Grabar
     Guardar como archivo de traza
     Grabación del viaje
     Trazas
     En caso de dirección inversa
-    Elige el archivo de la traza a seguir o importa una.
+    Elige el archivo de la traza a seguir o impórtala desde el dispositivo.
     Pausar grabación del viaje
     Reanudar grabación del viaje
     Elige el archivo de la traza a seguir
@@ -3886,4 +3885,20 @@
     Añadir a un archivo de trazas
     Añadir dirección
     Ingresar dirección
+    Rehacer
+    • Se ha actualizado el modo «Planificar ruta»: ahora permite usar diferentes tipos de navegación para cada segmento y adjunta cualquier traza a los caminos
+\n
+\n • Nuevas opciones en el aspecto de las trazas: elegir el color, cambiar el grosor de las flechas de dirección y las marcas de inicio/fin.
+\n
+\n • Mejoras en la visibilidad de los nodos de bicicleta
+\n
+\n • Menú contextual con información básica para las trazas
+\n
+\n • Algoritmos de búsqueda mejorados
+\n
+\n • Mejoras en las opciones de seguimiento de la navegación
+\n
+\n • Se han solucionado los problemas de la importación y exportación en los ajustes de los perfiles
+\n
+\n
 
\ No newline at end of file

From 07f760a64f0227138778c76c1d78cad0c806e285 Mon Sep 17 00:00:00 2001
From: Franco 
Date: Sat, 12 Sep 2020 17:38:49 +0000
Subject: [PATCH 0088/1366] Translated using Weblate (Spanish (American))

Currently translated at 100.0% (3822 of 3822 strings)
---
 OsmAnd/res/values-es-rUS/phrases.xml | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-es-rUS/phrases.xml b/OsmAnd/res/values-es-rUS/phrases.xml
index b59c0ec06b..d12ccb5eef 100644
--- a/OsmAnd/res/values-es-rUS/phrases.xml
+++ b/OsmAnd/res/values-es-rUS/phrases.xml
@@ -333,7 +333,7 @@
     Doctor
     Clínica
     Primeros auxilios
-    Dentista;Odontólogo
+    Dentista;Odontología
     Asilo de ancianos;Geriátrico
     Escotilla de bebé
     Veterinaria
@@ -2309,7 +2309,7 @@
     Cirugía maxilofacial
     Radiología diagnóstica
     Gastroenterología
-    Odontología
+    Dentista;Odontología
     Nefrología (enfermedades renales)
     Neurocirugía
     Neuropsiquiatría
@@ -3822,7 +3822,7 @@
     Nivel del agua: por encima del nivel medio del agua
     Nivel del agua: por debajo del nivel medio del agua
     Obstrucción
-    Recarga de agua potable: sí
+    
     Recarga de agua potable: no
     Red de recarga de agua potable
     Succión
@@ -3841,4 +3841,12 @@
     Municipio
     Ascensor
     Flecha: no
+    Pequeños electrodomésticos
+    Recarga de agua potable
+    
+    A horario
+    En tiempo real
+    Tablero de partidas: no
+    Con retraso
+    Tablero de partidas
 
\ No newline at end of file

From 2ca2e5a554b85d404b63deb982b3a21df96dba8d Mon Sep 17 00:00:00 2001
From: Dima-1 
Date: Sun, 13 Sep 2020 13:54:31 +0300
Subject: [PATCH 0089/1366] Close #9746 Request: Replace saving dialog in Route
 Details > Save

---
 OsmAnd/src/net/osmand/FileUtils.java          | 22 ++++++++
 .../plus/activities/MapActivityActions.java   | 31 ++++++----
 .../MeasurementToolFragment.java              | 17 +-----
 ...veAsNewTrackBottomSheetDialogFragment.java | 56 ++++++++++++-------
 .../ChooseRouteFragment.java                  | 37 ++++++++++--
 5 files changed, 114 insertions(+), 49 deletions(-)

diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java
index 661bf81f75..222b706e3c 100644
--- a/OsmAnd/src/net/osmand/FileUtils.java
+++ b/OsmAnd/src/net/osmand/FileUtils.java
@@ -19,8 +19,14 @@ import net.osmand.util.Algorithms;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
 import java.util.regex.Pattern;
 
+import static net.osmand.IndexConstants.GPX_FILE_EXT;
+import static net.osmand.IndexConstants.GPX_INDEX_DIR;
+
 public class FileUtils {
 
 	public static final Pattern ILLEGAL_FILE_NAME_CHARACTERS = Pattern.compile("[?:\"*|/<>]");
@@ -165,6 +171,22 @@ public class FileUtils {
 		return dest;
 	}
 
+	public static String createName(OsmandApplication app) {
+		String displayedName;
+		final String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date());
+		displayedName = suggestedName;
+		if (app != null) {
+			File dir = app.getAppPath(GPX_INDEX_DIR);
+			File fout = new File(dir, suggestedName + GPX_FILE_EXT);
+			int ind = 0;
+			while (fout.exists()) {
+				displayedName = suggestedName + "_" + (++ind);
+				fout = new File(dir, displayedName + GPX_FILE_EXT);
+			}
+		}
+		return displayedName;
+	}
+
 	public interface RenameCallback {
 		void renamedTo(File file);
 	}
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index d1096c74c4..b9a05ed00f 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -293,7 +293,8 @@ public class MapActivityActions implements DialogProvider {
 					dlg.findViewById(R.id.DuplicateFileName).setVisibility(View.VISIBLE);
 				} else {
 					dlg.dismiss();
-					new SaveDirectionsAsyncTask(app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, toSave);
+					new SaveDirectionsAsyncTask(app, false)
+							.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, toSave);
 				}
 			}
 		});
@@ -309,31 +310,41 @@ public class MapActivityActions implements DialogProvider {
 		return dlg;
 	}
 
-	private static class SaveDirectionsAsyncTask extends AsyncTask {
+	public static class SaveDirectionsAsyncTask extends AsyncTask {
 
 		private final OsmandApplication app;
+		boolean showOnMap;
 
-		public SaveDirectionsAsyncTask(OsmandApplication app) {
+		public SaveDirectionsAsyncTask(OsmandApplication app, boolean showOnMap) {
 			this.app = app;
+			this.showOnMap = showOnMap;
 		}
 
 		@Override
-		protected String doInBackground(File... params) {
+		protected GPXFile doInBackground(File... params) {
 			if (params.length > 0) {
 				File file = params[0];
 				String fileName = file.getName();
-				GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName.substring(0,fileName.length()-GPX_FILE_EXT.length()));
-				GPXUtilities.writeGpxFile(file, gpx);
-				return app.getString(R.string.route_successfully_saved_at, file.getName());
+				GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName.substring(0, fileName.length() - GPX_FILE_EXT.length()));
+				gpx.error = GPXUtilities.writeGpxFile(file, gpx);
+				return gpx;
 			}
 			return null;
 		}
 
 		@Override
-		protected void onPostExecute(String result) {
-			if (result != null) {
-				Toast.makeText(app, result, Toast.LENGTH_LONG).show();
+		protected void onPostExecute(GPXFile gpxFile) {
+			if (gpxFile.error != null) {
+				String errorMessage = gpxFile.error.getMessage();
+				if (errorMessage == null) {
+					errorMessage = app.getString(R.string.error_occurred_saving_gpx);
+				}
+				Toast.makeText(app, errorMessage, Toast.LENGTH_LONG).show();
+				return;
 			}
+			app.getSelectedGpxHelper().selectGpxFile(gpxFile, showOnMap, false);
+			String result = app.getString(R.string.route_successfully_saved_at, gpxFile.tracks.get(0).name);
+			Toast.makeText(app, result, Toast.LENGTH_LONG).show();
 		}
 
 	}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 8007470ba6..3ca09c6154 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -34,6 +34,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import com.google.android.material.snackbar.Snackbar;
 
 import net.osmand.AndroidUtils;
+import net.osmand.FileUtils;
 import net.osmand.GPXUtilities;
 import net.osmand.GPXUtilities.GPXFile;
 import net.osmand.GPXUtilities.Track;
@@ -85,11 +86,8 @@ import net.osmand.util.Algorithms;
 import java.io.File;
 import java.lang.ref.WeakReference;
 import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
-import java.util.Locale;
 
 import static net.osmand.IndexConstants.GPX_FILE_EXT;
 import static net.osmand.IndexConstants.GPX_INDEX_DIR;
@@ -1487,18 +1485,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		GpxData gpxData = editingCtx.getGpxData();
 		String displayedName;
 		if (gpxData == null) {
-			final String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date());
-			displayedName = suggestedName;
-			OsmandApplication app = getMyApplication();
-			if (app != null) {
-				File dir = app.getAppPath(GPX_INDEX_DIR);
-				File fout = new File(dir, suggestedName + GPX_FILE_EXT);
-				int ind = 0;
-				while (fout.exists()) {
-					displayedName = suggestedName + "_" + (++ind);
-					fout = new File(dir, displayedName + GPX_FILE_EXT);
-				}
-			}
+			displayedName = FileUtils.createName(getMyApplication());
 		} else {
 			displayedName = AndroidUtils.trimExtension(new File(gpxData.getGpxFile().path).getName());
 		}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
index 0355bba809..fb1badf2aa 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
@@ -8,6 +8,7 @@ import android.os.Bundle;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.View;
+import android.widget.EditText;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
@@ -59,6 +60,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 	private String folderName;
 	private boolean rightButtonEnabled = true;
 	private boolean showSimplifiedButton = true;
+	private TextInputLayout nameTextBox;
 
 	@Override
 	public void createMenuItems(Bundle savedInstanceState) {
@@ -80,7 +82,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 
 		View editNameView = View.inflate(UiUtilities.getThemedContext(app, nightMode),
 				R.layout.track_name_edit_text, null);
-		final TextInputLayout nameTextBox = editNameView.findViewById(R.id.name_text_box);
+		nameTextBox = editNameView.findViewById(R.id.name_text_box);
 		nameTextBox.setBoxBackgroundColorResource(R.color.material_text_input_layout_bg);
 		nameTextBox.setHint(app.getString(R.string.ltr_or_rtl_combine_via_colon,
 				app.getString(R.string.shared_string_file_name), "").trim());
@@ -100,7 +102,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 
 			@Override
 			public void afterTextChanged(Editable s) {
-				checkEmptyName(s, nameTextBox);
+				checkEmptyName(s.toString());
 			}
 		});
 		BaseBottomSheetItem editFileName = new BaseBottomSheetItem.Builder()
@@ -206,6 +208,10 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 			@Override
 			public void onItemSelected(String item) {
 				folderName = item;
+				EditText editText = nameTextBox.getEditText();
+				if (editText != null) {
+					checkEmptyName(editText.getText().toString());
+				}
 			}
 		};
 	}
@@ -260,17 +266,8 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 	private void renameFile() {
 		OsmandApplication app = getMyApplication();
 		if (app != null) {
-			File dir = getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR);
-			File source = dir;
-			if (sourceFolderName != null) {
-				source = new File(dir, sourceFolderName);
-			}
-			source = new File(source, sourceFileName + IndexConstants.GPX_FILE_EXT);
-			File dest = dir;
-			if (folderName != null) {
-				dest = new File(dir, folderName);
-			}
-			dest = new File(dest, fileName + IndexConstants.GPX_FILE_EXT);
+			File source = getFile(app, sourceFolderName, sourceFileName);
+			File dest = getFile(app, folderName, fileName);
 			if (!source.equals(dest)) {
 				if (dest.exists()) {
 					Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show();
@@ -290,25 +287,46 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 		}
 	}
 
+	private File getFile(OsmandApplication app, String folderName, String fileName) {
+		File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
+		File source = dir;
+		if (folderName != null) {
+			source = new File(dir, folderName);
+		}
+		source = new File(source, fileName + IndexConstants.GPX_FILE_EXT);
+		return source;
+	}
+
 	@Override
 	protected boolean isRightBottomButtonEnabled() {
 		return rightButtonEnabled;
 	}
 
-	private void checkEmptyName(Editable name, TextInputLayout nameCaption) {
-		String text = name.toString().trim();
+	private void checkEmptyName(String name) {
+		rightButtonEnabled = false;
+		String text = name.trim();
 		if (text.isEmpty()) {
-			nameCaption.setError(getString(R.string.empty_filename));
-			rightButtonEnabled = false;
+			nameTextBox.setError(getString(R.string.empty_filename));
+		} else if (isFileExist(name)) {
+			nameTextBox.setError(getString(R.string.file_with_name_already_exist));
 		} else {
-			nameCaption.setError(null);
+			nameTextBox.setError(null);
 			fileName = text;
 			rightButtonEnabled = true;
 		}
 		updateBottomButtons();
 	}
 
-	interface SaveAsNewTrackFragmentListener {
+	private boolean isFileExist(String name) {
+		OsmandApplication app = getMyApplication();
+		if (app != null) {
+			File file = getFile(app, folderName, name);
+			return file.exists();
+		}
+		return false;
+	}
+
+	public interface SaveAsNewTrackFragmentListener {
 
 		void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack);
 
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
index c94c6e2968..b3e773c881 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
@@ -6,6 +6,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
 import android.text.Html;
@@ -33,7 +34,9 @@ import androidx.fragment.app.FragmentPagerAdapter;
 import androidx.viewpager.widget.ViewPager;
 
 import net.osmand.AndroidUtils;
+import net.osmand.FileUtils;
 import net.osmand.GPXUtilities;
+import net.osmand.IndexConstants;
 import net.osmand.data.LatLon;
 import net.osmand.data.PointDescription;
 import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
@@ -42,17 +45,18 @@ import net.osmand.plus.OsmAndFormatter;
 import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
 import net.osmand.plus.activities.MapActivity;
-import net.osmand.plus.activities.MapActivityActions;
 import net.osmand.plus.activities.PrintDialogActivity;
 import net.osmand.plus.base.BaseOsmAndFragment;
 import net.osmand.plus.base.ContextMenuFragment;
 import net.osmand.plus.base.ContextMenuFragment.ContextMenuFragmentListener;
 import net.osmand.plus.base.ContextMenuFragment.MenuState;
 import net.osmand.plus.helpers.AndroidUiHelper;
+import net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment;
 import net.osmand.plus.routepreparationmenu.RouteDetailsFragment.CumulativeInfo;
 import net.osmand.plus.routepreparationmenu.RouteDetailsFragment.RouteDetailsFragmentListener;
 import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard;
 import net.osmand.plus.routing.RouteDirectionInfo;
+import net.osmand.plus.routing.RouteProvider;
 import net.osmand.plus.routing.RoutingHelper;
 import net.osmand.plus.routing.TransportRoutingHelper;
 import net.osmand.plus.settings.backend.OsmandSettings;
@@ -73,12 +77,15 @@ import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 
+import static net.osmand.IndexConstants.GPX_FILE_EXT;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.BACK_TO_LOC_HUD_ID;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_IN_HUD_ID;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_OUT_HUD_ID;
+import static net.osmand.plus.activities.MapActivityActions.*;
+import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.*;
 
 public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMenuFragmentListener,
-		RouteDetailsFragmentListener {
+		RouteDetailsFragmentListener, SaveAsNewTrackFragmentListener {
 
 	public static final String TAG = "ChooseRouteFragment";
 	public static final String ROUTE_INDEX_KEY = "route_index_key";
@@ -460,9 +467,19 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe
 			@Override
 			public void onClick(View v) {
 				MapActivity mapActivity = getMapActivity();
-				if (mapActivity != null) {
-					RoutingHelper routingHelper = mapActivity.getMyApplication().getRoutingHelper();
-					MapActivityActions.createSaveDirections(mapActivity, routingHelper).show();
+				OsmandApplication app = getMyApplication();
+				if (mapActivity != null && app != null) {
+					RoutingHelper routingHelper = app.getRoutingHelper();
+					final RouteProvider.GPXRouteParamsBuilder rp = routingHelper.getCurrentGPXRoute();
+					final String fileName;
+					if (rp == null || rp.getFile() == null || rp.getFile().path == null) {
+						fileName = FileUtils.createName(app);
+					} else {
+						fileName = new File(rp.getFile().path).getName();
+					}
+					SaveAsNewTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
+							ChooseRouteFragment.this, null, fileName,
+							false, true);
 				}
 			}
 		};
@@ -861,6 +878,16 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe
 		}
 	}
 
+	@Override
+	public void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack) {
+		OsmandApplication app = getMyApplication();
+		if (app != null) {
+			File fileDir = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), folderName == null ? "" : folderName);
+			File toSave = new File(fileDir, fileName + GPX_FILE_EXT);
+			new SaveDirectionsAsyncTask(app, showOnMap).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, toSave);
+		}
+	}
+
 	public class RoutesPagerAdapter extends FragmentPagerAdapter {
 		private int routesCount;
 

From e955652a6b31129792e90f548b718d4f693f739b Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Mon, 14 Sep 2020 15:02:14 +0300
Subject: [PATCH 0090/1366] Clean up MapActivity from back fragments

---
 .../osmand/plus/activities/MapActivity.java   | 80 +------------------
 .../plus/mapmarkers/PlanRouteFragment.java    | 16 +++-
 .../GpxApproximationFragment.java             | 11 +++
 .../MeasurementToolFragment.java              | 11 +++
 .../SnapTrackWarningFragment.java             | 17 +++-
 .../ChooseRouteFragment.java                  | 11 +++
 .../fragments/ConfigureMenuItemsFragment.java | 22 +++--
 .../fragments/ImportCompleteFragment.java     |  7 ++
 .../fragments/ImportSettingsFragment.java     |  7 ++
 .../fragments/ProfileAppearanceFragment.java  | 11 ++-
 10 files changed, 102 insertions(+), 91 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index efe26164d2..cb83865ced 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -116,7 +116,6 @@ import net.osmand.plus.mapcontextmenu.editors.PointEditorFragmentNew;
 import net.osmand.plus.mapcontextmenu.editors.WptPtEditor;
 import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
 import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
-import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
 import net.osmand.plus.mapmarkers.PlanRouteFragment;
 import net.osmand.plus.measurementtool.GpxApproximationFragment;
 import net.osmand.plus.measurementtool.GpxData;
@@ -141,12 +140,8 @@ import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomiz
 import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.settings.fragments.BaseSettingsFragment;
 import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
-import net.osmand.plus.settings.fragments.ConfigureMenuItemsFragment;
 import net.osmand.plus.settings.fragments.ConfigureProfileFragment;
 import net.osmand.plus.settings.fragments.DataStorageFragment;
-import net.osmand.plus.settings.fragments.ImportCompleteFragment;
-import net.osmand.plus.settings.fragments.ImportSettingsFragment;
-import net.osmand.plus.settings.fragments.ProfileAppearanceFragment;
 import net.osmand.plus.track.TrackAppearanceFragment;
 import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
 import net.osmand.plus.views.AnimateDraggingMapThread;
@@ -684,42 +679,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 				return;
 			}
 		}
-		PlanRouteFragment planRouteFragment = getPlanRouteFragment();
-		if (planRouteFragment != null) {
-			if (planRouteFragment.quit(true)) {
-				MapMarkersDialogFragment.showInstance(this);
-			}
-			return;
-		}
-
-		SnapTrackWarningFragment snapTrackWarningFragment = getSnapTrackWarningBottomSheet();
-		if (snapTrackWarningFragment != null) {
-			snapTrackWarningFragment.dismissImmediate();
-			return;
-		}
-
-		GpxApproximationFragment gpxApproximationFragment = getGpxApproximationFragment();
-		if (gpxApproximationFragment != null) {
-			gpxApproximationFragment.dismissImmediate();
-			return;
-		}
-
-		MeasurementToolFragment measurementToolFragment = getMeasurementToolFragment();
-		if (measurementToolFragment != null) {
-			measurementToolFragment.quit(true);
-			return;
-		}
-		ChooseRouteFragment chooseRouteFragment = getChooseRouteFragment();
-		if (chooseRouteFragment != null) {
-			chooseRouteFragment.dismiss(true);
-			return;
-		}
-		ProfileAppearanceFragment profileAppearanceFragment = getProfileAppearanceFragment();
-		if (profileAppearanceFragment != null) {
-			if (profileAppearanceFragment.isProfileAppearanceChanged()) {
-				return;
-			}
-		}
 
 		PointEditorFragmentNew pointEditorFragmentNew = getPointEditorFragmentNew();
 		if (pointEditorFragmentNew != null) {
@@ -769,26 +728,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 		} else if (getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed()) {
 			return;
 		}
-		ImportSettingsFragment importSettingsFragment = getImportSettingsFragment();
-		if (importSettingsFragment != null) {
-			importSettingsFragment.showExitDialog();
-			return;
-		}
-		ImportCompleteFragment importCompleteFragment = getImportCompleteFragment();
-		if (importCompleteFragment != null) {
-			importCompleteFragment.dismissFragment();
-			return;
-		}
-		ConfigureMenuItemsFragment configureMenuItemsFragment = getConfigureMenuItemsFragment();
-		if (configureMenuItemsFragment != null) {
-			configureMenuItemsFragment.exitFragment();
-			return;
-		}
-
 		super.onBackPressed();
 	}
 
-
 	private void quitAddGpxPointMode() {
 		getMapLayers().getContextMenuLayer().getAddGpxPointBottomSheetHelper().hide();
 		getMapLayers().getContextMenuLayer().quitAddGpxPoint();
@@ -930,7 +872,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 						DataStoragePlaceDialogFragment.showInstance(getSupportFragmentManager(), true);
 					} else {
 						ActivityCompat.requestPermissions(this,
-								new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+								new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
 								DownloadActivity.PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
 					}
 				}
@@ -2301,24 +2243,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 		return getFragment(ChooseRouteFragment.TAG);
 	}
 
-	public ProfileAppearanceFragment getProfileAppearanceFragment() {
-		return getFragment(ProfileAppearanceFragment.TAG);
-	}
-
 	public QuickActionListFragment getQuickActionListFragment() {
-		return  getFragment(QuickActionListFragment.TAG);
-	}
-
-	public ImportSettingsFragment getImportSettingsFragment() {
-		return getFragment(ImportSettingsFragment.TAG);
-	}
-
-	public ImportCompleteFragment getImportCompleteFragment() {
-		return getFragment(ImportCompleteFragment.TAG);
-	}
-
-	public ConfigureMenuItemsFragment getConfigureMenuItemsFragment() {
-		return getFragment(ConfigureMenuItemsFragment.TAG);
+		return getFragment(QuickActionListFragment.TAG);
 	}
 
 	public TrackAppearanceFragment getTrackAppearanceFragment() {
@@ -2353,7 +2279,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 		}
 	}
 
-	 T getFragment(String fragmentTag){
+	 T getFragment(String fragmentTag) {
 		Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
 		return fragment != null && !fragment.isDetached() && !fragment.isRemoving() ? (T) fragment : null;
 	}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/PlanRouteFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/PlanRouteFragment.java
index 89a1016ea0..60399c3872 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/PlanRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/PlanRouteFragment.java
@@ -17,6 +17,7 @@ import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -57,8 +58,8 @@ import net.osmand.plus.measurementtool.SnapToRoadBottomSheetDialogFragment.SnapT
 import net.osmand.plus.routing.RoutingHelper;
 import net.osmand.plus.settings.backend.ApplicationMode;
 import net.osmand.plus.settings.backend.OsmandSettings;
-import net.osmand.plus.views.layers.MapMarkersLayer;
 import net.osmand.plus.views.OsmandMapTileView;
+import net.osmand.plus.views.layers.MapMarkersLayer;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
 import net.osmand.util.MapUtils;
@@ -96,6 +97,19 @@ public class PlanRouteFragment extends BaseOsmAndFragment implements OsmAndLocat
 	private View mainView;
 	private RecyclerView markersRv;
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				MapActivity mapActivity = getMapActivity();
+				if (mapActivity != null && quit(true)) {
+					MapMarkersDialogFragment.showInstance(mapActivity);
+				}
+			}
+		});
+	}
+
 	@Nullable
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java
index 68029eb36a..393e43b31b 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java
@@ -9,6 +9,7 @@ import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
@@ -97,6 +98,16 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
 		return MenuState.HALF_SCREEN;
 	}
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				dismissImmediate();
+			}
+		});
+	}
+
 	@Nullable
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index c176275725..e51890c75e 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -20,6 +20,7 @@ import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -170,6 +171,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		this.directionMode = directionMode;
 	}
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				quit(true);
+			}
+		});
+	}
+
 	@Nullable
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java
index 6730e4d923..49e1fa3d65 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java
@@ -9,7 +9,9 @@ import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
@@ -30,11 +32,12 @@ import net.osmand.plus.views.layers.MapInfoLayer;
 import org.apache.commons.logging.Log;
 
 import static android.view.Gravity.TOP;
-import static android.view.ViewGroup.LayoutParams.*;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.BACK_TO_LOC_HUD_ID;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_IN_HUD_ID;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_OUT_HUD_ID;
-import static net.osmand.plus.UiUtilities.DialogButtonType.*;
+import static net.osmand.plus.UiUtilities.DialogButtonType.PRIMARY;
+import static net.osmand.plus.UiUtilities.DialogButtonType.SECONDARY;
 
 public class SnapTrackWarningFragment extends BaseOsmAndFragment {
 
@@ -56,6 +59,16 @@ public class SnapTrackWarningFragment extends BaseOsmAndFragment {
 	private boolean nightMode;
 	private boolean portrait;
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				dismissImmediate();
+			}
+		});
+	}
+
 	public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 		OsmandApplication app = getMyApplication();
 		if (app != null) {
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
index c94c6e2968..6143db9fb2 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
@@ -21,6 +21,7 @@ import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -111,6 +112,16 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe
 	private boolean publicTransportMode;
 	private boolean needAdjustMap;
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				dismiss(true);
+			}
+		});
+	}
+
 	@Nullable
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java
index d9980e0640..44fb4bf7f6 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java
@@ -1,6 +1,5 @@
 package net.osmand.plus.settings.fragments;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Build;
@@ -11,6 +10,7 @@ import android.view.ViewGroup;
 import android.widget.ImageButton;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
@@ -24,11 +24,9 @@ import com.google.android.material.appbar.AppBarLayout;
 
 import net.osmand.AndroidUtils;
 import net.osmand.PlatformUtil;
-import net.osmand.plus.settings.backend.ApplicationMode;
 import net.osmand.plus.ContextMenuAdapter;
 import net.osmand.plus.ContextMenuItem;
 import net.osmand.plus.OsmandApplication;
-import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
@@ -36,11 +34,13 @@ import net.osmand.plus.base.BaseOsmAndFragment;
 import net.osmand.plus.dialogs.ConfigureMapMenu;
 import net.osmand.plus.mapcontextmenu.MapContextMenu;
 import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet;
-import net.osmand.plus.settings.fragments.ConfigureMenuRootFragment.ScreenType;
+import net.osmand.plus.settings.backend.ApplicationMode;
+import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.settings.bottomsheets.ChangeGeneralProfilesPrefBottomSheet;
-import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
-import net.osmand.plus.settings.fragments.RearrangeMenuItemsAdapter.RearrangeMenuAdapterItem;
+import net.osmand.plus.settings.fragments.ConfigureMenuRootFragment.ScreenType;
 import net.osmand.plus.settings.fragments.RearrangeMenuItemsAdapter.MenuItemsAdapterListener;
+import net.osmand.plus.settings.fragments.RearrangeMenuItemsAdapter.RearrangeMenuAdapterItem;
+import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
 
 import org.apache.commons.logging.Log;
 
@@ -83,7 +83,7 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment
 	private boolean nightMode;
 	private boolean wasReset = false;
 	private boolean isChanged = false;
-	private Activity activity;
+	private FragmentActivity activity;
 	private RecyclerView recyclerView;
 
 	@Override
@@ -149,7 +149,13 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment
 		nightMode = !app.getSettings().isLightContentForMode(appMode);
 		mInflater = UiUtilities.getInflater(app, nightMode);
 		mainActionItems = new ArrayList<>();
-		activity = getActivity();
+		activity = requireActivity();
+		activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			@Override
+			public void handleOnBackPressed() {
+				exitFragment();
+			}
+		});
 	}
 
 	private void initSavedIds(ApplicationMode appMode) {
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java
index a521e8e079..a18e2f6aa9 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java
@@ -12,6 +12,7 @@ import android.view.ViewTreeObserver;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentManager;
@@ -62,6 +63,12 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
 		super.onCreate(savedInstanceState);
 		app = requireMyApplication();
 		nightMode = !app.getSettings().isLightContent();
+		requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			@Override
+			public void handleOnBackPressed() {
+				dismissFragment();
+			}
+		});
 	}
 
 	@Nullable
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java
index 13dc2f94ce..284964b88d 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java
@@ -16,6 +16,7 @@ import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
@@ -106,6 +107,12 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
 		app = requireMyApplication();
 		settingsHelper = app.getSettingsHelper();
 		nightMode = !app.getSettings().isLightContent();
+		requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			@Override
+			public void handleOnBackPressed() {
+				showExitDialog();
+			}
+		});
 	}
 
 	@Nullable
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java
index 9ea296e925..6fcf8a17bf 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java
@@ -23,6 +23,7 @@ import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
@@ -151,6 +152,11 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment {
 			changedProfile.navigationIcon = profile.navigationIcon;
 			isNewProfile = ApplicationMode.valueOfStringKey(changedProfile.stringKey, null) == null;
 		}
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				showExitDialog();
+			}
+		});
 	}
 
 	public void setupAppProfileObjectFromAppMode(ApplicationMode baseModeForNewProfile) {
@@ -893,7 +899,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment {
 		profileNameOtfb.setError(errorMessage, true);
 	}
 
-	public boolean isProfileAppearanceChanged() {
+	public void showExitDialog() {
 		hideKeyboard();
 		if (isChanged()) {
 			AlertDialog.Builder dismissDialog = createWarningDialog(getActivity(),
@@ -906,9 +912,8 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment {
 				}
 			});
 			dismissDialog.show();
-			return true;
 		} else {
-			return false;
+			dismiss();
 		}
 	}
 

From 0a48fc586e39970972d20729082aefb479e09811 Mon Sep 17 00:00:00 2001
From: Nazar-Kutz 
Date: Mon, 14 Sep 2020 17:42:29 +0300
Subject: [PATCH 0091/1366] Ui fixes third part

---
 OsmAnd/src/net/osmand/AndroidUtils.java       | 23 ++++++++++
 .../osmand/plus/base/ContextMenuFragment.java | 38 ++++++++++++++--
 .../plus/base/OnNeedScrollUiAdapter.java      |  5 +++
 .../plus/base/OnVisibilityChangeListener.java |  5 +++
 .../plus/track/TrackAppearanceFragment.java   | 43 +++++++++++++++++--
 .../net/osmand/plus/track/TrackWidthCard.java | 31 +++++++++++--
 6 files changed, 135 insertions(+), 10 deletions(-)
 create mode 100644 OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java
 create mode 100644 OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java

diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java
index 3dea16fb15..87ade44343 100644
--- a/OsmAnd/src/net/osmand/AndroidUtils.java
+++ b/OsmAnd/src/net/osmand/AndroidUtils.java
@@ -63,6 +63,7 @@ import androidx.core.view.ViewCompat;
 
 import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
+import net.osmand.plus.base.OnVisibilityChangeListener;
 import net.osmand.util.Algorithms;
 
 import java.io.File;
@@ -602,6 +603,12 @@ public class AndroidUtils {
 		return coordinates;
 	}
 
+	public static boolean isPointInsideView(@NonNull View view, float x, float y) {
+		boolean matchVertical = y >= view.getY() && y <= view.getY() + view.getHeight();
+		boolean mathHorizontal = x >= view.getX() && x <= view.getX() + view.getWidth();
+		return matchVertical && mathHorizontal;
+	}
+
 	public static void enterToFullScreen(Activity activity, View view) {
 		if (Build.VERSION.SDK_INT >= 21) {
 			requestLayout(view);
@@ -889,4 +896,20 @@ public class AndroidUtils {
 		}
 		return builder;
 	}
+
+	public static void addVisibilityChangeListener(final @NonNull View parent,
+	                                               final @NonNull View v,
+	                                               final @NonNull OnVisibilityChangeListener listener) {
+		parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+			int visibility = v.getVisibility();
+
+			@Override
+			public void onGlobalLayout() {
+				if (visibility != v.getVisibility()) {
+					visibility = v.getVisibility();
+					listener.onVisibilityChange(visibility);
+				}
+			}
+		});
+	}
 }
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
index 57928eac50..32c746d323 100644
--- a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
@@ -24,6 +24,7 @@ import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.OverScroller;
+import android.widget.ScrollView;
 import android.widget.Toast;
 
 import androidx.annotation.IdRes;
@@ -49,7 +50,7 @@ import net.osmand.plus.views.controls.HorizontalSwipeConfirm;
 
 import static net.osmand.plus.mapcontextmenu.MapContextMenuFragment.CURRENT_Y_UNDEFINED;
 
-public abstract class ContextMenuFragment extends BaseOsmAndFragment {
+public abstract class ContextMenuFragment extends BaseOsmAndFragment implements OnNeedScrollUiAdapter {
 
 	public static class MenuState {
 		public static final int HEADER_ONLY = 1;
@@ -67,7 +68,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 	private OnLayoutChangeListener containerLayoutListener;
 	private View topShadow;
 	private ViewGroup topView;
-	private View bottomScrollView;
+	private ScrollView bottomScrollView;
 	private LinearLayout cardsContainer;
 	private FrameLayout bottomContainer;
 
@@ -247,7 +248,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 		return bottomContainer;
 	}
 
-	public View getBottomScrollView() {
+	public ScrollView getBottomScrollView() {
 		return bottomScrollView;
 	}
 
@@ -318,6 +319,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 		final GestureDetector swipeDetector = new GestureDetector(app, new HorizontalSwipeConfirm(true));
 
 		final OnTouchListener slideTouchListener = new OnTouchListener() {
+			private static final int SHORT_CLICK_DURATION_TOP_LIMIT = 500;
+
 			private float dy;
 			private float dyMain;
 			private float mDownY;
@@ -329,6 +332,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 
 			private boolean slidingUp;
 			private boolean slidingDown;
+			private boolean isHolding;
+
+			private long downMotionEventTimeMs;
 
 			{
 				OsmandApplication app = requireMyApplication();
@@ -352,6 +358,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 
 				switch (event.getAction()) {
 					case MotionEvent.ACTION_DOWN:
+						if (!isHolding) {
+							isHolding = true;
+							downMotionEventTimeMs = event.getDownTime();
+						}
 						mDownY = event.getRawY();
 						dy = event.getY();
 						dyMain = getViewY();
@@ -388,6 +398,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 						break;
 
 					case MotionEvent.ACTION_UP:
+						isHolding = false;
 						if (moving) {
 							moving = false;
 							int currentY = getViewY();
@@ -412,6 +423,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 							}
 
 							changeMenuState(currentY, slidingUp, slidingDown, true);
+						} else if (isShortClick(event.getEventTime())) {
+							onShortClick(v, event);
 						}
 						recycleVelocityTracker();
 						break;
@@ -445,6 +458,11 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 					velocityTracker = null;
 				}
 			}
+
+			private boolean isShortClick(long upActionTime) {
+				long holdingDuration = upActionTime - downMotionEventTimeMs;
+				return holdingDuration <= SHORT_CLICK_DURATION_TOP_LIMIT;
+			}
 		};
 
 		if (mainView instanceof InterceptorLinearLayout) {
@@ -467,6 +485,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 		return view;
 	}
 
+	protected void onShortClick(View v, MotionEvent event) { }
+
 	public float getToolbarAlpha(int y) {
 		float a = 0;
 		if (portrait) {
@@ -1047,4 +1067,16 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 			return false;
 		}
 	}
+
+	@Override
+	public void onNeedVerticalScroll(String tag, int y) { }
+
+	public void verticalScrollToYPosition(final int y) {
+		bottomScrollView.post(new Runnable() {
+			@Override
+			public void run() {
+				bottomScrollView.smoothScrollTo(0, y);
+			}
+		});
+	}
 }
diff --git a/OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java b/OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java
new file mode 100644
index 0000000000..4363139e1f
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java
@@ -0,0 +1,5 @@
+package net.osmand.plus.base;
+
+public interface OnNeedScrollUiAdapter {
+	void onNeedVerticalScroll(String tag, int yPosition);
+}
diff --git a/OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java b/OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java
new file mode 100644
index 0000000000..58a2da55de
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java
@@ -0,0 +1,5 @@
+package net.osmand.plus.base;
+
+public interface OnVisibilityChangeListener {
+	void onVisibilityChange(int visibility);
+}
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
index 4c6b80e539..53cbb17515 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
@@ -7,6 +7,7 @@ import android.os.Build;
 import android.os.Bundle;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
@@ -80,6 +81,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 
 	private ImageView trackIcon;
 	private View buttonsShadow;
+	private View routeMenuTopShadowAll;
+	private View controlButtons;
 
 	@Override
 	public int getMainLayoutId() {
@@ -179,6 +182,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 		if (view != null) {
 			trackIcon = view.findViewById(R.id.track_icon);
 			buttonsShadow = view.findViewById(R.id.buttons_shadow);
+			controlButtons = view.findViewById(R.id.control_buttons);
+			routeMenuTopShadowAll = view.findViewById(R.id.route_menu_top_shadow_all);
 
 			if (isPortrait()) {
 				updateCardsLayout();
@@ -191,7 +196,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 				int widthNoShadow = getLandscapeNoShadowWidth();
 				FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
 				params.gravity = Gravity.BOTTOM | Gravity.START;
-				view.findViewById(R.id.control_buttons).setLayoutParams(params);
+				controlButtons.setLayoutParams(params);
 			}
 			enterTrackAppearanceMode();
 			runLayoutListener();
@@ -201,8 +206,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 
 	@Override
 	protected void calculateLayout(View view, boolean initLayout) {
-		menuTitleHeight = view.findViewById(R.id.route_menu_top_shadow_all).getHeight()
-				+ view.findViewById(R.id.control_buttons).getHeight() - buttonsShadow.getHeight();
+		menuTitleHeight = routeMenuTopShadowAll.getHeight()
+				+ controlButtons.getHeight() - buttonsShadow.getHeight();
 		super.calculateLayout(view, initLayout);
 	}
 
@@ -353,6 +358,14 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 		trackIcon.setImageDrawable(icon);
 	}
 
+	@Override
+	protected void onShortClick(View v, MotionEvent event) {
+		if (routeMenuTopShadowAll != null &&
+				AndroidUtils.isPointInsideView(routeMenuTopShadowAll, event.getX(), event.getY())) {
+			adjustMapPosition(getViewY());
+		}
+	}
+
 	private void adjustMapPosition(int y) {
 		MapActivity mapActivity = getMapActivity();
 		if (mapActivity != null && mapActivity.getMapView() != null) {
@@ -583,7 +596,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 			trackColoringCard.setListener(this);
 			cardsContainer.addView(trackColoringCard.build(mapActivity));
 
-			trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo);
+			trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, this);
 			trackWidthCard.setListener(this);
 			cardsContainer.addView(trackWidthCard.build(mapActivity));
 		}
@@ -626,6 +639,28 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 		}
 	}
 
+	@Override
+	public void onNeedVerticalScroll(@NonNull String tag, int y) {
+		if (tag.equals(TrackWidthCard.TAG)) {
+			View trackWidthCardView = trackWidthCard.getView();
+			if (trackWidthCardView == null) return;
+
+			int currentScrollYPosition = getBottomScrollView().getScrollY();
+			int dialogHeight = getInnerScrollableHeight();
+			int resultYPosition = trackWidthCardView.getTop() + y;
+			if (resultYPosition > (currentScrollYPosition + dialogHeight)) {
+				verticalScrollToYPosition(resultYPosition - dialogHeight);
+			}
+		}
+	}
+
+	public int getInnerScrollableHeight() {
+		int totalScreenHeight = getViewHeight() - getMenuStatePosY(getCurrentMenuState());
+		int frameTotalHeight = routeMenuTopShadowAll.getHeight()
+				+ controlButtons.getHeight() + buttonsShadow.getHeight();
+		return totalScreenHeight - frameTotalHeight;
+	}
+
 	public static boolean showInstance(@NonNull MapActivity mapActivity, TrackAppearanceFragment fragment) {
 		try {
 			mapActivity.getSupportFragmentManager()
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java b/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java
index 81208971bb..faf616b010 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java
@@ -19,6 +19,8 @@ import net.osmand.AndroidUtils;
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.base.OnNeedScrollUiAdapter;
+import net.osmand.plus.base.OnVisibilityChangeListener;
 import net.osmand.plus.dialogs.GpxAppearanceAdapter;
 import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem;
 import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType;
@@ -29,21 +31,26 @@ import net.osmand.util.Algorithms;
 import java.util.List;
 
 public class TrackWidthCard extends BaseCard {
+	public final static String TAG = TrackWidthCard.class.getName();
 
 	private final static String CUSTOM_WIDTH = "custom_width";
 	private final static int CUSTOM_WIDTH_MIN = 1;
 	private final static int CUSTOM_WIDTH_MAX = 24;
 
 	private TrackDrawInfo trackDrawInfo;
+	private OnNeedScrollUiAdapter onNeedScrollUiAdapter;
 
 	private AppearanceListItem selectedItem;
 	private List appearanceItems;
 
 	private GpxWidthAdapter widthAdapter;
+	private View sliderContainer;
 
-	public TrackWidthCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo) {
+	public TrackWidthCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo,
+	                      OnNeedScrollUiAdapter onNeedScrollUiAdapter) {
 		super(mapActivity);
 		this.trackDrawInfo = trackDrawInfo;
+		this.onNeedScrollUiAdapter = onNeedScrollUiAdapter;
 		appearanceItems = getWidthAppearanceItems();
 	}
 
@@ -110,6 +117,7 @@ public class TrackWidthCard extends BaseCard {
 	}
 
 	private void updateCustomWidthSlider() {
+		sliderContainer = view.findViewById(R.id.slider_container);
 		if (CUSTOM_WIDTH.equals(getSelectedItem().getAttrName())) {
 			Slider widthSlider = view.findViewById(R.id.width_slider);
 
@@ -143,9 +151,19 @@ public class TrackWidthCard extends BaseCard {
 				}
 			});
 			UiUtilities.setupSlider(widthSlider, nightMode, null);
-			AndroidUiHelper.updateVisibility(view.findViewById(R.id.slider_container), true);
+			AndroidUtils.addVisibilityChangeListener(view, sliderContainer,
+					new OnVisibilityChangeListener() {
+						@Override
+						public void onVisibilityChange(int visibility) {
+							if (visibility == View.VISIBLE) {
+								onNeedScrollUiAdapter.onNeedVerticalScroll(TAG, sliderContainer.getBottom());
+							}
+						}
+					}
+			);
+			AndroidUiHelper.updateVisibility(sliderContainer, true);
 		} else {
-			AndroidUiHelper.updateVisibility(view.findViewById(R.id.slider_container), false);
+			AndroidUiHelper.updateVisibility(sliderContainer, false);
 		}
 	}
 
@@ -203,6 +221,13 @@ public class TrackWidthCard extends BaseCard {
 					if (listener != null) {
 						listener.onCardPressed(TrackWidthCard.this);
 					}
+
+					if (CUSTOM_WIDTH.equals(selectedItem.getAttrName())
+							&& sliderContainer != null
+							&& onNeedScrollUiAdapter != null
+							&& sliderContainer.getVisibility() == View.VISIBLE) {
+						onNeedScrollUiAdapter.onNeedVerticalScroll(TAG, sliderContainer.getBottom());
+					}
 				}
 			});
 		}

From c2e110604d233b552bd48bf911a90d1f76a4102e Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Mon, 14 Sep 2020 21:46:11 +0300
Subject: [PATCH 0092/1366] Clean up onBackPressed in MapActivity from
 fragments

---
 .../osmand/plus/activities/MapActivity.java   | 82 +++----------------
 .../plus/activities/MapActivityActions.java   |  1 +
 .../MapContextMenuFragment.java               | 36 ++++----
 .../editors/PointEditorFragmentNew.java       | 37 ++++++++-
 .../other/TrackDetailsMenuFragment.java       | 25 +++++-
 .../quickaction/QuickActionListFragment.java  | 24 +++++-
 .../plus/track/TrackAppearanceFragment.java   | 10 +++
 7 files changed, 123 insertions(+), 92 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index cb83865ced..45b4e8c105 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -86,7 +86,6 @@ import net.osmand.plus.base.FailSafeFuntions;
 import net.osmand.plus.base.MapViewTrackingUtilities;
 import net.osmand.plus.chooseplan.OsmLiveCancelledDialog;
 import net.osmand.plus.dashboard.DashboardOnMap;
-import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
 import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment;
 import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment;
 import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment;
@@ -109,11 +108,7 @@ import net.osmand.plus.helpers.ScrollHelper.OnScrollEventListener;
 import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
 import net.osmand.plus.mapcontextmenu.MapContextMenu;
 import net.osmand.plus.mapcontextmenu.MenuController;
-import net.osmand.plus.mapcontextmenu.MenuController.MenuState;
 import net.osmand.plus.mapcontextmenu.builders.cards.dialogs.ContextMenuCardDialogFragment;
-import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor;
-import net.osmand.plus.mapcontextmenu.editors.PointEditorFragmentNew;
-import net.osmand.plus.mapcontextmenu.editors.WptPtEditor;
 import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
 import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
 import net.osmand.plus.mapmarkers.PlanRouteFragment;
@@ -122,7 +117,6 @@ import net.osmand.plus.measurementtool.GpxData;
 import net.osmand.plus.measurementtool.MeasurementEditingContext;
 import net.osmand.plus.measurementtool.MeasurementToolFragment;
 import net.osmand.plus.measurementtool.SnapTrackWarningFragment;
-import net.osmand.plus.quickaction.QuickActionListFragment;
 import net.osmand.plus.render.RendererRegistry;
 import net.osmand.plus.resources.ResourceManager;
 import net.osmand.plus.routepreparationmenu.ChooseRouteFragment;
@@ -153,7 +147,6 @@ import net.osmand.plus.views.OsmandMapTileView.OnDrawMapListener;
 import net.osmand.plus.views.corenative.NativeCoreContext;
 import net.osmand.plus.views.layers.MapControlsLayer;
 import net.osmand.plus.views.layers.MapInfoLayer;
-import net.osmand.plus.views.layers.MapQuickActionLayer;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
 import net.osmand.render.RenderingRulesStorage;
@@ -668,44 +661,16 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 			showQuickSearch(ShowQuickSearchMode.CURRENT, false);
 			return;
 		}
-		if (trackDetailsMenu.isVisible()) {
-			trackDetailsMenu.hide(true);
-			if (mapContextMenu.isActive() && mapContextMenu.getPointDescription() != null
-					&& mapContextMenu.getPointDescription().isGpxPoint()) {
-				mapContextMenu.show();
-				return;
-			}
-			if (prevActivityIntent == null) {
-				return;
-			}
-		}
-
-		PointEditorFragmentNew pointEditorFragmentNew = getPointEditorFragmentNew();
-		if (pointEditorFragmentNew != null) {
-			pointEditorFragmentNew.showExitDialog();
-			return;
-		}
-
-		TrackAppearanceFragment trackAppearanceFragment = getTrackAppearanceFragment();
-		if (trackAppearanceFragment != null) {
-			trackAppearanceFragment.dismissImmediate();
-			if (prevActivityIntent == null) {
-				return;
-			}
-		}
-
-
-		if (mapContextMenu.isVisible() && mapContextMenu.isClosable()) {
-			if (mapContextMenu.getCurrentMenuState() != MenuState.HEADER_ONLY && !isLandscapeLayout()) {
-				mapContextMenu.openMenuHeaderOnly();
-			} else {
-				mapContextMenu.close();
-			}
-			return;
-		}
 		if (getMapLayers().getContextMenuLayer().isInAddGpxPointMode()) {
 			quitAddGpxPointMode();
 		}
+		if (launchPrevActivityIntent()) {
+			return;
+		}
+		super.onBackPressed();
+	}
+
+	public boolean launchPrevActivityIntent() {
 		if (prevActivityIntent != null && getSupportFragmentManager().getBackStackEntryCount() == 0) {
 			prevActivityIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
 			LatLon loc = getMapLocation();
@@ -714,21 +679,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 			if (mapViewTrackingUtilities.isMapLinkedToLocation()) {
 				prevActivityIntent.putExtra(SearchActivity.SEARCH_NEARBY, true);
 			}
-			this.startActivity(prevActivityIntent);
+			startActivity(prevActivityIntent);
 			prevActivityIntent = null;
-			return;
+			return true;
 		}
-		QuickActionListFragment quickActionListFragment = getQuickActionListFragment();
-		if (quickActionListFragment != null && quickActionListFragment.isVisible()) {
-			if (quickActionListFragment.fromDashboard()) {
-				this.getDashboard().setDashboardVisibility(true, DashboardType.CONFIGURE_SCREEN, null);
-			} else {
-				getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed();
-			}
-		} else if (getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed()) {
-			return;
-		}
-		super.onBackPressed();
+		return false;
 	}
 
 	private void quitAddGpxPointMode() {
@@ -2243,14 +2198,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 		return getFragment(ChooseRouteFragment.TAG);
 	}
 
-	public QuickActionListFragment getQuickActionListFragment() {
-		return getFragment(QuickActionListFragment.TAG);
-	}
-
-	public TrackAppearanceFragment getTrackAppearanceFragment() {
-		return getFragment(TrackAppearanceFragment.TAG);
-	}
-
 	public GpxApproximationFragment getGpxApproximationFragment() {
 		return getFragment(GpxApproximationFragment.TAG);
 	}
@@ -2259,15 +2206,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 		return getFragment(SnapTrackWarningFragment.TAG);
 	}
 
-	public PointEditorFragmentNew getPointEditorFragmentNew() {
-		PointEditorFragmentNew pointEditorFragmentNew;
-		pointEditorFragmentNew = getFragment(FavoritePointEditor.TAG);
-		if (pointEditorFragmentNew == null) {
-			pointEditorFragmentNew = getFragment(WptPtEditor.TAG);
-		}
-		return pointEditorFragmentNew;
-	}
-
 	public void backToConfigureProfileFragment() {
 		FragmentManager fragmentManager = getSupportFragmentManager();
 		int backStackEntryCount = fragmentManager.getBackStackEntryCount();
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index ab05b2e2f3..bdc1e5d737 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -476,6 +476,7 @@ public class MapActivityActions implements DialogProvider {
 				} else if (standardId == R.string.avoid_road) {
 					getMyApplication().getAvoidSpecificRoads().addImpassableRoad(mapActivity, new LatLon(latitude, longitude), true, false, null);
 				} else if (standardId == R.string.shared_string_add || standardId == R.string.favourites_context_menu_edit) {
+					mapActivity.getContextMenu().hide();
 					mapActivity.getContextMenu().buttonFavoritePressed();
 				} else if (standardId == R.string.shared_string_marker || standardId == R.string.shared_string_edit) {
 					mapActivity.getContextMenu().buttonWaypointPressed();
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java
index 44748e36bb..7a53629f4d 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java
@@ -37,6 +37,7 @@ import android.widget.OverScroller;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.content.res.AppCompatResources;
@@ -108,11 +109,8 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 	private InterceptorLinearLayout mainView;
 
 	private View toolbarContainer;
-	private View toolbarView;
-	private ImageView toolbarBackButton;
 	private TextView toolbarTextView;
 	private View topButtonContainer;
-	private LockableScrollView menuScrollView;
 
 	private LinearLayout mainRouteBadgeContainer;
 	private LinearLayout nearbyRoutesLayout;
@@ -123,8 +121,6 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 	private TextView localRoutesMoreTv;
 
 	private View zoomButtonsView;
-	private ImageButton zoomInButtonView;
-	private ImageButton zoomOutButtonView;
 
 	private MapContextMenu menu;
 	private OnLayoutChangeListener containerLayoutListener;
@@ -149,7 +145,6 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 	private int topScreenPosY;
 	private int bottomToolbarPosY;
 	private int minHalfY;
-	private int shadowHeight;
 	private int zoomPaddingTop;
 
 	private OsmandMapTileView map;
@@ -164,13 +159,28 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 	private boolean wasDrawerDisabled;
 	private boolean zoomIn;
 
-	private int screenOrientation;
 	private boolean created;
 
 	private boolean transportBadgesCreated;
 
 	private UpdateLocationViewCache updateLocationViewCache;
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				if (menu.isVisible() && menu.isClosable()) {
+					if (menu.getCurrentMenuState() != MenuState.HEADER_ONLY && !menu.isLandscapeLayout()) {
+						menu.openMenuHeaderOnly();
+					} else {
+						menu.close();
+					}
+				}
+			}
+		});
+	}
+
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 	                         Bundle savedInstanceState) {
@@ -188,7 +198,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 
 		markerPaddingPx = dpToPx(MARKER_PADDING_DP);
 		markerPaddingXPx = dpToPx(MARKER_PADDING_X_DP);
-		shadowHeight = dpToPx(SHADOW_HEIGHT_TOP_DP);
+		int shadowHeight = dpToPx(SHADOW_HEIGHT_TOP_DP);
 		topScreenPosY = addStatusBarHeightIfNeeded(-shadowHeight);
 		bottomToolbarPosY = addStatusBarHeightIfNeeded(getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar));
 		minHalfY = viewHeight - (int) (viewHeight * menu.getHalfScreenMaxHeightKoef());
@@ -204,8 +214,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 		mainView = view.findViewById(R.id.context_menu_main);
 
 		toolbarContainer = view.findViewById(R.id.context_menu_toolbar_container);
-		toolbarView = view.findViewById(R.id.context_menu_toolbar);
-		toolbarBackButton = view.findViewById(R.id.context_menu_toolbar_back);
+		ImageView toolbarBackButton = view.findViewById(R.id.context_menu_toolbar_back);
 		toolbarTextView = (TextView) view.findViewById(R.id.context_menu_toolbar_text);
 		updateVisibility(toolbarContainer, 0);
 		toolbarBackButton.setOnClickListener(new View.OnClickListener() {
@@ -510,9 +519,9 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 
 		// Zoom buttons
 		zoomButtonsView = view.findViewById(R.id.context_menu_zoom_buttons);
-		zoomInButtonView = (ImageButton) view.findViewById(R.id.context_menu_zoom_in_button);
-		zoomOutButtonView = (ImageButton) view.findViewById(R.id.context_menu_zoom_out_button);
 		if (menu.zoomButtonsVisible()) {
+			ImageButton zoomInButtonView = view.findViewById(R.id.context_menu_zoom_in_button);
+			ImageButton zoomOutButtonView = view.findViewById(R.id.context_menu_zoom_out_button);
 			AndroidUtils.updateImageButton(app, zoomInButtonView, R.drawable.ic_zoom_in, R.drawable.ic_zoom_in,
 					R.drawable.btn_circle_trans, R.drawable.btn_circle_night, nightMode);
 			AndroidUtils.updateImageButton(app, zoomOutButtonView, R.drawable.ic_zoom_out, R.drawable.ic_zoom_out,
@@ -2302,5 +2311,4 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 		updateAdditionalInfoVisibility();
 		runLayoutListener();
 	}
-}
-
+}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
index ae5bb9355b..cd7a783a7b 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
@@ -25,6 +25,7 @@ import android.widget.ImageView;
 import android.widget.ScrollView;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.ColorInt;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
@@ -49,6 +50,7 @@ import net.osmand.plus.activities.MapActivity;
 import net.osmand.plus.base.BaseOsmAndFragment;
 import net.osmand.plus.helpers.AndroidUiHelper;
 import net.osmand.plus.helpers.ColorDialogs;
+import net.osmand.plus.mapcontextmenu.MapContextMenu;
 import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
 import net.osmand.plus.widgets.FlowLayout;
 import net.osmand.util.Algorithms;
@@ -99,6 +101,19 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 	private EditText addressEdit;
 	private int layoutHeightPrevious = 0;
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				MapActivity mapActivity = getMapActivity();
+				if (mapActivity != null) {
+					showExitDialog();
+				}
+			}
+		});
+	}
+
 	@SuppressLint("ClickableViewAccessibility")
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
@@ -867,14 +882,28 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 			dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
 				@Override
 				public void onClick(DialogInterface dialog, int which) {
-					cancelled = true;
-					dismiss();
+					exitEditing();
 				}
 			});
 			dismissDialog.show();
 		} else {
-			cancelled = true;
-			dismiss();
+			exitEditing();
+		}
+	}
+
+	private void exitEditing() {
+		cancelled = true;
+		dismiss();
+		showContextMenu();
+	}
+
+	private void showContextMenu() {
+		MapActivity mapActivity = getMapActivity();
+		if (mapActivity != null) {
+			MapContextMenu mapContextMenu = mapActivity.getContextMenu();
+			if (!mapContextMenu.isVisible() && mapContextMenu.isActive()) {
+				mapContextMenu.show();
+			}
 		}
 	}
 
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenuFragment.java
index f456ba0360..2a06fe71a7 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenuFragment.java
@@ -12,6 +12,7 @@ import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
@@ -49,11 +50,33 @@ public class TrackDetailsMenuFragment extends BaseOsmAndFragment implements OsmA
 		return (MapActivity) requireMyActivity();
 	}
 
+	@Override
+	public void onCreate(@Nullable Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		final MapActivity mapActivity = requireMapActivity();
+		menu = mapActivity.getTrackDetailsMenu();
+
+		mapActivity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				if (menu.isVisible()) {
+					menu.hide(true);
+
+					MapContextMenu contextMenu = mapActivity.getContextMenu();
+					if (contextMenu.isActive() && contextMenu.getPointDescription() != null
+							&& contextMenu.getPointDescription().isGpxPoint()) {
+						contextMenu.show();
+					} else {
+						mapActivity.launchPrevActivityIntent();
+					}
+				}
+			}
+		});
+	}
+
 	@Override
 	public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 							 Bundle savedInstanceState) {
 		MapActivity mapActivity = requireMapActivity();
-		menu = mapActivity.getTrackDetailsMenu();
 		nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
 		View view = UiUtilities.getInflater(mapActivity, nightMode).inflate(R.layout.track_details, container, false);
 		if (!AndroidUiHelper.isOrientationPortrait(mapActivity)) {
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java
index 036b60230f..ef7f8970b1 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java
@@ -18,6 +18,7 @@ import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.widget.SwitchCompat;
@@ -38,11 +39,12 @@ import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
 import net.osmand.plus.base.BaseOsmAndFragment;
+import net.osmand.plus.dashboard.DashboardOnMap;
 import net.osmand.plus.settings.backend.ApplicationMode;
-import net.osmand.plus.views.layers.MapQuickActionLayer;
 import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
 import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback.OnItemMoveCallback;
 import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback.UnmovableItem;
+import net.osmand.plus.views.layers.MapQuickActionLayer;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -100,6 +102,26 @@ public class QuickActionListFragment extends BaseOsmAndFragment
             }
             screenType = savedInstanceState.getInt(SCREEN_TYPE_KEY, SCREEN_TYPE_REORDER);
         }
+        requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+            public void handleOnBackPressed() {
+                MapActivity mapActivity = getMapActivity();
+                if (mapActivity != null) {
+                    if (isVisible()) {
+                        if (fromDashboard()) {
+                            mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.CONFIGURE_SCREEN, null);
+                        } else {
+                            mapActivity.getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed();
+                        }
+                    } else if (mapActivity.getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed()) {
+                        return;
+                    }
+                    FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
+                    if (!fragmentManager.isStateSaved()) {
+                        fragmentManager.popBackStackImmediate();
+                    }
+                }
+            }
+        });
     }
 
     @Nullable
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
index c0fe05d060..5061323bc5 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
@@ -14,6 +14,7 @@ import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -147,6 +148,15 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 			}
 			updateTrackColor();
 		}
+		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				MapActivity mapActivity = getMapActivity();
+				if (mapActivity != null) {
+					dismissImmediate();
+					mapActivity.launchPrevActivityIntent();
+				}
+			}
+		});
 	}
 
 	private void updateTrackColor() {

From 14b94b7051dbc5bbd2207528d8426ec473abcc88 Mon Sep 17 00:00:00 2001
From: Hardy 
Date: Mon, 14 Sep 2020 21:26:11 +0200
Subject: [PATCH 0093/1366] some string improvements

---
 OsmAnd/res/values/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 7f95db8cd1..5df1c73d6e 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -12,10 +12,10 @@
 
 -->
     
-    • Updated "Plan Route" mode allows using different navigation types for each segment and attaches any track to the roads\n\n
-    • New "Appearance" options for tracks: select color, thickness turn on the direction arrows and start/finish marks\n\n
-    • Improved bicycle nodes visibility\n\n
-    • Context menu for tracks with basic info\n\n
+    • Updated "Plan a route" function: allows using different navigation types per segment and the inclusion of tracks\n\n
+    • New "Appearance" menu for tracks: select color, thickness, and direction arrows. Tracks now indicate start/finish icons.\n\n
+    • Improved visibility of bicycle nodes\n\n
+    • Tracks are now tappable, have context menu with basic info\n\n
     • Improved "Search" algorithms\n\n
     • Improved "Follow track" options in Navigation\n\n
     • Fixed issues with import/export of profile settings\n\n
@@ -78,8 +78,8 @@
     Next, snap your track to the nearest allowed road with one of your navigation profiles to use this option.
     Next segment
     Whole track
-    Select how to connect points, with a straight line, or calculate a route between them with selected profile.
-    Only the next segment will be recalculated using selected profile.
+    Select how to connect points, by a straight line, or calculate a route between them as specified below.
+    Only the next segment will be recalculated using the selected profile.
     The whole track will be recalculated using the selected profile.
     Reverse route
     Save as new track

From d1dbc4a4a44c4b71fabefdb26d7c051cd172c6a1 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Mon, 14 Sep 2020 22:30:25 +0300
Subject: [PATCH 0094/1366] Remove search from onBackPressed

---
 .../osmand/plus/activities/MapActivity.java   |  6 +----
 .../MapContextMenuFragment.java               | 22 +++++++++++--------
 .../search/QuickSearchDialogFragment.java     | 15 ++++++++++++-
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index 45b4e8c105..7b152c5ec5 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -657,14 +657,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 			closeDrawer();
 			return;
 		}
-		if (getQuickSearchDialogFragment() != null) {
-			showQuickSearch(ShowQuickSearchMode.CURRENT, false);
-			return;
-		}
 		if (getMapLayers().getContextMenuLayer().isInAddGpxPointMode()) {
 			quitAddGpxPointMode();
 		}
-		if (launchPrevActivityIntent()) {
+		if (!getOnBackPressedDispatcher().hasEnabledCallbacks() && launchPrevActivityIntent()) {
 			return;
 		}
 		super.onBackPressed();
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java
index 7a53629f4d..5f88a13607 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java
@@ -168,17 +168,21 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
 	@Override
 	public void onCreate(@Nullable Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
-			public void handleOnBackPressed() {
-				if (menu.isVisible() && menu.isClosable()) {
-					if (menu.getCurrentMenuState() != MenuState.HEADER_ONLY && !menu.isLandscapeLayout()) {
-						menu.openMenuHeaderOnly();
-					} else {
-						menu.close();
+		MapActivity mapActivity = getMapActivity();
+		if (mapActivity != null) {
+			boolean enabled = mapActivity.getQuickSearchDialogFragment() == null;
+			mapActivity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(enabled) {
+				public void handleOnBackPressed() {
+					if (menu.isVisible() && menu.isClosable()) {
+						if (menu.getCurrentMenuState() != MenuState.HEADER_ONLY && !menu.isLandscapeLayout()) {
+							menu.openMenuHeaderOnly();
+						} else {
+							menu.close();
+						}
 					}
 				}
-			}
-		});
+			});
+		}
 	}
 
 	@Override
diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java
index 0e34a4ca35..3c55261668 100644
--- a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java
@@ -34,6 +34,7 @@ import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
@@ -41,6 +42,7 @@ import androidx.appcompat.widget.Toolbar;
 import androidx.core.content.ContextCompat;
 import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentPagerAdapter;
 import androidx.fragment.app.FragmentTransaction;
@@ -232,13 +234,24 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
+		FragmentActivity activity = requireActivity();
 		app = getMyApplication();
 		nightMode = !app.getSettings().isLightContent();
 		navigationInfo = new NavigationInfo(app);
-		accessibilityAssistant = new AccessibilityAssistant(getActivity());
+		accessibilityAssistant = new AccessibilityAssistant(activity);
+
 		boolean isLightTheme = app.getSettings().isLightContent();
 		int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
 		setStyle(STYLE_NO_FRAME, themeId);
+
+		activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+			public void handleOnBackPressed() {
+				MapActivity mapActivity = getMapActivity();
+				if (mapActivity != null) {
+					mapActivity.showQuickSearch(ShowQuickSearchMode.CURRENT, false);
+				}
+			}
+		});
 	}
 
 	@Override

From 7d72f0fb92fbfeb340d6a06e6d30ffe4627b1015 Mon Sep 17 00:00:00 2001
From: Hardy 
Date: Mon, 14 Sep 2020 22:30:14 +0200
Subject: [PATCH 0095/1366] Update strings.xml

---
 OsmAnd/res/values/strings.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 5df1c73d6e..7e80b4c02d 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -13,9 +13,9 @@
 -->
     
     • Updated "Plan a route" function: allows using different navigation types per segment and the inclusion of tracks\n\n
-    • New "Appearance" menu for tracks: select color, thickness, and direction arrows. Tracks now indicate start/finish icons.\n\n
-    • Improved visibility of bicycle nodes\n\n
-    • Tracks are now tappable, have context menu with basic info\n\n
+    • New "Appearance" menu for tracks: select color, thickness, display direction arrows, start/finish icons\n\n
+    • Improved visibility of bicycle nodes.\n\n
+    • Tracks are now tappable, have context menu with basic info.\n\n
     • Improved "Search" algorithms\n\n
     • Improved "Follow track" options in Navigation\n\n
     • Fixed issues with import/export of profile settings\n\n

From fae5d95dbd6b5cc96133179ab886eaada5757cdf Mon Sep 17 00:00:00 2001
From: Hardy 
Date: Mon, 14 Sep 2020 22:38:31 +0200
Subject: [PATCH 0096/1366] Update strings.xml

---
 OsmAnd/res/values/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 7e80b4c02d..3f8159283b 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -51,7 +51,7 @@
     Nearest point
     Start of the track
     Point of the track to navigate
-    Navigate from my location to the track
+    Navigate from my position to the track
     Select another track
     Choose track file to follow or import it from your device.
     Choose track file to follow

From 454ab23eed444d1b7dd099109fba18332a6ed59e Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 15 Sep 2020 01:57:21 +0300
Subject: [PATCH 0097/1366] Refactor createUniqueFileName

---
 .../main/java/net/osmand/util/Algorithms.java |  2 +-
 OsmAnd/src/net/osmand/FileUtils.java          | 29 +++++++------------
 .../src/net/osmand/plus/MapMarkersHelper.java | 12 ++++----
 .../plus/activities/MapActivityActions.java   | 18 +++++-------
 .../CoordinateInputDialogFragment.java        | 14 ++++-----
 .../SaveAsTrackBottomSheetDialogFragment.java | 22 +++++---------
 .../MeasurementToolFragment.java              |  6 +++-
 .../ChooseRouteFragment.java                  | 25 ++++++++--------
 8 files changed, 56 insertions(+), 72 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java
index 21e7fbd58c..ea2869aaa3 100644
--- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java
+++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java
@@ -119,7 +119,7 @@ public class Algorithms {
 	}
 
 	public static String getFileNameWithoutExtension(String name) {
-		int i = name.indexOf('.');
+		int i = name.lastIndexOf('.');
 		if (i >= 0) {
 			name = name.substring(0, i);
 		}
diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java
index 222b706e3c..59fb36c88d 100644
--- a/OsmAnd/src/net/osmand/FileUtils.java
+++ b/OsmAnd/src/net/osmand/FileUtils.java
@@ -8,6 +8,7 @@ import android.view.View;
 import android.widget.EditText;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 
 import net.osmand.plus.GpxSelectionHelper;
@@ -19,14 +20,8 @@ import net.osmand.util.Algorithms;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
 import java.util.regex.Pattern;
 
-import static net.osmand.IndexConstants.GPX_FILE_EXT;
-import static net.osmand.IndexConstants.GPX_INDEX_DIR;
-
 public class FileUtils {
 
 	public static final Pattern ILLEGAL_FILE_NAME_CHARACTERS = Pattern.compile("[?:\"*|/<>]");
@@ -171,20 +166,16 @@ public class FileUtils {
 		return dest;
 	}
 
-	public static String createName(OsmandApplication app) {
-		String displayedName;
-		final String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date());
-		displayedName = suggestedName;
-		if (app != null) {
-			File dir = app.getAppPath(GPX_INDEX_DIR);
-			File fout = new File(dir, suggestedName + GPX_FILE_EXT);
-			int ind = 0;
-			while (fout.exists()) {
-				displayedName = suggestedName + "_" + (++ind);
-				fout = new File(dir, displayedName + GPX_FILE_EXT);
-			}
+	public static String createUniqueFileName(@NonNull OsmandApplication app, String name, String dirName, String extension) {
+		String uniqueFileName = name;
+		File dir = app.getAppPath(dirName);
+		File fout = new File(dir, name + extension);
+		int ind = 0;
+		while (fout.exists()) {
+			uniqueFileName = name + "_" + (++ind);
+			fout = new File(dir, uniqueFileName + extension);
 		}
-		return displayedName;
+		return uniqueFileName;
 	}
 
 	public interface RenameCallback {
diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java
index 322c19e8e4..636fcddb72 100644
--- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java
+++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java
@@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
 import androidx.core.content.ContextCompat;
 
 import net.osmand.AndroidUtils;
+import net.osmand.FileUtils;
 import net.osmand.GPXUtilities;
 import net.osmand.GPXUtilities.GPXFile;
 import net.osmand.GPXUtilities.WptPt;
@@ -1005,15 +1006,14 @@ public class MapMarkersHelper {
 	}
 
 	public String generateGpx(String fileName) {
-		final File dir = ctx.getAppPath(IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR);
+		String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR;
+		File dir = ctx.getAppPath(dirName);
 		if (!dir.exists()) {
 			dir.mkdirs();
 		}
-		File fout = new File(dir, fileName + IndexConstants.GPX_FILE_EXT);
-		int ind = 1;
-		while (fout.exists()) {
-			fout = new File(dir, fileName + "_" + (++ind) + IndexConstants.GPX_FILE_EXT);
-		}
+		String uniqueFileName = FileUtils.createUniqueFileName(ctx, fileName, dirName, IndexConstants.GPX_FILE_EXT);
+		File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT);
+
 		GPXFile file = new GPXFile(Version.getFullVersion(ctx));
 		for (MapMarker marker : mapMarkers) {
 			WptPt wpt = new WptPt();
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 9ba64ab50e..19d273c9ca 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -294,8 +294,7 @@ public class MapActivityActions implements DialogProvider {
 					dlg.findViewById(R.id.DuplicateFileName).setVisibility(View.VISIBLE);
 				} else {
 					dlg.dismiss();
-					new SaveDirectionsAsyncTask(app, false)
-							.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, toSave);
+					new SaveDirectionsAsyncTask(app, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, toSave);
 				}
 			}
 		});
@@ -325,8 +324,8 @@ public class MapActivityActions implements DialogProvider {
 		protected GPXFile doInBackground(File... params) {
 			if (params.length > 0) {
 				File file = params[0];
-				String fileName = file.getName();
-				GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName.substring(0, fileName.length() - GPX_FILE_EXT.length()));
+				String fileName = Algorithms.getFileNameWithoutExtension(file);
+				GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName);
 				gpx.error = GPXUtilities.writeGpxFile(file, gpx);
 				return gpx;
 			}
@@ -335,19 +334,18 @@ public class MapActivityActions implements DialogProvider {
 
 		@Override
 		protected void onPostExecute(GPXFile gpxFile) {
-			if (gpxFile.error != null) {
+			if (gpxFile.error == null) {
+				app.getSelectedGpxHelper().selectGpxFile(gpxFile, showOnMap, false);
+				String result = app.getString(R.string.route_successfully_saved_at, gpxFile.tracks.get(0).name);
+				Toast.makeText(app, result, Toast.LENGTH_LONG).show();
+			} else {
 				String errorMessage = gpxFile.error.getMessage();
 				if (errorMessage == null) {
 					errorMessage = app.getString(R.string.error_occurred_saving_gpx);
 				}
 				Toast.makeText(app, errorMessage, Toast.LENGTH_LONG).show();
-				return;
 			}
-			app.getSelectedGpxHelper().selectGpxFile(gpxFile, showOnMap, false);
-			String result = app.getString(R.string.route_successfully_saved_at, gpxFile.tracks.get(0).name);
-			Toast.makeText(app, result, Toast.LENGTH_LONG).show();
 		}
-
 	}
 
 	public void addActionsToAdapter(final double latitude,
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java
index 8c36930451..a68bd4c714 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java
@@ -43,7 +43,6 @@ import androidx.annotation.DrawableRes;
 import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatDelegate;
 import androidx.appcompat.content.res.AppCompatResources;
 import androidx.appcompat.widget.PopupMenu;
 import androidx.core.content.ContextCompat;
@@ -57,6 +56,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import com.google.android.material.snackbar.Snackbar;
 
 import net.osmand.AndroidUtils;
+import net.osmand.FileUtils;
 import net.osmand.GPXUtilities;
 import net.osmand.GPXUtilities.GPXFile;
 import net.osmand.GPXUtilities.WptPt;
@@ -67,7 +67,6 @@ import net.osmand.plus.MapMarkersHelper;
 import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
 import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
 import net.osmand.plus.OsmandApplication;
-import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.Version;
@@ -79,6 +78,7 @@ import net.osmand.plus.mapmarkers.CoordinateInputFormats.DDM;
 import net.osmand.plus.mapmarkers.CoordinateInputFormats.DMS;
 import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
 import net.osmand.plus.mapmarkers.adapters.CoordinateInputAdapter;
+import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.widgets.EditTextEx;
 import net.osmand.util.Algorithms;
 import net.osmand.util.LocationParser;
@@ -1498,15 +1498,13 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm
 		protected Void doInBackground(Void... params) {
 			if (Algorithms.isEmpty(gpx.path)) {
 				if (!Algorithms.isEmpty(fileName)) {
-					final File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR);
+					String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR;
+					File dir = app.getAppPath(dirName);
 					if (!dir.exists()) {
 						dir.mkdirs();
 					}
-					File fout = new File(dir, fileName + IndexConstants.GPX_FILE_EXT);
-					int ind = 1;
-					while (fout.exists()) {
-						fout = new File(dir, fileName + "_" + (++ind) + IndexConstants.GPX_FILE_EXT);
-					}
+					String uniqueFileName = FileUtils.createUniqueFileName(app, fileName, dirName, IndexConstants.GPX_FILE_EXT);
+					File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT);
 					GPXUtilities.writeGpxFile(fout, gpx);
 				}
 			} else {
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/SaveAsTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/SaveAsTrackBottomSheetDialogFragment.java
index f176437ebd..a2a72d3f64 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/SaveAsTrackBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/SaveAsTrackBottomSheetDialogFragment.java
@@ -21,6 +21,7 @@ import androidx.core.content.ContextCompat;
 import com.google.android.material.textfield.TextInputLayout;
 
 import net.osmand.AndroidUtils;
+import net.osmand.FileUtils;
 import net.osmand.IndexConstants;
 import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
@@ -28,7 +29,6 @@ import net.osmand.plus.base.BottomSheetDialogFragment;
 import net.osmand.plus.helpers.AndroidUiHelper;
 import net.osmand.plus.widgets.OsmandTextFieldBoxes;
 
-import java.io.File;
 import java.util.Date;
 
 import static net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.ADDED_POINTS_NUMBER_KEY;
@@ -85,21 +85,13 @@ public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragm
 			}
 		}
 
-		final File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR + "/map markers");
-		if (!dir.exists()) {
-			dir.mkdirs();
-		}
 		Date date = new Date();
-		final String suggestedName = app.getString(R.string.markers) + "_" + DateFormat.format("yyyy-MM-dd", date).toString();
-		String displayedName = suggestedName;
-		File fout = new File(dir, suggestedName + IndexConstants.GPX_FILE_EXT);
-		int ind = 1;
-		while (fout.exists()) {
-			displayedName = suggestedName + "_" + (++ind);
-			fout = new File(dir, displayedName + IndexConstants.GPX_FILE_EXT);
-		}
-		final EditText nameEditText = (EditText) mainView.findViewById(R.id.name_edit_text);
-		nameEditText.setText(displayedName);
+		String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR;
+		String suggestedName = app.getString(R.string.markers) + "_" + DateFormat.format("yyyy-MM-dd", date).toString();
+		String uniqueFileName = FileUtils.createUniqueFileName(app, suggestedName, dirName, IndexConstants.GPX_FILE_EXT);
+
+		final EditText nameEditText = mainView.findViewById(R.id.name_edit_text);
+		nameEditText.setText(uniqueFileName);
 		nameEditText.setTextColor(ContextCompat.getColor(getContext(), textPrimaryColor));
 
 		mainView.findViewById(R.id.save_button).setOnClickListener(new View.OnClickListener() {
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 5e2f1befdf..3c87f6a7f3 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -86,8 +86,11 @@ import net.osmand.util.Algorithms;
 import java.io.File;
 import java.lang.ref.WeakReference;
 import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Locale;
 
 import static net.osmand.IndexConstants.GPX_FILE_EXT;
 import static net.osmand.IndexConstants.GPX_INDEX_DIR;
@@ -1443,7 +1446,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		GpxData gpxData = editingCtx.getGpxData();
 		String displayedName;
 		if (gpxData == null) {
-			displayedName = FileUtils.createName(getMyApplication());
+			String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date());
+			displayedName = FileUtils.createUniqueFileName(requireMyApplication(), suggestedName, GPX_INDEX_DIR, GPX_FILE_EXT);
 		} else {
 			displayedName = AndroidUtils.trimExtension(new File(gpxData.getGpxFile().path).getName());
 		}
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
index b3e773c881..3f690c1d81 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
@@ -56,12 +56,12 @@ import net.osmand.plus.routepreparationmenu.RouteDetailsFragment.CumulativeInfo;
 import net.osmand.plus.routepreparationmenu.RouteDetailsFragment.RouteDetailsFragmentListener;
 import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard;
 import net.osmand.plus.routing.RouteDirectionInfo;
-import net.osmand.plus.routing.RouteProvider;
+import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
 import net.osmand.plus.routing.RoutingHelper;
 import net.osmand.plus.routing.TransportRoutingHelper;
 import net.osmand.plus.settings.backend.OsmandSettings;
-import net.osmand.plus.views.layers.MapControlsLayer;
 import net.osmand.plus.views.OsmandMapTileView;
+import net.osmand.plus.views.layers.MapControlsLayer;
 import net.osmand.router.TransportRouteResult;
 import net.osmand.util.Algorithms;
 
@@ -81,8 +81,8 @@ import static net.osmand.IndexConstants.GPX_FILE_EXT;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.BACK_TO_LOC_HUD_ID;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_IN_HUD_ID;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.ZOOM_OUT_HUD_ID;
-import static net.osmand.plus.activities.MapActivityActions.*;
-import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.*;
+import static net.osmand.plus.activities.MapActivityActions.SaveDirectionsAsyncTask;
+import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener;
 
 public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMenuFragmentListener,
 		RouteDetailsFragmentListener, SaveAsNewTrackFragmentListener {
@@ -467,15 +467,16 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe
 			@Override
 			public void onClick(View v) {
 				MapActivity mapActivity = getMapActivity();
-				OsmandApplication app = getMyApplication();
-				if (mapActivity != null && app != null) {
-					RoutingHelper routingHelper = app.getRoutingHelper();
-					final RouteProvider.GPXRouteParamsBuilder rp = routingHelper.getCurrentGPXRoute();
-					final String fileName;
-					if (rp == null || rp.getFile() == null || rp.getFile().path == null) {
-						fileName = FileUtils.createName(app);
+				if (mapActivity != null) {
+					OsmandApplication app = mapActivity.getMyApplication();
+					GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
+
+					String fileName;
+					if (paramsBuilder == null || paramsBuilder.getFile() == null || paramsBuilder.getFile().path == null) {
+						String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date());
+						fileName = FileUtils.createUniqueFileName(app, suggestedName, IndexConstants.GPX_INDEX_DIR, GPX_FILE_EXT);
 					} else {
-						fileName = new File(rp.getFile().path).getName();
+						fileName = new File(paramsBuilder.getFile().path).getName();
 					}
 					SaveAsNewTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
 							ChooseRouteFragment.this, null, fileName,

From af0c40bb41fd5892c2d599242eaadf24803c9cf3 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 15 Sep 2020 02:02:16 +0300
Subject: [PATCH 0098/1366] Remove unnecessary check

---
 OsmAnd/src/net/osmand/plus/activities/MapActivity.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index 7b152c5ec5..e23e596dcf 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -660,14 +660,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
 		if (getMapLayers().getContextMenuLayer().isInAddGpxPointMode()) {
 			quitAddGpxPointMode();
 		}
-		if (!getOnBackPressedDispatcher().hasEnabledCallbacks() && launchPrevActivityIntent()) {
+		if (getSupportFragmentManager().getBackStackEntryCount() == 0 && launchPrevActivityIntent()) {
 			return;
 		}
 		super.onBackPressed();
 	}
 
 	public boolean launchPrevActivityIntent() {
-		if (prevActivityIntent != null && getSupportFragmentManager().getBackStackEntryCount() == 0) {
+		if (prevActivityIntent != null) {
 			prevActivityIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
 			LatLon loc = getMapLocation();
 			prevActivityIntent.putExtra(SearchActivity.SEARCH_LAT, loc.getLatitude());

From 083929512d53bc354585b29737035e75b7e56edd Mon Sep 17 00:00:00 2001
From: Nazar-Kutz 
Date: Tue, 15 Sep 2020 11:11:34 +0300
Subject: [PATCH 0099/1366] Change text field style for decrease height

---
 OsmAnd/res/layout/custom_color_picker.xml |  3 +--
 OsmAnd/res/values/styles.xml              | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/layout/custom_color_picker.xml b/OsmAnd/res/layout/custom_color_picker.xml
index db6c3a254c..9e6c1bb9b1 100644
--- a/OsmAnd/res/layout/custom_color_picker.xml
+++ b/OsmAnd/res/layout/custom_color_picker.xml
@@ -34,12 +34,11 @@
 
 		
 
 			?android:textColorSecondary
     
 
+
+    
+
+    
+
+    
+
 

From a7d77dc5f28acbc79fecf7f1cfb40ac1a63ec4d9 Mon Sep 17 00:00:00 2001
From: xmd5a 
Date: Tue, 15 Sep 2020 12:07:43 +0300
Subject: [PATCH 0100/1366] Add phrase

---
 OsmAnd/res/values/phrases.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml
index fe274284d9..cd482756ec 100644
--- a/OsmAnd/res/values/phrases.xml
+++ b/OsmAnd/res/values/phrases.xml
@@ -4253,4 +4253,6 @@
 	Realtime
 	Timetable
 
+	Beehive
+
 

From 0bccf22beb30a58217909d3f04bb7a0f8d0053bb Mon Sep 17 00:00:00 2001
From: josep constanti 
Date: Mon, 14 Sep 2020 17:52:16 +0000
Subject: [PATCH 0101/1366] Translated using Weblate (Catalan)

Currently translated at 96.0% (3345 of 3484 strings)
---
 OsmAnd/res/values-ca/strings.xml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml
index b6944c01bf..4ae94a57c7 100644
--- a/OsmAnd/res/values-ca/strings.xml
+++ b/OsmAnd/res/values-ca/strings.xml
@@ -3812,4 +3812,7 @@ Abasta l\'àrea: %1$s x %2$s
     REC
     Aturarà l\'enregistrament de traces quan es mati l\'aplicació (mitjançant aplicacions recents). (La indicació de fons OsmAnd desapareix de la barra de notificacions d\'Android.)
     Trieu l\'interval d\'enregistrament general dels desplaçaments (s\'activa mitjançant el giny de gravació del mapa).
+    Traça simplificada
+    Només es desarà la línia del trajecte, les fites s\'esborraran.
+    %s arxius de traces seleccionats
 
\ No newline at end of file

From 5b946a08800685ee0943f772f3b2e85b2c35bda9 Mon Sep 17 00:00:00 2001
From: Hinagiku Zeppeki 
Date: Sun, 13 Sep 2020 09:00:03 +0000
Subject: [PATCH 0102/1366] Translated using Weblate (Japanese)

Currently translated at 97.9% (3414 of 3484 strings)
---
 OsmAnd/res/values-ja/strings.xml | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml
index 4e8391bc49..843dada170 100644
--- a/OsmAnd/res/values-ja/strings.xml
+++ b/OsmAnd/res/values-ja/strings.xml
@@ -3863,4 +3863,31 @@ POIの更新は利用できません
     次年度以降 %1$s
     初%2$s度 %1$s
     初%2$s度 %1$s
+    ルート記録を一時停止
+    ルート記録を続行
+    システムのデフォルト
+    以後のすべてのセグメントは、選択したプロファイルを使用して再計算されます。
+    以後のすべてのセグメント
+    前のセグメント
+    以前のすべてのセグメント
+    選択したセグメントのみ、選択したプロファイルを使用して再計算されます。
+    以前のセグメントは、選択したプロファイルを使用して再計算されます。
+    保存した経路を開く
+    少なくとも2つの地点を追加してください。
+    繰り返し
+    • アップデートで追加されたルート計画モードは、セグメントごとに異なるナビゲーションタイプを使用でき、おおまかな指定を実際の道路に沿って反映可能に。
+\n
+\n• 経路の新しい外観オプション : 色、厚さを選択し、方向矢印のオン、マークの開始/終了など
+\n
+\n• 自転車ノードの可視性の向上
+\n
+\n• 基本情報を含む経路のコンテキストメニュー追加
+\n
+\n• 検索アルゴリズムの改善
+\n
+\n• ナビゲーションの追跡オプションの改善
+\n
+\n• プロファイル設定のインポート/エクスポートに関する問題を修正
+\n
+\n
 
\ No newline at end of file

From c6874211dc3b42118b7375b7d2b3bd1cee73d2a5 Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Tue, 15 Sep 2020 06:56:11 +0000
Subject: [PATCH 0103/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 8252ed2138..eac0618f0e 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -2357,7 +2357,7 @@
     Сохранить точки, как точки маршрута или как линию.
     Выберите профиль навигации
     %1$d из %2$d
-    Списком
+    Список
     Группы
     Использовано: %1$s
     Сделать активным
@@ -2703,7 +2703,7 @@
     С
     Необязательное имя точки
     Спортивные сплавы
-    По удалённости (сначала дальние)
+    Сначала дальние
     Удалённость (сначала ближние)
     Группа удалена
     Очистить все промежуточные точки
@@ -3833,8 +3833,8 @@
 \nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
     Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем.
     При обратном направлении
-    Вы уверены, что хотите отменить все изменения в запланированном маршруте, закрыв его\?
-    Изображения на уровне улиц
+    Все изменения будут утеряны. Закрыть план маршрута\?
+    Съёмка уличного уровня
     Сохранить как новый файл трека
     Добавить в файл трека
     Треки

From d4c8a20c5d0009c3b07dd188117e11ef6cba22b3 Mon Sep 17 00:00:00 2001
From: Dmitriy Prodchenko 
Date: Mon, 14 Sep 2020 10:35:28 +0000
Subject: [PATCH 0104/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 40 ++++++++++++++++----------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index eac0618f0e..61a1b00868 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -145,9 +145,9 @@
     Фактор рельефа местности (по данным SRTM, ASTER и EU-DEM).
     Действие переименовано в %1$s, чтобы избежать дублирования.
     Обнаружен дубликат имени
-    Переключатель, чтобы показать или скрыть сохранённые точки на карте.
+    Переключатель, чтобы показать или скрыть избранные точки на карте.
     Переключатель, чтобы показать или скрыть POI на карте.
-    Показать/скрыть Мои места
+    Показать/скрыть избранные
     Добавить категорию
     Действия
     Если оставить это поле пустым, то оно будет автоматически заполнено адресом или названием места.
@@ -462,7 +462,7 @@
     Определение положения…
     Моё местоположение (найдено)
     Адрес…
-    Сохранённые…
+    Избранные…
     Неопределённо
     Текущий центр карты
     Начало:
@@ -475,7 +475,7 @@
     Отправить в OSM
     Детализированная карта
     Показывать детали (дороги и др.), начиная с мелких масштабов.
-    Сохранённые места удалены.
+    Избранные точки удалены.
     Вы уверены, что хотите удалить %1$d избранных и %2$d избранных групп\?
     Дом
     Друзья
@@ -610,7 +610,7 @@
 \nНавигация временно переключена на онлайн-сервис CloudMade.
     Невозможно найти указанную папку.
     Папка хранилища данных
-    У вас установлена предыдущая версия OsmAnd. Все локальные данные поддерживаются новой версией. Однако сохранённые точки нужно вручную экспортировать из старой версии и импортировать в новую.
+    У вас установлена предыдущая версия OsmAnd. Все локальные данные поддерживаются новой версией. Однако избранные точки нужно выгрузить из предыдущей версии приложения и загрузить в новую.
     Сборка {0} успешно установлена ({1}).
     Загружается сборка…
     Установить OsmAnd — {0} из {1} {2} МБ\?
@@ -675,7 +675,7 @@
     Выравнивание карты:
     Ориентация карты
     Детали маршрута
-    Сохранённые успешно импортированы
+    Избранные точки успешно импортированы
     GPX-файл с сохранёнными точками отсутствует в {0}
     Точки сохранены в {0}
     Нет избранных точек для сохранения
@@ -796,7 +796,7 @@
     Загружается список доступных регионов…
     Не удалось получить список регионов с https://osmand.net.
     Отредактирована избранная точка
-    Нет сохранённых точек
+    Избранные точки отсутствуют
     Заменить
     Только показать
     Запуск сопровождения
@@ -906,11 +906,11 @@
     Отмена
     Нет
     Название точки
-    Сохранённая
-    Точка «{0}» сохранена.
+    Избранная
+    Точка «{0}» была успешно добавлена к избранным.
     Редактировать место
     Удалить из моих
-    Удалить точку «%s» из сохранённых\?
+    Удалить точку «%s» из избранных\?
     Точка {0} удалена.
     Комментарий добавлен
     Не удалось добавить комментарий.
@@ -1460,7 +1460,7 @@
     Мировые пункты обмена bitcoin
     дней
     Соединение
-    Сохранить данные в файл GPX или импортировать путевые точки в Мои места\?
+    Сохранить данные как трек файл или импортировать путевые точки в избранные\?
     Розовый
     Коричневый
     Пустой файл GPX
@@ -1701,7 +1701,7 @@
     Переименовать
     Удалить
     Удалить все
-    Сохранить
+    Добавить
     Применить
     Старт
     Стоп
@@ -1722,7 +1722,7 @@
     Показывать на карте
     Карта
     Сохранено
-    Сохранённые
+    Избранные
     Добавить к избранным
     Аудио
     Видео
@@ -1958,7 +1958,7 @@
     Опасность
     Регионы
     Карты мира
-    Добавить в избранное
+    Добавить в избранные
     Региональные карты
     Задайте название, которое ещё не используется.
     Название категории
@@ -2207,7 +2207,7 @@
     Очистить всю плитку
     Снижать расход топлива
     Использование топливо-сберегающего пути (обычно короче).
-    Вы уверены, что хотите заменить %1$s\?
+    Вы уверены, что хотите заменить избранные %1$s\?
     Изменить
     Начать
     от
@@ -2264,11 +2264,11 @@
     Добавить место парковки
     Добавить действие
     Редактировать действие
-    Добавить в избранное
+    Добавить в избранные
     Добавить действие
     Удалить действие
     Вы уверены, что хотите удалить действие «%s»\?
-    Показать сохранённые
+    Показать избранные
     Скрыть сохранённые
     Показать/скрыть POI
     Показать %1$s
@@ -2476,7 +2476,7 @@
     Налево
     Показать цифровую панель
     Нажатие на карте переключает кнопки управления и виджеты.
-    возможет импорт в сохранённые точки или как файл GPX.
+    возможен импорт в избранные точки или как трек файл.
     Больше
     Импортировать как файл GPX
     Импортировать в Мои места
@@ -2583,7 +2583,7 @@
     Сохранить точку маршрута
     Путевая точка 1
     Точка маршрута 1
-    Добавить сохранённые
+    Добавить избранные
     Избранное можно импортировать или создать, отмечая точки на карте.
     Импортировать файл GPX
     Переместить точку
@@ -3346,7 +3346,7 @@
     Положение значка в состоянии покоя
     После нажатия кнопки «Применить» удалённые профили будут полностью потеряны.
     Базовый профиль
-    Цвет
+    Выберите цвет
     Вы не можете удалить стандартные профили OsmAnd, но вы можете отключить их на предыдущем экране или переместить вниз.
     Редактировать профили
     «Тип навигации» определяет способ расчета маршрутов.

From ec77d6dd06732267170ab2347bf066817838a4f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Babos=20G=C3=A1bor?= 
Date: Mon, 14 Sep 2020 15:38:27 +0000
Subject: [PATCH 0105/1366] Translated using Weblate (Hungarian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-hu/strings.xml | 61 +++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml
index 0be4073d8b..bf5f700fa4 100644
--- a/OsmAnd/res/values-hu/strings.xml
+++ b/OsmAnd/res/values-hu/strings.xml
@@ -134,11 +134,11 @@
     Térképforrás beállítások
     Vektoros térkép beállítások
     Biztosan törli: %1$s\?
-    településrész
-    falucska
-    község
-    város
-    város
+    Településrész
+    Falucska
+    Község
+    Kisváros
+    Város
     Szimuláció leállítása
     Szimuláció indítása
     Nem sikerült átnevezni a fájlt.
@@ -350,7 +350,7 @@
     Megjelenítési stílus kiválasztása
     POI weboldal megtekintése
     POI telefonszám megtekintése
-    weboldal
+    Weboldal
     telefon
     szűrés
     Nagy felbontású kijelző
@@ -901,7 +901,7 @@
     Lejátszás
     Felvétel
     Indítás
-    hang/videojegyzetek
+    Hang/videojegyzetek
     OsmAnd-bővítmény offline szintvonalakhoz
     Távolságmérés
     Készítsen hang/fénykép/videó jegyzeteket utazás közben egy térképen lévő gomb vagy egy pozíció helyi menüjének használatával.
@@ -1727,7 +1727,7 @@
     Telepítés és hibaelhárítás
     Technikai cikkek
     Verziók
-    szavazás
+    Visszajelzés
     Kapcsolat
     Bővebben
     Újdonságok
@@ -2493,9 +2493,9 @@
     A csoport összes pontja
     Nyitva ekkortól:
     Nyitva eddig:
-    Ekkor fog bezárni:
-    Ekkor fog kinyitni:
-    Ekkor fog kinyitni:
+    Bezár ekkor:
+    Kinyit ekkor:
+    Kinyit ekkor:
     További műveletek
     GPX fájl a kijelölt jegyzetek koordinátáival és adataival.
     GPX fájl az összes jegyzet koordinátáival és adataival.
@@ -2747,8 +2747,8 @@
     Köztes célpont hozzáadása
     Kiindulópont megadása
     Köztes célpont
-    átszállások
-    gyalog
+    Átszállások
+    Gyalog
     Út
     Érdekes helyek (POI)
     Útvonal tervezése…
@@ -3314,7 +3314,7 @@
     Profilok listájának szerkesztése
     Kiválasztott profil
     A létrehozandó egyedi profil az alkalmazás egyik alapprofilján fog alapulni, ez határozza meg az alapvető beállításokat, mint például a widgetek láthatóságát vagy a sebesség és távolság mértékegységeit. Ezek az alapprofilok, néhány pédával az egyedi profilokra, amikre kiterjeszthetők:
-    Szerezze meg %1$d %2$s %3$s kedvezménnyel
+    Szerezze meg %1$d %2$s %3$s kedvezménnyel.
     %1$s az első %2$s
     %1$s az első %2$s
     utána %1$s
@@ -3702,7 +3702,7 @@
     Bizonyos országokban a traffipax riasztások törvényileg tiltottak.
     Tájolás
     %1$s törölve
-    A traffipax adatok végleges eltávolításához újraindítás szükséges.
+    A traffipaxadatok végleges törléséhez indítsa újra az alkalmazást.
     Eltávolítás és Újraindítás
     Adja meg az útvonalakon a járművekre vonatkozó hosszkorlátozást.
     Hosszkorlátozás
@@ -3728,12 +3728,12 @@
     Legkisebb pontosság
     Legkisebb elmozdulás
     Bővítménybeállítások visszaállítása alapértelmezettre
-    Engedélyezésével a térkép nagyítási szintje az eszköz hangerőgombjaival állítható.
+    A térképnagyítás szintjének vezérlése a készülék hangerőgombjaival.
     Hangerőgombok használata nagyításhoz
     Görkorcsolya
     Kérem, adjon nevet a pontnak
     Adja meg a járműve hosszát (a hosszú járművekre útvonalkorlátozások vonatkozhatnak).
-    Következő célpont törlése
+    Legközelebbi célpont törlése
     Wikipédia térképek letöltése
     További adatokat is kijelölhet exportálásra a profillal együtt.
     Kiegészítő adatok átvétele
@@ -3745,14 +3745,14 @@
 \n
 \nAz előfizetéseit a Google Play beállításainál tudja kezelni és lemondani.
     Törli az útvonal soron következő célpontját. Amennyiben ez a végző célpont, a navigáció megáll.
-    Szerezzen információt az érdekes helyekkel kapcsolatban a Wikipédiáról. Ez az ön offline zseb útikönyve - egyszerűen engedélyezze a Wikipédia bővítményt és élvezze az ön körül lévő objektumokról szóló cikkeket.
+    Tudjon meg többet az érdekes pontokról a Wikipédiából. Ez az Ön offline zsebútikönyve – egyszerűen kapcsolja be a Wikipédia-bővítményt, és élvezze az Ön körüli objektumokról szóló cikkeket.
     Salakmotor
     Robogó
     Kerekesszék
     Gokart
     Lezárt OSM-jegyzet
     Előre döntött kerekesszék
-    A folytatáshoz adja meg a munkanapokat
+    A folytatáshoz állítsa be a munkanapokat
     Útvonal pontok között
     Útvonaltervezés
     Hozzáadás nyomvonalhoz
@@ -3826,7 +3826,7 @@
     Mentés nyomvonalfájlként
     Másik nyomvonal kiválasztása
     Elmentett nyomvonal megnyitása
-    Válassza ki a követni kívánt nyomvonalfájlt, vagy importáljon egyet.
+    Válassza ki a követni kívánt nyomvonalfájlt, vagy importáljon egyet a készülékéről.
     Irányt mutató nyilak
     Javaslat: Az 5 méteres beállítás megfelelő lehet, ha nem szükséges ennél finomabb részleteket rögzítenie, és nyugalmi állapotban sem akar kifejezetten adatokat rögzíteni.
     Következő szakasz
@@ -3848,9 +3848,7 @@
     Tömör
     Adja meg a címet
     Csak a következő szakasz lesz újraszámítva a kiválasztott profilnak megfelelően.
-    Ennek a beállításnak a használatához az OsmAndnak hozzá kell tördelnie a nyomvonalát a térképen található utakhoz.
-\n
-\n A következő lépésben ki kell választania a navigációs profilt az engedélyezett utak és a küszöbtávolság észleléséhez, hogy a nyomvonalát közelíteni lehessen az utakhoz.
+    Ezután a beállítás használatához igazítsa a nyomvonalat a legközelebbi úthoz az egyik navigációs profil segítségével.
     Egyedi
     Utazás rögzítésének szüneteltetése
     Mentés új nyomvonalfájlként
@@ -3861,7 +3859,7 @@
     Navigációs profil
     Megjegyzés a „sebesség > 0” ellenőrzéséhez: A legtöbb GPS lapkakészlet (chipset) csak akkor mutat sebességértéket, ha az algoritmus megállapítja, hogy mozgásban van. Ha nincs mozgás, akkor nem mutatnak sebességet. Ezért ebben a szűrőben a „> 0” beállítás bizonyos értelemben a GPS lapkakészlet mozgásérzékelését használja. De – még ha a rögzítés ideje alatt itt nem is szűrjük – a GPX elemzése során mégis használjuk ezt a funkciót a korrigált távolság meghatározásához, vagyis az abban a mezőben megjelenített érték a mozgás közben rögzített távolság.
     Csak a kijelölt szakasz lesz újraszámítva a kiválasztott profilnak megfelelően.
-    Biztos, hogy mentés nélkül bezárja az útvonaltervezőt\? Minden változást elveszít.
+    Biztos, hogy mentés nélkül bezárja az útvonaltervezőt\? Minden változást elvész.
     Válassza ki a követendő nyomvonalfájlt
     A felsorolt %1$s már létezik az OsmAndban.
     Minden korábbi szakasz
@@ -3880,4 +3878,19 @@
     Jelölje ki azt a nyomvonalfájlt, amelyhez az új szakasz hozzáadódjék.
     Nyomvonalak
     Mégis
+    • A Tervezett útvonal mód frissítésével különböző navigációtípusok is használathatók az egyes szakaszokhoz, és bármilyen nyomvonal az utakhoz köthető
+\n
+\n • Új megjelenési lehetőségek a nyomvonalakhoz: válassza ki a színt, a vastagságot, kapcsolja be az iránynyilakat és a kezdő / befejező jeleket
+\n
+\n • A kerékpáros csomópontok jobb láthatósága
+\n
+\n • Helyi menü a nyomvonalak az alapvető adataival
+\n
+\n • Továbbfejlesztett keresési algoritmusok
+\n
+\n • Javított nyomvonalkövetési beállítások a Navigációban
+\n
+\n • Javítva a profilbeállítások importálásával / exportálásával kapcsolatos problémák
+\n
+\n
 
\ No newline at end of file

From a252a2a4ce22d93620fc56726cac76904638ccb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1ns?= 
Date: Mon, 14 Sep 2020 23:41:04 +0000
Subject: [PATCH 0106/1366] Translated using Weblate (Galician)

Currently translated at 97.8% (3408 of 3484 strings)
---
 OsmAnd/res/values-gl/strings.xml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml
index 283c4ba01c..9b411b0d7f 100644
--- a/OsmAnd/res/values-gl/strings.xml
+++ b/OsmAnd/res/values-gl/strings.xml
@@ -3839,4 +3839,17 @@ Lon %2$s
     Personalizado
     Frechas de dirección
     Sólido
+    Deter a gravación da viaxe
+    Retomar a gravación da viaxe
+    Predefinido do sistema
+    Todos os segmentos seguintes
+    Segmento anterior
+    Todos os segmentos anteriores
+    Só o segmento marcado será recalculado empregando o perfil escollido.
+    Todos os segmentos seguintes serán recalculados empregando o perfil escollido.
+    Todos os segmentos anteriores serán recalculados empregando o perfil escollido.
+    Abrir pista gardada
+    está gardado
+    Engade polo menos dous puntos.
+    Refacer
 
\ No newline at end of file

From 1abca0d0fd9a7dd120e647963333cf77e258be5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Babos=20G=C3=A1bor?= 
Date: Mon, 14 Sep 2020 15:44:53 +0000
Subject: [PATCH 0107/1366] Translated using Weblate (Hungarian)

Currently translated at 99.9% (3819 of 3822 strings)
---
 OsmAnd/res/values-hu/phrases.xml | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml
index d5738abcb9..891959e0b0 100644
--- a/OsmAnd/res/values-hu/phrases.xml
+++ b/OsmAnd/res/values-hu/phrases.xml
@@ -1863,7 +1863,7 @@
     Cserkésztáborhely
     Nomád
     Típus
-    Autós
+    Autós (drive-in)
     Szolgáltatás
     Típus
     Elfogadott hulladék
@@ -3050,7 +3050,7 @@
     Dagadóláp (palsa-láp)
     Avgas 100LL repülőbenzin
     Jet A-1 kerozin
-    AdBlue adalékanyag
+    Diesel kipufogó-folyadék
     Szolgáltatóközpont hátrányos helyzetűeknek
     Erődítmény típusa: földsánc
     Erődítmény típusa: újkőkori körárok
@@ -3808,7 +3808,7 @@
     Cső
     Ivóvíz-utántöltő hálózat
     Ivóvíz-utántöltés nincs
-    Ivóvíz-utántöltés
+    van
     Vízszint: közepes vízszint alatt
     Vízszint: közepes vízszint fölött
     Vízszint: lebegő
@@ -3821,4 +3821,16 @@
     Félrevezető
     Véletlenül használható más elemek
     Kontrasztos színű
+    Menetrend
+    Valós idejű
+    Késés
+    van
+    Indulásiidő-kijelző nincs
+    Lift
+    Nyíl nincs
+    Szivattyú állapota: hiányzik a kar
+    Szívás
+    Kis elektronikus készülékek
+    Indulásiidő-kijelző
+    Ivóvíz-utántöltés
 
\ No newline at end of file

From 6b1cffb6af7373fc057539e26d0243461a83d696 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Sun, 13 Sep 2020 11:02:46 +0000
Subject: [PATCH 0108/1366] Translated using Weblate (Estonian)

Currently translated at 98.4% (3431 of 3484 strings)
---
 OsmAnd/res/values-et/strings.xml | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml
index 80fdecc6df..b8c7fbfd34 100644
--- a/OsmAnd/res/values-et/strings.xml
+++ b/OsmAnd/res/values-et/strings.xml
@@ -2673,7 +2673,7 @@
     Laiuspiirang
     Määra teedel lubatud sõiduki laius.
     Simuleeri oma asukohta kasutades salvestatud GPX rada.
-    Nupp ekraani keskkoha lähtekohaks muutmiseks ja sihtkohta teekonna arvutamiseks või sihtkoha valimise dialoogi avamiseks kui sihtkoha marker puudub kaardil.
+    Nupp ekraani keskkoha lähtekohaks muutmiseks. Seejärel on kas võimalik valida sihtkohta või alustada teekonna arvutamist.
     See lisa aktiveerib radade salvestamise funktsionaalsuse, puudutades käsitsi kaardil GPX logimisvidinat või logides automaatselt kõik oma navigeerimise marsruudid GPX faili.
 \n
 \nSalvestatud radu saab jagada oma sõpradega või kasutada OSM kaastöödeks. Sportlased saavad kasutada salvestatud radu oma treeningute jälgimiseks. Mõningast raja põhianalüüsi saab teha otse OsmAnd sees, näiteks ringiajad, keskmine kiirus jne. Lisaks muidugi saab radu hiljem analüüsia ka spetsiaalsetete 3. osapoolte analüüsitööriistadega.
@@ -2706,7 +2706,7 @@
     Võimaldab registreerida oma auto parkimiskoha ja jälgida järelejäänud parkimisaega.
 \nNii asukoht kui aeg on nähtavad nii OsmAnd armatuurlaual kui kaardi vidinas. Meeldetuletust saab lisada Androidi kalendrisse.
     Muuda kauguse mõõtmise ühikuid.
-    See lisa annab kaardi vidina, mis võimaldab teekondade loomist kaarti koputades või olemasolevaid GPX-faile kasutades, et reise kavandada ja punktide vahelist kaugust mõõta. Tulemusi saab salvestada GPX-failina, mida saab hiljem juhendamiseks kasutada.
+    Selleks, et reise kavandada ja punktide vahelist kaugust mõõta, loo teekondi kaardil koputades või olemasolevaid GPX-faile kasutades, Tulemusi saad salvestada GPX-failina, mida on hiljem võimalik juhendamiseks kasutada.
     See lisa teeb seadme erivajadusega kasutajatele mõeldud funktsioonid otse OsmAndis kättesaadavaks. See lihtsustab nt. kõnesünteesi häälte kõnekiiruse reguleerimist, ekraanil navigeerimise suuna seadistamist, rulliku kasutamist suurenduse juhtimiseks või kõnesünteesi tagasisidet, näiteks oma asukoha automaatseks teatamiseks.
     See lisa võimaldab OsmAnd abil OSM kaastöid teha, näiteks OSM huvipunkte luua või muuta, OSM märkmeid avada või kommenteerida ning salvestatud GPX faile lisada. OSM on kogukonna juhitud globaalne üldkasutatav kaardistamisprojekt. Üksikasju leiad https://openstreetmap.org. Aktiivset osalemist hinnatakse ja panust saab teha otse OsmAnd rakendusest, kui seadistada rakenduses oma isiklikud OSM kasutajatunnused.
     See lisa kuvab arendus- ja silumisfunktsioonide sätteid nagu teekonna arvutamine, renderdamise jõudlus või hääljuhiste testimine ja simuleerimine. Need seaded on mõeldud arendajatele ja pole tavakasutaja jaoks vajalikud.
@@ -3495,7 +3495,7 @@
     Aragoni
     Lombardi
     Kohandatud värv
-    Jätkamiseks pead valima tööpäevad
+    Jätkamiseks vali tööpäevad
     Teekond punktide vahel
     Kavanda teekonda
     Lisa rajale
@@ -3552,8 +3552,8 @@
     Nupp, mis näitab või peidab kaardil Mapillary kihti.
     Eemalda ja taaskäivita
     Rulluisud
-    Kustuta järgmine sihtpunkt
-    Sisselülitades saad seadme helitugevuse nuppudega kontrollida kaardi suumi taset.
+    Kustuta lähim sihtpunkt
+    Nutiseadme helitugevuse nuppudega kontrollida saad kaardi suumi taset.
     Helitugevuse nupud toimivad suumina
     Palun sisestage punkti nimi
     Lae alla Vikipeedia kaardid
@@ -3582,7 +3582,7 @@
     Pikkuse piirang
     Kurss
     %1$s on kustutatud
-    Selleks, et eemaldada kõik kiiruskaamerate andmed on vajalik seadme taaskäivitamine.
+    Kiiruskaamerate kõikide andmete eemaldamiseks on vajalik nutiseadme taaskäivitamine.
     Siin seadmes puudub teave liikluskaamerate kohta.
     Lisa profiil
     Muuda rakenduse profiili
@@ -3682,7 +3682,7 @@
     Salvesta rada failina
     Jälgi rada
     Vali rajafail, mida soovid kasutada
-    Vali rajafail, mida soovid kasutada või impordi see.
+    Vali rajafail, mida soovid kasutada või impordi see oma nutiseadmest.
     Vali muu rada
     Navigeeri minu asukohast rajale
     Asukoht rajal, kuhu me liigume
@@ -3729,4 +3729,13 @@
     Kinnita teede külge
     Selle valiku kasutamiseks mõne oma navigeerimisprofiili kasutamisel kinnita oma rada lähimale lubatud teele.
     Valitud profiili alusel arvutatakse uus teekond vaid järgmise segmendi osas.
+    Põhitegevused
+    Ostu kinnitusel võetakse sinu Google Play kontolt tasu.
+\n
+\nTellimus uuendatakse automaatselt, kui sa seda enne uuendamise kuupäeva ei tühista. Sonu kontolt võetakse pikendamisperioodi eest (kuu/kolm kuud/aasta) tasu ainult uuendamise kuupäeval.
+\n
+\nTellimuste haldamiseks ja tühistamiseks ava Google Play seadistused.
+    Kiirtegevusi saad eksportida või importida koos rakenduse profiilidega.
+    Kas sa oled kindel, et soovid pöördumatult kustutada %d kiirtegevust\?
+    Vali kas soovid ühendada punkte sirge joonega või arvutada nendevahelist teekonda vastavalt oma valitud profiilile.
 
\ No newline at end of file

From 3f733f5ae43bf26fff6d523cb38805f08d1dda88 Mon Sep 17 00:00:00 2001
From: Verdulo 
Date: Mon, 14 Sep 2020 22:01:32 +0000
Subject: [PATCH 0109/1366] Translated using Weblate (Esperanto)

Currently translated at 99.7% (3812 of 3822 strings)
---
 OsmAnd/res/values-eo/phrases.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml
index 41115a7aed..cc31985829 100644
--- a/OsmAnd/res/values-eo/phrases.xml
+++ b/OsmAnd/res/values-eo/phrases.xml
@@ -2335,7 +2335,7 @@
     Akvokrano
     Butonprema: jes
     Butonprema: ne
-    Bicikla mem-riparejo;memriparejo bicikla;riparejo bicikla;pumpilo bicikla;aerpumpilo bicikla
+    Bicikla memriparejo;memriparejo bicikla;riparejo bicikla;pumpilo bicikla;aerpumpilo bicikla
     Aersportoj
     elteriĝejo
     surteriĝejo

From f90825fc370a2855be208bd1be7feaf8454aeda1 Mon Sep 17 00:00:00 2001
From: Selyan Sliman Amiri 
Date: Sun, 13 Sep 2020 08:38:53 +0000
Subject: [PATCH 0110/1366] Translated using Weblate (Kabyle)

Currently translated at 37.7% (1314 of 3484 strings)
---
 OsmAnd/res/values-b+kab/strings.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-b+kab/strings.xml b/OsmAnd/res/values-b+kab/strings.xml
index 43d88c80b1..8a49267439 100644
--- a/OsmAnd/res/values-b+kab/strings.xml
+++ b/OsmAnd/res/values-b+kab/strings.xml
@@ -1339,4 +1339,5 @@
     Amaɣnu n tunigin
     Fren afaylu n uḍfar iɣer ara yernu uḥric amaynut.
     Tebɣiḍ s tidet ad tmedleḍ abrid n uɣawas war asekles\? Ad tesruḥeḍ akk ibeddilen.
+    Ittwasekles
 
\ No newline at end of file

From 7055c20529fd161729b642bddf00f11dd00c9406 Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Mon, 14 Sep 2020 02:00:31 +0000
Subject: [PATCH 0111/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-zh-rTW/strings.xml | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml
index 249e2bfb70..6bed71474e 100644
--- a/OsmAnd/res/values-zh-rTW/strings.xml
+++ b/OsmAnd/res/values-zh-rTW/strings.xml
@@ -3778,27 +3778,27 @@
     某些國家禁止使用測速照相的警報裝置。
     方向
     %1$s 已刪除
-    必須重新啟動才能完全刪除測速照相的資料。
+    重新啟動應用程式以刪除所有測速照相的資料。
     解除安裝並重新啟動
     指定路線上允許的車輛長度。
     長度限制
     此裝置沒有測速照相機。
     直排輪鞋
-    啟用裝置音量按鈕控制地圖縮放等級。
+    使用裝置音量按鈕控制地圖縮放等級。
     音量按鈕以縮放
     提供您的車輛長度,某些路徑限制可能適用於較長的車輛。
-    刪除下一個目的地點
+    刪除最近的目的地點
     請提供點的名稱
     目前路徑上的目的地點將會被刪除。如果其將為目的地,導航就會停止。
     下載維基百科地圖
-    從維基百科取得關於興趣點的資訊。這是您的離線口袋指南 ── 只要啟用維基百科外掛程式並享受有關於您周圍景點的文章。
+    從維基百科取得關於興趣點的資訊。這是您的離線口袋指南 ── 只要開啟維基百科外掛程式並享受有關於您周圍景點的文章。
     耐力賽摩托車
     小型摩托車
     輪椅
     輪椅向前
     卡丁車
     已關閉的 OSM 註記
-    您必須設定工作天以繼續
+    設定工作天以繼續
     點與點之間的路線
     規劃路線
     新增到軌跡
@@ -3824,14 +3824,12 @@
     選取如何連接點,用直線或以選定的設定檔計算其間的路徑。
     整個軌道
     下一段
-    要使用此選項,OsmAnd 必須將您的軌跡捕捉到地圖道路上。
-\n
-\n在下一步,您只需要選取設定檔以偵測允許的道路與距離門檻以追蹤道路。
+    接下來,使用您其中一個導航設定檔來將路線貼齊到最近可用的道路上以使用此選項。
     門檻距離
     導航設定檔
     選取要加入新片段的軌道檔案。
     街道級照片
-    您確定要不儲存就關閉計劃錄線嗎?您將會失去所有變更。
+    您確定要關閉計畫路線來放棄所有變更嗎?
     反向時
     儲存為新的軌跡檔案
     新增到軌跡檔案
@@ -3849,7 +3847,7 @@
     儲存為軌跡檔案
     跟隨軌跡
     選擇要跟隨的軌跡檔案
-    選擇要跟隨的軌跡檔案,或是匯入一個。
+    選擇要跟隨的軌跡檔案,或是從您的裝置匯入。
     選取其他軌跡
     從我的位置導航到軌跡
     要導航的軌跡點

From 47afe0556bd7c5b0da46e22e1714b949af48a1c5 Mon Sep 17 00:00:00 2001
From: Dmitriy Prodchenko 
Date: Mon, 14 Sep 2020 10:35:28 +0000
Subject: [PATCH 0112/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (267 of 267 strings)

Translation: OsmAnd/Telegram
Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/ru/
---
 OsmAnd-telegram/res/values-ru/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd-telegram/res/values-ru/strings.xml b/OsmAnd-telegram/res/values-ru/strings.xml
index b76aa52417..daff0e950b 100644
--- a/OsmAnd-telegram/res/values-ru/strings.xml
+++ b/OsmAnd-telegram/res/values-ru/strings.xml
@@ -63,7 +63,7 @@
     У меня нет учетной записи Telegram
     Введите номер телефона
     Введите код аутентификации
-    Сохранить
+    Добавить
     Назовите новое устройство макс. 200 символов.
     Расстояние
     Моя локация

From 3bc6ec76edd4f3cd116af8003c47d5e8a16d088a Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 15 Sep 2020 16:13:08 +0300
Subject: [PATCH 0113/1366] Remove default gpx color and width

---
 OsmAnd/res/layout/track_coloring_card.xml     |  1 +
 .../plus/dialogs/GpxAppearanceAdapter.java    | 19 ++++++++-----------
 .../osmand/plus/track/TrackColoringCard.java  | 11 +++++------
 .../net/osmand/plus/track/TrackWidthCard.java | 14 ++++++++++----
 4 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/OsmAnd/res/layout/track_coloring_card.xml b/OsmAnd/res/layout/track_coloring_card.xml
index 5775a98c7d..2c7721f61d 100644
--- a/OsmAnd/res/layout/track_coloring_card.xml
+++ b/OsmAnd/res/layout/track_coloring_card.xml
@@ -21,6 +21,7 @@
 		android:layout_height="wrap_content"
 		android:orientation="horizontal"
 		android:paddingTop="@dimen/context_menu_padding_margin_tiny"
+		android:visibility="gone"
 		android:paddingBottom="@dimen/content_padding">
 
 		
Date: Tue, 15 Sep 2020 17:19:04 +0300
Subject: [PATCH 0114/1366] Edit_favorite_screen

---
 .../res/layout/point_editor_fragment_new.xml  | 69 ++++++++++++++-----
 .../FavouritePointMenuController.java         | 12 ++--
 .../FavoritePointEditorFragmentNew.java       |  8 +--
 .../editors/PointEditorFragmentNew.java       | 51 ++++++++++++--
 4 files changed, 108 insertions(+), 32 deletions(-)

diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml
index e39a1dbf44..a3a8000b0a 100644
--- a/OsmAnd/res/layout/point_editor_fragment_new.xml
+++ b/OsmAnd/res/layout/point_editor_fragment_new.xml
@@ -142,29 +142,62 @@
 							android:paddingEnd="@dimen/content_padding_small"
 							android:paddingRight="@dimen/content_padding_small"
 							android:textSize="@dimen/default_list_text_size"
+							android:gravity="left"
 							tools:text="@string/lorem_ipsum" />
 
 					
 				
 
-				
+				
+
+					
+
+					
+
+				
+
+				
 
 				
Date: Tue, 15 Sep 2020 12:28:40 +0000
Subject: [PATCH 0115/1366] Translated using Weblate (Persian)

Currently translated at 97.3% (3392 of 3484 strings)
---
 OsmAnd/res/values-fa/strings.xml | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml
index 14fd623bee..4cc7cc83c8 100644
--- a/OsmAnd/res/values-fa/strings.xml
+++ b/OsmAnd/res/values-fa/strings.xml
@@ -3843,4 +3843,23 @@
     یک فایل رد انتخاب کنید تا باز شود.
     تمام
     بَرنویسی رد
+    آهنگ ذخیره شده را باز کنید
+    ذخیره شده
+    لطفا حداقل دو امتیاز اضافه کنید.
+    آماده
+    "به روز شده برنامه یک عملکرد مسیر: اجازه می دهد تا از انواع مختلف پیمایش در هر بخش و گنجاندن مسیرها استفاده کنید
+\n
+\n  • منوی New Appearance برای آهنگ ها، رنگ ، ضخامت ، فلش جهت نمایش ، نمادهای شروع / پایان استفاده می شوئ
+\n
+\n  • بهبود دید نود های دوچرخه.
+\n
+\n  • آهنگ ها اکنون قابل لمس هستند ، دارای منوی زمینه با اطلاعات اولیه هستند.
+\n
+\n  • بهبود الگوریتم های جستجو
+\n
+\n  • گزینه های ردیابی را در پیمایش بهبود بخشید
+\n
+\n  • مشکلات مربوط به واردات / صادرات تنظیمات نمایه برطرف شده است
+\n
+\n"
 
\ No newline at end of file

From f543d40b1a1641a74675085a7cc866f436085823 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 15 Sep 2020 18:09:50 +0300
Subject: [PATCH 0116/1366] Fix possible npe

---
 OsmAnd/src/net/osmand/data/FavouritePoint.java     |  2 ++
 .../controllers/FavouritePointMenuController.java  | 14 ++++++++++----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/src/net/osmand/data/FavouritePoint.java b/OsmAnd/src/net/osmand/data/FavouritePoint.java
index 72cde20159..e5f4f6c8ea 100644
--- a/OsmAnd/src/net/osmand/data/FavouritePoint.java
+++ b/OsmAnd/src/net/osmand/data/FavouritePoint.java
@@ -7,6 +7,7 @@ import android.graphics.BitmapFactory;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 
 import net.osmand.GPXUtilities.WptPt;
@@ -89,6 +90,7 @@ public class FavouritePoint implements Serializable, LocationPoint {
 			return color;
 	}
 
+	@Nullable
 	public String getAddress() {
 		return address;
 	}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
index c1420b7d24..a6a84bee67 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
@@ -28,6 +28,7 @@ import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragment;
 import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragmentNew;
 import net.osmand.plus.transport.TransportStopRoute;
 import net.osmand.plus.widgets.style.CustomTypefaceSpan;
+import net.osmand.util.Algorithms;
 import net.osmand.util.OpeningHoursParser;
 import net.osmand.view.GravityDrawable;
 
@@ -160,11 +161,16 @@ public class FavouritePointMenuController extends MenuController {
 	@NonNull
 	@Override
 	public CharSequence getSubtypeStr() {
-		Typeface typeface = FontCache.getRobotoRegular(getMapActivity());
-		SpannableString addressSpannable = new SpannableString(fav.getAddress());
-		addressSpannable.setSpan(new CustomTypefaceSpan(typeface), 0, addressSpannable.length(), 0);
+		MapActivity mapActivity = getMapActivity();
+		if (mapActivity != null && !Algorithms.isEmpty(fav.getAddress())) {
+			Typeface typeface = FontCache.getRobotoRegular(mapActivity);
+			SpannableString addressSpannable = new SpannableString(fav.getAddress());
+			addressSpannable.setSpan(new CustomTypefaceSpan(typeface), 0, addressSpannable.length(), 0);
 
-		return addressSpannable;
+			return addressSpannable;
+		} else {
+			return "";
+		}
 	}
 
 	@Override

From 485368d2624677b83bc8f256f234d03f0b365d32 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 15 Sep 2020 18:12:29 +0300
Subject: [PATCH 0117/1366] Request inventory on start only

---
 OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java
index 2fe36e624d..ac7e2c77fb 100644
--- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java
+++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java
@@ -63,6 +63,7 @@ public class InAppPurchaseHelper {
 
 	private InAppPurchases purchases;
 	private long lastValidationCheckTime;
+	private boolean inventoryRequested;
 
 	private static final long PURCHASE_VALIDATION_PERIOD_MSEC = 1000 * 60 * 60 * 24; // daily
 	// (arbitrary) request code for the purchase flow
@@ -333,8 +334,8 @@ public class InAppPurchaseHelper {
 	}
 
 	public boolean needRequestInventory() {
-		return (isSubscribedToLiveUpdates(ctx) && Algorithms.isEmpty(ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.get()))
-				|| System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC;
+		return !inventoryRequested && ((isSubscribedToLiveUpdates(ctx) && Algorithms.isEmpty(ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.get()))
+				|| System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC);
 	}
 
 	public void requestInventory() {
@@ -803,6 +804,7 @@ public class InAppPurchaseHelper {
 		protected void onPostExecute(String response) {
 			logDebug("Response=" + response);
 			if (response != null) {
+				inventoryRequested = true;
 				try {
 					JSONObject obj = new JSONObject(response);
 					JSONArray names = obj.names();

From 6e856f2ee36aaa13d3da80485e8d41eba0604f17 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 15 Sep 2020 18:28:03 +0300
Subject: [PATCH 0118/1366] Fix possible npe in ProfileCard

---
 .../src/net/osmand/plus/measurementtool/ProfileCard.java | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java b/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java
index 98d180e48f..8fc3be3037 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java
@@ -8,6 +8,8 @@ import android.widget.LinearLayout;
 import android.widget.RadioButton;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
@@ -23,7 +25,7 @@ public class ProfileCard extends BaseCard {
 	private ApplicationMode selectedMode;
 	private ProfileCardListener listener;
 
-	public ProfileCard(MapActivity mapActivity, ApplicationMode selectedMode) {
+	public ProfileCard(@NonNull MapActivity mapActivity, @NonNull ApplicationMode selectedMode) {
 		super(mapActivity);
 		this.selectedMode = selectedMode;
 	}
@@ -75,7 +77,10 @@ public class ProfileCard extends BaseCard {
 	}
 
 	private void resetSelected(List modes) {
-		((RadioButton) view.findViewWithTag(selectedMode.getStringKey()).findViewById(R.id.compound_button)).setChecked(true);
+		View profileView = view.findViewWithTag(selectedMode.getStringKey());
+		if (profileView != null) {
+			((RadioButton) profileView.findViewById(R.id.compound_button)).setChecked(true);
+		}
 	}
 
 	private void addProfileView(LinearLayout container, View.OnClickListener onClickListener, Object tag,

From e6ab61c6c8d349d20b1c5b4ebc9c21f58277f11b Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 15 Sep 2020 18:43:42 +0300
Subject: [PATCH 0119/1366] Fix UnknownFormatConversionException

---
 OsmAnd/res/values-de/strings.xml                          | 2 +-
 .../osmand/plus/search/SendSearchQueryBottomSheet.java    | 8 +-------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml
index 16672becc8..730f97c489 100644
--- a/OsmAnd/res/values-de/strings.xml
+++ b/OsmAnd/res/values-de/strings.xml
@@ -2785,7 +2785,7 @@
     Als Track speichern
     Sie haben %1$s Punkte hinzugefügt. Geben Sie einen Dateinamen ein und klicken Sie auf „Speichern“.
     Punkt %1$s gelöscht
-    Ihre Suchanfrage wird an: \"%1 s\" gesendet, zusammen mit Ihrem Standort.
+    Ihre Suchanfrage wird an: \"%1$s\" gesendet, zusammen mit Ihrem Standort.
 \n
 \nPersönliche Informationen werden nicht gesammelt, sondern nur Suchdaten, die zur Verbesserung der Suche benötigt werden.
     Keine Ergebnisse?
diff --git a/OsmAnd/src/net/osmand/plus/search/SendSearchQueryBottomSheet.java b/OsmAnd/src/net/osmand/plus/search/SendSearchQueryBottomSheet.java
index a46393fc67..39e91503ec 100644
--- a/OsmAnd/src/net/osmand/plus/search/SendSearchQueryBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/search/SendSearchQueryBottomSheet.java
@@ -1,8 +1,6 @@
 package net.osmand.plus.search;
 
-import android.os.Build;
 import android.os.Bundle;
-import android.text.Html;
 import android.view.ContextThemeWrapper;
 import android.view.View;
 import android.widget.TextView;
@@ -50,11 +48,7 @@ public class SendSearchQueryBottomSheet extends MenuBottomSheetDialogFragment {
 		final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
 		final TextView textView = (TextView) View.inflate(new ContextThemeWrapper(getContext(), themeRes),
 				R.layout.send_missing_search_query_tv, null);
-		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-			textView.setText(getString(R.string.send_search_query_description, searchQuery));
-		} else {
-			textView.setText(getString(R.string.send_search_query_description, searchQuery));
-		}
+		textView.setText(getString(R.string.send_search_query_description, searchQuery));
 		BaseBottomSheetItem sendSearchQueryDescription = new SimpleBottomSheetItem.Builder().setCustomView(textView)
 				.create();
 		items.add(sendSearchQueryDescription);

From 85e4f7b2258d8f917ccca22218299da7c2d103e0 Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Tue, 15 Sep 2020 20:24:22 +0300
Subject: [PATCH 0120/1366] Drawer: show navigation type for profiles

---
 OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 8e444b7d88..fe3c067e9e 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -1046,7 +1046,7 @@ public class MapActivityActions implements DialogProvider {
 		String modeDescription;
 		if (currentMode.isCustomProfile()) {
 			modeDescription = String.format(app.getString(R.string.profile_type_descr_string),
-					Algorithms.capitalizeFirstLetterAndLowercase(currentMode.getParent().toHumanString()));
+					Algorithms.capitalizeFirstLetterAndLowercase(currentMode.getRoutingProfile()));
 		} else {
 			modeDescription = getString(R.string.profile_type_base_string);
 		}

From 546ed7b4bcdef9975cd92b878d419dc1004552ea Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Tue, 15 Sep 2020 16:52:03 +0000
Subject: [PATCH 0121/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt/strings.xml | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml
index 9b348c9bbe..49f1d72d9e 100644
--- a/OsmAnd/res/values-pt/strings.xml
+++ b/OsmAnd/res/values-pt/strings.xml
@@ -3829,7 +3829,7 @@
     Rota inversa
     O trilho inteiro será recalculado a usar o perfil selecionado.
     Somente o próximo segmento será recalculado a usar o perfil selecionado.
-    Selecione como ligar pontos, com uma linha reta ou calcule uma rota entre eles com o perfil selecionado.
+    Selecione como ligar pontos, por uma linha reta ou a calcular uma rota entre eles como especificado abaixo.
     Trilho inteiro
     Próximo segmento
     Em seguida, encaixe a sua pista na estrada mais próxima permitida com um dos seus perfis de navegação para usar esta opção.
@@ -3840,7 +3840,7 @@
     Escolha o ficheiro de trilha a seguir
     Escolha o ficheiro de trilho a seguir ou importe um do seu aparelho.
     Selecionar outra trilha
-    Navegue de minha localização até a trilha
+    Navegue de minha posição até ao trilho
     Ponto da trilha para navegar
     Início da pista
     Ponto próximo
@@ -3888,19 +3888,19 @@
     Nome do ficheiro
     %s ficheiros de faixa selecionados
     Vai pausar o registo de faixas quando a aplicação for morta (através de aplicações recentes). (indicação de fundo de OsmAnd desaparece da barra de notificação do Android.)
-    - O modo Rota do Plano Atualizado permite usar diferentes tipos de navegação para cada segmento e anexa qualquer pista às estradas
+    - Função atualizada de Planear uma rota: permite utilizar diferentes tipos de navegação por segmento e a inclusão de faixas
 \n
-\n - Novas opções de aparência para pistas: selecionar cor, espessura, rodar nas setas de direcção e marcas de início/fim
+\n - Novo menu Aparência para trilhos: selecionar cor, espessura, setas de direção de visualização, ícones de início/fim
 \n
-\n - Melhoria da visibilidade dos nós da bicicleta
+\n - Melhoria da visibilidade dos nós da bicicleta.
 \n
-\n - Menu de contexto para faixas com informações básicas
+\n - Os trilhos agora podem ser tocados, ter menu de contexto com informações básicas.
 \n
 \n - Algoritmos de pesquisa melhorados
 \n
-\n - Opções de faixa de acompanhamento melhoradas na navegação
+\n - Opções de seguir faixas melhoradas na navegação
 \n
-\n - Problemas fixos com as configurações de importação/exportação de perfis
+\n - Problemas com as configurações de importação/exportação de perfis resolvidos
 \n
 \n
 
\ No newline at end of file

From 3e5248c4949f5807c305322719df0e33b9001e7f Mon Sep 17 00:00:00 2001
From: Ldm Public 
Date: Tue, 15 Sep 2020 11:39:05 +0000
Subject: [PATCH 0122/1366] Translated using Weblate (French)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-fr/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml
index bd4408d069..b116563f71 100644
--- a/OsmAnd/res/values-fr/strings.xml
+++ b/OsmAnd/res/values-fr/strings.xml
@@ -3801,7 +3801,7 @@
     Sélectionnez un fichier de trace à ouvrir.
     Terminé
     Remplacer la trace
-    Sélectionnez comment relier les points : par une ligne droite ou en calculant un itinéraire avec le profil sélectionné.
+    Sélectionnez comment relier les points : par une ligne droite ou en calculant un itinéraire reliant les points comme indiqué ci-dessous.
     Toute la trace sera recalculée en utilisant le profil sélectionné.
     Seul le prochain segment sera recalculé en utilisant le profil sélectionné.
     Ensuite, sélectionnez le profil de navigation pour détecter les routes autorisées et le seuil de distance afin de déplacer votre trace.
@@ -3836,7 +3836,7 @@
     Suivre la trace
     Sélectionner un fichier de trace à suivre
     Sélectionner une autre trace
-    Naviguez de ma position vers la trace
+    Naviguer de ma position vers la trace
     Point le plus proche
     Supprimer l\'adresse
     Ajouter une adresse

From 6c1cf4bf36c7567583200a6152d1a355c505eb46 Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Wed, 16 Sep 2020 02:02:14 +0000
Subject: [PATCH 0123/1366] Translated using Weblate (Russian)

Currently translated at 99.8% (3478 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 80 ++++++++++++++++----------------
 1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 61a1b00868..ea571d0bac 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -73,8 +73,8 @@
     Поиск почтового индекса
     Записать аудио
     Записать видео
-    Сделать фото
-    Добавить заметку OSM
+    Фотозаметка
+    Заметка OSM
     Функции парковки
     Благодарим вас за покупку платной версии OsmAnd.
     Не показывать сообщения при запуске
@@ -181,7 +181,7 @@
     Толщина горизонталей
     Толщина горизонталей
     Воду
-    Скрыть воду
+    Водные объекты
     Старый поиск
     Показывать старый поиск
     Добавить старый поиск в меню.
@@ -194,7 +194,7 @@
     Построение маршрута
     У вас пока нет файлов треков
     Вы также можете добавить файлы треков в папку
-    Добавь ещё…
+    Добавить…
     Внешний вид
     Включить быструю запись
     Отображение системного уведомления, позволяющего начать запись поездки.
@@ -233,7 +233,7 @@
     Сохранить фильтр
     Удалить фильтр
     Новый фильтр
-    Изменить позицию
+    Изменение позиции
     Текущий путь
     Навигация OsmAnd Live
     Уровень заряда батареи
@@ -244,7 +244,7 @@
     Режим карты
     Тонко
     Средне
-    Толстый
+    Жирно
     Выберите маркеры
     Верхняя панель
     Правок: %1$s, ранг: %2$s, всего правок: %3$s
@@ -317,8 +317,8 @@
     Открыть внешний проигрыватель
     Удалить эту запись?
     недоступно
-    Создать аудиозаметку
-    Создать видеозаметку
+    Аудиозаметка
+    Видеозаметка
     Слой аудиозаписей
     Запись не может быть воспроизведена.
     Удалить запись
@@ -466,7 +466,7 @@
     Неопределённо
     Текущий центр карты
     Начало:
-    Искать рядом
+    Поиск рядом
     Маршрут успешно сохранён в «%1$s».
     Имя файла: 
     Файл с таким именем уже существует.
@@ -518,9 +518,9 @@
     Обратное направление GPX
     Использовать текущий пункт назначения
     Пройти весь путь
-    Для этого региона доступны локальные векторные карты. 
-\n\t 
-\n\tДля их использования выберите в «Меню» → «Настройки карты» → «Источник карты…» → «Векторные карты».
+    Для этого региона есть локальные векторные карты.
+\n\t
+\n\tМеню → Настройки карты → Источник карты → Векторные карты.
     Голосовые инструкции
     Выберите канал вывода голосовых подсказок.
     Канал голосовых звонков (прерывает автомобильную Bluetooth стереосистему)
@@ -531,14 +531,14 @@
     Прозрачность наложения
     Отрегулируйте прозрачность основной карты.
     Прозрачность основной карты
-    Карта подложки…
+    Карта подложки
     Карта подложки
     Выберите карту подложки
-    Карта наложения…
+    Карта наложения
     Карта наложения
     Выберите слой наложения поверх основной карты
     Карта уже установлена, настройки будут обновлены.
-    Выберите (тайловые) карты для установки или обновления.
+    Выберите тайловые карты для установки или обновления.
     Для данной операции требуется подключение к интернету, но оно недоступно.
     Загрузить ещё…
     Минимальный масштаб для использования векторных карт.
@@ -689,7 +689,7 @@
     Маршрут
     Заметки OSM (онлайн)
     POI…
-    Источник карты…
+    Источник карты
     Слои
     Искать POI
     Использовать трекбол для перемещения по карте.
@@ -738,7 +738,7 @@
     Загрузить детальные карты регионов
     Поиск сигнала…
     Искать вокруг текущего центра карты
-    Искать рядом
+    Поиск рядом
     По умолчанию
     Портрет
     Ландшафт
@@ -819,7 +819,7 @@
     POI
     Не удалось сохранить файл GPX.
     Не удалось рассчитать маршрут.
-    Не удалось рассчитать маршрут.
+    Не удалось рассчитать маршрут
     Невозможно построить маршрут.
     Проложен новый маршрут, расстояние
     Вы прибыли.
@@ -864,7 +864,7 @@
     3D вид
     Показать последние использованные POI на карте.
     Показывать POI
-    Выберите источник онлайн или кешированных тайлов карты.
+    Выберите ресурс с картами онлайн или в кеше.
     Растровые карты
     Источник карты
     Использовать интернет
@@ -1258,7 +1258,7 @@
     Отменить маршрут
     Очистить пункт назначения
     Искать улицу в ближайших населённых пунктах
-    Сортировать от двери до двери
+    В порядке следования домов
     Доступно %1$d файлов для скачивания
     осталось %1$d файлов
     Подождите, пока завершится текущая операция
@@ -1267,7 +1267,7 @@
     Имя файла GPX
     Файл GPX сохранён в {0}
     Инструмент расчёта дистанции и планирования
-    Оптимальный порядок точек по пути к месту назначения.
+    Оптимальный порядок точек маршрута по пути к месту назначения.
     Не удалось выполнить резервное копирование изменений OSM.
     Резервное копирование как правка OSM
     высота
@@ -1304,7 +1304,7 @@
     К:
     Через:
     От:
-    У вас уже установлены промежуточные пункты.
+    Промежуточные пункты уже заданы.
     Названия улиц (TTS)
     Объявлять…
     Настройки озвучивания названий улиц, предупреждений о дорожном движении (принудительные остановки, искусственные неровности), камер контроля скорости и ограничений скорости.
@@ -2110,7 +2110,7 @@
     Запись удалена
     элементы удалены
     Автообновления
-    Выберите или скачайте голосовые оповещения для вашего языка.
+    Выберите или скачайте голосовые подсказки для вашего языка.
     Полный отчёт
     Пересчёт маршрута
     Имя пользователя и пароль OSM
@@ -2216,7 +2216,7 @@
     Скачать {0} файл(ов)\?
 \nИспользуется {3} МБ временного хранилища и {1} МБ постоянного. (Из {2} МБ)
     Найти моё местоположение
-    Прокладывайте маршруты и открывайте новые для себя места без подключения к интернету
+    Стройте маршруты и открывайте новые места без подключения к интернету
     Разрешить доступ к местоположению
     Дать разрешение
     Хранилище данных OsmAnd (для карт, файлов треков и пр.): %1$s.
@@ -2235,7 +2235,7 @@
     Получить
     Получайте неограниченное количество загрузок карт, вдобавок к еженедельным, ежедневным и даже почасовым обновлениям.
     Неограниченный доступ к картам, обновлениям и плагину «Википедия».
-    Выберите голосовое сопровождение
+    Голосовое сопровождение
     Абонентская плата взимается за выбранный период. Отменить подписку можно в Google Play в любой момент.
     Пожертвование для сообщества OSM
     Часть вашего пожертвования будет отправлена участникам OSM. Стоимость подписки при этом остаётся прежней.
@@ -2296,7 +2296,7 @@
     Фото с улиц онлайн для каждого. Открывайте места, взаимодействуйте, запечатлейте весь мир.
     Mapillary
     Уличные фотографии для всех. Открывайте для себя места, сотрудничайте, снимайте мир.
-    Название содержит слишком много заглавных букв. Вы хотите продолжить?
+    В названии слишком много заглавных букв. Продолжить\?
     Кнопка приостановки и возобновления навигации.
     Показывать диалог завершения навигации
     Запуск/остановка навигации
@@ -2320,12 +2320,12 @@
     Макс/Мин
     Мин/Макс
     Пауза/возобновление навигации
-    Перезагрузка тайлов для отображения актуальных данных.
+    Перезагрузить тайлы для актуализации данных.
     Введите имя пользователя
     Сбросить
     До
     От
-    Перезагрузить
+    Обновить
     Фильтровать фотографии по отправителю, дате или типу. Фильтры применяются только для больших масштабов.
     Не удалось импортировать файл. Убедитесь, что OsmAnd имеет разрешение на его чтение.
     Откорректированное расстояние
@@ -2447,7 +2447,7 @@
     Неправильный формат
     Введите новое имя
     Назад
-    Внешний вид на карте
+    Вид на карте
     Выберите категорию избранных для добавления к маркерам.
     Категория избранных
     Добавить группу
@@ -2669,8 +2669,8 @@
     Место без названия
     Текущий
     Добавляет промежуточную остановку
-    Добавляет первую остановку
-    Перемещает пункт назначения и создаёт промежуточную точку
+    Добавляет начальную остановку
+    Добавляет в конец точку в качестве нового пункта назначения
     Показать закрытые заметки
     Показать/скрыть заметки OSM на карте.
     GPX — подходит для экспорта в JOSM и другие OSM редакторы.
@@ -2701,10 +2701,10 @@
     З
     Ю
     С
-    Необязательное имя точки
+    Имя точки (необязательно)
     Спортивные сплавы
     Сначала дальние
-    Удалённость (сначала ближние)
+    Сначала ближние
     Группа удалена
     Очистить все промежуточные точки
     Использовать двузначную долготу
@@ -3721,7 +3721,7 @@
     Держать экран отключённым
     Держать экран включённым
     Файл SQLiteDB
-    Укажите имя источника онлайн-карты.
+    Название ресурса с онлайн-картами.
     Введите или вставьте URL онлайн-источника.
     Время устаревания
     Проекция Меркатора
@@ -3786,13 +3786,13 @@
     Предельная длина
     В этом устройстве нет камер контроля скорости.
     Роликовые коньки
-    Управляйте уровнем масштабирования карты с помощью кнопок громкости на устройстве.
+    Изменение масштаба карты кнопками громкости.
     Масштабирование кнопками громкости
     Укажите длину автомобиля, для длинных транспортных средств могут применяться ограничения на маршруте.
-    Удалить ближайшую точку назначения
+    Удалить следующий пункт
     Задайте название точки
     Следующая точка маршрута будет удалена. Если это конечный пункт, навигация завершится.
-    Получите информацию о достопримечательностях из Википедии. Это ваш карманный автономный путеводитель - просто включите плагин Википедии и наслаждайтесь статьями об объектах вокруг вас.
+    Информация о достопримечательностях из Википедии. Ваш карманный офлайн-путеводитель — просто включите плагин Википедии и читайте об объектах вокруг вас.
     Скачать карты Википедии
     Эндуро мотоцикл
     Мотороллер
@@ -3824,8 +3824,8 @@
     Предельная дистанция
     Сохранить как новый трек
     Обратный маршрут
-    Весь трек будет перестроен с использованием выбранного профиля.
-    Только следующий сегмент будет перестроен с использованием выбранного профиля.
+    Профиль будет примёнен ко всему маршруту.
+    Профиль будет применён только к следующему сегменту.
     Следующий сегмент
     Весь трек
     Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам.
@@ -3883,7 +3883,7 @@
     Открыть сохранённый трек
     Остановка записи GPX при принудительном закрытии (через последние приложения). (Из панели уведомлений Android исчезнет значок фонового режима.)
     сохранен
-    Добавьте как минимум две точки.
+    Добавьте хотя бы две точки.
     ПОВТОРИТЬ
     • Обновленный режим планирования маршрута позволяет использовать разные типы навигации для каждого сегмента и прикрепляет любой трек к дорогам
 \n

From 2b6ecdc2ffbe339aafbc9d9cc371838bc3ba6304 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Tue, 15 Sep 2020 14:31:50 +0000
Subject: [PATCH 0124/1366] Translated using Weblate (Turkish)

Currently translated at 99.5% (3469 of 3484 strings)
---
 OsmAnd/res/values-tr/strings.xml | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml
index fd9beef585..1498c8591c 100644
--- a/OsmAnd/res/values-tr/strings.xml
+++ b/OsmAnd/res/values-tr/strings.xml
@@ -3783,7 +3783,7 @@
     Ters güzergah
     Tüm yol, seçilen profil kullanılarak yeniden hesaplanacaktır.
     Sadece sonraki bölüm, seçilen profil kullanılarak yeniden hesaplanacaktır.
-    Düz bir çizgi ile noktaları nasıl birleştireceğinizi veya seçili profille aralarında nasıl güzergah hesaplayacağınızı seçin.
+    Düz bir çizgi ile noktaları nasıl birleştireceğinizi veya aşağıda belirtildiği gibi aralarında nasıl güzergah hesaplayacağınızı seçin.
     Tüm yol
     Sonraki bölüm
     Eşik mesafesi
@@ -3814,4 +3814,17 @@
     Genel yol kaydı için kayıt aralığını seçin (haritadaki seyahat kayıt widget\'ı aracılığıyla etkin).
     Seyahat kaydetmeyi duraklat
     Seyahat kaydetmeyi devam ettir
+    En yakın nokta
+    Adres sil
+    Adres ekle
+    Adres girin
+    Sadece güzergah hattı kaydedilecek, ara noktalar silinecektir.
+    Dosya adı
+    Sistem öntanımlı değeri
+    Sonraki tüm bölümler
+    Önceki bölüm
+    Önceki tüm bölümler
+    Sadece seçili bölüm, seçilen profil kullanılarak yeniden hesaplanacaktır.
+    Sonraki tüm bölümler, seçilen profil kullanılarak yeniden hesaplanacaktır.
+    Önceki tüm bölümler, seçilen profil kullanılarak yeniden hesaplanacaktır.
 
\ No newline at end of file

From a5912b75a3898609b206565dc78fe509b8e10f7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Babos=20G=C3=A1bor?= 
Date: Tue, 15 Sep 2020 20:29:28 +0000
Subject: [PATCH 0125/1366] Translated using Weblate (Hungarian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-hu/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml
index bf5f700fa4..4c6a6e4877 100644
--- a/OsmAnd/res/values-hu/strings.xml
+++ b/OsmAnd/res/values-hu/strings.xml
@@ -3834,7 +3834,7 @@
     Egyszerűsített nyomvonal
     Kész
     elmentve
-    Jelölje ki, hogyan legyenek összekötve a pontok: egyenes vonallal vagy a kiválasztott profilnak megfelelően kiszámított útvonallal.
+    Jelölje ki, hogyan legyenek összekötve a pontok: egyenes vonallal vagy az alábbiak szerint kiszámított útvonallal.
     Teljes nyomvonal
     Megjegyzés: Ha a GPS közvetlenül a felvétel előtt ki volt kapcsolva, akkor rosszabb lehet az első mért pont pontossága. A kódban ezért szeretnénk majd talán várni egy-két másodpercet egy pont rögzítése előtt (vagy a 3 egymást követő pont közül a legjobbat rögzíteni vagy valami hasonló), de ezt még nem programoztuk le.
     Cím törlése

From fd3d3f65c247814fd861fcaa81410200929c6cae Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Tue, 15 Sep 2020 12:25:04 +0000
Subject: [PATCH 0126/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-uk/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml
index 1b1ca18e75..678d5dfc72 100644
--- a/OsmAnd/res/values-uk/strings.xml
+++ b/OsmAnd/res/values-uk/strings.xml
@@ -3828,7 +3828,7 @@
     Зберегти як новий трек
     Весь трек буде перераховано за допомогою вибраного профілю.
     Лише наступний сегмент буде перераховано за допомогою обраного профілю.
-    Виберіть спосіб з\'єднання точок: прямою лінією чи розраховувати маршрут між ними за допомогою вибраного профілю.
+    Виберіть спосіб з\'єднання точок: прямою лінією чи обчислити маршрут між ними за, як зазначено далі.
     Зображення вулиць
     Ви дійсно бажаєте відхилити всі зміни у запланованому маршруті, закривши його\?
     Для зворотного напрямку
@@ -3881,13 +3881,13 @@
     Буде збережено лише лінію маршруту, а проміжні точки буде видалено.
     Назва файлу
     Повторити
-    • Оновлений режим планування маршруту дозволяє застосувати різні типи переходів для кожного сегмента і прив\'язує будь-який трек до доріг
+    • Оновлено функції планування маршруту: дозволено застосувати різні типи переходів для кожного сегмента і прив\'язати будь-який трек до доріг
 \n
-\n• Нові параметри вигляду треків: вибір кольору, товщина стрілки напрямку та позначки початку/завершення
+\n• Нове меню вигляду треків: вибір кольору, товщина, вигляд стрілки напрямку, піктограми початку/завершення
 \n
 \n• Покращено оглядовість велосипедних вузлів
 \n
-\n• Контекстне меню для треків з основною інформацією
+\n• На треки тепер можна натискати, є контекстне меню з основною інформацією.
 \n
 \n• Вдосконалено алгоритми пошуку
 \n

From 0cd2f655ae1beb34c18943cb077da9798c91b523 Mon Sep 17 00:00:00 2001
From: ace shadow 
Date: Tue, 15 Sep 2020 20:47:00 +0000
Subject: [PATCH 0127/1366] Translated using Weblate (Slovak)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-sk/strings.xml | 35 ++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml
index cc7c2f013a..454bf3203b 100644
--- a/OsmAnd/res/values-sk/strings.xml
+++ b/OsmAnd/res/values-sk/strings.xml
@@ -3780,17 +3780,17 @@
     Prepínač pre zobrazenie alebo skrytie vrstvy Mapillary na mape.
     Smerovanie
     %1$s vymazané
-    Pre úplné odstránenie údajov o rýchlostných radaroch je potrebný reštart.
+    Reštartovať aplikáciu pre úplné odstránenie údajov o rýchlostných radaroch.
     Odinštalovať a reštartovať
     Odinštalovať
     Zadajte aká dĺžka vozidla musí byť povolená na trase.
     Limit dĺžky
     Toto zariadenie neobsahuje rýchlostné radary.
     Kolieskové korčule
-    Umožní ovládať priblíženie mapy tlačidlami hlasitosti zariadenia.
+    Ovládať priblíženie mapy tlačidlami hlasitosti zariadenia.
     Tlačidlá hlasitosti na približovanie
     Zadajte dĺžku vášho vozidla, pretože na trase môžu byť obmedzenia pre dlhé vozidlá.
-    Vymazať ďalší cieľový bod
+    Vymazať najbližší cieľový bod
     Prosím zadajte názov pre bod
     Aktuálny cieľový bod na trase bude vymazaný. Ak je to posledný cieľ, navigácia sa zastaví.
     Stiahnuť mapy Wikipédia
@@ -3800,8 +3800,8 @@
     Invalidný vozík
     Invalidný vozík dopredu
     Motokára
-    Zatvorená OSM poznámka
-    Pre pokračovanie musíte zadať pracovné dni
+    OSM poznámka zatvorená
+    Zadať pracovné dni pre pokračovanie
     Trasa medzi bodmi
     Naplánovať trasu
     Pridať do stopy
@@ -3824,23 +3824,21 @@
     Otočiť trasu
     Celá stopa bude prepočítaná pomocou zvoleného profilu.
     Len nasledujúci úsek bude prepočítaný pomocou zvoleného profilu.
-    Zvoľte ako spojiť body, priamou čiarou alebo vypočítať trasu medzi nimi pomocou zvoleného profilu.
+    Zvoľte ako spojiť body, priamou čiarou alebo vypočítať trasu medzi nimi ako je určené ďalej.
     Celá stopa
     Ďalší úsek
-    Pre použitie tejto možnosti musí OsmAnd prichytiť vašu stopu na cesty v mape.
-\n
-\n V ďalšom kroku budete musieť zvoliť navigačný profil pre detekciu povolených ciest a hraničnú vzdialenosť pre aproximovanie vašej stopy cestami.
+    Ďalej, pre použitie tejto možnosti pripojte vašu stopu k najbližšej povolenej ceste s niektorým vaším navigačným profilom.
     Hraničná vzdialenosť
     Navigačný profil
     Zvoľte súbor stopy, pre ktorú bude pridaný nový úsek.
     Snímky z úrovne ulice
-    Naozaj chcete zatvoriť plánovanie trasy bez uloženia\? Všetky zmeny sa stratia.
+    Naozaj chcete zahodiť všetky zmeny v plánovanej trasy jej zatvorením\?
     V prípade opačného smeru
     Trasa zo stopy
     Pridať prechodný bod stopy
     Nasledovať stopu
     Zvoľte súbor stopy pre nasledovanie
-    Zvoľte súbor stopy pre nasledovanie, alebo nejaký importujte.
+    Zvoľte súbor stopy pre nasledovanie alebo nejaký importujte z vášho zariadenia.
     Zvoliť inú stopu
     Navigovať z mojej polohy k stope
     Bod stopy pre navigovanie
@@ -3886,4 +3884,19 @@
     Pokračovať v nahrávaní výletu
     Prosím pridajte aspoň dva body.
     Vykonať znova
+    • Vylepšená funkcia plánovania trasy: umožňuje použiť rôzne typy navigácie pre úseky trasy a začlenenie stôp
+\n
+\n • Nové menu pre vzhľad stôp: zvoľte farbu, hrúbku, smerové šípky, ikony štartu a cieľa
+\n
+\n • Zlepšená viditeľnosť bodov pre bicykle.
+\n
+\n • Stopy je teraz možné aktivovať, pre kontextové menu sú základnými údajmi.
+\n
+\n • Zlepšený algoritmus vyhľadávania
+\n
+\n • Zlepšené možnosti nasledovania stopy v navigácii
+\n
+\n • Opravené problému s importom a exportom nastavení profilov
+\n
+\n
 
\ No newline at end of file

From fd000b9554022a70150d894dcf3f128eb30d66e3 Mon Sep 17 00:00:00 2001
From: Softmap 
Date: Tue, 15 Sep 2020 23:39:06 +0000
Subject: [PATCH 0128/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index 57b4c76c7d..b64a6f63a3 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -3815,7 +3815,7 @@
     عكس الطريق
     سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد.
     سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد.
-    حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها مع ملف التعريف المحدد.
+    حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها على النحو المحدد أدناه.
     مسار كامل
     المقطع التالي
     بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد ملفات تعريف التنقل الخاصة بك لاستخدام هذا الخيار.
@@ -3873,17 +3873,17 @@
     اسم الملف
     الرجاء إضافة نقطتين على الأقل.
     إعادة
-    • وضع مخطط المسار المحدث يسمح باستخدام أنواع الملاحة المختلفة لكل جزء ويربط أي مسار بالطرق
+    • ميزة تخطيط المسار المحدثة: تسمح باستخدام أنواع الملاحة المختلفة لكل جزء وكذا اظافة طرق
 \n
-\n• خيارات المظهر الجديدة للمسارات: تحديد اللون، السماكة ستقوم بتفعيل أسهم التوجيه و علامات البداية والنهاية
+\n• قائمة مظهر جديدة للمسارات: تحديد اللون، السماكة، اظهار أسهم التوجيه، أيقونات الانطلاق والنهاية
 \n
 \n• تحسين رؤية عقد الدراجات
 \n
-\n• قائمة السياق للمسارات بمعلومات أساسية
+\n• المسارات قابلة للنقر عليها الان وقائمة سياق بمعلومات أساسية
 \n
-\n• تحسين خوارزميات البحث
+\n• خوارزميات بحث محسنة
 \n
-\n• تم تحسين خيارات متابعة المسار أثناء الملاحة
+\n• تم تحسين خيارات متابعة المسار خلال الملاحة
 \n
 \n• تم إصلاح المشكلات المتعلقة باستيراد/تصدير إعدادات الملف الشخصي
 \n

From f630d57b605e8f508c943d3f4357483ed1ba31d1 Mon Sep 17 00:00:00 2001
From: iman 
Date: Tue, 15 Sep 2020 14:26:12 +0000
Subject: [PATCH 0129/1366] Translated using Weblate (Persian)

Currently translated at 97.3% (3392 of 3484 strings)
---
 OsmAnd/res/values-fa/strings.xml | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml
index 4cc7cc83c8..dec0c68cd6 100644
--- a/OsmAnd/res/values-fa/strings.xml
+++ b/OsmAnd/res/values-fa/strings.xml
@@ -3843,23 +3843,23 @@
     یک فایل رد انتخاب کنید تا باز شود.
     تمام
     بَرنویسی رد
-    آهنگ ذخیره شده را باز کنید
-    ذخیره شده
-    لطفا حداقل دو امتیاز اضافه کنید.
-    آماده
-    "به روز شده برنامه یک عملکرد مسیر: اجازه می دهد تا از انواع مختلف پیمایش در هر بخش و گنجاندن مسیرها استفاده کنید
+    بازکردن رد ذخیره‌شده
+    ذخیره شد
+    لطفاً حداقل دو نقطه اضافه کنید.
+    ازنو
+    • قابلیت «طرح‌ریزی مسیر» روزآمد شد: امکان استفاده از شیوهٔ ناوبری متفاوت برای هر پاره از مسیر و در کار آوردن ردها اضافه شده است.
 \n
-\n  • منوی New Appearance برای آهنگ ها، رنگ ، ضخامت ، فلش جهت نمایش ، نمادهای شروع / پایان استفاده می شوئ
+\n• منوی جدید «ظاهر» برای ردها: رنگ و ضخامت را مشخص کنید، فلش‌های جهت‌نما و نمادهای آغاز/پایان را نمایش دهید.
 \n
-\n  • بهبود دید نود های دوچرخه.
+\n• پدیداری گره‌های شبکهٔ دوچرخه بهبود یافته است.
 \n
-\n  • آهنگ ها اکنون قابل لمس هستند ، دارای منوی زمینه با اطلاعات اولیه هستند.
+\n• اکنون می‌توان ردها را لمس کرد و منوی زمینه با اطلاعات پایه را مشاهده کرد.
 \n
-\n  • بهبود الگوریتم های جستجو
+\n• الگوریتم «جستجو» بهبود یافته است.
 \n
-\n  • گزینه های ردیابی را در پیمایش بهبود بخشید
+\n• گزینه‌های «دنبال‌کردن رد» در ناوبری بهبود یافته است.
 \n
-\n  • مشکلات مربوط به واردات / صادرات تنظیمات نمایه برطرف شده است
+\n• مشکلاتی مربوط به درون‌برد/برون‌برد تنظیمات پروفایل برطرف شده است.
 \n
-\n"
+\n
 
\ No newline at end of file

From 8e698a288e978ef089e0b58ef2ba9f5044300321 Mon Sep 17 00:00:00 2001
From: Ajeje Brazorf 
Date: Tue, 15 Sep 2020 14:00:50 +0000
Subject: [PATCH 0130/1366] Translated using Weblate (Sardinian)

Currently translated at 99.7% (3474 of 3484 strings)
---
 OsmAnd/res/values-sc/strings.xml | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml
index facff58683..4036899b1a 100644
--- a/OsmAnd/res/values-sc/strings.xml
+++ b/OsmAnd/res/values-sc/strings.xml
@@ -3783,27 +3783,27 @@
     Disinstalla
     Orientamentu
     %1$s iscantzelladu
-    Depes torrare a allùghere pro iscantzellare de su totu sos datos de sos autovelox.
+    Torra a allùghere s\'aplicatzione pro iscantzellare totu sos datos de sos autovelox.
     Disinstalla e torra a allùghere
     Dillinda sa longària de su veìculu permìtida in sas àndalas.
     Lìmite de longària
     Custu dispositivu non tenet autovelox.
     Pàtinos in lìnia
-    Abìlita pro controllare su livellu de ismanniamentu cun sos butones de su volume de su dispositivu.
+    Controlla su livellu de ismanniamentu de sa mapa cun sos butones de su volume de su dispositivu.
     Butones de su volume pro s\'ismanniamentu
     Inserta sa longària de su veìculu tuo. Bi diant pòdere èssere unas cantas restritziones de sas àndalas pro sos veìculos longos.
-    Iscantzella su puntu de destinatzione imbeniente
+    Iscantzella su puntu de destinatzione prus a curtzu
     Fruni unu nùmene pro su puntu
     Su puntu de destinatzione atuale in s\'àndala at a èssere iscantzelladu. Si at a èssere sa destinatzione, sa navigatzione s\'at a firmare.
     Iscàrriga sas mapas de Wikipedia
-    Otene informatziones a pitzu de puntos de interesse dae Wikipedia. Est sa ghia non in lìnia tua de mantènnere in butzaca - abìlita s\'estensione Wikipedia e ispassia·ti cun sos artìculos a pitzu de sos ogetos a fùrriu de tie.
+    Otene informatziones a pitzu de puntos de interesse dae Wikipedia. Est sa ghia non in lìnia tua de mantènnere in butzaca - allughe s\'estensione Wikipedia e ispassia·ti cun sos artìculos a pitzu de sos ogetos a fùrriu de tie.
     Moto enduro
     Motorinu
     Cadira a rodas cara a in antis
     Cadira a rodas
     Go-kart
     Nota de OSM serrada
-    Depes impostare sas dies de traballu pro sighire
+    Imposta sas dies de traballu pro sighire
     Àndala intre puntos
     Pranìfica un\'àndala
     Annanghe a una rasta
@@ -3826,7 +3826,7 @@
     Fùrria s\'àndala
     Sa rasta intrea at a èssere torrada a calculare impreende su profilu ischertadu.
     Petzi su segmentu imbeniente at a èssere torradu a calculare impreende su profilu ischertadu.
-    Ischerta comente connètere sos puntos: cun una lìnia reta o calculende un\'àndala intre issos cun su profilu ischertadu.
+    Ischerta comente connètere sos puntos: cun una lìnia reta o calculende un\'àndala intre issos comente dislindadu inoghe in suta.
     Rasta intrea
     Segmentu imbeniente
     Pro impreare custa optzione OsmAnd tenet bisòngiu de alliniare sa rasta tua a sos caminos de sa mapa.
@@ -3836,7 +3836,7 @@
     Profilu de navigatzione
     Ischerta unu documentu de rasta in ue annànghere su segmentu nou.
     Fotografias a livellu de sas carreras
-    Ses seguru de chèrrere serrare sa pianificatzione de s\'àndala chene sarvare\? As a pèrdere totu sas modìficas.
+    Ses seguru de chèrrere serrare sa pianificatzione de s\'àndala e pèrdere totu sas modìficas\?
     In casu de diretzione furriada
     Rastas
     Càrriga sa rasta in unu documentu GPX
@@ -3859,7 +3859,7 @@
     Àndala de una rasta
     Sighi sa rasta
     Issèbera su documentu de sa rasta de sighire
-    Issèbera su documentu de sa rasta de sighire, o importa·nde unu.
+    Issèbera su documentu de sa rasta de sighire o importa·lu dae su dispositivu tuo.
     Ischerta un\'àtera rasta
     Nàviga dae sa positzione mea a sa rasta
     Puntu de sa rasta de navigare

From 5c978babf2d29e77080f6457c8870bec41d80b88 Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Tue, 15 Sep 2020 12:15:48 +0000
Subject: [PATCH 0131/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-uk/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml
index 086eba5d78..1bcbb91957 100644
--- a/OsmAnd/res/values-uk/phrases.xml
+++ b/OsmAnd/res/values-uk/phrases.xml
@@ -3830,4 +3830,5 @@
     Дошка відправлень
     Поповнення питної води
     Невеликі електроприлади
+    Вулик
 
\ No newline at end of file

From 17951876c7f823fd156609e45cb473efa6d249c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Tue, 15 Sep 2020 15:55:40 +0000
Subject: [PATCH 0132/1366] Translated using Weblate (Estonian)

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-et/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml
index 5ea981e678..226d25f3ad 100644
--- a/OsmAnd/res/values-et/phrases.xml
+++ b/OsmAnd/res/values-et/phrases.xml
@@ -3824,4 +3824,5 @@
     Väljuvate reiside tabloo
     Joogivee täitmine
     Väikesed elektriseadmed
+    Mesitaru
 
\ No newline at end of file

From 3ca9513d4ae8217f47d2a787ea5ddab7242f6d0e Mon Sep 17 00:00:00 2001
From: Franco 
Date: Tue, 15 Sep 2020 17:52:26 +0000
Subject: [PATCH 0133/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-es-rAR/strings.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml
index 4eed292de2..6b55481e6e 100644
--- a/OsmAnd/res/values-es-rAR/strings.xml
+++ b/OsmAnd/res/values-es-rAR/strings.xml
@@ -3829,7 +3829,7 @@
     Ruta inversa
     Recalcular sólo el siguiente segmento usando el perfil elegido.
     Recalcular toda la traza usando el perfil elegido.
-    Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido.
+    Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos como se detalla a continuación.
     Traza completa
     Siguiente segmento
     A continuación, ajusta la traza al camino permitido más cercano con un perfil de navegación.
@@ -3889,13 +3889,13 @@
     %s archivo(s) de trazas marcado(s)
     Añade al menos dos puntos.
     Rehacer
-    • Se ha actualizado el modo «Planificar ruta»: ahora permite usar diferentes tipos de navegación para cada segmento y adjunta cualquier traza a los caminos
+    • Se ha actualizado la función «Planificar ruta»: permite utilizar diferentes tipos de navegación por segmento y la inclusión de trazas
 \n
-\n • Nuevas opciones en el aspecto de las trazas: elegir el color, cambiar el grosor de las flechas de dirección y las marcas de inicio/fin.
+\n • Nuevo menú con el aspecto de las trazas: elegir el color, el grosor, mostrar las flechas de dirección y los iconos de inicio/fin.
 \n
-\n • Mejoras en la visibilidad de los nodos de bicicleta
+\n • Mejoras en la visibilidad de los nodos de bicicleta.
 \n
-\n • Menú contextual con información básica para las trazas
+\n • Las trazas ahora se pueden pulsar, contiene un menú contextual con información básica.
 \n
 \n • Algoritmos de búsqueda mejorados
 \n

From 30a61cd6a7403d9ecf0b71e97ac9156928be79bb Mon Sep 17 00:00:00 2001
From: Franco 
Date: Tue, 15 Sep 2020 17:53:13 +0000
Subject: [PATCH 0134/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-es-rAR/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml
index cfe9475d1e..e1839d42f2 100644
--- a/OsmAnd/res/values-es-rAR/phrases.xml
+++ b/OsmAnd/res/values-es-rAR/phrases.xml
@@ -3849,4 +3849,5 @@
     Tablero de partidas
     Recarga de agua potable
     Pequeños electrodomésticos
+    Panal de abejas
 
\ No newline at end of file

From 36ef16b28a2d9b99ed1a2fd2faeada725a0bf4cb Mon Sep 17 00:00:00 2001
From: Eduardo Addad de Oliveira 
Date: Tue, 15 Sep 2020 22:06:47 +0000
Subject: [PATCH 0135/1366] Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt-rBR/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml
index ea83d5b1b6..1182d20a65 100644
--- a/OsmAnd/res/values-pt-rBR/strings.xml
+++ b/OsmAnd/res/values-pt-rBR/strings.xml
@@ -3819,7 +3819,7 @@
     Rota reversa
     A trilha inteira será recalculada usando o perfil selecionado.
     Apenas o próximo segmento será recalculado usando o perfil selecionado.
-    Selecione como conectar pontos, com uma linha reta, ou calcular uma rota entre eles com o perfil selecionado.
+    Selecione como conectar pontos, por uma linha reta, ou calcular uma rota entre eles conforme especificado abaixo.
     Trilha inteira
     Próximo segmento
     Para usar esta opção, OsmAnd precisa ajustar sua trilha para as estradas do mapa.
@@ -3849,7 +3849,7 @@
     Escolha o arquivo de trilha a seguir
     Escolha o arquivo de trilha a seguir ou importe-o de seu dispositivo.
     Selecionar outra trilha
-    Navegue de minha localização até a trilha
+    Navegue da minha posição até a trilha
     Ponto da trilha para navegar
     Início da pista
     Ponto próximo
@@ -3881,13 +3881,13 @@
     está salvo
     Adicione pelo menos dois pontos.
     Refazer
-    "• O modo de rota de plano atualizado permite o uso de diferentes tipos de navegação para cada segmento e anexa qualquer trilha às estradas
+    "• Função de planejamento de rota atualizada: permite o uso de diferentes tipos de navegação por segmento e a inclusão de trilhas
 \n
-\n • Novas opções de aparência para trilhas: selecione a cor, a espessura, ative as setas de direção e as marcas de início/fim
+\n  • Novo menu de aparência para trilhas: selecione cor, espessura, setas de direção de exibição, ícones de início / término
 \n
-\n  • Melhor visibilidade dos nós da bicicleta
+\n  • Melhor visibilidade dos nós da bicicleta.
 \n
-\n  • Menu de contexto para trilhas com informações básicas
+\n  • As trilhas agora podem ser tocadas, têm menu de contexto com informações básicas.
 \n
 \n  • Algoritmos de pesquisa aprimorados
 \n

From 697f96e7b7b5c63a6945253d42c29c1f25ef2874 Mon Sep 17 00:00:00 2001
From: Eduardo Addad de Oliveira 
Date: Tue, 15 Sep 2020 22:08:09 +0000
Subject: [PATCH 0136/1366] Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-pt-rBR/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml
index 27475442c8..c6eea35aa5 100644
--- a/OsmAnd/res/values-pt-rBR/phrases.xml
+++ b/OsmAnd/res/values-pt-rBR/phrases.xml
@@ -3842,4 +3842,5 @@
     Quadro de partidas
     Recarga de água potável
     Pequenos aparelhos elétricos
+    Colmeia
 
\ No newline at end of file

From ea819ddb1c7169943e3602154de21550a3d6b301 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Tue, 15 Sep 2020 15:51:23 +0000
Subject: [PATCH 0137/1366] Translated using Weblate (Estonian)

Currently translated at 98.4% (3429 of 3484 strings)
---
 OsmAnd/res/values-et/strings.xml | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml
index b8c7fbfd34..2c829dcfd0 100644
--- a/OsmAnd/res/values-et/strings.xml
+++ b/OsmAnd/res/values-et/strings.xml
@@ -166,7 +166,7 @@
     Näita OSM märkmed
     Peida OSM Notes
     Täname sind tagasiside eest
-    Punkti või teed ei leitud.
+    Sõlme või teed ei leidunud.
     Otsingutulemused puuduvad\?
 \nJaga tagasisidet
     Laienda otsingu raadiust kuni %1$s
@@ -3738,4 +3738,19 @@
     Kiirtegevusi saad eksportida või importida koos rakenduse profiilidega.
     Kas sa oled kindel, et soovid pöördumatult kustutada %d kiirtegevust\?
     Vali kas soovid ühendada punkte sirge joonega või arvutada nendevahelist teekonda vastavalt oma valitud profiilile.
+    • Uuendatud teekonnaplaneerija: võimaldab kasutada igal segmendil erinevat liikumisviisi ning radade kaasamist
+\n
+\n • Uus radade kujunduse seadistamise menüü: valida saad värve, joone paksust, suunanoolte kuvamist ning alguse ja lõpu ikoone
+\n
+\n • Rattasõlmede parandatud nähtavus
+\n
+\n • Radasid saad nüüd puudutada, misjärel kuvatakse põhiteabega kontekstimenüü
+\n
+\n • Parandatud on otsingualgoritme
+\n
+\n • Parandatud raja jälgimise valikud navigeerimisel
+\n
+\n • Parandatud on profiili seadistuste impordi ja ekspordiga seotud vead
+\n
+\n
 
\ No newline at end of file

From 68598ced91231d845fc1140b8fb5a7e02b6c7513 Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Tue, 15 Sep 2020 16:44:44 +0000
Subject: [PATCH 0138/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-pt/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml
index 744b9de0ca..0eb960c2f2 100644
--- a/OsmAnd/res/values-pt/phrases.xml
+++ b/OsmAnd/res/values-pt/phrases.xml
@@ -3827,4 +3827,5 @@
     Quadro de partidas
     Reabastecimento de água potável
     Pequenos aparelhos elétricos
+    Colmeia
 
\ No newline at end of file

From 196fb9cb1f360b9a5fcb0e059b5cbcbaa9096301 Mon Sep 17 00:00:00 2001
From: Mitsuha Miamizu 
Date: Tue, 15 Sep 2020 12:28:13 +0000
Subject: [PATCH 0139/1366] Translated using Weblate (Persian)

Currently translated at 29.2% (78 of 267 strings)

Translation: OsmAnd/Telegram
Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/fa/
---
 OsmAnd-telegram/res/values-fa/strings.xml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/OsmAnd-telegram/res/values-fa/strings.xml b/OsmAnd-telegram/res/values-fa/strings.xml
index 824443b2c5..af2e8f441c 100644
--- a/OsmAnd-telegram/res/values-fa/strings.xml
+++ b/OsmAnd-telegram/res/values-fa/strings.xml
@@ -73,4 +73,9 @@
     یکاهای طول را تغییر دهید.
     یکاهای طول
     ظاهر
+    آخرین پاسخ:٪ 1 $ s پیش
+    آخرین به روزرسانی از تلگرام:٪ 1 $ s پیش
+    آخرین پاسخ: %1$s
+    آخرین به روز رسانی در تلگرام:%1$s
+    اشتباه بودن
 
\ No newline at end of file

From 16cffe3bc6b0f04e7fffbacdeeae86686d4c29be Mon Sep 17 00:00:00 2001
From: xmd5a 
Date: Wed, 16 Sep 2020 10:14:07 +0300
Subject: [PATCH 0140/1366] Add phrase

---
 OsmAnd/res/values/phrases.xml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml
index cd482756ec..3f4394578a 100644
--- a/OsmAnd/res/values/phrases.xml
+++ b/OsmAnd/res/values/phrases.xml
@@ -4255,4 +4255,7 @@
 
 	Beehive
 
+	Nut store
+
+
 

From 137faffe3b09f2bd76f0b5d5c36ee8288cf4f22e Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Wed, 16 Sep 2020 10:55:15 +0300
Subject: [PATCH 0141/1366] Type_for_not_selected_profile

---
 OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index fe3c067e9e..83a470b903 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -735,7 +735,7 @@ public class MapActivityActions implements DialogProvider {
 		for (final ApplicationMode appMode : activeModes) {
 			if (appMode.isCustomProfile()) {
 				modeDescription = String.format(app.getString(R.string.profile_type_descr_string),
-						Algorithms.capitalizeFirstLetterAndLowercase(appMode.getParent().toHumanString()));
+						Algorithms.capitalizeFirstLetterAndLowercase(appMode.getRoutingProfile()));
 			} else {
 				modeDescription = getString(R.string.profile_type_base_string);
 			}

From d61d76f558032f7f62191d4e0c697cd30a9ea9c7 Mon Sep 17 00:00:00 2001
From: Hinagiku Zeppeki 
Date: Wed, 16 Sep 2020 08:08:25 +0000
Subject: [PATCH 0142/1366] Translated using Weblate (Japanese)

Currently translated at 98.1% (3420 of 3484 strings)
---
 OsmAnd/res/values-ja/strings.xml | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml
index 843dada170..636fc3995b 100644
--- a/OsmAnd/res/values-ja/strings.xml
+++ b/OsmAnd/res/values-ja/strings.xml
@@ -472,7 +472,7 @@ POIの更新は利用できません
     POI 変更
     他のタグは全て保存されました
     コミット
-    削除する
+    削除
     フィルタ
     名前をつけて保存
     選択したフィルタを削除しますか?
@@ -3820,7 +3820,7 @@ POIの更新は利用できません
     長さ制限
     ベアリング
     %1$sを削除しました
-    スピードカメラのデータを完全に削除するには、再起動が必要です。
+    アプリを再起動し、すべてのスピードカメラデータを削除します。
     アンインストールして再起動
     このアプリには、スピードカメラに関する情報はありません。
     インラインスケート
@@ -3835,7 +3835,7 @@ POIの更新は利用できません
     経路
     経路
     経路
-    GPX
+    REC
     GPXファイルへの経路ログ
     ルート経路
     経路ファイルを追加
@@ -3875,13 +3875,13 @@ POIの更新は利用できません
     保存した経路を開く
     少なくとも2つの地点を追加してください。
     繰り返し
-    • アップデートで追加されたルート計画モードは、セグメントごとに異なるナビゲーションタイプを使用でき、おおまかな指定を実際の道路に沿って反映可能に。
+    • ルート計画機能を更新 : セグメントごとに異なるナビゲーションタイプを使用し、経路として反映することが可能に
 \n
-\n• 経路の新しい外観オプション : 色、厚さを選択し、方向矢印のオン、マークの開始/終了など
+\n• 経路の新しい外観オプション : 色、太さ、表示方向矢印、開始/終了アイコン選択
 \n
-\n• 自転車ノードの可視性の向上
+\n• 自転車ノードの視認性を向上
 \n
-\n• 基本情報を含む経路のコンテキストメニュー追加
+\n• 経路のタップで、基本情報を含むコンテキストメニューの表示
 \n
 \n• 検索アルゴリズムの改善
 \n
@@ -3890,4 +3890,10 @@ POIの更新は利用できません
 \n• プロファイル設定のインポート/エクスポートに関する問題を修正
 \n
 \n
+    簡略化された経路
+    ルートライン(経路)のみが保存され、経由地点は削除されます。
+    %s個の経路ファイルが選択されました
+    ファイル名
+    (最近使用したアプリを介して) OsmAndを終了すると、GPXの記録が一時停止されます(バックグラウンドサービスインジケーターがAndroid通知バーから消えます。)
+    一般的な経路記録の記録間隔を定義します(マップ画面の\'GPX\'ボタンを使用)
 
\ No newline at end of file

From 4a7f50b44e769967d77352ac3f4a8b03254712c8 Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Wed, 16 Sep 2020 07:56:54 +0000
Subject: [PATCH 0143/1366] Translated using Weblate (Russian)

Currently translated at 99.8% (3478 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index ea571d0bac..bfceebc942 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -73,8 +73,8 @@
     Поиск почтового индекса
     Записать аудио
     Записать видео
-    Фотозаметка
-    Заметка OSM
+    Сделать фото
+    Добавить заметку OSM
     Функции парковки
     Благодарим вас за покупку платной версии OsmAnd.
     Не показывать сообщения при запуске
@@ -233,11 +233,11 @@
     Сохранить фильтр
     Удалить фильтр
     Новый фильтр
-    Изменение позиции
+    Изменить положение
     Текущий путь
     Навигация OsmAnd Live
     Уровень заряда батареи
-    Переместите карту, чтобы изменить положение маркера
+    Двигайте карту, чтобы изменить позицию маркера
     
     Магнитный пеленг
     Курсовой угол
@@ -317,8 +317,8 @@
     Открыть внешний проигрыватель
     Удалить эту запись?
     недоступно
-    Аудиозаметка
-    Видеозаметка
+    Записать аудио
+    Записать видео
     Слой аудиозаписей
     Запись не может быть воспроизведена.
     Удалить запись
@@ -466,7 +466,7 @@
     Неопределённо
     Текущий центр карты
     Начало:
-    Поиск рядом
+    Искать рядом
     Маршрут успешно сохранён в «%1$s».
     Имя файла: 
     Файл с таким именем уже существует.
@@ -738,7 +738,7 @@
     Загрузить детальные карты регионов
     Поиск сигнала…
     Искать вокруг текущего центра карты
-    Поиск рядом
+    Искать рядом
     По умолчанию
     Портрет
     Ландшафт
@@ -2170,7 +2170,7 @@
     Не пересчитывать маршрут при обратном направлении движения
     Предотвращает автоматический пересчёт маршрута при обратном направлении движения.
     Пункт назначения не задан
-    Звуковая индикация направления
+    Озвучивать направление
     Индицировать звуком направление на целевую точку.
     Тактильная индикация направления
     Индицировать вибрацией направление на целевую точку.
@@ -3846,7 +3846,7 @@
     Добавить файлы треков
     Импортируйте или запишите файлы треков
     Добавить путевую точку
-    Добавить к маршруту
+    Добавить точку к треку
     Запись поездки
     Сохранить как файл трека
     Следовать по маршруту

From f4e82e6cac2a973cac4ead81a3a56ce4d5fe4f81 Mon Sep 17 00:00:00 2001
From: Zmicer Turok 
Date: Wed, 16 Sep 2020 05:34:47 +0000
Subject: [PATCH 0144/1366] Translated using Weblate (Belarusian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-be/strings.xml | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml
index 47399cfdf0..c80bd4dfe0 100644
--- a/OsmAnd/res/values-be/strings.xml
+++ b/OsmAnd/res/values-be/strings.xml
@@ -3609,7 +3609,7 @@
     Ліміт даўжыні
     Арыентацыя
     Выдалена: %1$s
-    Перазапуск патрабуецца для поўнага выдалення даных камер кантролю хуткасці.
+    Перазапусціце праграму для поўнага выдалення даных камер кантролю хуткасці.
     Кіраванне ўзроўнем маштабавання мапы пры дапамозе кнопак рэгулявання гучнасці.
     Інфармацыя пра славутасці з Вікіпедыі. Гэта ваш кішэнны даведнік - уключыце ўбудову вікіпедыі і чытайце артыкулы пра аб’екты вакол вас.
     Матацыкл Эндура
@@ -3699,22 +3699,20 @@
     Зваротны маршрут
     Увесь след будзе пералічаны з выкарыстаннем абранага профілю.
     Толькі наступны сегмент будзе пералічаны паводле абранага профілю.
-    Абярыце спосаб злучэння пунктаў. Варыянты: прамая лінія; разлік маршруту паводле абранага профілю.
+    Абярыце спосаб злучэння пунктаў. Варыянты: прамая лінія; разлік маршруту як вызначана ніжэй.
     Увесь след
     Наступны сегмент
-    Для выкарыстання гэтага параметру OsmAnd пракладзе ваш след па дарогах.
-\n
-\n Пасля вам патрэбна абраць профіль навігацыі для вызначэння маршруту з улікам параметраў і абмежаванняў гэтага профілю.
+    Пасля вам патрэбна абраць профіль навігацыі для вызначэння маршруту з улікам параметраў і абмежаванняў гэтага профілю.
     Максімальная дыстанцыя
     Профіль навігацыі
     Абраць файл следу, да якога будзе дададзены новы сегмент.
     Выявы на ўзроўні вуліц
-    Сапраўды закрыць план маршруту без захавання\? Усе змены страцяцца.
+    Усе змены страцяцца. Закрыць план маршруту\?
     У выпадку адваротнага кірунку
     Маршрут следу
     Кіравацца следу
     Абярыце файл следу
-    Абярыце альбо імпартуйце файл следу.
+    Абярыце альбо імпартуйце файл следу са сваёй прылады.
     Абраць іншы след
     Перайдзіце ад маёй пазіцыі да следу
     Пункт следу для навігацыі

From 6022680ec60b1124f70fedf57a9f55c7ece2fecf Mon Sep 17 00:00:00 2001
From: Zmicer Turok 
Date: Wed, 16 Sep 2020 05:31:28 +0000
Subject: [PATCH 0145/1366] Translated using Weblate (Belarusian)

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-be/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-be/phrases.xml b/OsmAnd/res/values-be/phrases.xml
index c1811632b4..b801ecedb5 100644
--- a/OsmAnd/res/values-be/phrases.xml
+++ b/OsmAnd/res/values-be/phrases.xml
@@ -3842,4 +3842,5 @@
     Рэальны час
     Затрымка
     Маленькія электрапрыборы
+    Вулей
 
\ No newline at end of file

From 0db1f3e755077dd9acc14198d1fcdcba4fb65eec Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Wed, 16 Sep 2020 06:31:32 +0000
Subject: [PATCH 0146/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-zh-rTW/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml
index 6bed71474e..33b644b362 100644
--- a/OsmAnd/res/values-zh-rTW/strings.xml
+++ b/OsmAnd/res/values-zh-rTW/strings.xml
@@ -3821,7 +3821,7 @@
     反向路線
     整個軌跡都會使用選定的設定檔重新計算。
     僅下一個片段會使用選定的設定檔重新計算。
-    選取如何連接點,用直線或以選定的設定檔計算其間的路徑。
+    選取如何連接點,透過直線或以下面選定的方法計算其間的路徑。
     整個軌道
     下一段
     接下來,使用您其中一個導航設定檔來將路線貼齊到最近可用的道路上以使用此選項。
@@ -3881,13 +3881,13 @@
     已儲存
     請至少新增兩個點。
     重做
-    • 更新的規劃路線模式允許對不同路段使用不同的導航類型,並可將任何軌跡附加到道路上
+    • 更新「規劃路線」功能:允許每個路段使用不同的導航類型並包含軌跡
 \n
-\n • 新的軌跡外觀選項:選取顏色、厚度、開啟方向箭頭與開始/結束標記
+\n • 新的軌跡外觀選項:選取顏色、厚度、開啟方向箭頭與開始/結束圖示
 \n
 \n • 改善自行車節點的能見度
 \n
-\n • 有基本資訊的軌跡情境選單
+\n • 軌跡現在是可點擊的,且有包含基本資訊的內容選單
 \n
 \n • 改進了搜尋演算法
 \n

From 1e278be5c69fbe2b1f5b4cc2f13342d7cea8d548 Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Wed, 16 Sep 2020 06:33:04 +0000
Subject: [PATCH 0147/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3823 of 3823 strings)
---
 OsmAnd/res/values-zh-rTW/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml
index c078b2c6e7..352282d071 100644
--- a/OsmAnd/res/values-zh-rTW/phrases.xml
+++ b/OsmAnd/res/values-zh-rTW/phrases.xml
@@ -3841,4 +3841,5 @@
     時刻表
     飲用水補充
     小電器
+    蜂箱
 
\ No newline at end of file

From a11dd191ae81183c4749308992b8daae5127a55d Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Wed, 16 Sep 2020 12:12:20 +0300
Subject: [PATCH 0148/1366] Fix latLon formatting in search

---
 .../net/osmand/search/core/SearchCoreFactory.java    | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
index a4916d4187..360fafbdf9 100644
--- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
+++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
@@ -33,6 +33,7 @@ import net.osmand.util.LocationParser.ParsedOpenLocationCode;
 import net.osmand.util.MapUtils;
 
 import java.io.IOException;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -1407,6 +1408,7 @@ public class SearchCoreFactory {
 		private LatLon olcPhraseLocation;
 		private ParsedOpenLocationCode cachedParsedCode;
 		private final List citySubTypes = Arrays.asList("city", "town", "village");
+		private final DecimalFormat latLonFormatter = new DecimalFormat("#.0####");
 
 		public SearchLocationAndUrlAPI() {
 			super(ObjectType.LOCATION, ObjectType.PARTIAL_LOCATION);
@@ -1498,7 +1500,7 @@ public class SearchCoreFactory {
 						sp.priority = SEARCH_LOCATION_PRIORITY;
 
 						sp.object = sp.location = ll;
-						sp.localeName = ((float) sp.location.getLatitude()) + ",  ";
+						sp.localeName = formatLatLon(sp.location.getLatitude()) + ",  ";
 						sp.objectType = ObjectType.PARTIAL_LOCATION;
 						resultMatcher.publish(sp);
 					}
@@ -1510,7 +1512,7 @@ public class SearchCoreFactory {
 			SearchResult sp = new SearchResult(phrase);
 			sp.priority = SEARCH_LOCATION_PRIORITY;
 			sp.object = sp.location = l;
-			sp.localeName = ((float) sp.location.getLatitude()) + ", " + ((float) sp.location.getLongitude());
+			sp.localeName = formatLatLon(sp.location.getLatitude()) + ", " + formatLatLon(sp.location.getLongitude());
 			sp.objectType = ObjectType.LOCATION;
 			sp.wordsSpan = lw;
 			resultMatcher.publish(sp);
@@ -1525,7 +1527,7 @@ public class SearchCoreFactory {
 				sp.object = pnt;
 				sp.wordsSpan = text;
 				sp.location = new LatLon(pnt.getLatitude(), pnt.getLongitude());
-				sp.localeName = ((float)pnt.getLatitude()) +", " + ((float) pnt.getLongitude());
+				sp.localeName = formatLatLon(pnt.getLatitude()) +", " + formatLatLon(pnt.getLongitude());
 				if (pnt.getZoom() > 0) {
 					sp.preferredZoom = pnt.getZoom();
 				}
@@ -1555,6 +1557,10 @@ public class SearchCoreFactory {
 			}
 			return cachedParsedCode == null ? SEARCH_LOCATION_PRIORITY : SEARCH_MAX_PRIORITY;
 		}
+
+		private String formatLatLon(double latLon) {
+			return latLonFormatter.format(latLon);
+		}
 	}
 
 	private static String stripBraces(String localeName) {

From 8403fbf0623a852396f17ebce42ec73239f61345 Mon Sep 17 00:00:00 2001
From: simon 
Date: Wed, 16 Sep 2020 12:29:38 +0300
Subject: [PATCH 0149/1366] executor pla a route bug fix

---
 .../main/java/net/osmand/router/RoutePlannerFrontEnd.java  | 5 ++++-
 OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java    | 7 ++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java
index 5aefb2ac44..663c9ea384 100644
--- a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java
+++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java
@@ -243,6 +243,9 @@ public class RoutePlannerFrontEnd {
 			start = gpxPoints.get(0); 
 		}
 		while (start != null && !gctx.ctx.calculationProgress.isCancelled) {
+			if (Thread.currentThread().isInterrupted()) {
+				return null;
+			}
 			double routeDist = gctx.MAXIMUM_STEP_APPROXIMATION;
 			GpxPoint next = findNextGpxPointWithin(gctx, gpxPoints, start, routeDist);
 			boolean routeFound = false;
@@ -256,7 +259,7 @@ public class RoutePlannerFrontEnd {
 						if (routeFound) {
 							// route is found - cut the end of the route and move to next iteration
 //							start.stepBackRoute = new ArrayList();
-//							boolean stepBack = true; 
+//							boolean stepBack = true;
 							boolean stepBack = stepBackAndFindPrevPointInRoute(gctx, gpxPoints, start, next);
 							if (!stepBack) {
 								// not supported case (workaround increase MAXIMUM_STEP_APPROXIMATION)
diff --git a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
index 7e6b089620..61d8408fe6 100644
--- a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
+++ b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
@@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -44,6 +45,7 @@ public class GpxApproximator {
 
 	private ThreadPoolExecutor singleThreadedExecutor;
 	private GpxApproximationProgressCallback approximationProgress;
+	private Future currentApproximationTask;
 
 	public interface GpxApproximationProgressCallback {
 
@@ -152,7 +154,10 @@ public class GpxApproximator {
 		this.gctx = gctx;
 		startProgress();
 		updateProgress(gctx);
-		singleThreadedExecutor.submit(new Runnable() {
+		if (currentApproximationTask != null) {
+			currentApproximationTask.cancel(true);
+		}
+		currentApproximationTask = singleThreadedExecutor.submit(new Runnable() {
 			@Override
 			public void run() {
 				try {

From f03f30469f4ef318903f7efc92b74431aed81113 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Wed, 16 Sep 2020 13:18:56 +0300
Subject: [PATCH 0150/1366] Remove unnecessary changes

---
 OsmAnd/res/layout/custom_color_picker.xml     |  9 ++-
 OsmAnd/res/values/styles.xml                  | 15 -----
 OsmAnd/src/net/osmand/AndroidUtils.java       | 23 --------
 .../osmand/plus/base/ContextMenuFragment.java | 58 ++++++++-----------
 .../plus/base/OnNeedScrollUiAdapter.java      |  5 --
 .../plus/base/OnVisibilityChangeListener.java |  5 --
 .../plus/track/CustomColorBottomSheet.java    |  4 +-
 .../plus/track/TrackAppearanceFragment.java   | 44 +++++++-------
 .../osmand/plus/track/TrackColoringCard.java  | 41 +++++++++++--
 .../net/osmand/plus/track/TrackWidthCard.java | 34 ++++-------
 10 files changed, 102 insertions(+), 136 deletions(-)
 delete mode 100644 OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java
 delete mode 100644 OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java

diff --git a/OsmAnd/res/layout/custom_color_picker.xml b/OsmAnd/res/layout/custom_color_picker.xml
index 9e6c1bb9b1..f2133e410b 100644
--- a/OsmAnd/res/layout/custom_color_picker.xml
+++ b/OsmAnd/res/layout/custom_color_picker.xml
@@ -34,20 +34,23 @@
 
 		
 
 			?android:textColorSecondary
     
 
-
-    
-
-    
-
-    
-
 
diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java
index 87ade44343..3dea16fb15 100644
--- a/OsmAnd/src/net/osmand/AndroidUtils.java
+++ b/OsmAnd/src/net/osmand/AndroidUtils.java
@@ -63,7 +63,6 @@ import androidx.core.view.ViewCompat;
 
 import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
-import net.osmand.plus.base.OnVisibilityChangeListener;
 import net.osmand.util.Algorithms;
 
 import java.io.File;
@@ -603,12 +602,6 @@ public class AndroidUtils {
 		return coordinates;
 	}
 
-	public static boolean isPointInsideView(@NonNull View view, float x, float y) {
-		boolean matchVertical = y >= view.getY() && y <= view.getY() + view.getHeight();
-		boolean mathHorizontal = x >= view.getX() && x <= view.getX() + view.getWidth();
-		return matchVertical && mathHorizontal;
-	}
-
 	public static void enterToFullScreen(Activity activity, View view) {
 		if (Build.VERSION.SDK_INT >= 21) {
 			requestLayout(view);
@@ -896,20 +889,4 @@ public class AndroidUtils {
 		}
 		return builder;
 	}
-
-	public static void addVisibilityChangeListener(final @NonNull View parent,
-	                                               final @NonNull View v,
-	                                               final @NonNull OnVisibilityChangeListener listener) {
-		parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
-			int visibility = v.getVisibility();
-
-			@Override
-			public void onGlobalLayout() {
-				if (visibility != v.getVisibility()) {
-					visibility = v.getVisibility();
-					listener.onVisibilityChange(visibility);
-				}
-			}
-		});
-	}
 }
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
index b59e20202a..e1436bb400 100644
--- a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
@@ -24,7 +24,6 @@ import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.OverScroller;
-import android.widget.ScrollView;
 import android.widget.Toast;
 
 import androidx.annotation.IdRes;
@@ -47,10 +46,11 @@ import net.osmand.plus.activities.MapActivity;
 import net.osmand.plus.helpers.AndroidUiHelper;
 import net.osmand.plus.mapcontextmenu.InterceptorLinearLayout;
 import net.osmand.plus.views.controls.HorizontalSwipeConfirm;
+import net.osmand.plus.views.controls.SingleTapConfirm;
 
 import static net.osmand.plus.mapcontextmenu.MapContextMenuFragment.CURRENT_Y_UNDEFINED;
 
-public abstract class ContextMenuFragment extends BaseOsmAndFragment implements OnNeedScrollUiAdapter {
+public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 
 	public static class MenuState {
 		public static final int HEADER_ONLY = 1;
@@ -68,7 +68,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 	private OnLayoutChangeListener containerLayoutListener;
 	private View topShadow;
 	private ViewGroup topView;
-	private ScrollView bottomScrollView;
+	private View bottomScrollView;
 	private LinearLayout cardsContainer;
 	private FrameLayout bottomContainer;
 
@@ -248,7 +248,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 		return bottomContainer;
 	}
 
-	public ScrollView getBottomScrollView() {
+	public View getBottomScrollView() {
 		return bottomScrollView;
 	}
 
@@ -316,11 +316,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 		processScreenHeight(container);
 		minHalfY = getMinHalfY(mapActivity);
 
-		final GestureDetector swipeDetector = new GestureDetector(app, new HorizontalSwipeConfirm(true));
+		final GestureDetector singleTapDetector = new GestureDetector(view.getContext(), new SingleTapConfirm());
+		final GestureDetector swipeDetector = new GestureDetector(view.getContext(), new HorizontalSwipeConfirm(true));
 
 		final OnTouchListener slideTouchListener = new OnTouchListener() {
-			private static final int SHORT_CLICK_DURATION_TOP_LIMIT = 500;
-
 			private float dy;
 			private float dyMain;
 			private float mDownY;
@@ -332,9 +331,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 
 			private boolean slidingUp;
 			private boolean slidingDown;
-			private boolean isHolding;
 
-			private long downMotionEventTimeMs;
+			private boolean hasMoved;
 
 			{
 				OsmandApplication app = requireMyApplication();
@@ -346,7 +344,15 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 
 			@Override
 			public boolean onTouch(View v, MotionEvent event) {
+				if (!hasMoved && getHeaderViewHeight() > 0 && event.getY() <= getHeaderViewHeight()) {
+					if (singleTapDetector.onTouchEvent(event)) {
+						moving = false;
+						onHeaderClick();
 
+						recycleVelocityTracker();
+						return true;
+					}
+				}
 				if (!portrait) {
 					if (swipeDetector.onTouchEvent(event)) {
 						dismiss();
@@ -358,10 +364,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 
 				switch (event.getAction()) {
 					case MotionEvent.ACTION_DOWN:
-						if (!isHolding) {
-							isHolding = true;
-							downMotionEventTimeMs = event.getDownTime();
-						}
+						hasMoved = false;
 						mDownY = event.getRawY();
 						dy = event.getY();
 						dyMain = getViewY();
@@ -375,6 +378,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 							moving = true;
 						}
 						if (moving) {
+							hasMoved = true;
 							float y = event.getY();
 							float newY = getViewY() + (y - dy);
 							if (!portrait && newY > topScreenPosY) {
@@ -398,9 +402,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 						break;
 
 					case MotionEvent.ACTION_UP:
-						isHolding = false;
 						if (moving) {
 							moving = false;
+							hasMoved = false;
 							int currentY = getViewY();
 							int fullScreenTopPosY = getMenuStatePosY(MenuState.FULL_SCREEN);
 							final VelocityTracker velocityTracker = this.velocityTracker;
@@ -423,13 +427,12 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 							}
 
 							changeMenuState(currentY, slidingUp, slidingDown, true);
-						} else if (isShortClick(event.getEventTime())) {
-							onShortClick(v, event);
 						}
 						recycleVelocityTracker();
 						break;
 					case MotionEvent.ACTION_CANCEL:
 						moving = false;
+						hasMoved = false;
 						recycleVelocityTracker();
 						break;
 
@@ -458,11 +461,6 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 					velocityTracker = null;
 				}
 			}
-
-			private boolean isShortClick(long upActionTime) {
-				long holdingDuration = upActionTime - downMotionEventTimeMs;
-				return holdingDuration <= SHORT_CLICK_DURATION_TOP_LIMIT;
-			}
 		};
 
 		if (mainView instanceof InterceptorLinearLayout) {
@@ -485,8 +483,6 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 		return view;
 	}
 
-	protected void onShortClick(View v, MotionEvent event) { }
-
 	public float getToolbarAlpha(int y) {
 		float a = 0;
 		if (portrait) {
@@ -923,6 +919,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 		runLayoutListener();
 	}
 
+	protected void onHeaderClick() {
+
+	}
+
 	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 	protected void runLayoutListener() {
 		if (view != null) {
@@ -1071,16 +1071,4 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment implements
 			return false;
 		}
 	}
-
-	@Override
-	public void onNeedVerticalScroll(String tag, int y) { }
-
-	public void verticalScrollToYPosition(final int y) {
-		bottomScrollView.post(new Runnable() {
-			@Override
-			public void run() {
-				bottomScrollView.smoothScrollTo(0, y);
-			}
-		});
-	}
 }
diff --git a/OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java b/OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java
deleted file mode 100644
index 4363139e1f..0000000000
--- a/OsmAnd/src/net/osmand/plus/base/OnNeedScrollUiAdapter.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.osmand.plus.base;
-
-public interface OnNeedScrollUiAdapter {
-	void onNeedVerticalScroll(String tag, int yPosition);
-}
diff --git a/OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java b/OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java
deleted file mode 100644
index 58a2da55de..0000000000
--- a/OsmAnd/src/net/osmand/plus/base/OnVisibilityChangeListener.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.osmand.plus.base;
-
-public interface OnVisibilityChangeListener {
-	void onVisibilityChange(int visibility);
-}
diff --git a/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java b/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java
index a2015693a0..b5ef5e1961 100644
--- a/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/track/CustomColorBottomSheet.java
@@ -55,7 +55,9 @@ public class CustomColorBottomSheet extends MenuBottomSheetDialogFragment implem
 	public void createMenuItems(Bundle savedInstanceState) {
 		if (savedInstanceState != null) {
 			newColor = savedInstanceState.getInt(NEW_SELECTED_COLOR);
-			prevColor = savedInstanceState.getInt(PREV_SELECTED_COLOR);
+			if (savedInstanceState.containsKey(PREV_SELECTED_COLOR)) {
+				prevColor = savedInstanceState.getInt(PREV_SELECTED_COLOR);
+			}
 		} else {
 			Bundle args = getArguments();
 			if (args != null) {
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
index 03e3a21419..53d49bd2a7 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
@@ -7,13 +7,13 @@ import android.os.Build;
 import android.os.Bundle;
 import android.view.Gravity;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.ScrollView;
 
 import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.ColorInt;
@@ -369,11 +369,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 	}
 
 	@Override
-	protected void onShortClick(View v, MotionEvent event) {
-		if (routeMenuTopShadowAll != null &&
-				AndroidUtils.isPointInsideView(routeMenuTopShadowAll, event.getX(), event.getY())) {
-			adjustMapPosition(getViewY());
-		}
+	protected void onHeaderClick() {
+		adjustMapPosition(getViewY());
 	}
 
 	private void adjustMapPosition(int y) {
@@ -606,7 +603,21 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 			trackColoringCard.setListener(this);
 			cardsContainer.addView(trackColoringCard.build(mapActivity));
 
-			trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, this);
+			trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, new OnNeedScrollListener() {
+
+				@Override
+				public void onVerticalScrollNeeded(int y) {
+					View view = trackWidthCard.getView();
+					if (view != null) {
+						int resultYPosition = view.getTop() + y;
+						int dialogHeight = getInnerScrollableHeight();
+						ScrollView scrollView = (ScrollView) getBottomScrollView();
+						if (resultYPosition > (scrollView.getScrollY() + dialogHeight)) {
+							scrollView.smoothScrollTo(0, resultYPosition - dialogHeight);
+						}
+					}
+				}
+			});
 			trackWidthCard.setListener(this);
 			cardsContainer.addView(trackWidthCard.build(mapActivity));
 		}
@@ -649,21 +660,6 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 		}
 	}
 
-	@Override
-	public void onNeedVerticalScroll(@NonNull String tag, int y) {
-		if (tag.equals(TrackWidthCard.TAG)) {
-			View trackWidthCardView = trackWidthCard.getView();
-			if (trackWidthCardView == null) return;
-
-			int currentScrollYPosition = getBottomScrollView().getScrollY();
-			int dialogHeight = getInnerScrollableHeight();
-			int resultYPosition = trackWidthCardView.getTop() + y;
-			if (resultYPosition > (currentScrollYPosition + dialogHeight)) {
-				verticalScrollToYPosition(resultYPosition - dialogHeight);
-			}
-		}
-	}
-
 	public int getInnerScrollableHeight() {
 		int totalScreenHeight = getViewHeight() - getMenuStatePosY(getCurrentMenuState());
 		int frameTotalHeight = routeMenuTopShadowAll.getHeight()
@@ -723,4 +719,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 			return R.drawable.ic_action_track_line_thin_direction;
 		}
 	}
+
+	public interface OnNeedScrollListener {
+		void onVerticalScrollNeeded(int y);
+	}
 }
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java
index 5f598a5cde..e8ab755507 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java
@@ -23,6 +23,8 @@ import com.google.android.material.internal.FlowLayout;
 
 import net.osmand.AndroidUtils;
 import net.osmand.PlatformUtil;
+import net.osmand.plus.GPXDatabase.GpxDataItem;
+import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
 import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
@@ -294,16 +296,45 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener {
 
 	@Override
 	public void onColorSelected(Integer prevColor, int newColor) {
-		if (prevColor == null && customColors.size() < 6) {
-			customColors.add(newColor);
-			trackDrawInfo.setColor(newColor);
-		} else if (!Algorithms.isEmpty(customColors)) {
+		if (prevColor != null) {
 			int index = customColors.indexOf(prevColor);
 			if (index != INVALID_VALUE) {
 				customColors.set(index, newColor);
+				saveCustomColorsToTracks(prevColor, newColor);
+			}
+			if (trackDrawInfo.getColor() == prevColor) {
+				trackDrawInfo.setColor(newColor);
+			}
+		} else if (customColors.size() < 6) {
+			customColors.add(newColor);
+			trackDrawInfo.setColor(newColor);
+		}
+		saveCustomColors();
+		updateContent();
+	}
+
+	private void saveCustomColorsToTracks(int prevColor, int newColor) {
+		List gpxDataItems = app.getGpxDbHelper().getItems();
+		for (GpxDataItem dataItem : gpxDataItems) {
+			if (prevColor == dataItem.getColor()) {
+				app.getGpxDbHelper().updateColor(dataItem, newColor);
 			}
 		}
-		updateContent();
+		List files = app.getSelectedGpxHelper().getSelectedGPXFiles();
+		for (SelectedGpxFile selectedGpxFile : files) {
+			if (prevColor == selectedGpxFile.getGpxFile().getColor(0)) {
+				selectedGpxFile.getGpxFile().setColor(newColor);
+			}
+		}
+	}
+
+	private void saveCustomColors() {
+		List colorNames = new ArrayList<>();
+		for (Integer color : customColors) {
+			String colorHex = Algorithms.colorToString(color);
+			colorNames.add(colorHex);
+		}
+		app.getSettings().CUSTOM_TRACK_COLORS.setStringsList(colorNames);
 	}
 
 	private class TrackColoringAdapter extends RecyclerView.Adapter {
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java b/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java
index 22651ea04c..2a8f34c024 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackWidthCard.java
@@ -14,32 +14,31 @@ import androidx.core.content.ContextCompat;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
 import com.google.android.material.slider.Slider;
 
 import net.osmand.AndroidUtils;
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
-import net.osmand.plus.base.OnNeedScrollUiAdapter;
-import net.osmand.plus.base.OnVisibilityChangeListener;
 import net.osmand.plus.dialogs.GpxAppearanceAdapter;
 import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem;
 import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType;
 import net.osmand.plus.helpers.AndroidUiHelper;
 import net.osmand.plus.routepreparationmenu.cards.BaseCard;
+import net.osmand.plus.track.TrackAppearanceFragment.OnNeedScrollListener;
 import net.osmand.util.Algorithms;
 
 import java.util.List;
 
 public class TrackWidthCard extends BaseCard {
-	public final static String TAG = TrackWidthCard.class.getName();
 
 	private final static String CUSTOM_WIDTH = "custom_width";
 	private final static int CUSTOM_WIDTH_MIN = 1;
 	private final static int CUSTOM_WIDTH_MAX = 24;
 
 	private TrackDrawInfo trackDrawInfo;
-	private OnNeedScrollUiAdapter onNeedScrollUiAdapter;
+	private OnNeedScrollListener onNeedScrollListener;
 
 	private AppearanceListItem selectedItem;
 	private List appearanceItems;
@@ -48,10 +47,10 @@ public class TrackWidthCard extends BaseCard {
 	private View sliderContainer;
 
 	public TrackWidthCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo,
-	                      OnNeedScrollUiAdapter onNeedScrollUiAdapter) {
+	                      OnNeedScrollListener onNeedScrollListener) {
 		super(mapActivity);
 		this.trackDrawInfo = trackDrawInfo;
-		this.onNeedScrollUiAdapter = onNeedScrollUiAdapter;
+		this.onNeedScrollListener = onNeedScrollListener;
 		appearanceItems = getWidthAppearanceItems();
 	}
 
@@ -157,16 +156,14 @@ public class TrackWidthCard extends BaseCard {
 				}
 			});
 			UiUtilities.setupSlider(widthSlider, nightMode, null);
-			AndroidUtils.addVisibilityChangeListener(view, sliderContainer,
-					new OnVisibilityChangeListener() {
-						@Override
-						public void onVisibilityChange(int visibility) {
-							if (visibility == View.VISIBLE) {
-								onNeedScrollUiAdapter.onNeedVerticalScroll(TAG, sliderContainer.getBottom());
-							}
-						}
+			ScrollUtils.addOnGlobalLayoutListener(sliderContainer, new Runnable() {
+				@Override
+				public void run() {
+					if (sliderContainer.getVisibility() == View.VISIBLE) {
+						onNeedScrollListener.onVerticalScrollNeeded(sliderContainer.getBottom());
 					}
-			);
+				}
+			});
 			AndroidUiHelper.updateVisibility(sliderContainer, true);
 		} else {
 			AndroidUiHelper.updateVisibility(sliderContainer, false);
@@ -227,13 +224,6 @@ public class TrackWidthCard extends BaseCard {
 					if (listener != null) {
 						listener.onCardPressed(TrackWidthCard.this);
 					}
-
-					if (CUSTOM_WIDTH.equals(selectedItem.getAttrName())
-							&& sliderContainer != null
-							&& onNeedScrollUiAdapter != null
-							&& sliderContainer.getVisibility() == View.VISIBLE) {
-						onNeedScrollUiAdapter.onNeedVerticalScroll(TAG, sliderContainer.getBottom());
-					}
 				}
 			});
 		}

From 79d70c9b3485bac02b4f45fabfd268212a59e3d1 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Wed, 16 Sep 2020 14:26:24 +0300
Subject: [PATCH 0151/1366] Fix translation for navigation type

---
 .../plus/activities/MapActivityActions.java   | 28 +++++++++++++++----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 83a470b903..ea597558e1 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -61,6 +61,7 @@ import net.osmand.plus.mapmarkers.MarkersPlanRouteContext;
 import net.osmand.plus.measurementtool.MeasurementToolFragment;
 import net.osmand.plus.measurementtool.StartPlanRouteBottomSheet;
 import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
+import net.osmand.plus.profiles.RoutingProfileDataObject;
 import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
 import net.osmand.plus.routepreparationmenu.WaypointsFragment;
 import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
@@ -86,6 +87,7 @@ import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 import static net.osmand.IndexConstants.GPX_FILE_EXT;
 import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_MAP_ID;
@@ -115,6 +117,7 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_S
 import static net.osmand.plus.ContextMenuAdapter.PROFILES_CHOSEN_PROFILE_TAG;
 import static net.osmand.plus.ContextMenuAdapter.PROFILES_CONTROL_BUTTON_TAG;
 import static net.osmand.plus.ContextMenuAdapter.PROFILES_NORMAL_PROFILE_TAG;
+import static net.osmand.plus.settings.fragments.NavigationFragment.getRoutingProfiles;
 
 
 public class MapActivityActions implements DialogProvider {
@@ -731,11 +734,11 @@ public class MapActivityActions implements DialogProvider {
 		ApplicationMode currentMode = app.getSettings().APPLICATION_MODE.get();
 
 		String modeDescription;
-		
+
+		Map profilesObjects = getRoutingProfiles(app);
 		for (final ApplicationMode appMode : activeModes) {
 			if (appMode.isCustomProfile()) {
-				modeDescription = String.format(app.getString(R.string.profile_type_descr_string),
-						Algorithms.capitalizeFirstLetterAndLowercase(appMode.getRoutingProfile()));
+				modeDescription = getCustomProfileDescription(app, appMode, profilesObjects);
 			} else {
 				modeDescription = getString(R.string.profile_type_base_string);
 			}
@@ -1045,8 +1048,8 @@ public class MapActivityActions implements DialogProvider {
 		ApplicationMode currentMode = app.getSettings().APPLICATION_MODE.get();
 		String modeDescription;
 		if (currentMode.isCustomProfile()) {
-			modeDescription = String.format(app.getString(R.string.profile_type_descr_string),
-					Algorithms.capitalizeFirstLetterAndLowercase(currentMode.getRoutingProfile()));
+			Map profilesObjects = getRoutingProfiles(app);
+			modeDescription = getCustomProfileDescription(app, currentMode, profilesObjects);
 		} else {
 			modeDescription = getString(R.string.profile_type_base_string);
 		}
@@ -1081,6 +1084,21 @@ public class MapActivityActions implements DialogProvider {
 				.createItem());
 	}
 
+	private String getCustomProfileDescription(OsmandApplication app, ApplicationMode mode,
+	                                           Map profilesObjects){
+		String	description = getString(R.string.profile_type_custom_string);
+
+		String routingProfileKey = mode.getRoutingProfile();
+		if (!Algorithms.isEmpty(routingProfileKey)) {
+			RoutingProfileDataObject profileDataObject = profilesObjects.get(routingProfileKey);
+			if (profileDataObject != null) {
+				description = String.format(app.getString(R.string.profile_type_descr_string),
+						Algorithms.capitalizeFirstLetterAndLowercase(profileDataObject.getName()));
+			}
+		}
+		return description;
+	}
+
 	public void openIntermediatePointsDialog() {
 		mapActivity.hideContextAndRouteInfoMenues();
 		WaypointsFragment.showInstance(mapActivity.getSupportFragmentManager());

From d30532aac8074cd98e05eb61da2c1cad5386bd77 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Wed, 16 Sep 2020 16:36:47 +0300
Subject: [PATCH 0152/1366] Small fixes for description icon

---
 .../res/layout/point_editor_fragment_new.xml  | 27 +++---
 .../FavoritePointEditorFragmentNew.java       |  8 +-
 .../editors/PointEditorFragmentNew.java       | 88 +++++++++----------
 3 files changed, 61 insertions(+), 62 deletions(-)

diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml
index 6e00c48bfd..21c6396c53 100644
--- a/OsmAnd/res/layout/point_editor_fragment_new.xml
+++ b/OsmAnd/res/layout/point_editor_fragment_new.xml
@@ -135,6 +135,7 @@
 							android:id="@+id/address_edit"
 							android:layout_width="match_parent"
 							android:layout_height="wrap_content"
+							android:gravity="start"
 							android:maxLines="4"
 							android:minHeight="@dimen/favorites_list_item_height"
 							android:paddingStart="@dimen/content_padding_small"
@@ -142,7 +143,6 @@
 							android:paddingEnd="@dimen/content_padding_small"
 							android:paddingRight="@dimen/content_padding_small"
 							android:textSize="@dimen/default_list_text_size"
-							android:gravity="left"
 							tools:text="@string/lorem_ipsum" />
 
 					
@@ -158,36 +158,37 @@
 						android:id="@+id/address_button"
 						android:layout_width="0dp"
 						android:layout_height="wrap_content"
-						android:minHeight="@dimen/setting_list_item_small_height"
-						android:layout_weight="1"
 						android:layout_marginStart="@dimen/content_padding_half"
 						android:layout_marginLeft="@dimen/content_padding_half"
 						android:layout_marginEnd="@dimen/content_padding"
 						android:layout_marginRight="@dimen/content_padding"
-						android:paddingTop="@dimen/content_padding_half"
-						android:paddingBottom="@dimen/content_padding_half"
+						android:layout_weight="1"
 						android:drawablePadding="8dp"
 						android:duplicateParentState="true"
 						android:gravity="center_vertical"
+						android:minHeight="@dimen/setting_list_item_small_height"
 						android:paddingStart="@dimen/content_padding_half"
 						android:paddingLeft="@dimen/content_padding_half"
+						android:paddingTop="@dimen/content_padding_half"
 						android:paddingEnd="@dimen/content_padding_half"
 						android:paddingRight="@dimen/content_padding_half"
+						android:paddingBottom="@dimen/content_padding_half"
 						android:text="@string/add_address"
 						android:textSize="@dimen/default_desc_text_size"
 						osmand:typeface="@string/font_roboto_medium"
 						tools:text="@string/add_address" />
 
-					
 
 				
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java
index cd1910f929..9bfe58324a 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java
@@ -243,8 +243,8 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
 		if (favorite != null) {
 			final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(),
 					getNameTextValue(), getCategoryTextValue());
-			point.setDescription(isDescriptionAvailable()?getDescriptionTextValue():null);
-			point.setAddress(isAddressAvailable()?getAddressTextValue():null);
+			point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null);
+			point.setAddress(isAddressAvailable() ? getAddressTextValue() : null);
 			point.setColor(color);
 			point.setBackgroundType(backgroundType);
 			point.setIconId(iconId);
@@ -259,8 +259,8 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
 		if (favorite != null) {
 			final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(),
 					getNameTextValue(), getCategoryTextValue());
-			point.setDescription(isDescriptionAvailable()?getDescriptionTextValue():null);
-			point.setAddress(isAddressAvailable()?getAddressTextValue():null);
+			point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null);
+			point.setAddress(isAddressAvailable() ? getAddressTextValue() : null);
 			point.setColor(color);
 			point.setBackgroundType(backgroundType);
 			point.setIconId(iconId);
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
index 9856f907e1..3214817780 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
@@ -27,6 +27,7 @@ import android.widget.TextView;
 
 import androidx.activity.OnBackPressedCallback;
 import androidx.annotation.ColorInt;
+import androidx.annotation.ColorRes;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -39,7 +40,6 @@ import androidx.fragment.app.FragmentActivity;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.google.android.material.textfield.TextInputEditText;
 import com.google.android.material.textfield.TextInputLayout;
 
 import net.osmand.AndroidUtils;
@@ -81,6 +81,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 	private TextView addDelDescription;
 	private TextView addAddressBtn;
 	private TextView addToHiddenGroupInfo;
+	private ImageView deleteAddressIcon;
 	private boolean cancelled;
 	private boolean nightMode;
 	@DrawableRes
@@ -167,7 +168,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 			}
 		});
 
-		final int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
+		final int activeColorResId = getActiveColorRes();
 		ImageView toolbarAction = (ImageView) view.findViewById(R.id.toolbar_action);
 		view.findViewById(R.id.background_layout).setBackgroundResource(nightMode
 				? R.color.app_bar_color_dark : R.color.list_background_color_light);
@@ -247,78 +248,69 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 		if (getDescriptionInitValue() != null) {
 			descriptionEdit.setText(getDescriptionInitValue());
 		}
-		if (getAddressInitValue() != null){
-			addressEdit.setText(getAddressInitValue());
-			addressEdit.setSelection(addressEdit.getText().length());
-		}
 
 		descriptionCaption = view.findViewById(R.id.description);
 		addressCaption = view.findViewById(R.id.address);
 		addDelDescription = (TextView) view.findViewById(R.id.description_button);
 		addAddressBtn = view.findViewById(R.id.address_button);
+		deleteAddressIcon = view.findViewById(R.id.delete_address_icon);
+		deleteAddressIcon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_trash_basket_16, activeColorResId));
+
 		addDelDescription.setTextColor(getResources().getColor(activeColorResId));
 		addAddressBtn.setTextColor(getResources().getColor(activeColorResId));
-		addAddressBtn.setCompoundDrawablesWithIntrinsicBounds(
-				app.getUIUtilities().getIcon(R.drawable.ic_action_location_16,
-						activeColorResId),null,null,null);
-		selectIconDescription(activeColorResId);
+		Drawable addressIcon = app.getUIUtilities().getIcon(R.drawable.ic_action_location_16, activeColorResId);
+		addAddressBtn.setCompoundDrawablesWithIntrinsicBounds(addressIcon, null, null, null);
 		addDelDescription.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
 				if (descriptionCaption.getVisibility() != View.VISIBLE) {
 					descriptionCaption.setVisibility(View.VISIBLE);
 					addDelDescription.setText(view.getResources().getString(R.string.delete_description));
-					addDelDescription.setCompoundDrawablesWithIntrinsicBounds(
-							app.getUIUtilities().getIcon(R.drawable.ic_action_trash_basket_16,
-									activeColorResId),null,null,null);
 					View descriptionEdit = view.findViewById(R.id.description_edit);
 					descriptionEdit.requestFocus();
 					AndroidUtils.softKeyboardDelayed(getActivity(), descriptionEdit);
 				} else {
 					descriptionCaption.setVisibility(View.GONE);
 					addDelDescription.setText(view.getResources().getString(R.string.add_description));
-					addDelDescription.setCompoundDrawablesWithIntrinsicBounds(
-							app.getUIUtilities().getIcon(R.drawable.ic_action_description_16,
-									activeColorResId),null,null,null);
 					AndroidUtils.hideSoftKeyboard(requireActivity(), descriptionEdit);
 					descriptionEdit.clearFocus();
 				}
+				updateDescriptionIcon();
 			}
 		});
 		AndroidUiHelper.updateVisibility(addressCaption, false);
-		if(!Algorithms.isEmpty(getAddressInitValue())){
-			addAddressBtn.setText(getAddressInitValue());
+
+		String addressInitValue = getAddressInitValue();
+		if (!Algorithms.isEmpty(addressInitValue)) {
+			addressEdit.setText(addressInitValue);
+			addAddressBtn.setText(addressInitValue);
+			addressEdit.setSelection(addressInitValue.length());
+			AndroidUiHelper.updateVisibility(deleteAddressIcon, true);
 		} else {
 			addAddressBtn.setText(getString(R.string.add_address));
-		};
-		final ImageView deleteAddressIcon = (ImageView) view.findViewById(R.id.delete_address_icon);
-		deleteAddressIcon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_trash_basket_16, activeColorResId));
-		if(!Algorithms.isEmpty(getAddressInitValue())){
-			deleteAddressIcon.setVisibility(View.VISIBLE);
-		} else {
-			deleteAddressIcon.setVisibility(View.GONE);
+			AndroidUiHelper.updateVisibility(deleteAddressIcon, false);
 		}
+
 		deleteAddressIcon.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
-				addressCaption.setVisibility(View.GONE);
-				addAddressBtn.setText(view.getResources().getString(R.string.add_address));
 				addressEdit.setText("");
-				deleteAddressIcon.setVisibility(View.GONE);
+				addAddressBtn.setText(view.getResources().getString(R.string.add_address));
+				AndroidUiHelper.updateVisibility(addressCaption, false);
+				AndroidUiHelper.updateVisibility(deleteAddressIcon, false);
 			}
 		});
+
+		final View addressRow = view.findViewById(R.id.address_row);
 		addAddressBtn.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
 				if (addressCaption.getVisibility() != View.VISIBLE) {
 					addressCaption.setVisibility(View.VISIBLE);
-					TextInputEditText addressEdit = view.findViewById(R.id.address_edit);
-					View row = view.findViewById(R.id.address_row);
-					row.setVisibility(View.GONE);
-					addAddressBtn.setText(getString(R.string.add_address));
 					addressEdit.requestFocus();
 					addressEdit.setSelection(addressEdit.getText().length());
-					AndroidUtils.softKeyboardDelayed(requireActivity(),addressEdit);
+					AndroidUtils.softKeyboardDelayed(requireActivity(), addressEdit);
+					AndroidUiHelper.updateVisibility(addressRow, false);
 				} else {
 					addressCaption.setVisibility(View.GONE);
 					addAddressBtn.setText(getAddressTextValue());
@@ -393,19 +385,17 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 		return view;
 	}
 
-
-	private void selectIconDescription(int activeColorResId) {
-		if (descriptionCaption.getVisibility() != View.VISIBLE) {
-			addDelDescription.setCompoundDrawablesWithIntrinsicBounds(
-					app.getUIUtilities().getIcon(R.drawable.ic_action_description_16, activeColorResId),null,null,null);
+	private void updateDescriptionIcon() {
+		int iconId;
+		if (descriptionCaption.getVisibility() == View.VISIBLE) {
+			iconId = R.drawable.ic_action_trash_basket_16;
 		} else {
-			addDelDescription.setCompoundDrawablesWithIntrinsicBounds(
-					app.getUIUtilities().getIcon(R.drawable.ic_action_trash_basket_16,
-							activeColorResId),null,null,null);
+			iconId = R.drawable.ic_action_description_16;
 		}
+		Drawable icon = app.getUIUtilities().getIcon(iconId, getActiveColorRes());
+		addDelDescription.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
 	}
 
-
 	private void checkEmptyName(Editable name, TextInputLayout nameCaption, View saveButton) {
 		if (name.toString().trim().isEmpty()) {
 			nameCaption.setError(app.getString(R.string.please_provide_point_name_error));
@@ -443,14 +433,22 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 			descriptionCaption.setVisibility(View.GONE);
 			addDelDescription.setText(app.getString(R.string.add_description));
 		}
-
+		updateDescriptionIcon();
 	}
-	boolean isAddressAvailable(){
+
+	boolean isAddressAvailable() {
 		return addressCaption.getVisibility() == View.VISIBLE;
 	}
-	boolean isDescriptionAvailable(){
+
+	boolean isDescriptionAvailable() {
 		return descriptionCaption.getVisibility() == View.VISIBLE;
 	}
+
+	@ColorRes
+	private int getActiveColorRes() {
+		return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
+	}
+
 	private void createGroupSelector() {
 		groupListAdapter = new GroupAdapter();
 		groupRecyclerView = view.findViewById(R.id.group_recycler_view);

From b94be6c3448622b876abe84234eef3fa0e044a3e Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Wed, 16 Sep 2020 18:03:57 +0300
Subject: [PATCH 0153/1366] Update material library

---
 OsmAnd/build.gradle                         | 2 +-
 OsmAnd/src/net/osmand/plus/UiUtilities.java | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle
index e33b1ca75f..80c70c84b4 100644
--- a/OsmAnd/build.gradle
+++ b/OsmAnd/build.gradle
@@ -524,7 +524,7 @@ dependencies {
 	implementation 'androidx.gridlayout:gridlayout:1.0.0'
 	implementation 'androidx.cardview:cardview:1.0.0'
 	implementation 'androidx.appcompat:appcompat:1.1.0'
-	implementation 'com.google.android.material:material:1.2.0-beta01'
+	implementation 'com.google.android.material:material:1.2.1'
 	implementation 'androidx.browser:browser:1.0.0'
 	implementation 'androidx.preference:preference:1.1.0'
 	implementation fileTree(include:  ['gnu-trove-osmand.jar', 'icu4j-49_1_patched.jar'], dir: 'libs')
diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java
index 8dc59eccc9..a435bd975e 100644
--- a/OsmAnd/src/net/osmand/plus/UiUtilities.java
+++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java
@@ -42,6 +42,7 @@ import androidx.core.graphics.drawable.DrawableCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.widget.TintableCompoundButton;
 
+import com.google.android.material.slider.LabelFormatter;
 import com.google.android.material.slider.RangeSlider;
 import com.google.android.material.slider.Slider;
 import com.google.android.material.snackbar.BaseTransientBottomBar;
@@ -610,7 +611,7 @@ public class UiUtilities {
 		slider.setTrackHeight(ctx.getResources().getDimensionPixelSize(R.dimen.slider_track_height));
 
 		// label behavior
-		slider.setLabelBehavior(Slider.LABEL_GONE);
+		slider.setLabelBehavior(LabelFormatter.LABEL_GONE);
 	}
 
 	public static void setupSlider(RangeSlider slider, boolean nightMode,
@@ -650,7 +651,7 @@ public class UiUtilities {
 		slider.setTrackHeight(ctx.getResources().getDimensionPixelSize(R.dimen.slider_track_height));
 
 		// label behavior
-		slider.setLabelBehavior(Slider.LABEL_GONE);
+		slider.setLabelBehavior(LabelFormatter.LABEL_GONE);
 	}
 
 	public static void setupDialogButton(boolean nightMode, View buttonView, DialogButtonType buttonType, @StringRes int buttonTextId) {

From 3a05ad3228732e27794091378ad6d1820736b4e0 Mon Sep 17 00:00:00 2001
From: Hinagiku Zeppeki 
Date: Wed, 16 Sep 2020 09:31:08 +0000
Subject: [PATCH 0154/1366] Translated using Weblate (Japanese)

Currently translated at 98.6% (3437 of 3484 strings)
---
 OsmAnd/res/values-ja/strings.xml | 45 ++++++++++++++++----------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml
index 636fc3995b..7193842fe5 100644
--- a/OsmAnd/res/values-ja/strings.xml
+++ b/OsmAnd/res/values-ja/strings.xml
@@ -50,9 +50,9 @@
     マイル/ヤード
     キロメートル/メートル
     ヤード
-    フィート
+    ft
     mph
-    マイル
+    mi
     次の方法で位置を共有
     位置 : %1$s\n%2$s
     位置を見るには
@@ -2068,7 +2068,7 @@ POIの更新は利用できません
     中国語 (香港)
     オーストラリア
     フォルダ内に経路データが存在しません
-    以下フォルダーにトラックを追加することが可能です
+    フォルダに経路を追加することも可能です
     経路を追加
     表示形式
     最大速度
@@ -2412,10 +2412,10 @@ POIの更新は利用できません
     この近辺の写真はありません。
     近隣の写真(要オンライン)
     情報共有のための路上写真です(要オンライン)。新たな場所の発見に、協力しあい、この世界を写真で保存しましょう。
-    Mapillaryにて写真の有効領域を広げましょう
-    Mapillaryをインストールして、このマップの場所に写真を追加します。
+    Mapillaryにて写真によるレポートを強化しましょう
+    Mapillaryをインストールすれば、このマップの場所にストリート写真を追加できます。
     Mapillaryを開く
-    ストリート写真(Mapillary)
+    Mapillary
     Mapillaryウィジェット
     Mapillary画像
     Mapillaryを利用し、あなたが撮影した路上写真を共有します。
@@ -2611,7 +2611,7 @@ POIの更新は利用できません
     シンプルな運転用スタイルです。おだやかな夜間モード、等高線、対照的なオレンジ色スタイルの道路表示で、セカンダリマップオブジェクトは若干暗くしてあります。
     ハイキング、トレッキング、ネイチャーサイクリング向けです。屋外で視認しやすい配色になっています。対照的な道路と自然物、さまざまなルートタイプ、高度な等高線オプション、詳細の追加などがなされています。 路面の素材や質を表示するオプションを使えば、各道路の状態も把握できます。夜間モードはありません。
     昔のデフォルトであった『Mapnik』スタイルです。Mapnikそのものではありませんが似た配色になります。
-    地点/座標の編集
+    地点/座標の編集
     座標の追加
     経路として保存
     %1$sヶ所の座標を追加しました。ファイル名を付けて\"保存\"をタップしてください。
@@ -2745,7 +2745,7 @@ POIの更新は利用できません
     最後の中間経由地点として追加
     最初の中間経由地点として追加
     閉じたメモの表示
-    マップ上にあるOSMメモの表示/非表示を切り替えます。
+    マップ上にあるOSMメモの表示/非表示を切り替えます。
     GPX - JOSMまたは他のOSMエディタへ適したエクスポート形式です。
     OSC - OSMの利用に適したエクスポート形式です。
     GPXファイル
@@ -2855,10 +2855,10 @@ POIの更新は利用できません
     入れ替え
     詳細を見る
     マップ上の経路
-    GPX経路の表示/非表示
-    マップ上にある選択したGPX経路の表示/非表示を切り替えるボタンです。
-    GPX経路の非表示
-    GPX経路の表示
+    GPX経路の表示/非表示
+    マップ上にある選択したGPX経路の表示/非表示を切り替えるボタンです。
+    経路の非表示
+    経路の表示
     最初に目的地を設定して下さい
     前回のルート
     立方メートル
@@ -3338,14 +3338,14 @@ POIの更新は利用できません
     停留所標識
     オック語
     OSMの編集
-    マップ上の等高線の表示/非表示を切り替えられるボタンです。
+    マップ上の等高線の表示/非表示を切り替えられるボタンです。
     等高線を表示
     等高線を非表示
-    等高線を表示/非表示
-    マップ上の陰影起伏図の表示/非表示を切り替えられるボタンです。
+    等高線を表示/非表示
+    マップ上の陰影起伏図の表示/非表示を切り替えられるボタンです。
     陰影起伏図を表示
     陰影起伏図を非表示
-    陰影起伏図の表示/非表示
+    陰影起伏図の表示/非表示
     テキスト読み上げエンジンを起動できません。
     プロファイルのエクスポート
     OsmAndプロファイル:%1$s
@@ -3455,7 +3455,7 @@ POIの更新は利用できません
     カメラシャッター音
     認証に成功しました
     カテゴリーの並べ替え
-    リストの並び順を変更したり、不要なカテゴリを非表示にします。プロファイルデータのインポート/エクスポートも可能です。
+    リストの並び順を変更したり、不要なカテゴリを非表示にします。プロファイルデータのインポート/エクスポートも可能です。
     一つあるいは複数のカテゴリーを選択して、新しいカスタムカテゴリーを追加できます。
     利用可
     カスタムカテゴリーを追加
@@ -3718,7 +3718,7 @@ POIの更新は利用できません
     電源ボタン
     端末の音量ボタンでマップのズームレベルを変更できるようにします。
     音量ボタンでズーム
-    出発・目的地アイコンを表示
+    出発地点と目的地アイコンを表示
     幅の選択
     距離または時間のマーカーが経路に表示される間隔を選択します。
     時間または距離で、必要な分割オプションを選択します。
@@ -3735,7 +3735,7 @@ POIの更新は利用できません
     ルート反転
     選択したプロファイルを使用して、次のセグメントのみ再計算します。
     選択したプロファイルを使用して、経路全体が再計算されます。
-    直線で地点間をつなげる方法をとるか、選択したプロファイルで地点間のルートを計算します。
+    地点間を直線で結ぶ方法、または地点だけを指定しその後ルートを計算する方法のどちらかを選択します。
     全経路
     次のセグメント
     このオプションを使用するには、OsmAndで経路をマップ上の道路にスナップする必要があります。
@@ -3824,7 +3824,7 @@ POIの更新は利用できません
     アンインストールして再起動
     このアプリには、スピードカメラに関する情報はありません。
     インラインスケート
-    次の目的地を削除
+    最も近い目的地を削除
     地点の名前を入力してください
     ルート上の現在の目的地点が削除されます。目的地に着いた場合はナビは停止します。
     Wikipediaマップのダウンロード
@@ -3840,8 +3840,8 @@ POIの更新は利用できません
     ルート経路
     経路ファイルを追加
     経路ファイルを記録、またはインポートします
-    経路経由地点を追加
-    経路経由地点を追加
+    経路・経由地点を追加
+    経路・経由地点を追加
     道路に貼り付ける
     旅程の記録
     経路ファイルとして保存
@@ -3896,4 +3896,5 @@ POIの更新は利用できません
     ファイル名
     (最近使用したアプリを介して) OsmAndを終了すると、GPXの記録が一時停止されます(バックグラウンドサービスインジケーターがAndroid通知バーから消えます。)
     一般的な経路記録の記録間隔を定義します(マップ画面の\'GPX\'ボタンを使用)
+    保存されました
 
\ No newline at end of file

From b6753504a5ea0c1eea52f1bf052fbd6e1cd6fe2d Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Wed, 16 Sep 2020 15:21:35 +0000
Subject: [PATCH 0155/1366] Translated using Weblate (Russian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index bfceebc942..2edc91e6b2 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -1502,7 +1502,7 @@
     Строения
     Текст
     Леса и кустарники
-    Более подробно
+    Повышенная детализация
     Менее подробно
     Качество дорог
     Тип дорожного покрытия
@@ -3845,7 +3845,7 @@
     Маршрут трека
     Добавить файлы треков
     Импортируйте или запишите файлы треков
-    Добавить путевую точку
+    Добавить точку
     Добавить точку к треку
     Запись поездки
     Сохранить как файл трека

From c8b619b4a3c31cdb8ebac31bca9f006539dea32e Mon Sep 17 00:00:00 2001
From: Nikita Epifanov 
Date: Wed, 16 Sep 2020 09:51:43 +0000
Subject: [PATCH 0156/1366] Translated using Weblate (Russian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 2edc91e6b2..55ff01a9a1 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -518,9 +518,9 @@
     Обратное направление GPX
     Использовать текущий пункт назначения
     Пройти весь путь
-    Для этого региона есть локальные векторные карты.
-\n\t
-\n\tМеню → Настройки карты → Источник карты → Векторные карты.
+    Для этого региона доступны локальные векторные карты. 
+\n\t 
+\n\tДля их использования выберите в \"Меню\" → \"Настройка карты\" → \"Источник карты…\" → \"Векторные карты\".
     Голосовые инструкции
     Выберите канал вывода голосовых подсказок.
     Канал голосовых звонков (прерывает автомобильную Bluetooth стереосистему)
@@ -864,7 +864,7 @@
     3D вид
     Показать последние использованные POI на карте.
     Показывать POI
-    Выберите ресурс с картами онлайн или в кеше.
+    Выберите источник онлайн или кешированных тайлов карты
     Растровые карты
     Источник карты
     Использовать интернет
@@ -3721,7 +3721,7 @@
     Держать экран отключённым
     Держать экран включённым
     Файл SQLiteDB
-    Название ресурса с онлайн-картами.
+    Укажите название источника онлайн-карты.
     Введите или вставьте URL онлайн-источника.
     Время устаревания
     Проекция Меркатора
@@ -3831,7 +3831,7 @@
     Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам.
 \n
 \nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
-    Выберите способ соединения точек: прямой линией или прокладкой маршрута с выбранным профилем.
+    Выберите способ соединения точек прямой линией или рассчитайте маршрут между ними, как указано ниже.
     При обратном направлении
     Все изменения будут утеряны. Закрыть план маршрута\?
     Съёмка уличного уровня

From a93682b39e7da5e130d98d4025b205a2723e43b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Babos=20G=C3=A1bor?= 
Date: Wed, 16 Sep 2020 08:11:18 +0000
Subject: [PATCH 0157/1366] Translated using Weblate (Hungarian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-hu/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml
index 4c6a6e4877..3133035da6 100644
--- a/OsmAnd/res/values-hu/strings.xml
+++ b/OsmAnd/res/values-hu/strings.xml
@@ -3878,13 +3878,13 @@
     Jelölje ki azt a nyomvonalfájlt, amelyhez az új szakasz hozzáadódjék.
     Nyomvonalak
     Mégis
-    • A Tervezett útvonal mód frissítésével különböző navigációtípusok is használathatók az egyes szakaszokhoz, és bármilyen nyomvonal az utakhoz köthető
+    • Frissített útvonaltervezési funkció: szakaszonként különböző navigációtípusok használhatók és nyomvonalak is beilleszthetők
 \n
-\n • Új megjelenési lehetőségek a nyomvonalakhoz: válassza ki a színt, a vastagságot, kapcsolja be az iránynyilakat és a kezdő / befejező jeleket
+\n • Új megjelenési menü a nyomvonalakhoz: válassza ki a színt, a vastagságot, kapcsolja be az iránynyilakat és a kiindulás / célpont ikonjait
 \n
-\n • A kerékpáros csomópontok jobb láthatósága
+\n • Kerékpáros csomópontok jobb láthatósága
 \n
-\n • Helyi menü a nyomvonalak az alapvető adataival
+\n • Nyomvonalra koppintással megnyíló helyi menü a nyomvonalak az alapvető adataival
 \n
 \n • Továbbfejlesztett keresési algoritmusok
 \n

From d3bb110a04d84762a6119446e529fe40c360ea19 Mon Sep 17 00:00:00 2001
From: nasr pen 
Date: Wed, 16 Sep 2020 13:24:28 +0000
Subject: [PATCH 0158/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 52 ++++++++++++++++----------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index b64a6f63a3..480c480efe 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -3134,7 +3134,7 @@
     الإضافات المثبتة
     تكوين الملاحة
     ثيم التطبيق ، وحدات ، المنطقة
-    تكوين ملف التعريف
+    إعداد الوضع
     تظهر التنبيهات في أسفل اليسار أثناء التنقل.
     تبديل الوضع
     اللغة والإخراج
@@ -3291,7 +3291,7 @@
     وضع المستخدم ، مشتق من:%s
     تزلج
     النوع:%s
-    ملف التعريف الأساسي
+    وضع أساسي
     حدد نوع الملاحة
     يرجى تحديد نوع الملاحة للوضع الجديد
     أدخل اسم الوضع
@@ -3381,7 +3381,7 @@
     لا يمكنك حذف أوضاع أوسماند الافتراضية ، ولكن يمكنك تعطيلها في الشاشة السابقة ، أو نقلها إلى الأسفل.
     تحرير الأوضاع
     يؤثر نوع التنقل على قواعد حسابات المسار.
-    مظهر الملف الشخصي
+    مظهر الوضع
     اختر الايقونة واللون والاسم
     تحرير قائمة الأوضاع
     الملف الشخصي المحدد
@@ -3532,7 +3532,7 @@
     حدد البيانات التي سيتم استيرادها.
     أسلوب التقديم
     استيراد ملف الrendering
-    ستتم استعادة كافة إعدادات ملف التعريف إلى حالتها الأصلية بعد إنشاء/استيراد هذا الملف الشخصي.
+    ستتم استعادة كافة إعدادات الوضع إلى حالتها الأصلية بعد إنشاء/استيراد هذا الوضع.
     استعادة جميع إعدادات الملف الشخصي؟
     حفظ ملف تعريف جديد
     لا يمكن عمل نسخة احتياطية من الملف الشخصي.
@@ -3652,28 +3652,28 @@
     مسطرة البوصلة
     قياس المسافة
     السفر (Wikivoyage و Wikipedia)
-    علامات الخريطة
+    العلامات
     المفضلة
     اشتراك أوسماند لايف
     مشتريات أوسماند
     دليل رموز الخريطة.
     الملفات الشخصية للملاحة
-    • خرائط جديدة للمنحدرات غير المتصلة بالإنترنت 
-\n 
-\n • التخصيص الكامل للمفضلات ونقاط الطرق GPX - الألوان المخصصة والأيقونات والأشكال 
-\n 
-\n • تخصيص ترتيب العناصر في قائمة السياق ، تكوين الخريطة ، درج 
-\n 
-\n • ويكيبيديا كطبقة منفصلة في تكوين الخريطة ، حدد اللغات المطلوبة فقط 
-\n 
-\n • إنشاء مرشح / خرائط POI الخاصة بك مع مرونة تامة 
-\n 
-\n • تمت إضافة خيارات لاستعادة إعدادات ملفات التعريف المخصصة 
-\n 
-\n • مسارات GPX كاملة من الممرات دعم حركة المرور وتعليمات كاملة 
-\n 
-\n • إصلاح أحجام واجهة المستخدم على الأجهزة اللوحية 
-\n 
+    • خرائط جديدة للمنحدرات غير المتصلة بالإنترنت
+\n
+\n • التخصيص الكامل للمفضلات ونقاط الطرق GPX - الألوان المخصصة والأيقونات والأشكال
+\n
+\n • تخصيص ترتيب العناصر في قائمة السياق ، تكوين الخريطة ، درج
+\n
+\n • ويكيبيديا كطبقة منفصلة في تكوين الخريطة ، حدد اللغات المطلوبة فقط
+\n
+\n • إنشاء مرشح / خرائط POI الخاصة بك مع مرونة تامة
+\n
+\n • تمت إضافة خيارات لاستعادة إعدادات الأوضاع المخصصة
+\n
+\n • مسارات GPX كاملة من الممرات دعم حركة المرور وتعليمات كاملة
+\n
+\n • إصلاح أحجام واجهة المستخدم على الأجهزة اللوحية
+\n
 \n • إصلاح الخلل مع RTL
 \n
 \n
@@ -3691,7 +3691,7 @@
     سيتم تبديل زر الإجراء التسجيل بين التشكيلات الجانبية المحددة.
     إضافة ملف تعريف
     تغيير ملف تعريف التطبيق
-    لم يتم العثور على ملفات التعريف المحددة لهذا الإجراء.
+    لم يتم العثور على الأوضاع المحددة لهذا الإجراء.
     خريطة عامة للعالم (تفصيلية)
     نوع غير معتمد
     لم يتم تكوين OsmAnd GPX بشكل جيد ، يرجى الاتصال بفريق الدعم لمزيد من التحقيقات.
@@ -3813,8 +3813,8 @@
     حدد ملف المسار الذي سيتم إضافة مقطع جديد إليه.
     حفظ كمسار جديد
     عكس الطريق
-    سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد.
-    سيتم إعادة حساب المقطع التالي فقط باستخدام ملف التعريف المحدد.
+    سيتم إعادة حساب المقطع التالي فقط باستخدام الوضع المحدد.
+    سيتم إعادة حساب المقطع التالي فقط باستخدام الوضع المحدد.
     حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها على النحو المحدد أدناه.
     مسار كامل
     المقطع التالي
@@ -3863,7 +3863,7 @@
     جميع الأجزاء اللاحقة
     المقطع السابق
     جميع المقاطع السابقة
-    سيتم إعادة حساب المقطع المحدد فقط باستخدام ملف التعريف المحدد.
+    سيتم إعادة حساب المقطع المحدد فقط باستخدام الوضع المحدد.
     سيتم إعادة حساب كافة الشرائح اللاحقة باستخدام ملف التعريف المحدد.
     سيتم إعادة حساب كافة الشرائح السابقة باستخدام ملف التعريف المحدد.
     فتح المسار المحفوظ
@@ -3885,7 +3885,7 @@
 \n
 \n• تم تحسين خيارات متابعة المسار خلال الملاحة
 \n
-\n• تم إصلاح المشكلات المتعلقة باستيراد/تصدير إعدادات الملف الشخصي
+\n• تم إصلاح المشكلات المتعلقة باستيراد/تصدير الأوضاع الشخصية
 \n
 \n
 
\ No newline at end of file

From 58b2a74159c6afd19f6465f03a9d9e7569f58cea Mon Sep 17 00:00:00 2001
From: iman 
Date: Wed, 16 Sep 2020 12:01:20 +0000
Subject: [PATCH 0159/1366] Translated using Weblate (Persian)

Currently translated at 97.8% (3410 of 3484 strings)
---
 OsmAnd/res/values-fa/strings.xml | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml
index dec0c68cd6..e8c4cbb15c 100644
--- a/OsmAnd/res/values-fa/strings.xml
+++ b/OsmAnd/res/values-fa/strings.xml
@@ -1080,7 +1080,7 @@
     انتخاب از موارد موجود…
     تعریف/ویرایش…
     منطقهٔ رانندگی
-    مرکاتور بیضوی
+    فراتابی مرکاتور بیضوی
     نشانی اینترنتی
     ذره‌بین نقشه
     نقشهٔ جهانی پایه
@@ -1411,7 +1411,7 @@
     کنترل مرزی
     عوارضی
     علامت ایست
-    سرعتگیر
+    آرام‌سازی ترافیک
     دوربین سرعت
     هشدار ترافیکی
     فعال‌کردن پروکسی HTTP
@@ -1645,7 +1645,7 @@
     برای دانلود نقشه‌ها لازم است.
     در حال جست‌وجوی مکان…
     فضای خالی
-    ذخیره‌گاه اطلاعات OsmAnd (برای نقشه‌ها، فایل‌های GPX و...): %1$s.
+    ذخیره‌گاه دادهٔ OsmAnd (برای نقشه‌ها، فایل‌های رد و...): %1$s.
     اجازهٔ دسترسی
     اجازهٔ دسترسی به موقعیتتان را بدهید
     مسیریابی و کشف جاهای تازه بدون اتصال به اینترنت
@@ -2374,8 +2374,8 @@
     ذخیرهٔ ردهای ضبط‌شده در پوشه‌های ماهانه
     ردهای ضبط‌شده در زیرپوشه‌های ماهانه ذخیره می‌شود (مثلاً ‎۲۰۱۸-۰۱).
     زوم نمایش: %1$s
-    هنوز فایل GPXای ندارید
-    همچنین می‌توانید فایل‌های GPX را در این پوشه قرار دهید
+    هنوز فایل رد (track) ندارید
+    همچنین می‌توانید فایل‌های رد را در این پوشه قرار دهید
     استفاده از تقسیمگر ضبط‌کننده
     ایجاد یادداشت OSM
     یادداشت OSM بازگشوده
@@ -2919,10 +2919,10 @@
     نوع جاده‌ها
     ایستگاه پیاده‌شدن
     ایستگاه سوارشدن
-    آشکار/پنهان کردن ردهای GPX
-    دکمه‌ای برای آشکار/پنهان کردن ردهای GPX انتخابی بر روی نقشه.
-    پنهان‌کردن ردهای GPX
-    آشکارکردن ردهای GPX
+    آشکار/پنهان کردن ردها
+    دکمه‌ای برای آشکار/پنهان کردن ردهای انتخابی بر روی نقشه.
+    پنهان‌کردن ردها
+    آشکارکردن ردها
     • طراحی جدید برای صفحهٔ «مسیریابی»: اضافه‌شدن دکمه‌های خانه و محل کار برای انتخاب مقصد، میانبر «مسیر قبلی»، لیست نشانه‌ها و ردهای GPX فعال، سابقهٔ جست‌وجو 
 \n 
 \n • اطلاعات بیشتر در قسمت «جزئیات مسیر»: نوع جاده‌ها، سطح، شیب، همواری 
@@ -3771,7 +3771,7 @@
 \nیک هفته ۱۰ ۰۸۰ دقیقه است. 
 \nیک ماه ۴۳ ۸۲۹ دقیقه است.
     شیوهٔ ذخیره‌سازی کاشی‌های دانلودشده را انتخاب کنید.
-    زمان خاموشی پیشفرض صفحه
+    زمان پیشفرض خاموشی صفحه
     می‌توانید کنش‌های فوری را همراه با پروفایل‌های برنامه برون‌برد یا درون‌برد کنید.
     همه حذف شود؟
     آیا %d کنش فوری را حذف می‌کنید؟ (برگشت‌ناپذیر است)
@@ -3804,7 +3804,7 @@
     حذف نصب
     سویه
     ‏%1$s حذف شد
-    برای اینکه دادهٔ دوربین سرعت کاملاً حذف شود، یک بار برنامه را ببندید و باز کنید.
+    برای اینکه دادهٔ دوربین سرعت کاملاً حذف شود، برنامه را ببندید و باز کنید.
     نقاط توجه دوربین سرعت
     قانونِ برخی کشورها استفاده از نرم‌افزارهای هشداردهندهٔ دوربین سرعت را ممنوع کرده است. 
 \n
@@ -3814,16 +3814,16 @@
 \n
 \nبا انتخاب %2$s تا زمانی که OsmAnd را دوباره نصب کنید، تمام دادهٔ مربوط به دوربین‌های سرعت (هشدارها، اعلان‌ها، نقاط توجه) حذف می‌شود.
     قانونِ برخی از کشورها استفاده از هشداردهندهٔ دوربین سرعت را ممنوع کرده است.
-    با این گزینه می‌توانید با استفاده از دکمه‌های کم/زیاد صدای دستگاه سطح زوم را کنترل کنید.
+    با استفاده از دکمه‌های کم/زیاد صدای دستگاه، سطح زوم را کنترل کنید.
     زوم با دکمه‌های صدا
     طول مجاز
     طول مجاز خودرو در مسیرها را مشخص کنید.
     این دستگاه دوربین‌های سرعت را ندارد.
     فعال بماند
-    حذف مقصد بعدی
+    حذف نزدیک‌ترین مقصد
     لطفاً نام نقطه را بنویسید
     دانلود نقشه‌های ویکی‌پدیا
-    از ویکی‌پدیا دربارهٔ نقاط توجه اطلاعات کسب کنید. یک راهنمای آفلاین جیبی. کافی است افزونهٔ ویکی‌پدیا را فعال کنید و از مقاله‌ها دربارهٔ چیزهای دوروبرتان لذت ببرید.
+    از ویکی‌پدیا دربارهٔ نقاط توجه اطلاعات کسب کنید؛ مانند یک راهنمای آفلاین جیبی. کافی است افزونهٔ ویکی‌پدیا را فعال کنید و از مقاله‌های مربوط به چیزهای دوروبرتان لذت ببرید.
     صندلی چرخ‌دار
     یادداشت اُاِس‌اِمی بسته
     نقطهٔ اضافه‌شده روی نقشه دیده نمی‌شود، زیرا گروه انتخاب‌شده پنهان است. آن را در «%s» پیدا می‌کنید.

From e33d49409c8051c9b69bbd769cc677c321bb6a08 Mon Sep 17 00:00:00 2001
From: Ajeje Brazorf 
Date: Wed, 16 Sep 2020 16:31:01 +0000
Subject: [PATCH 0160/1366] Translated using Weblate (Sardinian)

Currently translated at 99.7% (3475 of 3484 strings)
---
 OsmAnd/res/values-sc/strings.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml
index 4036899b1a..8dba26d6c3 100644
--- a/OsmAnd/res/values-sc/strings.xml
+++ b/OsmAnd/res/values-sc/strings.xml
@@ -3887,4 +3887,19 @@
     est sarvadu
     Pro praghere annanghe a su mancu duos puntos.
     Torra a fàghere
+    • Funtzionalidade de pranificatione de un\'àndala agiornada: permitit de impreare castas diferentes de navigatzione pro segmentu e s\'inclusione de rastas
+\n
+\n • New Appearance menu for tracks: select color, thickness, display direction arrows, start/finish icons
+\n
+\n • Visibilidade megiorada de sos nodos pro sas bitzicletas.
+\n
+\n • Como podes incarcare in sas rastas, e faghende gasi as a abèrrere unu menù de cuntestu cun informatziones de base.
+\n
+\n • Algoritmu de chirca megioradu
+\n
+\n • Optziones pro sighire una rasta durante sa navigatzione megioradas
+\n
+\n • Problemas cun s\'importatzione e s\'esportatzione de sas impostatziones de sos profilos risoltos
+\n
+\n
 
\ No newline at end of file

From a7fc59d176f3b59d5fb173d3d550832caa7e19e0 Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Wed, 16 Sep 2020 13:56:27 +0000
Subject: [PATCH 0161/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-uk/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml
index 1bcbb91957..79fb238aee 100644
--- a/OsmAnd/res/values-uk/phrases.xml
+++ b/OsmAnd/res/values-uk/phrases.xml
@@ -3831,4 +3831,5 @@
     Поповнення питної води
     Невеликі електроприлади
     Вулик
+    Насіннєвий магазин
 
\ No newline at end of file

From efba6e140af9804ce172acab36c6f2a378c97821 Mon Sep 17 00:00:00 2001
From: Ajeje Brazorf 
Date: Wed, 16 Sep 2020 16:52:57 +0000
Subject: [PATCH 0162/1366] Translated using Weblate (Sardinian)

Currently translated at 99.4% (3804 of 3824 strings)
---
 OsmAnd/res/values-sc/phrases.xml | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-sc/phrases.xml b/OsmAnd/res/values-sc/phrases.xml
index 9c5f4c8384..df52122c1e 100644
--- a/OsmAnd/res/values-sc/phrases.xml
+++ b/OsmAnd/res/values-sc/phrases.xml
@@ -3811,9 +3811,9 @@
     Raportu cun su livellu de s\'abba: in foras de su livellu mèdiu de s\'abba
     Raportu cun su livellu de s\'abba: in suta de su livellu mèdiu de s\'abba
     Tapadura
-    Ricàrica de s\'abba potàbile: eja
-    Ricàrica de s\'abba potàbile: nono
-    Retza de ricàrica de s\'abba potàbile
+    Eja
+    Ricàrriga de abba potàbile: nono
+    Retza de ricàrriga de abba potàbile
     Sutzione
     Presurizada
     Abba suta de terra
@@ -3830,4 +3830,14 @@
     Unidade amministrativa (Borough)
     Ascensore
     Fritza: nono
+    Butega de pilarda (nughes e àteru)
+    Moju
+    Oràriu
+    Tempus reale
+    Ritardu
+    Eja
+    Tabella de sas tzucadas: nono
+    Eletrodomèsticos minores
+    Tabellone de sas tzucadas
+    Ricàrriga de abba potàbile
 
\ No newline at end of file

From 70cc3ddc58d5015f760acdac23428c5a86e3707c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Babos=20G=C3=A1bor?= 
Date: Wed, 16 Sep 2020 08:16:56 +0000
Subject: [PATCH 0163/1366] Translated using Weblate (Hungarian)

Currently translated at 99.9% (3821 of 3824 strings)
---
 OsmAnd/res/values-hu/phrases.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml
index 891959e0b0..4e0cce87d3 100644
--- a/OsmAnd/res/values-hu/phrases.xml
+++ b/OsmAnd/res/values-hu/phrases.xml
@@ -3833,4 +3833,6 @@
     Kis elektronikus készülékek
     Indulásiidő-kijelző
     Ivóvíz-utántöltés
+    Mag- és aszaltgyümölcsbolt
+    Méhkaptár
 
\ No newline at end of file

From f62c7c733190c9198338a9a82156b39b690b862f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Wed, 16 Sep 2020 16:02:58 +0000
Subject: [PATCH 0164/1366] Translated using Weblate (Estonian)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-et/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml
index 226d25f3ad..dc8cbbac79 100644
--- a/OsmAnd/res/values-et/phrases.xml
+++ b/OsmAnd/res/values-et/phrases.xml
@@ -3825,4 +3825,5 @@
     Joogivee täitmine
     Väikesed elektriseadmed
     Mesitaru
+    Pähklipood
 
\ No newline at end of file

From 59be8e4447154854980f4e1a681d4c36fc1f8447 Mon Sep 17 00:00:00 2001
From: Eduardo Addad de Oliveira 
Date: Wed, 16 Sep 2020 14:40:29 +0000
Subject: [PATCH 0165/1366] Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-pt-rBR/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml
index c6eea35aa5..dd7c249f87 100644
--- a/OsmAnd/res/values-pt-rBR/phrases.xml
+++ b/OsmAnd/res/values-pt-rBR/phrases.xml
@@ -3843,4 +3843,5 @@
     Recarga de água potável
     Pequenos aparelhos elétricos
     Colmeia
+    Loja de nozes
 
\ No newline at end of file

From fb1689e767daa39078f1c15d8aa9630085453ef1 Mon Sep 17 00:00:00 2001
From: iman 
Date: Wed, 16 Sep 2020 12:17:31 +0000
Subject: [PATCH 0166/1366] Translated using Weblate (Persian)

Currently translated at 29.2% (78 of 267 strings)

Translation: OsmAnd/Telegram
Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/fa/
---
 OsmAnd-telegram/res/values-fa/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd-telegram/res/values-fa/strings.xml b/OsmAnd-telegram/res/values-fa/strings.xml
index af2e8f441c..113a944e7c 100644
--- a/OsmAnd-telegram/res/values-fa/strings.xml
+++ b/OsmAnd-telegram/res/values-fa/strings.xml
@@ -73,9 +73,9 @@
     یکاهای طول را تغییر دهید.
     یکاهای طول
     ظاهر
-    آخرین پاسخ:٪ 1 $ s پیش
-    آخرین به روزرسانی از تلگرام:٪ 1 $ s پیش
+    آخرین پاسخ: %1$s پیش
+    آخرین به‌روزرسانی تلگرام: %1$s پیش
     آخرین پاسخ: %1$s
-    آخرین به روز رسانی در تلگرام:%1$s
-    اشتباه بودن
+    آخرین به‌روزرسانی تلگرام: %1$s
+    خطا
 
\ No newline at end of file

From c5b976d6b217a83de26d89598fb81877ca8589d9 Mon Sep 17 00:00:00 2001
From: Hinagiku Zeppeki 
Date: Wed, 16 Sep 2020 09:31:08 +0000
Subject: [PATCH 0167/1366] Translated using Weblate (Japanese)

Currently translated at 90.2% (241 of 267 strings)

Translation: OsmAnd/Telegram
Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/ja/
---
 OsmAnd-telegram/res/values-ja/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd-telegram/res/values-ja/strings.xml b/OsmAnd-telegram/res/values-ja/strings.xml
index 71c5af7daf..1829c1fcc9 100644
--- a/OsmAnd-telegram/res/values-ja/strings.xml
+++ b/OsmAnd-telegram/res/values-ja/strings.xml
@@ -219,8 +219,8 @@
     国際形式でTelegramを利用する端末の電話番号を入力してください(日本の場合+81を先頭につけて電話番号最初の0を除いた番号を入力)
     ようこそ
     ヤード
-    フィート
-    マイル
+    ft
+    mi
     km
     m
     海里

From 9409c779586e0d0e12ebac5b6b8ddfa88ff8ee57 Mon Sep 17 00:00:00 2001
From: Nikita Epifanov 
Date: Wed, 16 Sep 2020 09:52:49 +0000
Subject: [PATCH 0168/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-ru/phrases.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml
index 2f7dba711d..f67e31fb94 100644
--- a/OsmAnd/res/values-ru/phrases.xml
+++ b/OsmAnd/res/values-ru/phrases.xml
@@ -3830,4 +3830,6 @@
     Задержка
     Расписание
     Малые электроприборы
+    Магазин орехов
+    Улей
 
\ No newline at end of file

From c48822279a2ca5a113b4bc3a87d404072030cc07 Mon Sep 17 00:00:00 2001
From: Yaron Shahrabani 
Date: Wed, 16 Sep 2020 17:25:45 +0000
Subject: [PATCH 0169/1366] Translated using Weblate (Hebrew)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-iw/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml
index 1e25024941..2971332a22 100644
--- a/OsmAnd/res/values-iw/strings.xml
+++ b/OsmAnd/res/values-iw/strings.xml
@@ -3837,7 +3837,7 @@
     נא לבחור קובץ מסלול שבו יתווסף המקטע החדש.
     כל המסלול יחושב מחדש באמצעות הפרופיל הנבחר.
     רק המקטע הבא יחושב מחודש באמצעות הפרופיל הנבחר.
-    נא לבחור כיצד לחבר נקודות, בקו ישר, או לחבר מסלול ביניהן עם הפרופיל הנבחר.
+    נא לבחור כיצד לחבר נקודות, בקו ישר, או לחבר מסלול ביניהן כפי שצוין להלן.
     כדי להשתמש באפשרות זו על OsmAnd להצמיד את המסלול שלך לדרכים שעל המפה.
 \n
 \n בשלב הבא יהיה עליך לבחור בפרופיל ניווט כדי לזהות את הדרכים המורשות ואת סף המרחק כדי להעריך את המסלול שלך ביחס לדרכים.

From 21f9e6ac626e90c718afe350b4091663e98cb12b Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Wed, 16 Sep 2020 20:16:13 +0000
Subject: [PATCH 0170/1366] Translated using Weblate (Russian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 55ff01a9a1..211819502e 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -1386,7 +1386,7 @@
     Задать пункт назначения
     Предпочтения маршрута
     Информация про маршрут
-    Добавить следующим пунктом назначения
+    Добавить как новый пункт назначения
     Использовать показанный путь для навигации?
     Рассчитать сегмент маршрута OsmAnd без интернета
     Рассчитать маршрут OsmAnd для первого и последнего сегмента маршрута

From d771db6481821ab9615050c4819066b359fafbb4 Mon Sep 17 00:00:00 2001
From: Franco 
Date: Wed, 16 Sep 2020 21:02:04 +0000
Subject: [PATCH 0171/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-es-rAR/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml
index e1839d42f2..4019b950b2 100644
--- a/OsmAnd/res/values-es-rAR/phrases.xml
+++ b/OsmAnd/res/values-es-rAR/phrases.xml
@@ -3850,4 +3850,5 @@
     Recarga de agua potable
     Pequeños electrodomésticos
     Panal de abejas
+    Frutos secos
 
\ No newline at end of file

From 96650032b7da91df23c83b70cba359f2e2798d60 Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Thu, 17 Sep 2020 02:16:08 +0000
Subject: [PATCH 0172/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-zh-rTW/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml
index 352282d071..25766f928e 100644
--- a/OsmAnd/res/values-zh-rTW/phrases.xml
+++ b/OsmAnd/res/values-zh-rTW/phrases.xml
@@ -3842,4 +3842,5 @@
     飲用水補充
     小電器
     蜂箱
+    堅果店
 
\ No newline at end of file

From e2d83127717a411d320df2ad3eb6e0cab311cc9c Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 11:59:39 +0300
Subject: [PATCH 0173/1366] Fix #9746

---
 .../SaveAsNewTrackBottomSheetDialogFragment.java             | 4 +++-
 .../plus/measurementtool/adapter/FolderListAdapter.java      | 3 ++-
 .../plus/routepreparationmenu/ChooseRouteFragment.java       | 5 ++++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
index fb1badf2aa..40877bf8dc 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
@@ -76,6 +76,8 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 			sourceFileName = savedInstanceState.getString(SOURCE_FILE_NAME_KEY);
 			sourceFolderName = savedInstanceState.getString(SOURCE_FOLDER_NAME_KEY);
 			showSimplifiedButton = savedInstanceState.getBoolean(SHOW_SIMPLIFIED_BUTTON_KEY);
+		} else {
+			folderName = app.getAppPath(IndexConstants.GPX_INDEX_DIR).getName();
 		}
 
 		items.add(new TitleItem(getString(R.string.save_as_new_track)));
@@ -290,7 +292,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 	private File getFile(OsmandApplication app, String folderName, String fileName) {
 		File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
 		File source = dir;
-		if (folderName != null) {
+		if (folderName != null && !dir.getName().equals(folderName)) {
 			source = new File(dir, folderName);
 		}
 		source = new File(source, fileName + IndexConstants.GPX_FILE_EXT);
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java b/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java
index b207d7aac5..b383a4bef6 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java
@@ -48,7 +48,8 @@ public class FolderListAdapter extends RecyclerView.Adapter getFolders() {
 		List dirs = new ArrayList<>();
-		final File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
+		File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
+		dirs.add(gpxDir);
 		Algorithms.collectDirs(gpxDir, dirs);
 		List dirItems = new ArrayList<>();
 		for (File dir : dirs) {
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
index b7b87f01b2..0f804013ca 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
@@ -894,7 +894,10 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe
 	public void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack) {
 		OsmandApplication app = getMyApplication();
 		if (app != null) {
-			File fileDir = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), folderName == null ? "" : folderName);
+			File fileDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
+			if (!fileDir.getName().equals(folderName)) {
+				fileDir = new File(fileDir, folderName);
+			}
 			File toSave = new File(fileDir, fileName + GPX_FILE_EXT);
 			new SaveDirectionsAsyncTask(app, showOnMap).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, toSave);
 		}

From 685e519a38dcdefb1f882f1034e985ef88f5ed1a Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 12:13:05 +0300
Subject: [PATCH 0174/1366] Fix check for folder name

---
 .../osmand/plus/measurementtool/MeasurementToolFragment.java    | 2 +-
 .../osmand/plus/routepreparationmenu/ChooseRouteFragment.java   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index d80eddb6b7..e2e4d79531 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -1037,7 +1037,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		OsmandApplication app = getMyApplication();
 		if (app != null) {
 			File dir = getMyApplication().getAppPath(GPX_INDEX_DIR);
-			if (folderName != null) {
+			if (folderName != null && !dir.getName().equals(folderName)) {
 				dir = new File(dir, folderName);
 			}
 			fileName += GPX_FILE_EXT;
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
index 0f804013ca..004f5c4d2b 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
@@ -895,7 +895,7 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe
 		OsmandApplication app = getMyApplication();
 		if (app != null) {
 			File fileDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
-			if (!fileDir.getName().equals(folderName)) {
+			if (folderName != null && !fileDir.getName().equals(folderName)) {
 				fileDir = new File(fileDir, folderName);
 			}
 			File toSave = new File(fileDir, fileName + GPX_FILE_EXT);

From 0a034ab399cba745f56946fd893b4eacf498c01d Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Thu, 17 Sep 2020 12:31:26 +0300
Subject: [PATCH 0175/1366]  Address doesn't saved if it enters manualy while
 adding favorite

---
 .../editors/FavoritePointEditorFragmentNew.java              | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java
index 9bfe58324a..3e4093d253 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java
@@ -307,7 +307,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
 		FavoritePointEditor editor = getFavoritePointEditor();
 		if (editor != null && helper != null) {
 			if (editor.isNew()) {
-				doAddFavorite(name, category, description, color, backgroundType, iconId);
+				doAddFavorite(name, category, description, address, color, backgroundType, iconId);
 			} else {
 				doEditFavorite(favorite, name, category, description, address, color, backgroundType, iconId, helper);
 			}
@@ -341,7 +341,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
 		}
 	}
 
-	private void doAddFavorite(String name, String category, String description, @ColorInt int color,
+	private void doAddFavorite(String name, String category, String description, String address, @ColorInt int color,
 	                           BackgroundType backgroundType, @DrawableRes int iconId) {
 		OsmandApplication app = getMyApplication();
 		FavouritesDbHelper helper = getHelper();
@@ -350,6 +350,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
 			favorite.setName(name);
 			favorite.setCategory(category);
 			favorite.setDescription(description);
+			favorite.setAddress(address);
 			favorite.setColor(color);
 			favorite.setBackgroundType(backgroundType);
 			favorite.setIconId(iconId);

From 20e6b41cbe15875b829cd9cf1abd52e76d4f1729 Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Thu, 17 Sep 2020 13:06:25 +0300
Subject: [PATCH 0176/1366] Show type for "Base profiles" too, except "Browse
 map"

---
 .../plus/activities/MapActivityActions.java       | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index ea597558e1..36fa32f634 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -738,9 +738,9 @@ public class MapActivityActions implements DialogProvider {
 		Map profilesObjects = getRoutingProfiles(app);
 		for (final ApplicationMode appMode : activeModes) {
 			if (appMode.isCustomProfile()) {
-				modeDescription = getCustomProfileDescription(app, appMode, profilesObjects);
+				modeDescription = getCustomProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_custom_string));
 			} else {
-				modeDescription = getString(R.string.profile_type_base_string);
+				modeDescription = getCustomProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_base_string));
 			}
 
 			int tag = currentMode.equals(appMode) ? PROFILES_CHOSEN_PROFILE_TAG : PROFILES_NORMAL_PROFILE_TAG;
@@ -1047,12 +1047,13 @@ public class MapActivityActions implements DialogProvider {
 		//switch profile button
 		ApplicationMode currentMode = app.getSettings().APPLICATION_MODE.get();
 		String modeDescription;
+		Map profilesObjects = getRoutingProfiles(app);
 		if (currentMode.isCustomProfile()) {
-			Map profilesObjects = getRoutingProfiles(app);
-			modeDescription = getCustomProfileDescription(app, currentMode, profilesObjects);
+			modeDescription = getCustomProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_custom_string));
 		} else {
-			modeDescription = getString(R.string.profile_type_base_string);
+			modeDescription = getCustomProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_base_string));
 		}
+
 		int icArrowResId = listExpanded ? R.drawable.ic_action_arrow_drop_up : R.drawable.ic_action_arrow_drop_down;
 		final int nextMode = listExpanded ? DRAWER_MODE_NORMAL : DRAWER_MODE_SWITCH_PROFILE;
 		optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_switch_profile)
@@ -1085,8 +1086,8 @@ public class MapActivityActions implements DialogProvider {
 	}
 
 	private String getCustomProfileDescription(OsmandApplication app, ApplicationMode mode,
-	                                           Map profilesObjects){
-		String	description = getString(R.string.profile_type_custom_string);
+	                                           Map profilesObjects, String defaultDescription){
+		String	description = defaultDescription;
 
 		String routingProfileKey = mode.getRoutingProfile();
 		if (!Algorithms.isEmpty(routingProfileKey)) {

From a0e2b260212b38504aadb2fc47ac5c248b24c1c6 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 13:14:34 +0300
Subject: [PATCH 0177/1366] Fix context menu visibility

---
 .../editors/PointEditorFragmentNew.java         | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
index 3214817780..7500a17d77 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
@@ -817,11 +817,15 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 		hideKeyboard();
 		MapActivity mapActivity = getMapActivity();
 		if (mapActivity != null) {
+			MapContextMenu mapContextMenu = mapActivity.getContextMenu();
 			if (includingMenu) {
 				mapActivity.getSupportFragmentManager().popBackStack();
-				mapActivity.getContextMenu().close();
+				mapContextMenu.close();
 			} else {
 				mapActivity.getSupportFragmentManager().popBackStack();
+				if (!mapContextMenu.isVisible() && mapContextMenu.isActive()) {
+					mapContextMenu.show();
+				}
 			}
 		}
 	}
@@ -932,17 +936,6 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
 	private void exitEditing() {
 		cancelled = true;
 		dismiss();
-		showContextMenu();
-	}
-
-	private void showContextMenu() {
-		MapActivity mapActivity = getMapActivity();
-		if (mapActivity != null) {
-			MapContextMenu mapContextMenu = mapActivity.getContextMenu();
-			if (!mapContextMenu.isVisible() && mapContextMenu.isActive()) {
-				mapContextMenu.show();
-			}
-		}
 	}
 
 	private AlertDialog.Builder createWarningDialog(Activity activity, int title, int message, int negButton) {

From 4aabbfaef635a57b3869caf48e4d08243aad9cea Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 13:22:12 +0300
Subject: [PATCH 0178/1366] Rename method

---
 .../osmand/plus/activities/MapActivityActions.java   | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 36fa32f634..5414b9c0f7 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -738,9 +738,9 @@ public class MapActivityActions implements DialogProvider {
 		Map profilesObjects = getRoutingProfiles(app);
 		for (final ApplicationMode appMode : activeModes) {
 			if (appMode.isCustomProfile()) {
-				modeDescription = getCustomProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_custom_string));
+				modeDescription = getProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_custom_string));
 			} else {
-				modeDescription = getCustomProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_base_string));
+				modeDescription = getProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_base_string));
 			}
 
 			int tag = currentMode.equals(appMode) ? PROFILES_CHOSEN_PROFILE_TAG : PROFILES_NORMAL_PROFILE_TAG;
@@ -1049,9 +1049,9 @@ public class MapActivityActions implements DialogProvider {
 		String modeDescription;
 		Map profilesObjects = getRoutingProfiles(app);
 		if (currentMode.isCustomProfile()) {
-			modeDescription = getCustomProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_custom_string));
+			modeDescription = getProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_custom_string));
 		} else {
-			modeDescription = getCustomProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_base_string));
+			modeDescription = getProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_base_string));
 		}
 
 		int icArrowResId = listExpanded ? R.drawable.ic_action_arrow_drop_up : R.drawable.ic_action_arrow_drop_down;
@@ -1085,8 +1085,8 @@ public class MapActivityActions implements DialogProvider {
 				.createItem());
 	}
 
-	private String getCustomProfileDescription(OsmandApplication app, ApplicationMode mode,
-	                                           Map profilesObjects, String defaultDescription){
+	private String getProfileDescription(OsmandApplication app, ApplicationMode mode,
+	                                     Map profilesObjects, String defaultDescription){
 		String	description = defaultDescription;
 
 		String routingProfileKey = mode.getRoutingProfile();

From d263131a75b2ecae6ce8ac4aefba45cf62da3f25 Mon Sep 17 00:00:00 2001
From: Ferdi 
Date: Thu, 17 Sep 2020 08:10:12 +0000
Subject: [PATCH 0179/1366] Translated using Weblate (German)

Currently translated at 99.9% (3822 of 3824 strings)
---
 OsmAnd/res/values-de/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml
index 53f9e13926..14173b1d76 100644
--- a/OsmAnd/res/values-de/phrases.xml
+++ b/OsmAnd/res/values-de/phrases.xml
@@ -3844,4 +3844,5 @@
     Abbiegepfeil: nein
     Anzeige der Abreisezeiten
     Nachfüllen von Trinkwasser
+    Bienenstock
 
\ No newline at end of file

From 46be5ece691509bd876500e77e41d0b24917892e Mon Sep 17 00:00:00 2001
From: Ferdi 
Date: Thu, 17 Sep 2020 08:12:17 +0000
Subject: [PATCH 0180/1366] Translated using Weblate (French)

Currently translated at 99.7% (3813 of 3824 strings)
---
 OsmAnd/res/values-fr/phrases.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-fr/phrases.xml b/OsmAnd/res/values-fr/phrases.xml
index b90c5e8bde..638995c1f2 100644
--- a/OsmAnd/res/values-fr/phrases.xml
+++ b/OsmAnd/res/values-fr/phrases.xml
@@ -3814,7 +3814,7 @@
     Niveau d\'eau : au-dessus du niveau d\'eau moyen
     Niveau d\'eau : en-dessous du niveau d\'eau moyen
     Obstacle
-    Remplissage d\'eau potable : oui
+    Oui
     Remplissage d\'eau potable : non
     Réseau de remplissage d\'eau potable
     Uniquement si la marche est autorisée

From 554e6a1844b54394a7bc8d15b03d0120a8ecbf2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Thu, 17 Sep 2020 10:27:05 +0000
Subject: [PATCH 0181/1366] Translated using Weblate (Estonian)

Currently translated at 98.5% (3434 of 3484 strings)
---
 OsmAnd/res/values-et/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml
index 2c829dcfd0..fea216bce3 100644
--- a/OsmAnd/res/values-et/strings.xml
+++ b/OsmAnd/res/values-et/strings.xml
@@ -3181,7 +3181,7 @@
     Nupp alloleva loendi sirvimiseks.
     OsmAnd (OSM automatiseeritud navigeerimisjuhised) on kaardi- ja navigatsioonirakendus, millel on juurdepääs tasuta, ülemaailmsetele ja kvaliteetsetele OpenStreetMap (OSM) andmetele.
 \n
-\n Naudi hääl- ja optilist navigaatorit, HP-de (huvipunktide) vaatamist, GPX radade loomist ja haldamist, kõrgusjoonte visuaalse kuvamise ja kõrguse teabe kasutamist (lisa kaudu), valikut sõidu, jalgrattasõidu, jalakäijate režiimide, OSM redigeerimise ja palju muu vahel.
+\n Naudi hääl- ja optilist navigaatorit, HP-de (huvipunktide) vaatamist, GPX radade loomist ja haldamist, kõrgusjoonte visuaalse kuvamise ja kõrguse teabe kasutamist (lisa kaudu), valikut sõidu, jalgrattasõidu, jalakäijate režiimide, OSM\'i andmete muutmise ja palju muu vahel.
     Kaart
 \n • Kuvab HP-d (huvipunktid) sinu ümber
 \n • Kohandab kaarti sinu liikumissuunaga (või kompassiga)
@@ -3557,7 +3557,7 @@
     Helitugevuse nupud toimivad suumina
     Palun sisestage punkti nimi
     Lae alla Vikipeedia kaardid
-    Hangi huviväärsuste kohta teavet Vikipeediast. See on sinu võrguühenduseta reisiraamat - luba lihtsalt Vikipeedia lisaprogramm ja loe artikleid enda ümber asuvate objektide kohta.
+    Hangi huviväärsuste kohta teavet Vikipeediast. See on sinu võrguühenduseta reisiraamat - lihtsalt võta kasutusele Vikipeedia lisaprogramm ja loe artikleid enda ümber asuvate objektide kohta.
     Kuna valitud grupp on peidetud, siis lisatud punkt ei ole kaardil nähtav. Vajadusel leiad ta „%s“ alt.
     Kartauto
     Parkimiskohad
@@ -3728,7 +3728,7 @@
     Kärbi enne
     Kinnita teede külge
     Selle valiku kasutamiseks mõne oma navigeerimisprofiili kasutamisel kinnita oma rada lähimale lubatud teele.
-    Valitud profiili alusel arvutatakse uus teekond vaid järgmise segmendi osas.
+    Selle valitud profiili alusel arvutatakse uus teekond vaid järgmise segmendi osas.
     Põhitegevused
     Ostu kinnitusel võetakse sinu Google Play kontolt tasu.
 \n
@@ -3737,7 +3737,7 @@
 \nTellimuste haldamiseks ja tühistamiseks ava Google Play seadistused.
     Kiirtegevusi saad eksportida või importida koos rakenduse profiilidega.
     Kas sa oled kindel, et soovid pöördumatult kustutada %d kiirtegevust\?
-    Vali kas soovid ühendada punkte sirge joonega või arvutada nendevahelist teekonda vastavalt oma valitud profiilile.
+    Vali kas soovid ühendada punkte sirge joonega või arvutada nendevahelist teekonda selle alusel kuidas järgnevalt on määratud.
     • Uuendatud teekonnaplaneerija: võimaldab kasutada igal segmendil erinevat liikumisviisi ning radade kaasamist
 \n
 \n • Uus radade kujunduse seadistamise menüü: valida saad värve, joone paksust, suunanoolte kuvamist ning alguse ja lõpu ikoone

From 18572799c407de22758cd7f71adbb46e593cd9a1 Mon Sep 17 00:00:00 2001
From: Dmitry 
Date: Thu, 17 Sep 2020 13:50:04 +0300
Subject: [PATCH 0182/1366] Rename string value

---
 OsmAnd/res/values/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 3f8159283b..c497ffda36 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -3251,7 +3251,7 @@
     The selected language is not supported by the Android TTS (text-to-speech) engine installed, its preset TTS language will be used instead. Look for another TTS engine in the market?
     Missing data
     Go to the market to download selected language?
-    Reverse GPX direction
+    Reverse track direction
     Use current destination
     Pass along entire track
     

From 90292541ef92f067f3e143549321820f629e8b39 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 14:34:33 +0300
Subject: [PATCH 0183/1366] Show context menu with coordinates on long tap

---
 OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java
index 4567770e9c..7a8690fe2d 100644
--- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java
@@ -323,7 +323,9 @@ public class ContextMenuLayer extends OsmandMapLayer {
 			return false;
 		}
 
-		showContextMenu(point, tileBox, true);
+		LatLon pointLatLon = tileBox.getLatLonFromPixel(point.x, point.y);
+		menu.show(pointLatLon, null, null);
+
 		view.refreshMap();
 		return true;
 	}

From 2f6ccfe6be048b5cbebe9138214238afde34fafb Mon Sep 17 00:00:00 2001
From: Nazar-Kutz 
Date: Thu, 17 Sep 2020 15:26:18 +0300
Subject: [PATCH 0184/1366] Fix #9555

---
 .../net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java  | 4 ++--
 OsmAnd/src/net/osmand/plus/views/YandexTrafficAdapter.java  | 6 +-----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java
index e40a911027..da7a7882d3 100644
--- a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java
@@ -149,10 +149,10 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
 			underlayLayer.setMap(null);
 		}
 		if(settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.get() == LayerTransparencySeekbarMode.UNDERLAY &&
-				underlayLayer.getMap() != null) {
+				underlayLayer.getMap() != null || underlayLayer.getMapTileAdapter() != null) {
 			layers.getMapControlsLayer().showTransparencyBar(settings.MAP_TRANSPARENCY, true);
 		} else if(settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.get() == LayerTransparencySeekbarMode.OVERLAY &&
-				overlayLayer.getMap() != null) {
+				overlayLayer.getMap() != null || overlayLayer.getMapTileAdapter() != null) {
 			layers.getMapControlsLayer().showTransparencyBar(settings.MAP_OVERLAY_TRANSPARENCY, true);
 		} else {
 			layers.getMapControlsLayer().hideTransparencyBar();
diff --git a/OsmAnd/src/net/osmand/plus/views/YandexTrafficAdapter.java b/OsmAnd/src/net/osmand/plus/views/YandexTrafficAdapter.java
index a58713c4cc..1118cfd514 100644
--- a/OsmAnd/src/net/osmand/plus/views/YandexTrafficAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/views/YandexTrafficAdapter.java
@@ -25,6 +25,7 @@ public class YandexTrafficAdapter  extends MapTileAdapter {
 
 	private final static Log log = PlatformUtil.getLog(MapTileLayer.class);
 	private final static String YANDEX_PREFFIX = ".YandexTraffic_";
+	private final static String YANDEX_BASE_URL = "https://core-jams-rdr.maps.yandex.net";
 	private static final long DELTA = 10 * 60 * 1000;
 	
 	private long lastTimestampUpdated;
@@ -59,11 +60,6 @@ public class YandexTrafficAdapter  extends MapTileAdapter {
 	}
 
 	protected void updateTimeStampImpl() {
-		String YANDEX_BASE_URL;
-		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
-			YANDEX_BASE_URL = "https://core-jams-rdr.maps.yandex.net";
-		else
-			YANDEX_BASE_URL = "http://core-jams-rdr.maps.yandex.net";
 		if (mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) {
 			log.info("Updating timestamp"); //$NON-NLS-1$
 			try {

From 6e41ea64b3a145257cf07058f5179a8b2e46c09e Mon Sep 17 00:00:00 2001
From: Victor Shcherb 
Date: Thu, 17 Sep 2020 15:43:04 +0200
Subject: [PATCH 0185/1366] Fix gpx approximation

---
 OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
index 61d8408fe6..4650d527ae 100644
--- a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
+++ b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
@@ -91,8 +91,8 @@ public class GpxApproximator {
 		this.env = routingHelper.getRoutingEnvironment(ctx, mode, start, end);
 	}
 
-	private GpxRouteApproximation getNewGpxApproximationContext(@Nullable GpxRouteApproximation gctx) {
-		GpxRouteApproximation newContext = gctx != null ? new GpxRouteApproximation(gctx) : new GpxRouteApproximation(env.getCtx());
+	private GpxRouteApproximation getNewGpxApproximationContext() {
+		GpxRouteApproximation newContext = new GpxRouteApproximation(env.getCtx());
 		newContext.ctx.calculationProgress = new RouteCalculationProgress();
 		newContext.MINIMUM_POINT_APPROXIMATION = pointApproximation;
 		return newContext;
@@ -100,7 +100,7 @@ public class GpxApproximator {
 
 	private List getPoints() {
 		if (points == null) {
-			points = routingHelper.generateGpxPoints(env, getNewGpxApproximationContext(null), locationsHolder);
+			points = routingHelper.generateGpxPoints(env, getNewGpxApproximationContext(), locationsHolder);
 		}
 		List points = new ArrayList<>(this.points.size());
 		for (GpxPoint p : this.points) {
@@ -150,7 +150,7 @@ public class GpxApproximator {
 		if (gctx != null) {
 			gctx.ctx.calculationProgress.isCancelled = true;
 		}
-		final GpxRouteApproximation gctx = getNewGpxApproximationContext(this.gctx);
+		final GpxRouteApproximation gctx = getNewGpxApproximationContext();
 		this.gctx = gctx;
 		startProgress();
 		updateProgress(gctx);

From ed0f5a4c48fa1985253890a80b07acf7690ef771 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 16:58:02 +0300
Subject: [PATCH 0186/1366] Add ability to sort tracks initial commit

---
 .../plus/myplaces/AvailableGPXFragment.java   | 43 ++++++++++++++++++-
 .../plus/settings/backend/OsmandSettings.java |  3 ++
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 6e862b5d4b..4e3da567af 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -37,6 +37,7 @@ import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
@@ -102,7 +103,11 @@ import java.util.regex.Pattern;
 import static net.osmand.plus.GpxSelectionHelper.CURRENT_TRACK;
 import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB;
 import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID;
-import static net.osmand.util.Algorithms.*;
+import static net.osmand.util.Algorithms.capitalizeFirstLetter;
+import static net.osmand.util.Algorithms.collectDirs;
+import static net.osmand.util.Algorithms.formatDuration;
+import static net.osmand.util.Algorithms.objectEquals;
+import static net.osmand.util.Algorithms.removeAllFiles;
 
 public class AvailableGPXFragment extends OsmandExpandableListFragment implements
 	FavoritesFragmentStateHolder {
@@ -129,6 +134,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 	private boolean importing = false;
 	private View emptyView;
 	private GpxSelectionHelper.SelectGpxTaskListener gpxTaskListener;
+	private boolean sortByName;
 
 	@Override
 	public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -157,6 +163,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 	public void onAttach(Context activity) {
 		super.onAttach(activity);
 		this.app = (OsmandApplication) getActivity().getApplication();
+		sortByName = app.getSettings().SORT_TRACKS_BY_NAME.get();
 		final Collator collator = Collator.getInstance();
 		collator.setStrength(Collator.SECONDARY);
 		currentRecording = new GpxInfo(getMyApplication().getSavingTrackHelper().getCurrentGpx(), getString(R.string.shared_string_currently_recording_track));
@@ -495,6 +502,8 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 					addTrack();
 				}else if (itemId == R.string.coordinate_input) {
 					openCoordinatesInput();
+				} else if (itemId == R.string.shared_string_sort) {
+					updateTracksSort();
 				}
 				return true;
 			}
@@ -512,6 +521,8 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 				.setIcon(R.drawable.ic_action_delete_dark).setListener(listener).createItem());
 		optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.shared_string_refresh, getActivity())
 				.setIcon(R.drawable.ic_action_refresh_dark).setListener(listener).createItem());
+		optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.shared_string_sort, getActivity())
+				.setIcon(getSortIconId(!sortByName)).setListener(listener).createItem());
 		OsmandPlugin.onOptionsMenuActivity(getActivity(), this, optionsMenuAdapter);
 		for (int j = 0; j < optionsMenuAdapter.length(); j++) {
 			final MenuItem item;
@@ -536,6 +547,11 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		}
 	}
 
+	@DrawableRes
+	private int getSortIconId(boolean sortByName) {
+		return sortByName ? R.drawable.ic_action_sort_by_name : R.drawable.ic_action_list_sort;
+	}
+
 	public void doAction(int actionResId) {
 		if (actionResId == R.string.shared_string_delete) {
 			operationTask = new DeleteGpxTask();
@@ -554,6 +570,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		for (int i = 0; i < optionsMenuAdapter.length(); i++) {
 			ContextMenuItem contextMenuItem = optionsMenuAdapter.getItem(i);
 			if (itemId == contextMenuItem.getTitleId()) {
+				if (itemId == R.string.shared_string_sort) {
+					item.setIcon(getSortIconId(!sortByName));
+				}
 				contextMenuItem.getItemClickListener().onContextMenuClick(null, itemId, i, false, null);
 				return true;
 			}
@@ -565,6 +584,12 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		((FavoritesActivity) getActivity()).addTrack();
 	}
 
+	private void updateTracksSort() {
+		sortByName = !sortByName;
+		app.getSettings().SORT_TRACKS_BY_NAME.set(sortByName);
+		reloadTracks();
+	}
+
 	private void openCoordinatesInput() {
 		CoordinateInputDialogFragment fragment = new CoordinateInputDialogFragment();
 		fragment.setRetainInstance(true);
@@ -929,6 +954,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		@Override
 		protected void onPostExecute(List result) {
 			this.result = result;
+			allGpxAdapter.sort();
 			allGpxAdapter.refreshSelected();
 			hideProgressBar();
 			listView.setEmptyView(emptyView);
@@ -1112,8 +1138,21 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			data.get(category.get(found)).add(info);
 		}
 
-		// disable sort
 		public void sort() {
+			for (List items : data.values()) {
+				Collections.sort(items, new Comparator() {
+					@Override
+					public int compare(GpxInfo i1, GpxInfo i2) {
+						if (sortByName) {
+							return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+						} else {
+							long modified1 = i1.file.lastModified();
+							long modified2 = i2.file.lastModified();
+							return (modified1 < modified2) ? -1 : ((modified1 == modified2) ? 0 : 1);
+						}
+					}
+				});
+			}
 			Collections.sort(category, new Comparator() {
 				@Override
 				public int compare(String lhs, String rhs) {
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
index 4baca18a19..a860d4c65c 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
@@ -3936,6 +3936,9 @@ public class OsmandSettings {
 	public final CommonPreference FAVORITES_TAB =
 			new IntPreference("FAVORITES_TAB", 0).makeGlobal().cache();
 
+	public final CommonPreference SORT_TRACKS_BY_NAME
+			= new BooleanPreference("sort_tracks_by_name", true).makeGlobal().cache();
+
 	public final CommonPreference OSMAND_THEME =
 			new IntPreference("osmand_theme", OSMAND_LIGHT_THEME) {
 				@Override

From 080d9f4794f21bf430a3e43451252e8c8a67785c Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 17:46:02 +0300
Subject: [PATCH 0187/1366] Fix sorting selected tracks

---
 .../plus/myplaces/AvailableGPXFragment.java   | 31 +++++++++++++------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 4e3da567af..3856615d8e 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -570,10 +570,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		for (int i = 0; i < optionsMenuAdapter.length(); i++) {
 			ContextMenuItem contextMenuItem = optionsMenuAdapter.getItem(i);
 			if (itemId == contextMenuItem.getTitleId()) {
+				contextMenuItem.getItemClickListener().onContextMenuClick(null, itemId, i, false, null);
 				if (itemId == R.string.shared_string_sort) {
 					item.setIcon(getSortIconId(!sortByName));
 				}
-				contextMenuItem.getItemClickListener().onContextMenuClick(null, itemId, i, false, null);
 				return true;
 			}
 		}
@@ -954,7 +954,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		@Override
 		protected void onPostExecute(List result) {
 			this.result = result;
-			allGpxAdapter.sort();
 			allGpxAdapter.refreshSelected();
 			hideProgressBar();
 			listView.setEmptyView(emptyView);
@@ -974,11 +973,15 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			Arrays.sort(listFiles, new Comparator() {
 				@Override
 				public int compare(File f1, File f2) {
-					// here we could guess date from file name '2017-08-30 ...' - first part date
-					if (f1.lastModified() == f2.lastModified()) {
+					if (sortByName) {
 						return -f1.getName().compareTo(f2.getName());
+					} else {
+						// here we could guess date from file name '2017-08-30 ...' - first part date
+						if (f1.lastModified() == f2.lastModified()) {
+							return -f1.getName().compareTo(f2.getName());
+						}
+						return -Long.compare(f1.lastModified(), f2.lastModified());
 					}
-					return -Long.compare(f1.lastModified(), f2.lastModified());
 				}
 			});
 			return listFiles;
@@ -995,8 +998,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		}
 
 		private void loadGPXFolder(File mapPath, List result, LoadGpxTask loadTask, List progress,
-								   String gpxSubfolder) {
-			for (File gpxFile : listFilesSorted(mapPath)) {
+		                           String gpxSubfolder) {
+			File[] listFiles = listFilesSorted(mapPath);
+			for (File gpxFile : listFiles) {
 				if (gpxFile.isDirectory()) {
 					String sub = gpxSubfolder.length() == 0 ? gpxFile.getName() : gpxSubfolder + "/"
 							+ gpxFile.getName();
@@ -1011,7 +1015,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 						loadTask.loadFile(progress.toArray(new GpxInfo[progress.size()]));
 						progress.clear();
 					}
-
 				}
 			}
 		}
@@ -1019,7 +1022,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		public List getResult() {
 			return result;
 		}
-
 	}
 
 	protected class GpxIndexesAdapter extends OsmandBaseExpandableListAdapter implements Filterable {
@@ -1076,7 +1078,16 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			Collections.sort(selected, new Comparator() {
 				@Override
 				public int compare(GpxInfo i1, GpxInfo i2) {
-					return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+					if (sortByName) {
+						return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+					} else {
+						long time1 = i1.file.lastModified();
+						long time2 = i2.file.lastModified();
+						if (time1 == time2) {
+							return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+						}
+						return -Long.compare(time1, time2);
+					}
 				}
 			});
 		}

From 068e2ef3b5d003bf8f167aef85ebf1bd6a937064 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 17:47:58 +0300
Subject: [PATCH 0188/1366] remove unnecessary changes

---
 .../osmand/plus/myplaces/AvailableGPXFragment.java | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 3856615d8e..8432080bc8 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -1150,20 +1150,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		}
 
 		public void sort() {
-			for (List items : data.values()) {
-				Collections.sort(items, new Comparator() {
-					@Override
-					public int compare(GpxInfo i1, GpxInfo i2) {
-						if (sortByName) {
-							return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
-						} else {
-							long modified1 = i1.file.lastModified();
-							long modified2 = i2.file.lastModified();
-							return (modified1 < modified2) ? -1 : ((modified1 == modified2) ? 0 : 1);
-						}
-					}
-				});
-			}
 			Collections.sort(category, new Comparator() {
 				@Override
 				public int compare(String lhs, String rhs) {

From 25ec3c2059f1735960a3c1576c080cfbee292bc9 Mon Sep 17 00:00:00 2001
From: Dmitry 
Date: Thu, 17 Sep 2020 18:05:45 +0300
Subject: [PATCH 0189/1366] Added icons for sorting menu

---
 .../ic_action_sort_by_name_ascending.xml      | 31 +++++++++++++++++++
 .../ic_action_sort_by_name_descending.xml     | 31 +++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml
 create mode 100644 OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml

diff --git a/OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml b/OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml
new file mode 100644
index 0000000000..07406ae2c7
--- /dev/null
+++ b/OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml
@@ -0,0 +1,31 @@
+
+  
+  
+  
+  
+  
+  
+
diff --git a/OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml b/OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml
new file mode 100644
index 0000000000..04cd095335
--- /dev/null
+++ b/OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml
@@ -0,0 +1,31 @@
+
+  
+  
+  
+  
+  
+  
+

From 5a550e7f535f68e4085d6245d2ba8e0ce0672034 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 19:46:48 +0300
Subject: [PATCH 0190/1366] Try to fix #9829

---
 OsmAnd/res/values/styles.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/values/styles.xml b/OsmAnd/res/values/styles.xml
index 35f24529e1..e52dbdfd56 100644
--- a/OsmAnd/res/values/styles.xml
+++ b/OsmAnd/res/values/styles.xml
@@ -551,11 +551,11 @@
         @null
     
 
-    
 
-    
 

From d9a5d054c7ae08a9c35f3410e05f654f98c1d30e Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Thu, 17 Sep 2020 22:36:46 +0300
Subject: [PATCH 0191/1366] Remove group name at track selection screen

---
 .../osmand/plus/helpers/GpxTrackAdapter.java  | 14 +++++++++++--
 .../helpers/SelectGpxTrackBottomSheet.java    |  2 +-
 .../SelectFileBottomSheet.java                | 10 +++++++--
 .../StartPlanRouteBottomSheet.java            |  2 +-
 .../cards/TracksToFollowCard.java             | 21 ++++++++++++-------
 5 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java b/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java
index 01caa18083..00bb1e218b 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java
@@ -34,14 +34,17 @@ public class GpxTrackAdapter extends RecyclerView.Adapter gpxInfoList;
-	private boolean showCurrentGpx;
 	private OnItemClickListener onItemClickListener;
 
-	public GpxTrackAdapter(Context ctx, List gpxInfoList, boolean showCurrentGpx) {
+	private boolean showFolderName;
+	private boolean showCurrentGpx;
+
+	public GpxTrackAdapter(Context ctx, List gpxInfoList, boolean showCurrentGpx, boolean showFolderName) {
 		app = (OsmandApplication) ctx.getApplicationContext();
 		themedInflater = UiUtilities.getInflater(ctx, app.getDaynightHelper().isNightModeForMapControls());
 		iconsCache = app.getUIUtilities();
 		this.gpxInfoList = gpxInfoList;
+		this.showFolderName = showFolderName;
 		this.showCurrentGpx = showCurrentGpx;
 	}
 
@@ -57,6 +60,10 @@ public class GpxTrackAdapter extends RecyclerView.Adapter> gpxInfoMap;
 	private Mode fragmentMode;
 	private String selectedFolder;
+	private String allFilesFolder;
 
 	public void setFragmentMode(Mode fragmentMode) {
 		this.fragmentMode = fragmentMode;
@@ -91,7 +92,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
 		final File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
 		collectDirs(gpxDir, dirs);
 		List dirItems = new ArrayList<>();
-		String allFilesFolder = context.getString(R.string.shared_string_all);
+		allFilesFolder = context.getString(R.string.shared_string_all);
 		if (savedInstanceState == null) {
 			selectedFolder = allFilesFolder;
 		}
@@ -116,7 +117,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
 			gpxList.add(gpxInfo);
 		}
 
-		adapter = new GpxTrackAdapter(requireContext(), allGpxList, isShowCurrentGpx());
+		adapter = new GpxTrackAdapter(requireContext(), allGpxList, isShowCurrentGpx(), showFoldersName());
 		adapter.setAdapterListener(new OnItemClickListener() {
 			@Override
 			public void onItemClick(int position) {
@@ -157,11 +158,16 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
 
 	private void updateFileList(String folderName, HorizontalSelectionAdapter folderAdapter) {
 		List gpxInfoList = gpxInfoMap.get(folderName);
+		adapter.setShowFolderName(showFoldersName());
 		adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList());
 		adapter.notifyDataSetChanged();
 		folderAdapter.notifyDataSetChanged();
 	}
 
+	private boolean showFoldersName() {
+		return allFilesFolder.equals(selectedFolder);
+	}
+
 	private boolean isShowCurrentGpx() {
 		return fragmentMode == Mode.ADD_TO_TRACK;
 	}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java
index 666fe4f0a6..b81b015f32 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java
@@ -128,7 +128,7 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen
 			}
 		});
 		final List gpxTopList = gpxList.subList(0, Math.min(5, gpxList.size()));
-		adapter = new GpxTrackAdapter(requireContext(), gpxTopList, false);
+		adapter = new GpxTrackAdapter(requireContext(), gpxTopList, false, true);
 		adapter.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() {
 			@Override
 			public void onItemClick(int position) {
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
index 3357e4f2fa..94770e0135 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
@@ -23,6 +23,8 @@ public class TracksToFollowCard extends BaseCard {
 
 	private List gpxInfoList;
 	private String selectedCategory;
+	private String defaultCategory;
+	private String visibleCategory;
 
 	private GpxTrackAdapter tracksAdapter;
 
@@ -30,6 +32,8 @@ public class TracksToFollowCard extends BaseCard {
 		super(mapActivity);
 		this.gpxInfoList = gpxInfoList;
 		this.selectedCategory = selectedCategory;
+		defaultCategory = app.getString(R.string.shared_string_all);
+		visibleCategory = app.getString(R.string.shared_string_visible);
 		gpxInfoCategories = getGpxInfoCategories();
 	}
 
@@ -62,7 +66,7 @@ public class TracksToFollowCard extends BaseCard {
 		filesRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
 		filesRecyclerView.setNestedScrollingEnabled(false);
 
-		tracksAdapter = new GpxTrackAdapter(view.getContext(), gpxInfoList, false);
+		tracksAdapter = new GpxTrackAdapter(view.getContext(), gpxInfoList, false, showFoldersName());
 		tracksAdapter.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() {
 			@Override
 			public void onItemClick(int position) {
@@ -88,6 +92,7 @@ public class TracksToFollowCard extends BaseCard {
 			public void onItemSelected(String item) {
 				selectedCategory = item;
 				List items = gpxInfoCategories.get(item);
+				tracksAdapter.setShowFolderName(showFoldersName());
 				tracksAdapter.setGpxInfoList(items != null ? items : new ArrayList());
 				tracksAdapter.notifyDataSetChanged();
 
@@ -101,17 +106,19 @@ public class TracksToFollowCard extends BaseCard {
 		selectionAdapter.notifyDataSetChanged();
 	}
 
+	private boolean showFoldersName() {
+		return defaultCategory.equals(selectedCategory) || visibleCategory.equals(selectedCategory);
+	}
+
 	private Map> getGpxInfoCategories() {
-		String all = app.getString(R.string.shared_string_all);
-		String visible = app.getString(R.string.shared_string_visible);
 		Map> gpxInfoCategories = new LinkedHashMap<>();
 
-		gpxInfoCategories.put(visible, new ArrayList());
-		gpxInfoCategories.put(all, new ArrayList());
+		gpxInfoCategories.put(visibleCategory, new ArrayList());
+		gpxInfoCategories.put(defaultCategory, new ArrayList());
 
 		for (GPXInfo info : gpxInfoList) {
 			if (info.isSelected()) {
-				addGpxInfoCategory(gpxInfoCategories, info, visible);
+				addGpxInfoCategory(gpxInfoCategories, info, visibleCategory);
 			}
 			if (!Algorithms.isEmpty(info.getFileName())) {
 				File file = new File(info.getFileName());
@@ -120,7 +127,7 @@ public class TracksToFollowCard extends BaseCard {
 					addGpxInfoCategory(gpxInfoCategories, info, dirName);
 				}
 			}
-			addGpxInfoCategory(gpxInfoCategories, info, all);
+			addGpxInfoCategory(gpxInfoCategories, info, defaultCategory);
 		}
 
 		return gpxInfoCategories;

From c99f7d5b0e0941279b91806f6a6649ba15b27210 Mon Sep 17 00:00:00 2001
From: simon 
Date: Fri, 18 Sep 2020 13:27:05 +0300
Subject: [PATCH 0192/1366] null ptr crash fixed

---
 .../main/java/net/osmand/router/RoutePlannerFrontEnd.java   | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java
index 663c9ea384..54464afc32 100644
--- a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java
+++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java
@@ -549,8 +549,10 @@ public class RoutePlannerFrontEnd {
 		if (start != null && start.pnt == null) {
 			gctx.routePointsSearched++;
 			RouteSegmentPoint rsp = findRouteSegment(start.loc.getLatitude(), start.loc.getLongitude(), gctx.ctx, null, false);
-			if (MapUtils.getDistance(rsp.getPreciseLatLon(), start.loc) < distThreshold) {
-				start.pnt = rsp;
+			if (rsp != null) {
+				if (MapUtils.getDistance(rsp.getPreciseLatLon(), start.loc) < distThreshold) {
+					start.pnt = rsp;
+				}
 			}
  		} 
 		if (start != null && start.pnt != null) {

From e07d6486bfe730b81fe6a35ac2cda41e63a99bc8 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Fri, 18 Sep 2020 13:34:10 +0300
Subject: [PATCH 0193/1366] Fix #9807

---
 .../mapcontextmenu/controllers/TransportStopController.java | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java
index deeb139024..a56ae89c74 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java
@@ -231,9 +231,13 @@ public class TransportStopController extends MenuController {
 			stopAggregated = new TransportStopAggregated();
 			stopAggregated.setAmenity(amenity);
 			TransportStop nearestStop = null;
+			String amenityName = amenity.getName().toLowerCase();
 			for (TransportStop stop : transportStops) {
 				stop.setTransportStopAggregated(stopAggregated);
-				if ((stop.getName().startsWith(amenity.getName())
+				String stopName = stop.getName().toLowerCase();
+				if (((stopName.startsWith(amenity.getName())
+						|| stopName.contains(amenityName)
+						|| amenityName.contains(stopName))
 						&& (nearestStop == null
 						|| nearestStop.getLocation().equals(stop.getLocation())))
 						|| stop.getLocation().equals(loc)) {

From 407492d23022f00fb741253cb3dc0dda4ecb94e0 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Fri, 18 Sep 2020 13:35:47 +0300
Subject: [PATCH 0194/1366] Remove unnecessary check

---
 .../mapcontextmenu/controllers/TransportStopController.java   | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java
index a56ae89c74..2337031400 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java
@@ -235,9 +235,7 @@ public class TransportStopController extends MenuController {
 			for (TransportStop stop : transportStops) {
 				stop.setTransportStopAggregated(stopAggregated);
 				String stopName = stop.getName().toLowerCase();
-				if (((stopName.startsWith(amenity.getName())
-						|| stopName.contains(amenityName)
-						|| amenityName.contains(stopName))
+				if (((stopName.contains(amenityName) || amenityName.contains(stopName))
 						&& (nearestStop == null
 						|| nearestStop.getLocation().equals(stop.getLocation())))
 						|| stop.getLocation().equals(loc)) {

From 400a0ba9ea8012e1213096418ba93a62755c4c27 Mon Sep 17 00:00:00 2001
From: MadWasp79 
Date: Fri, 18 Sep 2020 14:30:37 +0300
Subject: [PATCH 0195/1366] #9773 #9774 fixes

---
 .../osmand/plus/measurementtool/MeasurementEditingContext.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index 105c947ddc..6e25bc67ab 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -546,7 +546,7 @@ public class MeasurementEditingContext {
 						points.add(pt);
 					}
 				} else {
-					for (int ik = seg.getEndPointIndex(); ik >= seg.getStartPointIndex(); ik--) {
+					for (int ik = seg.getStartPointIndex(); ik >= seg.getEndPointIndex(); ik--) {
 						LatLon l = seg.getPoint(ik);
 						WptPt pt = new WptPt();
 						pt.lat = l.getLatitude();

From c1a236560010bbb632127c561a1fdb680d45c954 Mon Sep 17 00:00:00 2001
From: Victor Shcherb 
Date: Fri, 18 Sep 2020 15:05:24 +0200
Subject: [PATCH 0196/1366] Fix editing context

---
 .../MeasurementEditingContext.java            | 27 +++++++++----------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index 105c947ddc..828681bc34 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -537,22 +537,19 @@ public class MeasurementEditingContext {
 			List segments = new ArrayList<>();
 			for (RouteSegmentResult seg : rp1.routeToTarget) {
 				segments.add(seg);
-				if (seg.isForwardDirection()) {
-					for (int ik = seg.getStartPointIndex(); ik <= seg.getEndPointIndex(); ik++) {
-						LatLon l = seg.getPoint(ik);
-						WptPt pt = new WptPt();
-						pt.lat = l.getLatitude();
-						pt.lon = l.getLongitude();
-						points.add(pt);
-					}
-				} else {
-					for (int ik = seg.getEndPointIndex(); ik >= seg.getStartPointIndex(); ik--) {
-						LatLon l = seg.getPoint(ik);
-						WptPt pt = new WptPt();
-						pt.lat = l.getLatitude();
-						pt.lon = l.getLongitude();
-						points.add(pt);
+				int ind = seg.getStartPointIndex();
+				boolean plus = seg.isForwardDirection();
+				float[] pf = seg.getObject().calculateHeightArray();
+				while (ind != seg.getEndPointIndex()) {
+					LatLon l = seg.getPoint(ind);
+					WptPt pt = new WptPt();
+					if (pf != null && pf.length > ind * 2 + 1) {
+						pt.ele = pf[ind * 2 + 1];
 					}
+					pt.lat = l.getLatitude();
+					pt.lon = l.getLongitude();
+					points.add(pt);
+					ind = plus ? ind + 1 : ind - 1;
 				}
 			}
 			roadSegmentData.put(pair, new RoadSegmentData(appMode, pair.first, pair.second, points, segments));

From 9ceead52dbc28970e8916bf62de11f4cfb4312dc Mon Sep 17 00:00:00 2001
From: Nazar-Kutz 
Date: Fri, 18 Sep 2020 16:14:05 +0300
Subject: [PATCH 0197/1366] Fix Dark theme

---
 OsmAnd/res/layout/follow_track_options.xml    |  2 +-
 OsmAnd/res/layout/import_track_card.xml       |  2 +-
 .../layout/plan_route_threshold_slider.xml    |  1 +
 OsmAnd/res/layout/track_appearance.xml        |  2 +-
 .../osmand/plus/base/ContextMenuFragment.java | 27 +++++++++++--
 .../base/MenuBottomSheetDialogFragment.java   | 32 ++++++++++------
 .../AddWaypointBottomSheetDialogFragment.java | 20 ----------
 .../GpxApproximationFragment.java             | 11 ++++--
 .../MeasurementToolFragment.java              | 12 +++++-
 ...veAsNewTrackBottomSheetDialogFragment.java | 19 +++++++---
 .../FollowTrackFragment.java                  | 15 ++++++--
 .../cards/ImportTrackCard.java                |  3 +-
 .../VehicleParametersBottomSheet.java         |  6 +--
 .../plus/track/TrackAppearanceFragment.java   | 11 ++++--
 .../plus/views/layers/MapControlsLayer.java   | 38 ++++++++++++++++++-
 15 files changed, 143 insertions(+), 58 deletions(-)

diff --git a/OsmAnd/res/layout/follow_track_options.xml b/OsmAnd/res/layout/follow_track_options.xml
index 69f0c467c3..123a7699e9 100644
--- a/OsmAnd/res/layout/follow_track_options.xml
+++ b/OsmAnd/res/layout/follow_track_options.xml
@@ -18,7 +18,7 @@
 			android:id="@+id/route_menu_top_shadow_all"
 			android:layout_width="match_parent"
 			android:layout_height="wrap_content"
-			android:background="?attr/card_and_list_background_basic"
+			android:background="?attr/bg_color"
 			android:minHeight="@dimen/bottom_sheet_title_height"
 			android:orientation="vertical">
 
diff --git a/OsmAnd/res/layout/import_track_card.xml b/OsmAnd/res/layout/import_track_card.xml
index 3f3ccf7d64..24ead3b9a6 100644
--- a/OsmAnd/res/layout/import_track_card.xml
+++ b/OsmAnd/res/layout/import_track_card.xml
@@ -4,7 +4,7 @@
 	android:id="@+id/import_track_card"
 	android:layout_width="match_parent"
 	android:layout_height="wrap_content"
-	android:background="?attr/card_and_list_background_basic"
+	android:background="?attr/bg_color"
 	android:orientation="vertical">
 
 	
 
diff --git a/OsmAnd/res/layout/track_appearance.xml b/OsmAnd/res/layout/track_appearance.xml
index 0be92d2bb0..ca9b03d589 100644
--- a/OsmAnd/res/layout/track_appearance.xml
+++ b/OsmAnd/res/layout/track_appearance.xml
@@ -18,7 +18,7 @@
 			android:id="@+id/route_menu_top_shadow_all"
 			android:layout_width="match_parent"
 			android:layout_height="wrap_content"
-			android:background="?attr/card_and_list_background_basic"
+			android:background="?attr/bg_color"
 			android:minHeight="@dimen/bottom_sheet_title_height"
 			android:orientation="vertical"
 			android:paddingLeft="@dimen/content_padding"
diff --git a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
index e1436bb400..06ea4dbef9 100644
--- a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java
@@ -47,10 +47,12 @@ import net.osmand.plus.helpers.AndroidUiHelper;
 import net.osmand.plus.mapcontextmenu.InterceptorLinearLayout;
 import net.osmand.plus.views.controls.HorizontalSwipeConfirm;
 import net.osmand.plus.views.controls.SingleTapConfirm;
+import net.osmand.plus.views.layers.MapControlsLayer;
 
 import static net.osmand.plus.mapcontextmenu.MapContextMenuFragment.CURRENT_Y_UNDEFINED;
 
-public abstract class ContextMenuFragment extends BaseOsmAndFragment {
+public abstract class ContextMenuFragment extends BaseOsmAndFragment
+		implements MapControlsLayer.MapControlsThemeInfoProvider {
 
 	public static class MenuState {
 		public static final int HEADER_ONLY = 1;
@@ -174,10 +176,19 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 		return topView;
 	}
 
+	@Override
+	public boolean isNightModeForMapControls() {
+		return nightMode;
+	}
+
 	public boolean isNightMode() {
 		return nightMode;
 	}
 
+	protected String getThemeInfoProviderTag() {
+		return null;
+	}
+
 	public void updateNightMode() {
 		OsmandApplication app = getMyApplication();
 		if (app != null) {
@@ -597,6 +608,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 			if (!wasDrawerDisabled) {
 				mapActivity.disableDrawer();
 			}
+			String tag = getThemeInfoProviderTag();
+			if (tag != null) {
+				mapActivity.getMapLayers().getMapControlsLayer().addThemeInfoProviderTag(tag);
+			}
 		}
 	}
 
@@ -611,8 +626,14 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
 			}
 		}
 		MapActivity mapActivity = getMapActivity();
-		if (!wasDrawerDisabled && mapActivity != null) {
-			mapActivity.enableDrawer();
+		if (mapActivity != null) {
+			if (!wasDrawerDisabled) {
+				mapActivity.enableDrawer();
+			}
+			String tag = getThemeInfoProviderTag();
+			if (tag != null) {
+				mapActivity.getMapLayers().getMapControlsLayer().removeThemeInfoProviderTag(tag);
+			}
 		}
 	}
 
diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java
index ef5d5790c9..7625e5de20 100644
--- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java
@@ -3,7 +3,9 @@ package net.osmand.plus.base;
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
 import android.os.Build;
 import android.os.Bundle;
 import android.view.ContextThemeWrapper;
@@ -207,12 +209,12 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
 				// 8dp is the shadow height
 				boolean showTopShadow = screenHeight - statusBarHeight - mainView.getHeight() >= AndroidUtils.dpToPx(activity, 8);
 				if (AndroidUiHelper.isOrientationPortrait(activity)) {
-					mainView.setBackgroundResource(showTopShadow ? getPortraitBgResId() : getBgColorId());
+					AndroidUtils.setBackground(mainView, showTopShadow ? getPortraitBg(activity) : getColoredBg(activity));
 					if (!showTopShadow) {
 						mainView.setPadding(0, 0, 0, 0);
 					}
 				} else {
-					mainView.setBackgroundResource(showTopShadow ? getLandscapeTopsidesBgResId() : getLandscapeSidesBgResId());
+					AndroidUtils.setBackground(mainView, showTopShadow ? getLandscapeTopsidesBg(activity) : getLandscapeSidesBg(activity));
 				}
 			}
 		});
@@ -304,19 +306,27 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
 		return nightMode ? R.color.list_background_color_dark : R.color.list_background_color_light;
 	}
 
-	@DrawableRes
-	protected int getPortraitBgResId() {
-		return nightMode ? R.drawable.bg_bottom_menu_dark : R.drawable.bg_bottom_menu_light;
+	protected Drawable getColoredBg(@NonNull Context ctx) {
+		int bgColor = ContextCompat.getColor(ctx, getBgColorId());
+		return new ColorDrawable(bgColor);
 	}
 
-	@DrawableRes
-	protected int getLandscapeTopsidesBgResId() {
-		return nightMode ? R.drawable.bg_bottom_sheet_topsides_landscape_dark : R.drawable.bg_bottom_sheet_topsides_landscape_light;
+	protected Drawable getPortraitBg(@NonNull Context ctx) {
+		return createBackgroundDrawable(ctx, R.drawable.bg_contextmenu_shadow_top_light);
 	}
 
-	@DrawableRes
-	protected int getLandscapeSidesBgResId() {
-		return nightMode ? R.drawable.bg_bottom_sheet_sides_landscape_dark : R.drawable.bg_bottom_sheet_sides_landscape_light;
+	protected Drawable getLandscapeTopsidesBg(@NonNull Context ctx) {
+		return createBackgroundDrawable(ctx, R.drawable.bg_shadow_bottomsheet_topsides);
+	}
+
+	protected Drawable getLandscapeSidesBg(@NonNull Context ctx) {
+		return createBackgroundDrawable(ctx, R.drawable.bg_shadow_bottomsheet_sides);
+	}
+
+	private LayerDrawable createBackgroundDrawable(@NonNull Context ctx, @DrawableRes int shadowDrawableResId) {
+		Drawable shadowDrawable = ContextCompat.getDrawable(ctx, shadowDrawableResId);
+		Drawable[] layers = new Drawable[]{shadowDrawable, getColoredBg(ctx)};
+		return new LayerDrawable(layers);
 	}
 
 	protected boolean isNightMode(@NonNull OsmandApplication app) {
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/AddWaypointBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/AddWaypointBottomSheetDialogFragment.java
index 2b8f7a07f5..fe3f6d5580 100644
--- a/OsmAnd/src/net/osmand/plus/dialogs/AddWaypointBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/dialogs/AddWaypointBottomSheetDialogFragment.java
@@ -140,26 +140,6 @@ public class AddWaypointBottomSheetDialogFragment extends MenuBottomSheetDialogF
 		return getIcon(id, nightMode ? R.color.ctx_menu_direction_color_dark : R.color.map_widget_blue);
 	}
 
-	@Override
-	protected int getBgColorId() {
-		return nightMode ? R.color.list_background_color_dark : R.color.list_background_color_light;
-	}
-
-	@Override
-	protected int getPortraitBgResId() {
-		return nightMode ? R.drawable.bg_additional_menu_dark : R.drawable.bg_bottom_menu_light;
-	}
-
-	@Override
-	protected int getLandscapeTopsidesBgResId() {
-		return nightMode ? R.drawable.bg_additional_menu_topsides_dark : R.drawable.bg_bottom_sheet_topsides_landscape_light;
-	}
-
-	@Override
-	protected int getLandscapeSidesBgResId() {
-		return nightMode ? R.drawable.bg_additional_menu_sides_dark : R.drawable.bg_bottom_sheet_sides_landscape_light;
-	}
-
 	private Drawable getBackgroundIcon(@DrawableRes int resId) {
 		return getIcon(resId, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light);
 	}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java
index 393e43b31b..87edaaf71b 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java
@@ -233,16 +233,16 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
 			} else {
 				topShadow.setVisibility(View.VISIBLE);
 				AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(),
-						R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
+						R.color.list_background_color_light, R.color.list_background_color_dark);
 				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(),
-						R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
+						R.color.list_background_color_light, R.color.list_background_color_dark);
 			}
 		}
 	}
 
 	private void updateButtons(View view) {
 		View buttonsContainer = view.findViewById(R.id.buttons_container);
-		buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.route_info_bg));
+		buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.bg_color));
 		applyButton.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
@@ -415,6 +415,11 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
 		}
 	}
 
+	@Override
+	protected String getThemeInfoProviderTag() {
+		return TAG;
+	}
+
 	public interface GpxApproximationFragmentListener {
 
 		void onGpxApproximationDone(GpxRouteApproximation gpxApproximation, ApplicationMode mode);
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index e2e4d79531..081c5098b1 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -78,6 +78,7 @@ import net.osmand.plus.measurementtool.command.ReversePointsCommand;
 import net.osmand.plus.settings.backend.ApplicationMode;
 import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
+import net.osmand.plus.views.layers.MapControlsLayer;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
 import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView;
@@ -107,7 +108,7 @@ import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCo
 
 public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener,
 		OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener,
-		SaveAsNewTrackFragmentListener {
+		SaveAsNewTrackFragmentListener, MapControlsLayer.MapControlsThemeInfoProvider {
 
 	public static final String TAG = MeasurementToolFragment.class.getSimpleName();
 	public static final String TAPS_DISABLED_KEY = "taps_disabled_key";
@@ -529,6 +530,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		super.onResume();
 		MapActivity mapActivity = getMapActivity();
 		if (mapActivity != null) {
+			mapActivity.getMapLayers().getMapControlsLayer().addThemeInfoProviderTag(TAG);
 			mapActivity.getMapLayers().getMapControlsLayer().showMapControlsIfHidden();
 			cachedMapPosition = mapActivity.getMapView().getMapPosition();
 			setDefaultMapPosition();
@@ -539,6 +541,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	@Override
 	public void onPause() {
 		super.onPause();
+		MapActivity mapActivity = getMapActivity();
+		if (mapActivity != null) {
+			mapActivity.getMapLayers().getMapControlsLayer().removeThemeInfoProviderTag(TAG);
+		}
 		setMapPosition(cachedMapPosition);
 	}
 
@@ -2052,4 +2058,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			AndroidUiHelper.setVisibility(mapActivity, View.VISIBLE, R.id.map_ruler_container);
 		}
 	}
+
+	public boolean isNightModeForMapControls() {
+		return nightMode;
+	}
 }
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
index 40877bf8dc..07c447f3d1 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java
@@ -68,6 +68,8 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 		if (app == null) {
 			return;
 		}
+
+		int highlightColorId = nightMode ? R.color.list_background_color_dark : R.color.activity_background_color_light;
 		if (savedInstanceState != null) {
 			showOnMap = savedInstanceState.getBoolean(SHOW_ON_MAP_KEY);
 			simplifiedTrack = savedInstanceState.getBoolean(SIMPLIFIED_TRACK_KEY);
@@ -85,7 +87,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 		View editNameView = View.inflate(UiUtilities.getThemedContext(app, nightMode),
 				R.layout.track_name_edit_text, null);
 		nameTextBox = editNameView.findViewById(R.id.name_text_box);
-		nameTextBox.setBoxBackgroundColorResource(R.color.material_text_input_layout_bg);
+		nameTextBox.setBoxBackgroundColorResource(highlightColorId);
 		nameTextBox.setHint(app.getString(R.string.ltr_or_rtl_combine_via_colon,
 				app.getString(R.string.shared_string_file_name), "").trim());
 		ColorStateList colorStateList = ColorStateList.valueOf(ContextCompat
@@ -190,14 +192,16 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 			GradientDrawable background = (GradientDrawable) AppCompatResources.getDrawable(app,
 					R.drawable.bg_select_group_button_outline);
 			if (background != null) {
-				int backgroundColor = AndroidUtils.getColorFromAttr(UiUtilities.getThemedContext(app, nightMode),
-						R.attr.activity_background_color);
+				int highlightColor = ContextCompat.getColor(app,nightMode ?
+						R.color.list_background_color_dark : R.color.activity_background_color_light);
+				int strokedColor = AndroidUtils.getColorFromAttr(UiUtilities.getThemedContext(app, nightMode),
+						R.attr.stroked_buttons_and_links_outline);
 				background = (GradientDrawable) background.mutate();
 				if (checked) {
 					background.setStroke(0, Color.TRANSPARENT);
-					background.setColor(backgroundColor);
+					background.setColor(highlightColor);
 				} else {
-					background.setStroke(app.getResources().getDimensionPixelSize(R.dimen.map_button_stroke), backgroundColor);
+					background.setStroke(app.getResources().getDimensionPixelSize(R.dimen.map_button_stroke), strokedColor);
 				}
 			}
 			return background;
@@ -328,6 +332,11 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial
 		return false;
 	}
 
+	@Override
+	protected int getBgColorId() {
+		return nightMode ? R.color.activity_background_color_dark : R.color.list_background_color_light;
+	}
+
 	public interface SaveAsNewTrackFragmentListener {
 
 		void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack);
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
index 4f9214438e..4884fe616c 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
@@ -62,6 +62,7 @@ import net.osmand.plus.routing.RouteProvider;
 import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
 import net.osmand.plus.routing.RoutingHelper;
 import net.osmand.plus.settings.backend.ApplicationMode;
+import net.osmand.plus.views.layers.MapControlsLayer;
 
 import org.apache.commons.logging.Log;
 
@@ -69,7 +70,8 @@ import java.io.File;
 import java.util.List;
 
 
-public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener, IRouteInformationListener {
+public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener,
+		IRouteInformationListener, MapControlsLayer.MapControlsThemeInfoProvider {
 
 	public static final String TAG = FollowTrackFragment.class.getName();
 
@@ -556,15 +558,15 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
 				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.drawable.travel_card_bg_light, R.drawable.travel_card_bg_dark);
 			} else {
 				topShadow.setVisibility(View.VISIBLE);
-				AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
-				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
+				AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
+				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
 			}
 		}
 	}
 
 	private void setupButtons(View view) {
 		View buttonsContainer = view.findViewById(R.id.buttons_container);
-		buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.route_info_bg));
+		buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.bg_color));
 
 		View cancelButton = view.findViewById(R.id.dismiss_button);
 		cancelButton.setOnClickListener(new View.OnClickListener() {
@@ -639,4 +641,9 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
 	public void routeWasFinished() {
 
 	}
+
+	@Override
+	protected String getThemeInfoProviderTag() {
+		return TAG;
+	}
 }
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/ImportTrackCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/ImportTrackCard.java
index 78633b080e..e8ac9e448e 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/ImportTrackCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/ImportTrackCard.java
@@ -29,7 +29,8 @@ public class ImportTrackCard extends BaseCard {
 
 	@Override
 	protected void updateContent() {
-		int color = ContextCompat.getColor(app, R.color.preference_category_title);
+		int color = ContextCompat.getColor(app, nightMode ?
+				R.color.active_color_primary_dark : R.color.active_color_primary_light);
 		Typeface typeface = FontCache.getRobotoMedium(app);
 		String importTrack = app.getString(R.string.plan_route_import_track);
 		SpannableString spannable = UiUtilities.createCustomFontSpannable(typeface, importTrack, importTrack, importTrack);
diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java
index ada5b13921..5ac7aea8e8 100644
--- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java
@@ -23,6 +23,7 @@ import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import net.osmand.AndroidUtils;
 import net.osmand.PlatformUtil;
 import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
@@ -196,13 +197,12 @@ public class VehicleParametersBottomSheet extends BasePreferenceBottomSheet {
 					return;
 				}
 				if (AndroidUiHelper.isOrientationPortrait(activity)) {
-					mainView.setBackgroundResource(showTopShadow ? getPortraitBgResId() : getBgColorId());
+					AndroidUtils.setBackground(mainView, showTopShadow ? getPortraitBg(activity) : getColoredBg(activity));
 					if (!showTopShadow) {
 						mainView.setPadding(0, 0, 0, 0);
 					}
 				} else {
-					mainView.setBackgroundResource(showTopShadow
-							? getLandscapeTopsidesBgResId() : getLandscapeSidesBgResId());
+					AndroidUtils.setBackground(mainView, showTopShadow ? getLandscapeTopsidesBg(activity) : getLandscapeSidesBg(activity));
 				}
 			}
 		};
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
index 53d49bd2a7..4381dd61f6 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
@@ -432,15 +432,15 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.drawable.travel_card_bg_light, R.drawable.travel_card_bg_dark);
 			} else {
 				topShadow.setVisibility(View.VISIBLE);
-				AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
-				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
+				AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
+				AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
 			}
 		}
 	}
 
 	private void setupButtons(View view) {
 		View buttonsContainer = view.findViewById(R.id.buttons_container);
-		buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.route_info_bg));
+		buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.bg_color));
 		View saveButton = view.findViewById(R.id.right_bottom_button);
 		saveButton.setOnClickListener(new View.OnClickListener() {
 			@Override
@@ -720,6 +720,11 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
 		}
 	}
 
+	@Override
+	protected String getThemeInfoProviderTag() {
+		return TAG;
+	}
+
 	public interface OnNeedScrollListener {
 		void onVerticalScrollNeeded(int y);
 	}
diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java
index 7663a4845b..21277e2426 100644
--- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java
@@ -28,6 +28,8 @@ import androidx.core.content.ContextCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.ViewPropertyAnimatorCompat;
 import androidx.core.view.ViewPropertyAnimatorListener;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
 
 import com.google.android.material.slider.Slider;
 
@@ -69,8 +71,10 @@ import net.osmand.plus.views.OsmandMapTileView;
 import net.osmand.plus.views.corenative.NativeCoreContext;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import gnu.trove.list.array.TIntArrayList;
 
@@ -133,6 +137,7 @@ public class MapControlsLayer extends OsmandMapLayer {
 	private boolean forceShowCompass;
 	private LatLon requestedLatLon;
 	private long compassPressed;
+	private Set themeInfoProviderTags = new HashSet<>();
 
 	public MapControlsLayer(MapActivity activity) {
 		this.mapActivity = activity;
@@ -836,7 +841,7 @@ public class MapControlsLayer extends OsmandMapLayer {
 	}
 
 	private void updateControls(@NonNull RotatedTileBox tileBox, DrawSettings drawSettings) {
-		boolean isNight = drawSettings != null && drawSettings.isNightMode();
+		boolean isNight = isNightModeForMapControls(drawSettings);
 		boolean portrait = isPotrait();
 //		int shadw = isNight ? mapActivity.getResources().getColor(R.color.widgettext_shadow_night) :
 //				mapActivity.getResources().getColor(R.color.widgettext_shadow_day);
@@ -916,6 +921,25 @@ public class MapControlsLayer extends OsmandMapLayer {
 		}
 	}
 
+	private boolean isNightModeForMapControls(DrawSettings drawSettings) {
+		MapControlsThemeInfoProvider themeInfoProvider = getThemeInfoProvider();
+		if (themeInfoProvider != null) {
+			return themeInfoProvider.isNightModeForMapControls();
+		}
+		return drawSettings != null && drawSettings.isNightMode();
+	}
+
+	private MapControlsThemeInfoProvider getThemeInfoProvider() {
+		FragmentManager fm = mapActivity.getSupportFragmentManager();
+		for (String tag : themeInfoProviderTags) {
+			Fragment f = fm.findFragmentByTag(tag);
+			if (f instanceof MapControlsThemeInfoProvider) {
+				return (MapControlsThemeInfoProvider) f;
+			}
+		}
+		return null;
+	}
+
 	public void updateCompass(boolean isNight) {
 		float mapRotate = mapActivity.getMapView().getRotate();
 		boolean showCompass = shouldShowCompass();
@@ -1419,4 +1443,16 @@ public class MapControlsLayer extends OsmandMapLayer {
 			}
 		}
 	}
+
+	public void addThemeInfoProviderTag(String tag) {
+		themeInfoProviderTags.add(tag);
+	}
+
+	public void removeThemeInfoProviderTag(String tag) {
+		themeInfoProviderTags.remove(tag);
+	}
+
+	public interface MapControlsThemeInfoProvider {
+		boolean isNightModeForMapControls();
+	}
 }

From 5c38526e0585fde39ed1cc634a1f8e745fe87428 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Fri, 18 Sep 2020 16:36:10 +0300
Subject: [PATCH 0198/1366] Minor UI fixes in plan route

---
 .../MeasurementToolFragment.java              |  4 +++-
 .../measurementtool/MeasurementToolLayer.java | 20 +++++++++++--------
 .../SnapTrackWarningFragment.java             |  2 +-
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 081c5098b1..7b823edb30 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -1960,12 +1960,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			setupDoneButton(view);
 			View shadow = view.getShadowView();
 			if (shadow != null) {
-				shadow.setVisibility(View.GONE);
+				AndroidUiHelper.updateVisibility(shadow, false);
 			}
 		}
 
 		private void setupDoneButton(TopToolbarView view) {
 			TextView done = view.getSaveView();
+			AndroidUiHelper.updateVisibility(done, isVisible());
+
 			Context ctx = done.getContext();
 			done.setAllCaps(false);
 			ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) done.getLayoutParams();
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java
index fdb8dc8887..23a69002f8 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java
@@ -182,13 +182,6 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
 		if (inMeasurementMode) {
 			lineAttrs.updatePaints(view.getApplication(), settings, tb);
 
-			TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
-			new Renderable.StandardTrack(new ArrayList<>(before.points), 17.2).
-					drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb);
-
-			TrkSegment after = editingCtx.getAfterTrkSegmentLine();
-			new Renderable.StandardTrack(new ArrayList<>(after.points), 17.2).
-					drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb);
 			if (editingCtx.isInApproximationMode()) {
 				List originalTrackPointList = editingCtx.getOriginalTrackPointList();
 				if (originalTrackPointList != null) {
@@ -198,6 +191,15 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
 							drawSegment(view.getZoom(), lineAttrs.customColorPaint, canvas, tb);
 				}
 			}
+
+			TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
+			new Renderable.StandardTrack(new ArrayList<>(before.points), 17.2).
+					drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb);
+
+			TrkSegment after = editingCtx.getAfterTrkSegmentLine();
+			new Renderable.StandardTrack(new ArrayList<>(after.points), 17.2).
+					drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb);
+
 			drawPoints(canvas, tb);
 		}
 	}
@@ -206,7 +208,9 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
 	public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
 		if (inMeasurementMode) {
 			lineAttrs.updatePaints(view.getApplication(), settings, tb);
-			drawBeforeAfterPath(canvas, tb);
+			if (!editingCtx.isInApproximationMode()) {
+				drawBeforeAfterPath(canvas, tb);
+			}
 
 			if (editingCtx.getSelectedPointPosition() == -1) {
 				drawCenterIcon(canvas, tb, settings.isNightMode());
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java
index 49e1fa3d65..f6835b963a 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SnapTrackWarningFragment.java
@@ -148,7 +148,7 @@ public class SnapTrackWarningFragment extends BaseOsmAndFragment {
 			}
 		});
 		UiUtilities.setupDialogButton(nightMode, cancelButton, SECONDARY, R.string.shared_string_cancel);
-		UiUtilities.setupDialogButton(nightMode, applyButton, PRIMARY, R.string.shared_string_apply);
+		UiUtilities.setupDialogButton(nightMode, applyButton, PRIMARY, R.string.shared_string_continue);
 		AndroidUiHelper.updateVisibility(applyButton, true);
 		AndroidUiHelper.updateVisibility(view.findViewById(R.id.buttons_divider), true);
 	}

From 69ab36293e96b34a51348e5b83341214b85bd084 Mon Sep 17 00:00:00 2001
From: simon 
Date: Fri, 18 Sep 2020 17:12:09 +0300
Subject: [PATCH 0199/1366] navigation fixed

---
 .../src/main/java/net/osmand/router/RouteSegmentResult.java   | 2 +-
 .../src/net/osmand/plus/routing/RouteCalculationResult.java   | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java
index 2aad93fd77..089de43fcd 100644
--- a/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java
+++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java
@@ -328,7 +328,7 @@ public class RouteSegmentResult implements StringExternalizable
 		for (int i = 0; i < length; i++) {
 			Location location = resources.getLocation(index);
 			if (location == null) {
-				break;
+				continue;
 			}
 			double dist = 0;
 			if (prevLocation != null) {
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
index 0dbbbb931b..2326bbaf4a 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
@@ -341,6 +341,10 @@ public class RouteCalculationResult {
 				LatLon point = s.getPoint(i);
 				n.setLatitude(point.getLatitude());
 				n.setLongitude(point.getLongitude());
+				//FIXME: investigate gpx file
+				if (s.getObject().getPoint31XTile(i) == 0 && s.getObject().getPoint31YTile(i) == 0){
+					break;
+				}
 				if (i == s.getEndPointIndex() && routeInd != list.size() - 1) {
 					break;
 				}

From 8499f4f9881e8be342c620aa46995a06df795397 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Fri, 18 Sep 2020 17:29:33 +0300
Subject: [PATCH 0200/1366] Fix icon after gpx approximation

---
 .../osmand/plus/measurementtool/MeasurementToolFragment.java | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 7b823edb30..6a36eba3cc 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -138,6 +138,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	private boolean pointsListOpened;
 	private boolean planRouteMode = false;
 	private boolean directionMode = false;
+	private boolean approximationApplied = false;
 	private boolean portrait;
 	private boolean nightMode;
 	private int cachedMapPosition;
@@ -1125,7 +1126,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		final ApplicationMode appMode = editingCtx.getAppMode();
 		if (mapActivity != null) {
 			Drawable icon;
-			if (editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData()) {
+			if (editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData() || approximationApplied) {
 				if (appMode == MeasurementEditingContext.DEFAULT_APP_MODE) {
 					icon = getActiveIcon(R.drawable.ic_action_split_interval);
 				} else {
@@ -2004,8 +2005,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 
 	@Override
 	public void onApplyGpxApproximation() {
+		approximationApplied = true;
 		exitApproximationMode();
 		doAddOrMovePointCommonStuff();
+		updateSnapToRoadControls();
 		if (directionMode) {
 			directionMode = false;
 			MapActivity mapActivity = getMapActivity();

From 27cace03f7f25f3378620eb31bea8b889dd34100 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Fri, 18 Sep 2020 17:44:32 +0300
Subject: [PATCH 0201/1366] Fix icon after gpx approximation in options dialog

---
 .../osmand/plus/measurementtool/MeasurementToolFragment.java   | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 6a36eba3cc..8c6693a8b6 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -319,9 +319,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		mainView.findViewById(R.id.options_button).setOnClickListener(new OnClickListener() {
 			@Override
 			public void onClick(View view) {
+				boolean trackSnappedToRoad = editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData() || approximationApplied;
 				OptionsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
 						MeasurementToolFragment.this,
-						editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData(),
+						trackSnappedToRoad,
 						editingCtx.getAppMode().getStringKey()
 				);
 			}

From 776cb79cd3c5198d37c2c389c22f4eabc2bb7aab Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Fri, 18 Sep 2020 18:32:53 +0300
Subject: [PATCH 0202/1366] Fix no track name after approximation

---
 .../plus/routepreparationmenu/MapRouteInfoMenu.java   | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
index f3576af790..f0216f1c9d 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
@@ -1633,7 +1633,16 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
 			String via = generateViaDescription();
 			GPXRouteParamsBuilder routeParamsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
 			if (routeParamsBuilder != null) {
-				String fileName = new File(routeParamsBuilder.getFile().path).getName();
+				GPXFile gpxFile = routeParamsBuilder.getFile();
+				String fileName = null;
+				if (!Algorithms.isEmpty(gpxFile.path)) {
+					fileName = new File(gpxFile.path).getName();
+				} else if (!Algorithms.isEmpty(gpxFile.tracks)) {
+					fileName = gpxFile.tracks.get(0).name;
+				}
+				if (Algorithms.isEmpty(fileName)) {
+					fileName = app.getString(R.string.shared_string_gpx_track);
+				}
 				title.setText(GpxUiHelper.getGpxTitle(fileName));
 				description.setText(R.string.follow_track);
 				buttonDescription.setText(R.string.shared_string_add);

From 01f8a0a7f22faf73ba50d4831bc876f4bdc12464 Mon Sep 17 00:00:00 2001
From: Victor Shcherb 
Date: Fri, 18 Sep 2020 17:33:02 +0200
Subject: [PATCH 0203/1366] Fix crash but leave  fixme

---
 .../plus/routing/RouteCalculationResult.java  | 23 ++++++++++++-------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
index 2326bbaf4a..df6a6eaafa 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
@@ -337,17 +337,13 @@ public class RouteCalculationResult {
 				tunnelAlarm = null;
 			}
 			while (true) {
+				if (i == s.getEndPointIndex() && routeInd != list.size() - 1) {
+					break;
+				}
 				Location n = new Location(""); //$NON-NLS-1$
 				LatLon point = s.getPoint(i);
 				n.setLatitude(point.getLatitude());
 				n.setLongitude(point.getLongitude());
-				//FIXME: investigate gpx file
-				if (s.getObject().getPoint31XTile(i) == 0 && s.getObject().getPoint31YTile(i) == 0){
-					break;
-				}
-				if (i == s.getEndPointIndex() && routeInd != list.size() - 1) {
-					break;
-				}
 				if (vls != null && i * 2 + 1 < vls.length) {
 					float h = vls[2 * i + 1];
 					n.setAltitude(h);
@@ -360,10 +356,21 @@ public class RouteCalculationResult {
 					}
 					lastHeight = h;
 				}
+				// FIXME: investigate gpx file
+				if (s.getObject().getPoint31XTile(i) == 0 && s.getObject().getPoint31YTile(i) == 0) {
+					if (locations.size() > 0) {
+						Location prev = locations.get(locations.size() - 1);
+						n.setLatitude(prev.getLatitude());
+						n.setLongitude(prev.getLongitude());
+						if (prev.hasAltitude()) {
+							n.setAltitude(prev.getAltitude());
+						}
+					}
+				}
 				locations.add(n);
 				attachAlarmInfo(alarms, s, i, locations.size());
 				segmentsToPopulate.add(s);
-				if (i == s.getEndPointIndex() ) {
+				if (i == s.getEndPointIndex()) {
 					break;
 				}
 				if (plus) {

From b773f0c9d3c840ed5b94c25f156a6cfe7b5f74a9 Mon Sep 17 00:00:00 2001
From: josep constanti 
Date: Thu, 17 Sep 2020 20:08:10 +0000
Subject: [PATCH 0204/1366] Translated using Weblate (Catalan)

Currently translated at 96.0% (3347 of 3484 strings)
---
 OsmAnd/res/values-ca/strings.xml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml
index 4ae94a57c7..ce8fda7ac6 100644
--- a/OsmAnd/res/values-ca/strings.xml
+++ b/OsmAnd/res/values-ca/strings.xml
@@ -3806,7 +3806,7 @@ Abasta l\'àrea: %1$s x %2$s
     Afegeix a un fitxer de traces
     Traces
     Enregistra el trajecte a un fitxer GPX
-    Navegua des de la meva ubicació fins a la traça
+    Navega des de la meva ubicació fins a la traça
     Afegeix una adreça
     Nom del fitxer
     REC
@@ -3815,4 +3815,8 @@ Abasta l\'àrea: %1$s x %2$s
     Traça simplificada
     Només es desarà la línia del trajecte, les fites s\'esborraran.
     %s arxius de traces seleccionats
+    Desa en un nou fitxer de traces
+    Traces
+    Importa o enregistra fitxers de traces
+    Trieu un fitxer de traces a seguir o importeu-lo des del dispositiu.
 
\ No newline at end of file

From 74cc27190a151fea919673bb0f307e2276820eed Mon Sep 17 00:00:00 2001
From: Oliver 
Date: Fri, 18 Sep 2020 20:41:45 +0000
Subject: [PATCH 0205/1366] Translated using Weblate (German)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-de/strings.xml | 35 +++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml
index 730f97c489..ba12de339b 100644
--- a/OsmAnd/res/values-de/strings.xml
+++ b/OsmAnd/res/values-de/strings.xml
@@ -3780,7 +3780,7 @@
     Blitzer-Warnungen sind in einigen Ländern gesetzlich verboten.
     Peilung
     %1$s gelöscht
-    Ein Neustart ist erforderlich, um Blitzerdaten vollständig zu löschen.
+    Starten Sie die Anwendung neu, um alle Blitzerdaten zu löschen.
     Deinstallieren und neu starten
     In einigen Ländern oder Regionen ist die Verwendung von Blitzer-Warneinrichtungen gesetzlich verboten. 
 \n
@@ -3793,26 +3793,26 @@
     Längenbegrenzung
     Diese App hat keine Informationen zu Blitzern.
     Inline-Skates
-    Aktivieren Sie die Steuerung der Zoomstufe der Karte mit den Lautstärketasten des Geräts.
+    Steuern Sie die Zoomstufen der Karte mit den Lautstärketasten des Geräts.
     Lautstärketasten als Zoom
     Bitte geben Sie Ihre Fahrzeuglänge an. Für lange Fahrzeuge könnten einige Streckenabschnitte nicht befahrbar sein.
-    Nächsten Zielpunkt löschen
+    Nächstgelegenen Zielpunkt löschen
     Bitte geben Sie einen Namen für das Profil an
     Der aktuelle Punkt auf der Route wird gelöscht. Wenn es das Ziel ist, wird die Navigation gestoppt.
     Wikipedia-Karten herunterladen
-    Informationen über Sehenswürdigkeiten erhalten Sie bei Wikipedia. Es ist Ihr Offline-Wegweiser für die Hosentasche - aktivieren Sie einfach das Wikipedia-Modul und genießen Sie Artikel über Objekte in Ihrer Umgebung.
+    Info über Sehenswürdigkeiten erhalten Sie bei Wikipedia. Es ist Ihr Offline-Wegweiser für die Hosentasche - aktivieren Sie einfach das Wikipedia-Modul und genießen Sie Artikel über Objekte in Ihrer Umgebung.
     Enduro
     Motorroller
     Rollstuhl
     Go-Kart
     Geschlossene OSM-Notiz
     Rollstuhl vorwärts
-    Zum Fortfahren müssen die Arbeitstage gesetzt sein
+    Zum Fortfahren bitte Arbeitstage auswählen
     Route zwischen Punkten
     Eine Route planen
     Zu einem Track hinzufügen
     Der hinzugefügte Punkt wird auf der Karte nicht sichtbar sein, da die ausgewählte Gruppe ausgeblendet ist, Sie können ihn in \"%s\" finden.
-    Start-Ziel-Symbole anzeigen
+    Start- und Ziel-Symbole anzeigen
     Breite auswählen
     Wählen Sie das Intervall, in dem Markierungen mit Abstand oder Zeit auf dem Track angezeigt werden.
     Wählen Sie die gewünschte Aufteilungsoption: nach Zeit oder nach Entfernung.
@@ -3831,7 +3831,7 @@
     Route umkehren
     Der gesamte Track wird mit dem ausgewählten Profil neu berechnet.
     Nur das nächste Segment wird mit dem ausgewählten Profil neu berechnet.
-    Wählen Sie, wie Punkte mit einer geraden Linie verbunden werden sollen, oder berechnen Sie eine Route zwischen ihnen mit dem ausgewählten Profil.
+    Wählen Sie, wie Punkte verbunden werden sollen; durch eine gerade Linie, oder eine berechnete Route zwischen ihnen, wie unten angegeben.
     Ganzer Track
     Nächstes Segment
     Navigationsprofil
@@ -3841,7 +3841,7 @@
     Adresse hinzufügen
     Adresse eingeben
     Bilder auf Straßenebene
-    Sind Sie sicher, die Routenplanung ohne speichern beenden zu wollen\? Sie werden alle Änderungen verlieren.
+    Sind Sie sicher, dass Sie alle Änderungen an der geplanten Route verwerfen wollen, indem Sie sie schließen\?
     Routentyp davor ändern
     Routentyp danach ändern
     Davor trimmen
@@ -3854,7 +3854,7 @@
     Track-Wegpunkt hinzufügen
     Streckenaufzeichnung
     Track folgen
-    Von meinem Standort zum Track navigieren
+    Von meiner Position zum Track navigieren
     Startpunkt des Tracks
     Auf Straßen einrasten
     Vereinfachter Track
@@ -3873,7 +3873,7 @@
     wird gespeichert
     Während der Navigation automatisch Track aufzeichnen
     Track Route
-    Track Datei zum Folgen auswählen, oder importieren.
+    Track Datei zum Folgen auswählen, oder vom Gerät importieren.
     Die GPX-Aufzeichnung wird angehalten, wenn OsmAnd beendet wird (über „zuletzt verwendete Apps“). (Die Hintergrunddienst-Anzeige verschwindet aus der Android-Benachrichtigungsleiste.)
     Aufzeichnungsintervall für die generelle Track-Aufzeichnung festlegen (via Schaltfläche \'GPX\' auf dem Kartenbildschirm).
     Um diese Option nutzen zu können, muss OsmAnd den Track auf die Straßen der Karte einrasten.
@@ -3892,4 +3892,19 @@
     Track-Punkt, zu dem navigiert werden soll
     Nächstgelegener Punkt
     Wiederholen
+    • Aktualisierte Funktion zum Planen einer Route: erlaubt die Verwendung verschiedener Navigationstypen pro Segment und die Einbeziehung von Tracks
+\n
+\n • Neues Menü zum Erscheinungsbild von Tracks: Wählen Sie Farbe, Dicke, Richtungspfeile, Start-/Ziel-Symbole
+\n
+\n • Verbesserte Darstellung von Fahrradknotenpunkten.
+\n
+\n • Tracks sind jetzt antippbar und haben ein Kontextmenü mit grundlegenden Informationen.
+\n
+\n • Verbesserte Suchalgorithmen
+\n
+\n • Verbesserte Trackverfolgungsoptionen in der Navigation
+\n
+\n • Probleme beim Import/Export von Profileinstellungen behoben
+\n
+\n
 
\ No newline at end of file

From 6cedbafcb514c19d401f3df06449393f2b53897f Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Thu, 17 Sep 2020 23:24:39 +0000
Subject: [PATCH 0206/1366] Translated using Weblate (Russian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 211819502e..6d48ebb5b2 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -3834,7 +3834,7 @@
     Выберите способ соединения точек прямой линией или рассчитайте маршрут между ними, как указано ниже.
     При обратном направлении
     Все изменения будут утеряны. Закрыть план маршрута\?
-    Съёмка уличного уровня
+    Уличная фотосъёмка
     Сохранить как новый файл трека
     Добавить в файл трека
     Треки

From adc46f7cd698158a8b2922835cffab2644ca9449 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Sat, 19 Sep 2020 00:49:01 +0000
Subject: [PATCH 0207/1366] Translated using Weblate (Turkish)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-tr/strings.xml | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml
index 1498c8591c..c48d2b66f2 100644
--- a/OsmAnd/res/values-tr/strings.xml
+++ b/OsmAnd/res/values-tr/strings.xml
@@ -1440,7 +1440,7 @@
     Değişiklik listesi kapatılıyor…
     Düğüm işleniyor …
     Yerel/İngilizce isimler dönüştürülüyor…
-    Son Osmand çalıştırmak çöktü. Log dosya {0} olduğunu. Sorunu bildirmek ve günlük dosyasını ekleyiniz.
+    Son OsmAnd çalıştırması çöktü. Günlük kaydı dosyası {0} konumunda. Lütfen sorunu bildirin ve günlük kaydı dosyasını ekleyin.
     OSM gönderimleri için gereken OpenStreetMap.org (OSM) ayarlarını belirtin.
     Sayfaya kiremit
     Çalışma saatleri biçimi değiştirilemez.
@@ -3827,4 +3827,33 @@
     Sadece seçili bölüm, seçilen profil kullanılarak yeniden hesaplanacaktır.
     Sonraki tüm bölümler, seçilen profil kullanılarak yeniden hesaplanacaktır.
     Önceki tüm bölümler, seçilen profil kullanılarak yeniden hesaplanacaktır.
+    Yol güzergahı
+    Yolu takip et
+    Takip edilecek yol dosyasını seçin
+    Takip etmek için yol dosyasını seçin veya cihazınızdan içe aktarın.
+    Başka bir yol seç
+    Konumumdan yola git
+    Gezinilecek yolun noktası
+    İzlenen yolun başlangıcı
+    Yollara ekle
+    Öncesinde kırp
+    Sonrasında kırp
+    Öncesinde güzergah türünü değiştir
+    Sonrasında güzergah türünü değiştir
+    Basitleştirilmiş yol
+    • Güzergah planlama işlevi güncellendi: her bölüm için farklı navigasyon türlerinin kullanılmasına ve izlenen yolların dahil edilmesine izin veriliyor
+\n
+\n • İzlenen yollar için yeni görünüm menüsü: renk ve kalınlık seçimi, yön oklarının gösterilmesi, başlangıç/bitiş simgeleri
+\n
+\n • Bisiklet düğümlerinin görünürlüğü iyileştirildi.
+\n
+\n • İzlenen yollar artık dokunulabilir, temel bilgiler bulunan içerik menüsüne sahip.
+\n
+\n • Arama algoritmaları iyileştirildi
+\n
+\n • Navigasyonda yol izleme seçenekleri iyileştirildi
+\n
+\n • Profil ayarlarının içe/dışa aktarımıyla ilgili sorunlar düzeltildi
+\n
+\n
 
\ No newline at end of file

From 42ab9e7e1e9b2cbdb33416b82f8ff038c899571c Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Fri, 18 Sep 2020 21:18:24 +0000
Subject: [PATCH 0208/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-uk/strings.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml
index 678d5dfc72..dcd577c052 100644
--- a/OsmAnd/res/values-uk/strings.xml
+++ b/OsmAnd/res/values-uk/strings.xml
@@ -257,7 +257,7 @@
     Новий пошук
     Виберіть розмір шрифту для позначень на мапі:
     Розмір тексту
-    Налагоджувальні відомості про відмалювання
+    Відомості для зневадження про відмальовування
     Відображає плідність відмалювання.
     Розпаковуються нові дані…
     Вибрано мережеву службу навігації, але ви не підключені до Інтернету.
@@ -1687,7 +1687,7 @@
     Запис подорожі
     Навігація
     Працює у фоновому режимі
-    Відомості по закладці
+    Відомості про закладки
     Зупинити симуляцію Вашої позиції.
     Пошук адреси
     Місця
@@ -3887,7 +3887,7 @@
 \n
 \n• Покращено оглядовість велосипедних вузлів
 \n
-\n• На треки тепер можна натискати, є контекстне меню з основною інформацією.
+\n• На треки тепер можна натискати, є контекстне меню з основними подробицями.
 \n
 \n• Вдосконалено алгоритми пошуку
 \n

From 21cced5759ea5185dc32ef1d4e60c5ab0fe7bb72 Mon Sep 17 00:00:00 2001
From: ovl-1 
Date: Fri, 18 Sep 2020 12:10:10 +0000
Subject: [PATCH 0209/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?=
 =?UTF-8?q?gian=20Bokm=C3=A5l)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Currently translated at 15.4% (539 of 3484 strings)
---
 OsmAnd/res/values-nb/strings.xml | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml
index e52dad60d0..683e185d58 100644
--- a/OsmAnd/res/values-nb/strings.xml
+++ b/OsmAnd/res/values-nb/strings.xml
@@ -3705,14 +3705,12 @@
     Velg en sporfil for åpning.
     Snu rute
     Overskriv spor
-    Hele sporet vil bli omregnet ved bruk av valgt profil.
-    Velg hvordan punkter skal knyttes sammen, i rett linje, eller utregnet rute mellom dem med valgt profil.
-    Kun neste segment vil bli omregnet ved bruk av valgt profil.
+    Hele sporet blir beregnet på nytt med den valgte profilen.
+    Velg hvordan punkter skal forbindes; med en rett linje, eller beregn en rute mellom dem som spesifisert nedenfor.
+    Kun det neste segmentet blir beregnet på nytt med den valgte profilen.
     Hele sporet
     Neste segment
-    For å bruke dette valget må OsmAnd rute sporet ditt til kartveiene.
-\n
-\n På neste steg vil du måtte velge navigasjonsprofil for oppdagelse av tillatte veier, og terskeldistanse for å anslå sporet ditt til veier.
+    Deretter juster ditt spor til nærmeste tillatte vei med en av navigeringsprofilene for å bruke dette alternativet.
     Velg en sporfil å legge til det nye segmentet i.
     Lagre som nytt spor
     Opprett ny rute
@@ -3739,11 +3737,11 @@
     Alle påfølgende segmenter
     Alle foregående segmenter
     Forrige segment
-    Kun valgt segment vil bli utregnet på ny i valgt profil.
-    Alle påfølgende segmenter vil bli utregnet på ny i valgt profil.
-    Alle tidligere segmenter vil bli utregnet på ny i valgt profil.
+    Kun det valgte segmentet blir beregnet på nytt med den valgte profilen.
+    Alle påfølgende segmenter blir beregnet på nytt med den valgte profilen.
+    Alle tidligere segmenter blir beregnet på nytt med den valgte profilen.
     Åpne lagret spor
     har blitt lagret
     Legg til minst to punkter.
-    Gjenta
+    Gjør om
 
\ No newline at end of file

From 6365cae638834ed9c79517d477eecaacff216f87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1ns?= 
Date: Fri, 18 Sep 2020 00:00:47 +0000
Subject: [PATCH 0210/1366] Translated using Weblate (Galician)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-gl/strings.xml | 99 +++++++++++++++++++++++++++-----
 1 file changed, 86 insertions(+), 13 deletions(-)

diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml
index 9b411b0d7f..c5e53fd258 100644
--- a/OsmAnd/res/values-gl/strings.xml
+++ b/OsmAnd/res/values-gl/strings.xml
@@ -13,7 +13,7 @@
     Favorito renomeado a \'%1$s\' para gardar a cadea que contén emoticonas nun ficheiro.
     Imprimir o itinerario
     Favorito especificado con nome duplicado
-    Lomba
+    Redutor de velocidade
     Aviso do tráfico
     Avisos de tráfico
     O servizo en segundo plano do OsmAnd aínda está en execución. Desexas detelo tamén\?
@@ -1878,8 +1878,8 @@ Lon %2$s
     Colla a %1$d saída e siga
     Enviar PDI
     Cálculo da ruta
-    Aínda non tes ningún ficheiro GPX
-    Tamén podes engadir ficheiros GPX ó cartafol
+    Aínda non tes ningún ficheiro de pistas
+    Tamén podes engadir ficheiros de pistas ó cartafol
     Engadir máis…
     Aparencia
     Activar a gravación rápida
@@ -1931,7 +1931,7 @@ Lon %2$s
     Localización non atopada
     Non hai conexión á Internet
     Espazo baleiro
-    Almacenamento dos datos do OsmAnd (para mapas, ficheiros GPX, etc.): %1$s.
+    Almacenamento dos datos do OsmAnd (para mapas, ficheiros de pistas, etc.): %1$s.
     Fornecer permiso
     Permitir acceso á localización
     Obtén indicacións e descobre lugares novos sen conexión á Internet
@@ -2901,10 +2901,10 @@ Lon %2$s
     Trocar
     Amosar máis
     Pistas amosadas
-    Amosar/agochar pistas GPX
-    Un botón que amosa ou agocha as pistas GPX escollidas no mapa.
-    Agochar pistas GPX
-    Amosar pistas GPX
+    Amosar/agochar pistas
+    Un botón que amosa ou agocha as pistas escollidas no mapa.
+    Agochar pistas
+    Amosar pistas
     %1$d transferencias
     Engadir orixe e destino
     Engadir punto de comezo
@@ -3804,7 +3804,7 @@ Lon %2$s
 \nEscolle %2$s. Todos os datos relacionados de radares de velocidade: alertas, notificacións e PDI serán eliminados até que o OsmAnd sexa reinstalado de xeito completo.
     Manter activo
     Desinstalar
-    É necesario reiniciar para eliminar de xeito completo os datos do radar de velocidade.
+    Reiniciar para eliminar todos os datos do radar de velocidade.
     As alertas de radares de velocidade nalgúns países están prohibidas por lei.
     Levando
     %1$s eliminado
@@ -3813,21 +3813,21 @@ Lon %2$s
     Límite de lonxitude
     Este dispositivo non ten radares de velocidade.
     Patíns en liña
-    Activar para controlar o nivel de achegamento (zoom) do mapa cos botóns de volume do dispositivo.
+    Controlar o nivel de achegamento (zoom) do mapa cos botóns de volume do dispositivo.
     Os botóns de volume mudan o achegamento
     Fornece a lonxitude do teu vehículo. Algunhas restricións de ruta poden ser aplicadas a vehículos longos.
-    Eliminar seguinte punto de destino
+    Eliminar punto de destino máis preto
     Fornece un nome para o punto
     O punto de destino actual na ruta será eliminado. Se fora o destino, a navegación sería interrompida.
     Baixar mapas da Wikipedia
-    Obter información sobre os puntos de interesse da Wikipédia. É o teu guía de peto sen conexión - só activar o complemento da Wikipédia e desfrutar dos artigos sobre os elementos ó teu redor.
+    Obter información sobre os puntos de interese da Wikipedia. É o teu guía de peto sen conexión - só activar o complemento da Wikipedia e desfrutar dos artigos sobre os elementos ó teu redor.
     Enduro
     Scooter
     Cadeira de rodas
     Cadeira de rodas só cara adiante
     Kart
     Nota do OSM pechada
-    Tes que definir os días laborais para continuar
+    Definir os días laborais para continuar
     Ruta entre puntos
     Planificar unha ruta
     Engadir a unha pista
@@ -3852,4 +3852,77 @@ Lon %2$s
     está gardado
     Engade polo menos dous puntos.
     Refacer
+    • Actualizouse a función \"Planificar ruta\": permite empregar diferentes tipos de navegación por segmento e o engadido de pistas
+\n
+\n • Novo menú coa aparencia das pistas: escoller a cor, o grosor, amosar as frechas de dirección e as iconas de comezo/final.
+\n
+\n • Melloras na visibilidade dos nós de bicicleta.
+\n
+\n • As pistas agora pódense premer, contén un menú con información básica.
+\n
+\n • Algoritmos de procura mellorados
+\n
+\n • Melloras nas opcións de seguimento da navegación
+\n
+\n • Solucionáronse os problemas da importación e exportación nos axustes dos perfís
+\n
+\n
+    Gravar a pista de xeito automático ó navegar
+    Última edición
+    Importar pista
+    Abrir pista existente
+    Crear nova ruta
+    Seleccionar un ficheiro de pista para abrir.
+    Feito
+    Substituír pista
+    Gardar coma nova pista
+    Ruta inversa
+    Recalcular toda a pista empregando o perfil escollido.
+    Recalcular só o seguinte segmento empregando o perfil escollido.
+    Marca de que xeito conectar os puntos, cunha liña recta ou calcular unha ruta entre eles como se detalla deseguido.
+    Pista enteira
+    Seguinte segmento
+    Deseguido, axusta a pista á estrada permitida máis preto cun perfil de navegación.
+    Distancia limiar
+    Perfil de navegación
+    Escolle un ficheiro de pista ó que se engadirá un novo segmento.
+    Imaxes a nivel de rúa
+    Pechar o plan de ruta sen gardar\?, desbotaranse todas as modificacións.
+    En caso de dirección inversa
+    Gardar coma novo ficheiro de pista
+    Engadir a un ficheiro de pistas
+    Pistas
+    Pistas
+    Pistas
+    Gardar pista en ficheiro GPX
+    Ruta da pista
+    Engadir ficheiros de pista
+    Importar ou gravar ficheiros de pista
+    Engadir punto de referencia da pista
+    Engadir punto de pasaxe da pista
+    Gravación da viaxe
+    Gardar coma ficheiro de pista
+    Seguir pista
+    Escoller o ficheiro da pista a seguir
+    Escoller o ficheiro da pista a seguir ou importar dende o dispositivo.
+    Escoller outra pista
+    Navegar dende a miña posición á pista
+    Punto da pista para navegar
+    Comezo da pista
+    Punto máis preto
+    Unir ás estradas
+    Eliminar enderezo
+    Engadir enderezo
+    Inserir o enderezo
+    Recurtar antes
+    Recurtar despois
+    Mudar o tipo de ruta anterior
+    Mudar o tipo de ruta seguinte
+    Pista simplificada
+    Só gravarase a liña da ruta, os puntos intermedios serán eliminados.
+    Nome do ficheiro
+    %s ficheiros de pista seleccionados
+    Gravar
+    A gravación da pista deterase ó pechar a aplicación (mediante aplicacións recentes). (A indicación de fondo do OsmAnd, desaparecerá da barra de notificacións do Android.)
+    Especifica o intre de gravación xeral para pistas (habilitado a través do trebello de gravación no mapa).
 
\ No newline at end of file

From b221b620118f0f68e6ac24f8795c5e47de9e8981 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= 
Date: Fri, 18 Sep 2020 08:05:10 +0000
Subject: [PATCH 0211/1366] Translated using Weblate (Czech)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-cs/phrases.xml | 53 +++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 8 deletions(-)

diff --git a/OsmAnd/res/values-cs/phrases.xml b/OsmAnd/res/values-cs/phrases.xml
index 6c95767d54..e63732cdc6 100644
--- a/OsmAnd/res/values-cs/phrases.xml
+++ b/OsmAnd/res/values-cs/phrases.xml
@@ -983,7 +983,7 @@
     Rozcestník
     Kuchyně
     Síranová
-    Charakteristika vody: bahnitá
+    Bahno
     Minerální
     Bez čerpadla
     Poháněné
@@ -1156,7 +1156,7 @@
     Ano
     Bez značení pro nevidomé
     Ano
-    Ne
+    Zvuk: ne
     Pouze pokud je chůze povolena
     Záchranná stanice
     Odpočívadlo se službami
@@ -1258,7 +1258,7 @@
     Vyzvednutí balíků
     Mléko
     Žvýkačky
-    Parkovací lístky; lístky na veřejnou dopravu
+    Parkovací lístky a lístky na veřejnou dopravu
     Káva
     Automat na mýto
     Hračky
@@ -1588,13 +1588,13 @@
     Žádné opravy
     Opravy elektrických vozidel
     Ano
-    Bez samoobsluhy
+    Ne
     Ano
     Neautomatizované
     Všechny služby
     Ano
     Bez kartáčů: ne
-    Automyčka: ne
+    Ne
     Veřejná sprcha
     Muži
     Zakázané pro muže
@@ -1955,7 +1955,7 @@
     Plány veřejné dopravy
     Pobočka
     Stéla
-    Ve tvaru kříže
+    Tvar kříže
     Kameny zmizelých
     Stúpa
     Tuf
@@ -2005,7 +2005,7 @@
     Palivo 100LL
     LPG
     Palivo tryskové A-1
-    Palivo AdBlue
+    Dieselové kapalné aditivum
     Palivo: dřevo
     Palivo: dřevěné uhlí
     Palivo: uhlí
@@ -3804,7 +3804,44 @@
     Výška vody: nad střední hladinou
     Výška vody: pod střední hladinou
     Překážka
-    Doplňování pitné vody: ano
+    Ano
     Doplňování pitné vody: ne
     Sít doplňování pitné vody
+    Včelí úl
+    Data v reálném čase
+    Ano
+    Výtah
+    Městská část
+    Obchod se suchými plody
+    Jízdní řád
+    Zpoždění
+    Odjezdová tabule: ne
+    Městský blok
+    Darovací místo
+    Šipka: ne
+    Ano
+    Ano
+    Vibrace: ne
+    Stav pumpy: chybí rukojeť
+    Sání
+    Pod tlakem
+    Podzemní voda
+    Roura
+    Internetový přístup: zdarma pro zákazníky
+    Typ klášteru: řeholnický
+    Typ klášteru: poustevnický
+    Typ klášteru: kanovnický
+    Typ klášteru: mnišský
+    Výběr hotovosti: u samoobslužné pokladny
+    Výběr hotovosti: u pokladny
+    Poplatek
+    Taxi kancelář
+    Polní hořák; fléra
+    Dosahující k moři
+    Malá elektrická zařízení
+    Odjezdová tabule
+    Doplňování pitné vody
+    Šipka
+    Vibrace
+    Tlak
 
\ No newline at end of file

From 04185ca0db6343f5cd5b06bfe5bdde6e710fab9d Mon Sep 17 00:00:00 2001
From: Oliver 
Date: Fri, 18 Sep 2020 20:26:41 +0000
Subject: [PATCH 0212/1366] Translated using Weblate (German)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-de/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml
index 14173b1d76..03347e1dd4 100644
--- a/OsmAnd/res/values-de/phrases.xml
+++ b/OsmAnd/res/values-de/phrases.xml
@@ -3845,4 +3845,5 @@
     Anzeige der Abreisezeiten
     Nachfüllen von Trinkwasser
     Bienenstock
+    Kleine Elektrogeräte
 
\ No newline at end of file

From 07d07c3e7bbaabc93b9175b5b7210f6062ad5cdd Mon Sep 17 00:00:00 2001
From: Ferdi 
Date: Fri, 18 Sep 2020 06:26:32 +0000
Subject: [PATCH 0213/1366] Translated using Weblate (German)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-de/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml
index 03347e1dd4..d091dc7fd5 100644
--- a/OsmAnd/res/values-de/phrases.xml
+++ b/OsmAnd/res/values-de/phrases.xml
@@ -3846,4 +3846,5 @@
     Nachfüllen von Trinkwasser
     Bienenstock
     Kleine Elektrogeräte
+    Nussladen
 
\ No newline at end of file

From 444abb24d60cb09d0a1eb6faaec405ed9bbbc16e Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Fri, 18 Sep 2020 21:17:23 +0000
Subject: [PATCH 0214/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-uk/phrases.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml
index 79fb238aee..4375b43720 100644
--- a/OsmAnd/res/values-uk/phrases.xml
+++ b/OsmAnd/res/values-uk/phrases.xml
@@ -793,7 +793,7 @@
     Релігійне землекористування
     Придорожній хрест
     Придорожня святиня
-    Інформація
+    Відомості
     Годинник
     Турагентство
     Місце з хорошим видом

From f15c6afb79706223861de1e06e1af8f1d059ca82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1ns?= 
Date: Fri, 18 Sep 2020 00:04:49 +0000
Subject: [PATCH 0215/1366] Translated using Weblate (Galician)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-gl/phrases.xml | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-gl/phrases.xml b/OsmAnd/res/values-gl/phrases.xml
index 88f562e0ac..ce9cdbbeea 100644
--- a/OsmAnd/res/values-gl/phrases.xml
+++ b/OsmAnd/res/values-gl/phrases.xml
@@ -3800,7 +3800,7 @@
     Incorrecto
     Rede de recarga de auga potábel
     Recarga de auga potábel: non
-    Recarga de auga potábel: si
+    Si
     Obstrución
     Nivel da auga: por debaixo do nivel medio da auga
     Nivel da auga: por encima do nivel medio da auga
@@ -3825,4 +3825,16 @@
     Caixa de distribución
     Predio
     Concello
+    Froitos secos
+    Colmea
+    Horarios
+    Tempo real
+    Atraso
+    Si
+    Taboleiro de saídas: non
+    Ascensor
+    Frecha: non
+    Pequenos aparellos eléctricos
+    Taboleiro de saídas
+    Recarga de auga potábel
 
\ No newline at end of file

From 8969585acde24d50b25baa8967f3d846e9c22b5a Mon Sep 17 00:00:00 2001
From: ovl-1 
Date: Fri, 18 Sep 2020 12:12:07 +0000
Subject: [PATCH 0216/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?=
 =?UTF-8?q?gian=20Bokm=C3=A5l)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Currently translated at 41.4% (1586 of 3824 strings)
---
 OsmAnd/res/values-nb/phrases.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-nb/phrases.xml b/OsmAnd/res/values-nb/phrases.xml
index 46c0e7a5e7..b7c1e63c18 100644
--- a/OsmAnd/res/values-nb/phrases.xml
+++ b/OsmAnd/res/values-nb/phrases.xml
@@ -1556,7 +1556,7 @@
     Rør
     Nettverk for påfyll av drikkevann
     Drikkevannspåfylling: Nei
-    Drikkevannspåfylling: Ja
+    Ja
     Vann-nivå: Nedsenket
     Hindring
     Vann-nivå: Under vanlig vann-nivå

From 639dcc2d57d0dca7521f53fafcaf5c18927a0ba1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Sat, 19 Sep 2020 01:12:06 +0000
Subject: [PATCH 0217/1366] Translated using Weblate (Turkish)

Currently translated at 62.6% (2395 of 3824 strings)
---
 OsmAnd/res/values-tr/phrases.xml | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml
index b4f98a709f..ce16c3b5ef 100644
--- a/OsmAnd/res/values-tr/phrases.xml
+++ b/OsmAnd/res/values-tr/phrases.xml
@@ -2364,7 +2364,7 @@
     Megalit
     Basınç
     İçme suyu doldurma: hayır
-    İçme suyu doldurma: evet
+    Evet
     İçme suyu doldurma şebekesi
     Malzeme: kompozit
     Malzeme: mermer
@@ -2398,4 +2398,12 @@
     Mobilet: evet
     Mobilet
     Şehir
+    Petroglif
+    Nekropol
+    Yuvarlak kulübe kalıntısı
+    Yerleşim yeri
+    İstihkam
+    Küçük elektrikli aletler
+    Kalkış bilgileri panosu
+    İçme suyu doldurma
 
\ No newline at end of file

From 368763e848b565697d148b5f2b53758ff4ef32f8 Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Thu, 17 Sep 2020 13:41:59 +0000
Subject: [PATCH 0218/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-pt/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml
index 0eb960c2f2..8d22b73dbe 100644
--- a/OsmAnd/res/values-pt/phrases.xml
+++ b/OsmAnd/res/values-pt/phrases.xml
@@ -3828,4 +3828,5 @@
     Reabastecimento de água potável
     Pequenos aparelhos elétricos
     Colmeia
+    Loja de nozes
 
\ No newline at end of file

From b7a6d89b18f881d5eec83a01d783e9efb33bbbd6 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Sat, 19 Sep 2020 19:18:22 +0300
Subject: [PATCH 0219/1366] Fix route to gpx issues

---
 .../net/osmand/router/RouteSegmentResult.java |  33 +++--
 .../MeasurementEditingContext.java            | 114 ++++++++++++------
 .../plus/routing/RouteCalculationResult.java  |  11 --
 3 files changed, 93 insertions(+), 65 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java
index 089de43fcd..e31f8ef03b 100644
--- a/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java
+++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteSegmentResult.java
@@ -271,7 +271,7 @@ public class RouteSegmentResult implements StringExternalizable
 				bundle.putString("turnLanes", TurnType.lanesToString(turnLanes));
 			}
 		}
-		bundle.putLong("id", object.id);
+		bundle.putLong("id", object.id >> 6); // OsmAnd ID to OSM ID
 		bundle.putArray("types", convertTypes(object.types, rules));
 
 		int start = Math.min(startPointIndex, endPointIndex);
@@ -327,22 +327,21 @@ public class RouteSegmentResult implements StringExternalizable
 		Location prevLocation = null;
 		for (int i = 0; i < length; i++) {
 			Location location = resources.getLocation(index);
-			if (location == null) {
-				continue;
-			}
-			double dist = 0;
-			if (prevLocation != null) {
-				dist = MapUtils.getDistance(prevLocation.getLatitude(), prevLocation.getLongitude(), location.getLatitude(), location.getLongitude());
-				distance += dist;
-			}
-			prevLocation = location;
-			object.pointsX[i] = MapUtils.get31TileNumberX(location.getLongitude());
-			object.pointsY[i] = MapUtils.get31TileNumberY(location.getLatitude());
-			if (location.hasAltitude() && object.heightDistanceArray.length > 0) {
-				object.heightDistanceArray[i * 2] = (float) dist;
-				object.heightDistanceArray[i * 2 + 1] = (float) location.getAltitude();
-			} else {
-				object.heightDistanceArray = new float[0];
+			if (location != null) {
+				double dist = 0;
+				if (prevLocation != null) {
+					dist = MapUtils.getDistance(prevLocation.getLatitude(), prevLocation.getLongitude(), location.getLatitude(), location.getLongitude());
+					distance += dist;
+				}
+				prevLocation = location;
+				object.pointsX[i] = MapUtils.get31TileNumberX(location.getLongitude());
+				object.pointsY[i] = MapUtils.get31TileNumberY(location.getLatitude());
+				if (location.hasAltitude() && object.heightDistanceArray.length > 0) {
+					object.heightDistanceArray[i * 2] = (float) dist;
+					object.heightDistanceArray[i * 2 + 1] = (float) location.getAltitude();
+				} else {
+					object.heightDistanceArray = new float[0];
+				}
 			}
 			if (plus) {
 				index++;
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index dd3295b2c2..d1dae05a6d 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -517,47 +517,90 @@ public class MeasurementEditingContext {
 		roadSegmentData.clear();
 		List routePoints = new ArrayList<>();
 		List gpxPoints = gpxApproximation.finalPoints;
-		for (int i = 0; i < gpxPoints.size() - 1; i++) {
-			GpxPoint rp1 = gpxPoints.get(i);
-			GpxPoint rp2 = gpxPoints.get(i + 1);
-			WptPt p1 = new WptPt();
-			p1.lat = rp1.loc.getLatitude();
-			p1.lon = rp1.loc.getLongitude();
-			p1.setProfileType(mode.getStringKey());
-			if (i == 0) {
-				routePoints.add(p1);
-			}
-			WptPt p2 = new WptPt();
-			p2.lat = rp2.loc.getLatitude();
-			p2.lon = rp2.loc.getLongitude();
-			p2.setProfileType(mode.getStringKey());
-			routePoints.add(p2);
-			Pair pair = new Pair<>(p1, p2);
+		for (int i = 0; i < gpxPoints.size(); i++) {
+			GpxPoint gp1 = gpxPoints.get(i);
+			boolean lastGpxPoint = isLastGpxPoint(gpxPoints, i);
 			List points = new ArrayList<>();
 			List segments = new ArrayList<>();
-			for (RouteSegmentResult seg : rp1.routeToTarget) {
-				segments.add(seg);
-				int ind = seg.getStartPointIndex();
-				boolean plus = seg.isForwardDirection();
-				float[] pf = seg.getObject().calculateHeightArray();
-				while (ind != seg.getEndPointIndex()) {
-					LatLon l = seg.getPoint(ind);
-					WptPt pt = new WptPt();
-					if (pf != null && pf.length > ind * 2 + 1) {
-						pt.ele = pf[ind * 2 + 1];
-
-					}
-					pt.lat = l.getLatitude();
-					pt.lon = l.getLongitude();
-					points.add(pt);
-					ind = plus ? ind + 1 : ind - 1;
+			for (int k = 0; k < gp1.routeToTarget.size(); k++) {
+				RouteSegmentResult seg = gp1.routeToTarget.get(k);
+				if (seg.getStartPointIndex() != seg.getEndPointIndex()) {
+					segments.add(seg);
 				}
 			}
-			roadSegmentData.put(pair, new RoadSegmentData(appMode, pair.first, pair.second, points, segments));
+			for (int k = 0; k < segments.size(); k++) {
+				RouteSegmentResult seg = segments.get(k);
+				fillPointsArray(points, seg, lastGpxPoint && k == segments.size() - 1);
+			}
+			if (!points.isEmpty()) {
+				WptPt wp1 = new WptPt();
+				wp1.lat = gp1.loc.getLatitude();
+				wp1.lon = gp1.loc.getLongitude();
+				wp1.setProfileType(mode.getStringKey());
+				routePoints.add(wp1);
+				WptPt wp2 = new WptPt();
+				if (lastGpxPoint) {
+					wp2.lat = points.get(points.size() - 1).getLatitude();
+					wp2.lon = points.get(points.size() - 1).getLongitude();
+					routePoints.add(wp2);
+				} else {
+					GpxPoint gp2 = gpxPoints.get(i + 1);
+					wp2.lat = gp2.loc.getLatitude();
+					wp2.lon = gp2.loc.getLongitude();
+				}
+				wp2.setProfileType(mode.getStringKey());
+				Pair pair = new Pair<>(wp1, wp2);
+				roadSegmentData.put(pair, new RoadSegmentData(appMode, pair.first, pair.second, points, segments));
+			}
+			if (lastGpxPoint) {
+				break;
+			}
 		}
 		addPoints(routePoints);
 	}
 
+	private boolean isLastGpxPoint(List gpxPoints, int index) {
+		if (index == gpxPoints.size() - 1) {
+			return true;
+		} else {
+			for (int i = index + 1; i < gpxPoints.size(); i++) {
+				GpxPoint gp = gpxPoints.get(i);
+				for (int k = 0; k < gp.routeToTarget.size(); k++) {
+					RouteSegmentResult seg = gp.routeToTarget.get(k);
+					if (seg.getStartPointIndex() != seg.getEndPointIndex()) {
+						return false;
+					}
+				}
+
+			}
+		}
+		return true;
+	}
+
+	private void fillPointsArray(List points, RouteSegmentResult seg, boolean includeEndPoint) {
+		int ind = seg.getStartPointIndex();
+		boolean plus = seg.isForwardDirection();
+		float[] heightArray = seg.getObject().calculateHeightArray();
+		while (ind != seg.getEndPointIndex()) {
+			addPointToArray(points, seg, ind, heightArray);
+			ind = plus ? ind + 1 : ind - 1;
+		}
+		if (includeEndPoint) {
+			addPointToArray(points, seg, ind, heightArray);
+		}
+	}
+
+	private void addPointToArray(List points, RouteSegmentResult seg, int index, float[] heightArray) {
+		LatLon l = seg.getPoint(index);
+		WptPt pt = new WptPt();
+		if (heightArray != null && heightArray.length > index * 2 + 1) {
+			pt.ele = heightArray[index * 2 + 1];
+		}
+		pt.lat = l.getLatitude();
+		pt.lon = l.getLongitude();
+		points.add(pt);
+	}
+
 	private int findPointIndex(WptPt point, List points, int firstIndex) {
 		double minDistance = Double.MAX_VALUE;
 		int index = 0;
@@ -740,10 +783,7 @@ public class MeasurementEditingContext {
 					}
 					locations.add(l);
 				}
-				pair.second.setTrkPtIndex(locations.size() - 1);
-				if (i < size - 2 && !locations.isEmpty()) {
-					locations.remove(locations.size() - 1);
-				}
+				pair.second.setTrkPtIndex(i < size - 1 ? locations.size() : locations.size() - 1);
 				route.addAll(data.segments);
 			}
 		}
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
index df6a6eaafa..a6dcc20fca 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
@@ -356,17 +356,6 @@ public class RouteCalculationResult {
 					}
 					lastHeight = h;
 				}
-				// FIXME: investigate gpx file
-				if (s.getObject().getPoint31XTile(i) == 0 && s.getObject().getPoint31YTile(i) == 0) {
-					if (locations.size() > 0) {
-						Location prev = locations.get(locations.size() - 1);
-						n.setLatitude(prev.getLatitude());
-						n.setLongitude(prev.getLongitude());
-						if (prev.hasAltitude()) {
-							n.setAltitude(prev.getAltitude());
-						}
-					}
-				}
 				locations.add(n);
 				attachAlarmInfo(alarms, s, i, locations.size());
 				segmentsToPopulate.add(s);

From 5c98b9660e9cb8455853decbc43062a0aadebc77 Mon Sep 17 00:00:00 2001
From: ssantos 
Date: Sun, 20 Sep 2020 20:44:37 +0000
Subject: [PATCH 0220/1366] Translated using Weblate (Portuguese)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml
index 49f1d72d9e..fe6c5d23b1 100644
--- a/OsmAnd/res/values-pt/strings.xml
+++ b/OsmAnd/res/values-pt/strings.xml
@@ -91,7 +91,7 @@
     Reinicializar pesquisa de transporte
     Voz gravada
     Nenhum mapa vetorial foi carregado
-    Caminho reverso
+    Inverter a direção do trilho
     Nenhum ficheiro GPX encontrado na pasta tracks
     Não foi possível ler os dados de GPX.
     Mapas vetoriais offline

From d98ffea12cd736af069fd3fda408109714375060 Mon Sep 17 00:00:00 2001
From: Ldm Public 
Date: Sat, 19 Sep 2020 06:15:45 +0000
Subject: [PATCH 0221/1366] Translated using Weblate (French)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-fr/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml
index b116563f71..408aa58e53 100644
--- a/OsmAnd/res/values-fr/strings.xml
+++ b/OsmAnd/res/values-fr/strings.xml
@@ -147,7 +147,7 @@
     La langue sélectionnée n\'est pas disponible dans le moteur de synthèse vocale installé. Souhaitez-vous rechercher d\'autres moteurs de synthèse vocale sur Google Play \? Sinon la langue par défaut sera utilisée.
     Données manquantes
     Souhaitez-vous installer la langue sélectionnée depuis Google Play ?
-    Inverser l\'itinéraire GPX
+    Inverser le sens de la trace
     Utiliser la destination en cours
     Suivre l\'ensemble de la trace
     Cartes vectorielles hors-lignes disponibles pour cette position. 

From aebd611b1c336912d17a10097f3662777baab27a Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Mon, 21 Sep 2020 06:32:32 +0000
Subject: [PATCH 0222/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 6d48ebb5b2..968382e664 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -3833,7 +3833,7 @@
 \nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
     Выберите способ соединения точек прямой линией или рассчитайте маршрут между ними, как указано ниже.
     При обратном направлении
-    Все изменения будут утеряны. Закрыть план маршрута\?
+    Все изменения будут утеряны.
     Уличная фотосъёмка
     Сохранить как новый файл трека
     Добавить в файл трека

From 0b315a77c3ea40b43aa3610d6b93c78a31ce611d Mon Sep 17 00:00:00 2001
From: solokot 
Date: Sat, 19 Sep 2020 10:04:20 +0000
Subject: [PATCH 0223/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 968382e664..f8ae3f5674 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -515,7 +515,7 @@
     Выбранный язык не поддерживается установленным движком Android TTS (text-to-speech или текст-в-речь), вместо него будет использоваться предустановленный язык TTS. Посмотреть в Google Play другой TTS\?
     Данные отсутствуют
     Перейти в маркет для загрузки выбранного языка?
-    Обратное направление GPX
+    Обратное направление трека
     Использовать текущий пункт назначения
     Пройти весь путь
     Для этого региона доступны локальные векторные карты. 
@@ -1460,7 +1460,7 @@
     Мировые пункты обмена bitcoin
     дней
     Соединение
-    Сохранить данные как трек файл или импортировать путевые точки в избранные\?
+    Сохранить данные как файл трека или импортировать путевые точки в избранные\?
     Розовый
     Коричневый
     Пустой файл GPX
@@ -3830,7 +3830,7 @@
     Весь трек
     Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам.
 \n
-\nНа следующем шаге необходимо выбрать профиль навигации для определения разрешенных дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
+\nНа следующем шаге необходимо выбрать профиль навигации для определения разрешённых дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
     Выберите способ соединения точек прямой линией или рассчитайте маршрут между ними, как указано ниже.
     При обратном направлении
     Все изменения будут утеряны.
@@ -3870,7 +3870,7 @@
     Будет сохранена только линия маршрута, путевые точки будут удалены.
     Имя файла
     Выбрано файлов треков: %s
-    Укажите интервал общей записи трека (включается через виджет «Запись GPX» на карте).
+    Укажите интервал общей записи трека (включается через виджет «Запись поездки» на карте).
     Остановить запись
     Возобновить запись поездки
     По выбору системы
@@ -3885,9 +3885,9 @@
     сохранен
     Добавьте хотя бы две точки.
     ПОВТОРИТЬ
-    • Обновленный режим планирования маршрута позволяет использовать разные типы навигации для каждого сегмента и прикрепляет любой трек к дорогам
+    • Обновлённый режим планирования маршрута позволяет использовать разные типы навигации для каждого сегмента и прикрепляет любой трек к дорогам
 \n
-\n • Новые параметры внешнего вида для треков: выберите цвет, толщину, включите стрелки направления и отметки начала/окончания
+\n • Новые параметры внешнего вида для треков: можно выбрать цвет, толщину, включите стрелки направления и отметки начала/окончания
 \n
 \n • Улучшена видимость велосипедных узлов
 \n

From 3c50d495d1b4862c48a4c4b4ab810fb319adf9c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Sat, 19 Sep 2020 05:36:47 +0000
Subject: [PATCH 0224/1366] Translated using Weblate (Turkish)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-tr/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml
index c48d2b66f2..88d2ecc725 100644
--- a/OsmAnd/res/values-tr/strings.xml
+++ b/OsmAnd/res/values-tr/strings.xml
@@ -937,7 +937,7 @@
     Düşük yakınlaştırma seviyelerinde tüm dünyayı kapsayan bir genel bakış elde etmek için ana dünya haritasını indirin.
     %1$s\'a öğe yok
     Seçilen dil yüklü Android TTS (metinden konuşmaya) motoru tarafından desteklenmemektedir, bunun yerine önceden ayarlanmış TTS dili kullanılacak. Mağazada başka bir TTS motoru aramak ister misiniz\?
-    GPX yönünü tersine çevir
+    İzlenen yol yönünü tersine çevir
     Bu konum için çevrim dışı vektör haritası. 
 \n\t
 \n\tKullanmak için \'Menü\' → \'Harita Katmanları\' → \'Harita Kaynağı…\' → \'Çevrim dışı vektör haritalar\'.

From 0ff785a55035d06a2aa2449dfebf67587e74197d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Babos=20G=C3=A1bor?= 
Date: Sat, 19 Sep 2020 14:46:17 +0000
Subject: [PATCH 0225/1366] Translated using Weblate (Hungarian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-hu/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml
index 3133035da6..519a8cce66 100644
--- a/OsmAnd/res/values-hu/strings.xml
+++ b/OsmAnd/res/values-hu/strings.xml
@@ -213,7 +213,7 @@
     A kijelölt nyelvet az Android TTS (text-to-speech, szövegfelolvasó) rendszere nem támogatja, helyette az előre beállított szövegfelolvasási nyelv lesz használatban. Keresen másik TTS rendszert a Play Áruházban\?
     Hiányzó adat
     Átváltasz az áruházra a kiválasztott nyelv letöltéséhez?
-    GPX irány megfordítása
+    Nyomvonal irányának megfordítása
     Jelenlegi célpont használata
     Végig az egész útvonalon
     Offline vektoros térkép érhető el ezen a helyen.

From 9b7c1af90fce3b640384c2f4a8b7babb73de0bd5 Mon Sep 17 00:00:00 2001
From: ihor_ck 
Date: Sat, 19 Sep 2020 12:26:57 +0000
Subject: [PATCH 0226/1366] Translated using Weblate (Ukrainian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-uk/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml
index dcd577c052..d3a1ebd846 100644
--- a/OsmAnd/res/values-uk/strings.xml
+++ b/OsmAnd/res/values-uk/strings.xml
@@ -265,7 +265,7 @@
     Вибрана мова не підтримується встановленим двигуном Android TTS (текстовим мовленням), замість цього буде використана його попередньо налаштована мова TTS. Шукаєте інший двигун TTS\?
     Дані відсутні
     Перейти в магазин для завантаження обраної мови?
-    Зворотній напрямок GPX
+    Зворотний напрямок треку
     Використовувати поточний пункт призначення
     Пройдіть по усьому треку
     Для цього регіону доступні автономні векторні мапи

From 0a6cde8b5d07e66e5862971e5941cc16128e6a1d Mon Sep 17 00:00:00 2001
From: Mirco Zorzo 
Date: Sun, 20 Sep 2020 18:17:00 +0000
Subject: [PATCH 0227/1366] Translated using Weblate (Italian)

Currently translated at 90.2% (3144 of 3484 strings)
---
 OsmAnd/res/values-it/strings.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml
index 505d5ee27f..018ca3edb1 100644
--- a/OsmAnd/res/values-it/strings.xml
+++ b/OsmAnd/res/values-it/strings.xml
@@ -3816,15 +3816,15 @@
     Seleziona larghezza
     Ultima modificata
     Importa una traccia
-    Apri una traccia esistente
+    Apri traccia esistente
     Crea un nuovo percorso
-    Scegli il file di una traccia da aprire.
+    Scegli un file traccia da aprire.
     Fatto
     Profilo di navigazione
     Poi approssima la traccia alle strade più vicine permesse da uno dei tuoi profili di navigazione per utilizzare questa opzione.
-    Scegli come collegare i punti, con una linea retta, o calcolando un percorso che li colleghi utilizzando il profilo scelto.
+    Scegli come collegare i punti, con una linea retta, o calcolando un percorso che li colleghi come specificato sotto.
     Sovrascrivi traccia
-    Salva come nuova Traccia
+    Salva come nuova traccia
     Inverti il percorso
     Solo il nuovo segmento sarà ricalcolato utilizzando il profilo scelto.
     Tutta la traccia sarà ricalcolata utilizzando il profilo scelto.
@@ -3870,7 +3870,7 @@
     Nome del file
     %s file traccia selezionati
     Metterà in pausa la registrazione della traccia quando l\'applicazione viene terminata (attraverso le app recenti). (L\'indicazione di OsmAnd in background scomparirà dalla barra delle notifiche di Android.)
-    Specifica l\'intervallo di registrazione per la registrazione delle tracce (abilitata attraverso il pulsante di Registrazione del viaggio sulla mappa).
+    Specifica l\'intervallo per la registrazione delle tracce (abilitata attraverso il pulsante di Registrazione del viaggio sulla mappa).
     Sospendi la registrazione del viaggio
     Riprendi la registrazione del viaggio
     Preimpostazioni di sistema
@@ -3881,7 +3881,7 @@
     Tutti i segmenti successivi verranno ricalcolati con il profilo selezionato.
     Tutti i segmenti precedenti verranno ricalcolati con il profilo selezionato.
     Apri una traccia salvata
-    è stato salvato
+    è salvato
     Per favore aggiungi almeno due punti.
     Ripeti
     • Aggiornata la modalità Pianificazione dell\'Itinerario che permette l\'utilizzo di diversi profili di navigazione per ogni segmento e incolla le tracce alle strade
@@ -3890,7 +3890,7 @@
 \n
 \n • Migliorata la visibilità dei nodi ciclistici
 \n
-\n • Menù contestuale con informazioni di base
+\n • Le tracce adesso sono tappabili, hanno un nuovo menù contestuale con informazioni di base
 \n
 \n • Migliorato l\'algoritmo di ricerca
 \n

From 61438d94388338a28e98e2a6b15e14fd1ac9e1ce Mon Sep 17 00:00:00 2001
From: ace shadow 
Date: Sun, 20 Sep 2020 00:13:15 +0000
Subject: [PATCH 0228/1366] Translated using Weblate (Slovak)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-sk/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml
index 454bf3203b..379b112de9 100644
--- a/OsmAnd/res/values-sk/strings.xml
+++ b/OsmAnd/res/values-sk/strings.xml
@@ -281,7 +281,7 @@
     Zvolený jazyk nie je podporovaný nainštalovaným TTS (text-to-speech) modulom v Androide. Bude použitý jeho prednastavený TTS jazyk. Nájsť iný TTS modul v obchode\?
     Chýbajúce údaje
     Prejsť do obchodu pre stiahnutie zvoleného jazyka?
-    Obrátiť GPX smerovanie
+    Obrátiť smer stopy
     Použiť aktuálny cieľový bod
     Prejsť pozdĺž celej trasy
     Pre túto oblasť je dostupná offline vektorová mapa.

From 7c83a2d4b7936e758e70969ca25f659a562916b2 Mon Sep 17 00:00:00 2001
From: Yaron Shahrabani 
Date: Sat, 19 Sep 2020 09:56:13 +0000
Subject: [PATCH 0229/1366] Translated using Weblate (Hebrew)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-iw/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml
index 2971332a22..afc41fbb36 100644
--- a/OsmAnd/res/values-iw/strings.xml
+++ b/OsmAnd/res/values-iw/strings.xml
@@ -400,7 +400,7 @@
     השפה הנבחרת אינה נתמכת על ידי המנגנון של Android הממיר טקסט לדיבור (TTS) המותקן, ייעשה שימוש בשפת ההמרה במקום. לחפש מנוע המרה אחר של טקסט לדיבור בחנות\?
     חסרים נתונים
     לגשת לחנות להוריד את השפה הנבחרת?
-    היפוך כיוון ה־GPX
+    היפוך כיוון המסלול
     שימוש ביעד הנוכחי
     לעבור לאורך דרך שלמה
     קיימת מפה וקטורית עבור מיקום זה.

From 4ed07267c50e4fc9f756134a60f97bb089dc3d81 Mon Sep 17 00:00:00 2001
From: Zmicer Turok 
Date: Mon, 21 Sep 2020 05:56:41 +0000
Subject: [PATCH 0230/1366] Translated using Weblate (Belarusian)

Currently translated at 99.9% (3483 of 3484 strings)
---
 OsmAnd/res/values-be/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml
index c80bd4dfe0..0696333fe4 100644
--- a/OsmAnd/res/values-be/strings.xml
+++ b/OsmAnd/res/values-be/strings.xml
@@ -657,7 +657,7 @@
     Абраная мова не падтрымліваецца Android TTS (пераўтварэнне тэксту ў гук), таму будзе выкарыстоўвацца прадвызначаная мова TTS. Пашукаць іншы TTS у краме\?
     Даныя адсутнічаюць
     Перайсці ў краму, каб спампаваць абраную мову\?
-    Развярнуць кірунак GPX
+    Развярнуць кірунак следу
     Выкарыстоўваць дзейны пункт прызначэння
     Прайсці ўвесь шлях
     Для гэтага рэгіёну даступныя лакальныя вектарныя мапы.

From 0be5fc36d79c935ee4bb5ec0c4b7e962fc7ce802 Mon Sep 17 00:00:00 2001
From: Guntis Ozols 
Date: Sun, 20 Sep 2020 08:37:36 +0000
Subject: [PATCH 0231/1366] Translated using Weblate (Latvian)

Currently translated at 63.0% (2197 of 3484 strings)
---
 OsmAnd/res/values-lv/strings.xml | 91 +++++++++++++++++---------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/OsmAnd/res/values-lv/strings.xml b/OsmAnd/res/values-lv/strings.xml
index 95f040be10..437c20e592 100644
--- a/OsmAnd/res/values-lv/strings.xml
+++ b/OsmAnd/res/values-lv/strings.xml
@@ -118,7 +118,7 @@
     Mainīt maršruta iestatījumus
     Globālie iestatījumi
     Kartes faili
-    "Lejupielādēt un pārraudzīt kartes daļas,  balss pakas un vikipēdijas interešu punktus (POI)"
+    Lejupielādēt un pārvaldīt bezsaistes kartes failus, kas saglabāti jūsu ierīcē.
     Vispārīgie iestatījumi
     Mainīt lietotnes iestatījumus.
     Globālie lietotnes iestatījumi
@@ -220,7 +220,7 @@
     Atpako jaunos datus…
     Lai darbotos tiešsaistes navigācijas serviss, ir nepieciešams interneta savienojums.
     Valoda netiek atbalstīta
-    Izvēlētā valoda nav atbalstīta instalētajā ierīces Android TTS (teksta izrunāšana) dzinējā. Vai vēlaties meklēt citu TTS dzinēju? Pretējā gadījumā tiks lietota iepriekš uzstādītā TTS valoda.
+    Izvēlētā valoda nav atbalstīta ierīces Android TTS (teksta izrunāšana) dzinējā, tāpēc tiks lietota instalētā TTS valoda. Vai meklēt Google Play veikalā citu TTS dzinēju\?
     Iztrūkst dati
     Valodas dati nav instalēti. Vai atvērt Google Play veikalu, lai instalētu?
     Pretējs GPX virziens
@@ -327,7 +327,7 @@
     Izvēlieties, kuru OsmAnd versiju instalēt
     Instalācijas versija
     GPS statusa lietotne nav instalēta. Meklēt Google Play veikalā\?
-    "Nav pieejama balss vadība,  lūdzu ejiet uz \'Iestatījumi\' → \'Vispārīgie Iestatījumi\' → \'Balss vadība\' un izvēlieties vai lejupielādējiet balss pakotni."
+    Nav pieejama balss vadība, lūdzu ejiet uz \'Iestatījumi\' → \'Vispārīgie Iestatījumi\' → \'Balss vadība\' un izvēlieties kādu vai lejupielādējiet balss pakotni.
     Nav izvēlēta balss vadība
     Diena
     Nakts
@@ -440,7 +440,7 @@
     Turpināt
     Vēlāk
     Lejupielādēt reģionus
-    "Paldies, ka izvēlējāties OsmAnd. Lejupielādējiet reģiona datus bezsaistes lietošanai caur \'Izvēlne\' -> → \'Lejupielādes\'. Pēc tam jūs varēsiet skatīt kartes, atrast adreses,  interešu punktus (POI), meklēt sabiedrisko transportu un vēl."
+    "Paldies, ka izvēlējāties OsmAnd. Lejupielādējiet reģiona datus bezsaistes lietošanai caur \'Izvēlne\' -> → \'Lejupielādes\', lai skatītu kartes, atrastu adreses,  interešu punktus (POI), meklētu sabiedrisko transportu un vēl."
     Meklē signālu…
     Meklēt blakus kartes centram
     Meklēt tuvumā
@@ -544,7 +544,7 @@
     Iestatiet valodu, lejupielādējiet/atjaunojiet datus
     Dati
     OSM labošana
-    Automātiski mērogot karti atkarībā no pārvietošanās ātruma
+    Automātiski mērogot karti atkarībā no pārvietošanās ātruma.
     Automātiski mērogot karti
     Papildus iestatījumi
     Iestatījumi
@@ -663,11 +663,11 @@
     Lietot tiešaistes kartes (lejuplādējot un kešojot bildes SD kartē)
     Tiešsaistes kartes
     Konfigurēt tiešaistes vai kešotās kartes bildes
-    "Ar šo spraudni jūs varēsiet piekļūt dažādām tiešsaistes (t.s. bilžu vai rastru) kartēm, sākot no iepriekš definētām OpenStreetMap bildēm ( kā Mapnik) līdz satelītu fotoattēliem un īpašajiem klājumiem kā laikapstākļu kartes, klimata kartes, ğeoloğiskās kartes,  kalnu reljefi u.t.t.
+    "Ar šo spraudni jūs varēsiet piekļūt dažādām tiešsaistes (t.s. bilžu vai rastru) kartēm, sākot no iepriekš definētām OpenStreetMap bildēm (kā Mapnik) līdz satelītu fotoattēliem un īpašajiem klājumiem kā laikapstākļu kartes, klimata kartes, ğeoloğiskās kartes,  kalnu reljefi u.t.t.
 \n
 \nJebkuras no šīm kartēm var tik pielietotas kā pamata (bāzes) kartes vai kā virsklājs vai apakšklājs citai bāzes kartei (kā piemēram, OsmAnd standarta bezsaistes kartei). Lai apakšklāja kartes būtu labāk redzamas, noteiktus elementus no OsmAnd vektoru kartēm ir iespējams paslēpt caur kartes konfigurācijas izvēlni.
 \n
-\nBilžu kartes var lietot no tiešsaistes avotiem vai sagatavot bezsaistes lietošanai (iekopējot OsmAnd datu mapē) kā SQLite databāzi, to izveidojot ar kādu no atsevišķi pieejamajām kartēšanas aplikācijām. "
+\nBilžu kartes var lietot no tiešsaistes avotiem vai sagatavot bezsaistes lietošanai (iekopējot OsmAnd datu mapē) kā SQLite databāzi, to izveidojot ar kādu no atsevišķi pieejamajām kartēšanas aplikācijām."
     Rāda iestatījumus navigācijas darbībai fonā (izslēgts ekrāns), periodiski ieslēdzot GPS.
     Rādīt iestatījumus atsevišķām pieejamības iespējām kā TTS runas ātrums, atrašanās vietas izruna, ekrāna mērogošana u.t.t.
     Rādīt izstrādes un atkļūdošanas iestatījumus, kā piemēram, animētā navigācija, renderēšanas izpildījuma attēlošana vai balss uzvednes. Šie iestatījumi ir paredzēti izstrādātājiem un nav vajadzīgi gala lietotājam.
@@ -762,7 +762,7 @@
     Izvairīties no pārceltuvēm
     Izvairīties no…
     Rādīt signālus…
-    Satiksmes ierobežojumus (ātruma limitus, stopzīmes, rampas), gājēju pārejas, fotoradarus, ceļa joslas
+    Iestatīt satiksmes brīdinājumus (ātruma limitus, apstāšanās vietas, ātrumvaļņus, tuneļus), foto radarus un ceļa joslas.
     Fluorescējošs maršruts
     Lineāls
     Skata virziens
@@ -860,9 +860,9 @@
     Eiropa, Āzija, Latīņamerika
     Apvienotā Karaliste, Indija un citas
     Paziņot…
-    Ielu nosaukumus, satiksmes brīdinājumus (stopzīmes, ceļa rampas), fotoradarus, ātruma ierobežojumus
+    Izrunāt ielu nosaukumus, satiksmes brīdinājumus (piespiedu apstāšanos, ātrumvaļņus), fotoradarus un ātruma ierobežojumus.
     Ielu nosaukumi (TTS)
-    Ātruma ierrobežojums
+    Ātruma ierobežojums
     Fotoradari
     Satiksmes brīdinājumi
     Lūdzu norādiet iestatījumos OSM lietotāja vārdu un paroli
@@ -900,7 +900,7 @@
     Noņemt visus mērķus
     Atvērt GPX failu
     Lūdzu uzgaidiet, kamēr tiks pabeigta patreizējā darbība
-    "Samazina kompasa svārstības,  palielinot inertumu"
+    Samazina kompasa svārstības, palielinot inertumu.
     Lietot Kalmana filtru
     Lietot magnētisko sensoru orientācijas sensora vietā, lai noteiktu kompasa stāvokli
     Lietot magnētisko sensoru
@@ -949,7 +949,7 @@
     Mainīt kārtību
     Lūdzu apsveriet iespēju pirkt Contour Lines spraudni, lai atbalstītu tā tālāko attīstību.
     Kontūrlīniju spraudnis
-    Atlasīt pēc pieprasījuma
+    Pēc pieprasījuma\?
     Ierakstīt video
     Ierakstīt audio
     Izvēlieties noklusēto logrīka darbību
@@ -996,7 +996,7 @@
     Ceļu kartes
     Robežas
     Noņemt reģionālo robežu attēlošanu (admin līmeņi 5-9)
-    Ātruma limiti
+    Ātruma ierobežojumi
     Nav atrastas ēkas.
     Meklēt apdzīvotās vietas/pasta indeksus
     Izvēlieties, kad rādīt tikai ceļu tīkla kartes:
@@ -1204,9 +1204,9 @@
     Persiešu
     Nosaukumi kartē (ja valoda nebūs pieejama, tiks lietoti vietvārdi vai angļu valoda)
     Kartes pamatvaloda
-    "Ar šo spraudni jūs varat manuāli saglabāt trekus, nospiežot GPX ieraksta logrīku uz kartes vai veikt automātisku visu maršrutu ierakstu GPX failā.
+    Ar šo spraudni jūs varat manuāli saglabāt trekus, nospiežot GPX ieraksta logrīku uz kartes vai veikt automātisku visu maršrutu ierakstu GPX failā.
 \n
-\nIerakstītie treki vēlāk var tikt izmantoti treka analīzei, koplietošanai ar draugiem vai OSM izstrādei.  Atlēti var izmantot trekus, lai monitorētu treniņus. Pamata treku analīze var tikt veikta tieši caur OsmAnd kā piemēram, apļu laiki, vidējais ātrums utt., bet paplašinātai analīzei trekus var atvērt citās programmās. "
+\nIerakstītie treki vēlāk var tikt izmantoti treka analīzei, koplietošanai ar draugiem vai OSM izstrādei. Atlēti var izmantot trekus, lai monitorētu treniņus. Pamata treku analīze var tikt veikta tieši caur OsmAnd kā piemēram, apļu laiki, vidējais ātrums utt., bet paplašinātai analīzei trekus var atvērt citās programmās.
     Ceļa ieraksts
     h
     Laiks
@@ -1290,7 +1290,7 @@
     Izvairīties no ceļiem…
     Vilciena maršruti
     Tramvaja maršruti
-    "Kopīgot  taksometru maršrutus"
+    Kopīgot taksometru maršrutus
     Trolejbusu maršruti
     Autobusu maršruti
     Paslēpt
@@ -1315,10 +1315,10 @@
     Izlases vietas vārds tika pārdēvēts uz %1$s, lai varētu saglabāt kopu ar sejiņām failā.
     Printēt maršrutu
     Šāds vārds izlasē jau eksistē
-    "Norādītais izlases vārds tika pārdēvēts uz  %1$s lai izvairītos no dublēšanas."
+    "Izlases vārds tika nomainīts uz  %1$s, lai izvairītos no dublikāta."
     Teksta lielums uz kartes.
     Teksta izmērs
-    Ātruma robeža
+    Ātruma ierobežojums
     Robežkontrole
     Nodevu kabīne
     STOP zīme
@@ -1529,7 +1529,9 @@
     Daļa no jūsu ziedojuma tiks nosūtīta OSM lietotājiem, kas veic labojumus apgabala kartē
     Abonomenta iestatījumi
     Lūdzu, vispirms nopērciet abonomentu OSM atjauninājumiem
-    "Abonēšana nodrošina ik stundu karšu atjauninājumus no visas pasaules. Daļa no ienākumiem nonāk OSM kopienai par ieguldījumu OSM. Ja jums patīk OsmAnd un OSM  un vēlaties tos atbalstīt, tad šis ir lielisks veids, kā to darīt."
+    Abonēšana nodrošina ik stundu karšu atjauninājumus no visas pasaules.
+\nDaļa ienākumu nonāk OSM kopienā un tiek izmaksāta par ieguldījumu OSM.
+\nJa jums patīk OsmAnd un OSM un vēlaties sniegt, kā arī saņemt atbalstu, šis ir lielisks veids, kā to izdarīt.
     Izvēlieties marķieri
     Citi marķieri
     Augšupielādēt anonīmi
@@ -1646,7 +1648,7 @@
     Kontūrlīnijas ir deaktivizētas
     Izveidot jaunu
     Izvēlieties kategoriju
-    Izvēlieties ātruma mērvienību
+    Izvēlieties ātruma mērvienību.
     Ātruma mērvienības
     Jūras jūdze
     Kilometri stundā
@@ -1721,7 +1723,7 @@
     Izslēgts
     Krāsas pēc infrastruktūras veida
     Krāsas pēc OSMC simbola
-    "Vai vēlaties izdzēst  %1$d ierakstus?"
+    Vai vēlaties izdzēst %1$d ierakstus\?
     Slēpošanas trases
     Pārklājuma veidi
     Izvairīties no kāpnēm
@@ -1771,7 +1773,7 @@
     Vai esiet pārliecināts?
     Izmaiņas netiks saglabātas. Vai turpināt?
     Ceļi
-    "Lejupielādē  - %1$d failu"
+    Lejupielādē - %1$d failu
     Rādīt bezmaksas versijas banneri
     Arī maksas versijā jūs varat redzēt bezmaksas versijas banneri
     Lūdzu aktivizējiet jūras kartes spraudni
@@ -1857,7 +1859,7 @@ failu(s)?
     Lūdzu, pievienojiet marķierus caur karti
     Nav atrasts neviens ceļa punkts
     Pārskats
-    "Lietotnei tika piešķirta atļauja rakstīt ārējā glabātuvē,  tagad nepieciešams restartēt lietotni."
+    Lietotnei tika piešķirta atļauja rakstīt ārējā glabātuvē. Ir nepieciešams restartēt lietotni.
     Uz augšu
     Uz leju
     Beigt navigāciju
@@ -1925,7 +1927,7 @@ failu(s)?
     Abonoments tiks apmaksāts automātiski katru mēnesi. Jūs varat atteikties no abonomenta Google Play jebkurā laikā.
     Ziedojums OpenStreetMap kopienai
     Daļa no jūsu ziedojuma tiks OSM lietotājiem, kuri piedalās OpenStreetMaps kartes veidošanā. Abonomenta izmaksas paliek nemainīgas.
-    "Abonoments iespējo ik stundu,  dienu vai nedēļu atjauninājumus un neierobežotas lejupielādes visām pasaules kartēm."
+    Abonoments iespējo ik stundu, dienu vai nedēļu atjauninājumus un neierobežotas lejupielādes visām pasaules kartēm.
     Saņemt
     Saņemt par %1$s
     Saņemt neierobežotas karšu lejupielādes un atjauninājumus biežāk nekā reizi mēnesī: reizi stundā, dienā vai nedēļā.
@@ -2185,7 +2187,7 @@ Apraksta laukumu: %1$s x %2$s
     Meklēt Izlasē
     Lai attēlotu reljefa griezumu kartē, ir nepieciešams lejupielādēt reljefa virsklāja karti šim reğionam.
     Lai attēlotu reljefa griezumu kartē, ir nepieciešams iegādāties un instalēt Kontūrlīniju spraudni
-    "Lejupielādējiet  \"Kontūrlīnijas\" karti šim reğionam."
+    Lejupielādējiet \"Kontūrlīnijas\" karti šim reğionam.
     Spraudnis
     Lai redzētu kontūrlīnijas uz kartes, jums ir nepieciešams nopirkt un instalēt \"Kontūrlīniju\" spraudni
     Krāsu shēma
@@ -2213,17 +2215,17 @@ Apraksta laukumu: %1$s x %2$s
     Rādīt/nerādīt OSM piezīmes
     Atļaut piekļūšanu privātajām teritorijām.
     Maršruta gaitā iespējot kartes pagriešanas animāciju no manas atrašanās vietas.
-    Darbības pogas nospiešana ieslēdz vai izslēdz kartes auto mērogošanu pēc kustības ātruma.
+    Ieslēdz vai izslēdz automātisko tālummaiņu, atkarībā no kustības ātruma.
     Pievienot mērķi
     Nomainīt mērķi
     Pievienot pirmo starppunktu
     Spiežot šo darbības pogu, ekrāna centrs kļūst par galamērķi, bet iepriekš izvēlētais galamērķis par pēdējo starppunktu.
-    "Spiežot šo darbības pogu,  ekrāna centrs kļūst par jauno galamērķi, nomainot iepriekšējo (ja tāds bija)."
+    Poga ekrāna centra iestatīšanai par jauno galamērķi, nomainot iepriekšējo galamērķi (ja tāds bija).
     Spiežot šo darbības pogu, ekrāna centrs kļūst par pirmo starppunku maršrutā.
     Nav virsklāja
     Nav apakšklāja
     Kļūda
-    "Pierakstieties epastu ziņojumiem par lietotnes atlaidēm un saņemiet  3 papildus lejupielādes kartēm!"
+    Pierakstieties ziņojumu sūtīšanai uz epastu par izdevīgiem lietotnes piedāvājumiem un saņemiet 3 papildus kartes lejupielādei!
     Kartes, kas satur jūras dziļuma kontūrlīnijas un punktus.
     Paldies par jūras dziļuma kontūrkaršu pirkumu!
     Jūras dziļuma kontūras
@@ -2475,7 +2477,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Importēt failu
     Izvēlieties kā rādīt distanci un virzienu uz marķieriem kartē:
     Kartes orientācijas maiņa
-    Izvēlieties zem kāda ātruma kartes orientācija pārslēgsies no \'kustības virzienā\' uz \'pēc kompasa\'.
+    Izvēlieties ātrumu, pie kura pārslēgsies kartes orientācija no \'kustības virzienā\' uz \'kompasa virzienā\'.
     Visi kartes marķieri ir pārvietoti uz vēsturi
     Kartes marķieris ir pārvietots uz vēsturi
     Kartes marķieris ir aktivizēts
@@ -2515,7 +2517,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Ievadiet lietotājvārdu
     Skatīt lietotāja bildes
     Lietotājvārds
-    "Filtrē bildes pēc iesūtītāja,  datuma vai tipa. Filtri darbojas tikai tuvos mērogos."
+    Filtrē bildes pēc iesūtītāja, datuma vai tipa. Filtri darbojas tikai tuvos mērogos.
     Distance ir koriģēta
     Tumši dzeltens
     Caurspīdīgs rozā
@@ -2555,7 +2557,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Viens
     Spiežot darbības pogu, tiks pārslēgts dienas un nakts režīms
     Smaiļošana pa upēm
-    "Lūdzu veltiet 30 sekundes laika atsauksmēm  un novērtējiet mūsu darbu Google Play."
+    Lūdzu veltiet 30 sekundes laika atsauksmēm un novērtējiet mūsu darbu Google Play.
     Privātuma politika
     Palīdziet mums veidot OsmAnd labāku!
     OsmAnd lejupielādes serviss
@@ -2568,7 +2570,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Mainīt noklusētā ātruma iestatījumus
     Iestatīt min./maks. ātrumu
     Jauns profils
-    "Pēdējā OsmAnd palaišana beidzās ar avāriju.  Palīdziet uzlabot OsmAnd, nosūtot kļūdas ziņojumu."
+    Pēdējā OsmAnd palaišana beidzās ar avāriju. Palīdziet uzlabot OsmAnd, nosūtot kļūdas ziņojumu.
     NLO
     Segway
     Monoritenis
@@ -2586,7 +2588,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Pamodināt pagriezienos
     Iestatīt ekrāna pamošanās laiku.
     Lietot tuvuma sensoru
-    "Novelciet ar roku pāri ekrāna augšmalai, lai ieslēgtu  ekrānu navigācijas laikā."
+    pārvelkot roku pāri ierīcei, ekrāns ieslēgsies.
     Ziemas ceļi
     Ledus ceļi
     Ziemas un ledus ceļi
@@ -2610,8 +2612,9 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Jūs pievienojāt %1$s punktus. Ievadiet faila vārdu un nospiediet \"Saglabāt\".
     Punkts %1$s izdzēsts
     Pasaule
-    Mēs nosūtīsim jūsu meklēšanas pieprasījumu: \"%1$s\", kā arī atrašanās vietas datus. \n
-        \n"  Personīgā informācija netiks iekļauta, šie dati tiks izmantoti vienīgi meklēšanas algoritma uzlabošanai. "
+    Mēs nosūtīsim jūsu meklēšanas pieprasījumu: \"%1$s\" kopā ar jūsu atrašanos vietu.
+\n
+\nPersonīgā informācija netiek iekļauta un iegūtie dati tiek izmantoti vienīgi meklēšanas pieredzes uzlabošanai.
     Sūtīt meklēšanas pieprasījumu\?
     Paldies par Jūsu atsauksmi
     Vietu vai objektu nevar atrast.
@@ -2743,7 +2746,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Grādi
     Miliradiāni
     Azimuts
-    "Mainīt azimuta  mērvienības."
+    Mainīt azimuta mērvienības.
     Nelietot tramvajus
     Nelietot tramvajus
     Nelietot autobusus
@@ -2817,7 +2820,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Izvēlieties sākuma profilu
     Balstiet savu profilu uz vienu no noklusētajiem profiliem, kas definēs tādus pamata iestatījumus kā logrīku redzamību un attāluma vai ātruma mērvienības. Šie ir noklusētie lietotnes profili, kopā ar lietotāja veidotajiem profiliem tie var tikt paplašināti uz:
     Izvēlieties navigācijas veidu
-    "Auto,  kravas auto, motocikls"
+    Auto, kravas auto, motocikls
     MTB, mopēds, zirgs
     Iešana kājām, pastaigas, skriešana
     Visi sabiedriskie transporti
@@ -2986,8 +2989,8 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Darīt
     Tikai WiFi tīklā
     Lejupielādēt bildes
-    "Rakstu bildes iespējams lejupielādēt arī bezsaistes lietošanai.
-\nIestatījums pieejams  caur \"Pārlūkot\" → \"Iespējas\"."
+    Rakstu bildes iespējams lejupielādēt bezsaistes lietošanai.
+\nIestatījums pieejams caur \"Pārlūkot\" → \"Iespējas\".
     Tikai Wi-Fi tīklā
     Izvēlieties ceļojumu grāmatu
     Ceļojumu grāmata
@@ -3045,12 +3048,12 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Jūras navigācijas stils: bojas, bākas, upju ceļi, jūras līnijas un zīmes, tauvas joslas, pakalpojumi, dziļuma kontūras.
     Slēpošanas stils: rāda slēpošanas trases, pacēlājus un citus ar slēpošanu saistītus izcēlumus. Mazāk uzmanību novērsoši sekundārie objekti uz kartes.
     Vienkāršs un kontrastains stils auto navigācijai. Saudzējošs acīm nakts režīmā. Īpašības: kontūrlīnijas, kontrastējoši oranži ceļi, mazāk uzmanību novērsoši sekundārie objekti uz kartes.
-    "Kontrastējošs stils pārgājieniem, trekingam un velo braukšanai brīvā dabā. Īpašības: kontrastējoši ceļi un dabas objekti, dažādi maršruti, kontūrlīnijas ar paplašinātiem iestatījumiem, vairāk detaļu mērogojot karti nekā noklusētajā stilā.  Seguma integritātes opcija ļauj noteikt ceļa seguma kvalitāti. Nav nakts režīms."
+    Pārgājieniem, trekingam un velobraucieniem ārpus pilsētas. Vieglāk salasāms saulainā laikā, ar kontrastējošiem ceļiem un dabas objektiem, maršrutu tipiem, paplašinātiem iestatījumiem kontūrlīnijām, papildus detaļas. Ceļa seguma kvalitātes rādīšana. Bez nakts režīma.
     Vecāks \"Mapnik\" noklusētais stils. Īpašības: krāsu palete veidota \"Mapnik\" stilā.
     Vispārējas lietošanas stils. Vienkāršota caurskatāma renderēšana blīvi apdzīvotās vietās. Īpašības: kontūrlīnijas, maršruti, seguma kvalitāte, iebraukšanas ierobežojumi, ceļu numurācija, renderēšana pēc SAC skalas, ūdenssporta veidi.
     Palielināts detaļu daudzums tūristu vajadzībām. Iekļauj visas noklusētā stila konfigurēšanas opcijas, papildus: rāda pēc iespējas vairāk detaļu, īpaši ceļus, takas un pārējās iespējas pārvietoties. Vizuāli izceļ atšķirīgus ceļu veidus, līdzinoties tūristu kartēm. Augsta kontrasta krāsu palete lietošanai dienas un nakts režīmā.
     Grāmatzīme
-    "Piemērots braukšanai bezceļa apstākļos,  kā arī piemērots lietošanai kopā ar zaļās krāsas satelīta bildēm apakšklāja veidā. Īpašības: samazināts galveno ceļu biezums, palielināts taku, celiņu, veloceliņu u.c. maršrutu līniju biezums. Veidots \"Topo\" stilā."
+    Bezceļa braukšanai ar \'Topo\' stila karti un lietošanai kopā ar zaļajiem satelīta uzņēmumiem kā apakšklāju. Samazināts galvenu ceļu līniju biezums, izcelti treki, takas, velo celiņi u.c. maršruti.
     Starppunkta ierašanās laiks
     Ierašanās laiks
     Uzlabots kontrasts kājāmgājēju un velosipēdu celiņiem. Izmanto vecākas Mapnik krāsas.
@@ -3118,7 +3121,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
 \n • Rāda azimutu iekš Mērīt Attālumu
 \n
 \n
-    "• Lietotnes profili: veidojiet personisku profilu savām vajadzībām,  izvēlieties ikonu un krāsu
+    • Lietotnes profili: veidojiet personisku profilu savām vajadzībām, izvēlieties ikonu un krāsu
 \n
 \n • Tagad mainiet katra profila noklusējumus un min/max ātrumus
 \n
@@ -3138,7 +3141,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
 \n
 \n • Citi kļūdu labojumi
 \n
-\n"
+\n
     Visi zemāk esošie iestatījumi attiecas tikai uz izvēlēto profilu.
     OsmAnd lieto UTM standarta formātu, kas ir līdzīgs, bet ne vienāds ar UTM NATO formātu.
     Piemērs
@@ -3269,7 +3272,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
     Atjaunot
     Rediģēt profilu sarakstu
     Rediģēt profilus
-    "OsmAnd pamata profilus nevar izdzēst, bet atspējot (no iepriekšējā ekrāna) vai pārkārtot uz  leju."
+    OsmAnd pamata profilus nevar izdzēst, bet atspējot (uz iepriekšējā ekrāna) vai pārkārtot uz leju.
     Izvēlētais profils
     Nekas nav izvēlēts
 
\ No newline at end of file

From 83d226123507dcd1bec069e89be70d6936c3a2cf Mon Sep 17 00:00:00 2001
From: Softmap 
Date: Sat, 19 Sep 2020 11:39:50 +0000
Subject: [PATCH 0232/1366] Translated using Weblate (Arabic)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ar/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml
index 480c480efe..4c30071193 100644
--- a/OsmAnd/res/values-ar/strings.xml
+++ b/OsmAnd/res/values-ar/strings.xml
@@ -718,7 +718,7 @@
     اللغة المحددة غير مدعومة من قبل محرك أندرويد لتحويل النص إلى كلام (TTS). ستُستخدم اللغة السابقة في المحرك ، هل تريد البحث عن محركات أخرى في السوق؟
     البيانات ناقصة
     لا توجد بيانات مُثبّتة للغة المحددة. هل تريد أن تذهب إلى السوق لتثبيتها؟
-    عكس المسار
+    عكس اتجاه المسار
     استخدم الوجهة الحالية
     يمر على طول المسار باكمله
     خريطة التنقل المتوفرة حاليا لهذا الموقع. 

From 011f650e473b623be6e673edea1d4b6af997ca9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1ns?= 
Date: Sun, 20 Sep 2020 23:11:38 +0000
Subject: [PATCH 0233/1366] Translated using Weblate (Galician)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-gl/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml
index c5e53fd258..18e88d4dab 100644
--- a/OsmAnd/res/values-gl/strings.xml
+++ b/OsmAnd/res/values-gl/strings.xml
@@ -897,7 +897,7 @@
     A lingua escollida é incompatíbel co motor TTS (texto lido a voz) instalado no Android, empregarase a lingua TTS predefinida. Procurar outro motor TTS na tenda de aplicacións\?
     faltan datos
     Ir á tenda de aplicacións para baixar a lingua escollida\?
-    Inverter a dirección do GPX
+    Inverter dirección da pista
     Empregar o destino actual
     Percorrer toda a pista
     Hai un mapa vectorial sen conexión para este sitio. 
@@ -2708,7 +2708,7 @@ Lon %2$s
     Náutico
     Localización sen nome
     Túnel adiante
-    Túneis
+    Túneles
     Baixa os artigos da Wikipedia de %1$s para lelos sen conexión.
     Baixar datos da Wikipedia
     Abrir artigo en liña

From 41e8ab7a742ed9fca7e06addc47d5cd21775bcba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1ns?= 
Date: Sun, 20 Sep 2020 16:13:25 +0000
Subject: [PATCH 0234/1366] Translated using Weblate (Galician)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-gl/phrases.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-gl/phrases.xml b/OsmAnd/res/values-gl/phrases.xml
index ce9cdbbeea..82048f8ed6 100644
--- a/OsmAnd/res/values-gl/phrases.xml
+++ b/OsmAnd/res/values-gl/phrases.xml
@@ -36,7 +36,7 @@
     Tenda de telefonía móbil
     Tenda de motos
     Instrumentos musicais
-    Axencia de xornalismo
+    Venda de prensa
     Produtos ecolóxicos
     Tenda de pinturas
     Tenda de animais

From 69195c45c3422097c661b7990405b1bdd634bb9a Mon Sep 17 00:00:00 2001
From: Zmicer Turok 
Date: Mon, 21 Sep 2020 05:57:10 +0000
Subject: [PATCH 0235/1366] Translated using Weblate (Belarusian)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-be/phrases.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd/res/values-be/phrases.xml b/OsmAnd/res/values-be/phrases.xml
index b801ecedb5..f96eaef3ab 100644
--- a/OsmAnd/res/values-be/phrases.xml
+++ b/OsmAnd/res/values-be/phrases.xml
@@ -3843,4 +3843,5 @@
     Затрымка
     Маленькія электрапрыборы
     Вулей
+    Крама арэхаў
 
\ No newline at end of file

From 80e9b94c6398be9dbbef79b4b13366c03f25401e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Sun, 20 Sep 2020 09:00:51 +0000
Subject: [PATCH 0236/1366] Translated using Weblate (Estonian)

Currently translated at 100.0% (3824 of 3824 strings)
---
 OsmAnd/res/values-et/phrases.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml
index dc8cbbac79..6d72d50576 100644
--- a/OsmAnd/res/values-et/phrases.xml
+++ b/OsmAnd/res/values-et/phrases.xml
@@ -3,7 +3,7 @@
     Pood
     Hädaabi
     Transport
-    Käsitsi tehtud
+    Rajatis
     Haridus
     Administratiiv
     Tervishoid

From d9ecc225398659d059171f3a0f464cbb6f64871d Mon Sep 17 00:00:00 2001
From: Eduardo Addad de Oliveira 
Date: Sun, 20 Sep 2020 22:17:20 +0000
Subject: [PATCH 0237/1366] Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-pt-rBR/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml
index 1182d20a65..4ce78f580e 100644
--- a/OsmAnd/res/values-pt-rBR/strings.xml
+++ b/OsmAnd/res/values-pt-rBR/strings.xml
@@ -1174,7 +1174,7 @@
     O idioma selecionado não é suportado pelo mecanismo Android TTS (conversão de texto em fala) instalado; o idioma predefinido do TTS será usado. Procura outro mecanismo TTS no mercado\?
     Faltam dados
     Ir a loja para baixar o idioma selecionado\?
-    Inverter direção GPX
+    Inverter direção da trilha
     Usar destino atual
     Percorrer toda a trilha
     Mapa vetorial off-line presente para esse local.
@@ -3883,7 +3883,7 @@
     Refazer
     "• Função de planejamento de rota atualizada: permite o uso de diferentes tipos de navegação por segmento e a inclusão de trilhas
 \n
-\n  • Novo menu de aparência para trilhas: selecione cor, espessura, setas de direção de exibição, ícones de início / término
+\n • Novo menu de aparência para trilhas: selecione cor, espessura, setas de direção de exibição, ícones de início / término
 \n
 \n  • Melhor visibilidade dos nós da bicicleta.
 \n

From ed12bec770b5d30fffd13342ebf1ecea3325620a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= 
Date: Sun, 20 Sep 2020 08:06:58 +0000
Subject: [PATCH 0238/1366] Translated using Weblate (Estonian)

Currently translated at 99.2% (3458 of 3484 strings)
---
 OsmAnd/res/values-et/strings.xml | 74 ++++++++++++++++----------------
 1 file changed, 38 insertions(+), 36 deletions(-)

diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml
index fea216bce3..f05f7fbf4c 100644
--- a/OsmAnd/res/values-et/strings.xml
+++ b/OsmAnd/res/values-et/strings.xml
@@ -811,7 +811,7 @@
     Ärka pöördel
     Reguleeri kui kaua ekraan peaks olema sisse lülitatud.
     Kasuta lähedusandurit
-    Liiguta oma kätt üle ekraani ülaosa selle navigeerimise ajal sisse lülitamiseks.
+    Käe liigutamine üle ekraani lülitab selle sisse.
     1. järk
     2. järk
     3. järk
@@ -879,7 +879,7 @@
     Analüütika
     Kuva navigeerimise ajal lukustuskuval kaarti.
     Marsruutimise seaded valitud profiilis \"%1$s\".
-    Ärkamisaeg
+    Aegumine peale ärkamist
     Ühikud ja formaadid
     Välimus
     Kaardi välimus
@@ -1200,11 +1200,11 @@
     Raja salvestamine
     Rajalõigud
     Rajapunktid
-    Selle lisaga saad ligipääsu mitut liiki veebikaartidele (nn paanid või rasterkaardid), alates eelnevalt määratletud OpenStreetMap-i paanidest (nagu Mapnik) kuni satelliidipiltide ja eriotstarbeliste kihtideni nagu ilmakaardid, kliimakaardid, geoloogilised kaardid, künklikihi kihid jne. 
-\n 
-\nKõiki neid kaarte saab kasutada kas peamise (põhi) kaardina, mida kuvatakse OsmAnd kaardil, või ülekattena või aluskihina mõnele muule põhikaardile (nagu OsmAndi standardsed võrguühenduseta kaardid). Mis tahes aluskihi paremini nähtavamaks muutmiseks saab OsmAndi vektorkaartide teatud elemente soovi korral hõlpsalt peita menüü \'Kaardi seadistamine\' abil. 
-\n 
-\nPlaatide kaarte saab hankida otse veebiallikatest või neid saab võrguühenduseta kasutamiseks ette valmistada (ja käsitsi kopeerida OsmAndi andmekataloogi) SQLite andmebaasina, mida saab toota mitmesuguste kolmandate osapoolte kaardi ettevalmistamise tööriistade abil.
+    Selle lisaga saad ligipääsu mitut liiki veebikaartidele (nn paanid või rasterkaardid), alates eelnevalt määratletud OpenStreetMap-i paanidest (nagu Mapnik) kuni satelliidipiltide ja eriotstarbeliste kihtideni nagu ilmakaardid, kliimakaardid, geoloogilised kaardid, künklikihi kihid jne.
+\n
+\nKõiki neid kaarte saad kasutada kas peamise (põhi) kaardina, mida kuvatakse OsmAnd kaardil, või ülekattena või aluskihina mõnele muule põhikaardile (nagu OsmAndi standardsed võrguühenduseta kaardid). Mis tahes aluskihi paremini nähtavamaks muutmiseks saad OsmAndi vektorkaartide teatud elemente soovi korral hõlpsalt peita menüü „Kaardi seadistamine“ abil.
+\n
+\nKaardipaane saad hankida otse veebiallikatest või neid saad võrguühenduseta kasutamiseks ette valmistada (ja käsitsi kopeerida OsmAndi andmekataloogi) SQLite andmebaasina, mida võid luua mitmesuguste kolmandate osapoolte kaardi ettevalmistamise tööriistade abil.
     Kõrgusjoonte lisa
     OsmAnd lisa võrguühenduseta kõrgusjoontele
     Kõrgusjooned
@@ -1511,14 +1511,14 @@
     Maailma aluskaart
     Versioon:
     Versiooni info, litsentsid, projekti liikmed
-    Suurendab laetud: %1$s
-    Aegub (minutit): %1$s
+    Allalaetud suumitasemed: %1$s
+    Aegumine (minutites): %1$s
     Alla laetav: %1$s
     Maksimaalne suurendus: %1$s
     Minimaalne suurendus: %1$s
-    Elliptiline merkator
+    Mercatori elliptiline projektsioon
     Maksimaalne suurendus
-    Aegumine (minutit)
+    Aegumine (minutites)
     Minimaalne suurendus
     URL
     Vali olemasolev…
@@ -1529,7 +1529,7 @@
     Ameerika Ühendriigid
     Kanada
     Euroopa, Aasia, Ladina-Ameerika ja sarnased
-    UK, India, Austraalia ja sarnased
+    Suurbritannia, India, Austraalia ja sarnased
     Teata…
     Tänavanimed (TTS)
     Kiiruspiirang
@@ -2018,7 +2018,7 @@
     Mittetoetatud keel
     Puuduvad andmed
     Mine turule valitud keele alla laadimiseks\?
-    Vastupidine GPX suund
+    Raja vastupidine suund
     Kasuta olemasoleva sihtkohta
     Mööda kogu rada
     Hääljuhiste väljund
@@ -2417,7 +2417,7 @@
     Vajalik kaartide alla laadimiseks.
     Asukoha otsing…
     Vaba ruum
-    OsmAnd andmekasutus (kaardid, GPX failid, jne.): %1$s.
+    OsmAnd\'i andmekasutus (kaardid, rajafailid, jne.): %1$s.
     Anna luba
     Anna ligipääs asukohale
     Hangi juhiseid ja avasta uusi kohti ilma internetiühenduseta
@@ -2468,10 +2468,10 @@
     Salvesta
     Andmed puuduvad
     Lülita sisse kiire salvestamine
-    Kuva teekonna salvestamist lubav süsteemi märguanne.
+    Kuva teekonna salvestamise algust lubav süsteemi märguanne.
     Märguanded
-    Sul pole veel ühtegi GPX faili
-    Võid lisada kausta ka GPX faile
+    Sul pole veel ühtegi rajafaili
+    Võid lisada kausta ka rajafaile
     Lisa veel…
     Välimus
     Peen
@@ -2674,9 +2674,9 @@
     Määra teedel lubatud sõiduki laius.
     Simuleeri oma asukohta kasutades salvestatud GPX rada.
     Nupp ekraani keskkoha lähtekohaks muutmiseks. Seejärel on kas võimalik valida sihtkohta või alustada teekonna arvutamist.
-    See lisa aktiveerib radade salvestamise funktsionaalsuse, puudutades käsitsi kaardil GPX logimisvidinat või logides automaatselt kõik oma navigeerimise marsruudid GPX faili.
+    See lisa aktiveerib radade salvestamise funktsionaalsuse, puudutades käsitsi kaardil GPX logimisvidinat või logides automaatselt kõik oma teekonnad GPX faili.
 \n
-\nSalvestatud radu saab jagada oma sõpradega või kasutada OSM kaastöödeks. Sportlased saavad kasutada salvestatud radu oma treeningute jälgimiseks. Mõningast raja põhianalüüsi saab teha otse OsmAnd sees, näiteks ringiajad, keskmine kiirus jne. Lisaks muidugi saab radu hiljem analüüsia ka spetsiaalsetete 3. osapoolte analüüsitööriistadega.
+\nSalvestatud radu saad jagada oma sõpradega või kasutada OSM kaastöödeks. Sportlased saavad kasutada salvestatud radu oma treeningute jälgimiseks. Mõningast raja põhianalüüsi saad teha otse OsmAnd sees, näiteks ringiajad, keskmine kiirus jne. Lisaks muidugi saad radu hiljem analüüsida ka spetsiaalsetete kolmandate osapoolte analüüsitööriistadega.
     See lisa pakub nii kõrgusjoonte ülekatte kui ka (reljeefse) künkavarjutuse kihi, mida kuvatakse OsmAnd standardkaartidel. Seda funktsionaalsust hindavad sportlased, matkajad, rändajad ja kõik teised, kes on huvitatud maastiku reljeefstruktuurist.
 \n
 \nGlobaalsed andmed (vahemikus 70 ° põhja ja 70 ° lõuna) põhinevad mõõtmistel, mille on teinud SRTM (süstiku radari topograafiamissioon) ja ASTER (täiustatud kosmose termilise kiirguse ja peegelduse radiomeeter), NASA maavaatlussatelliitide süsteemi lipulaeva Terra pardal olev pildistamisinstrument. ASTER on NASA, Jaapani majandus-, kaubandus- ja tööstusministeeriumi (METI) ja Jaapani kosmosesüsteemide (J-kosmosesüsteemid) koostöö.
@@ -2707,9 +2707,9 @@
 \nNii asukoht kui aeg on nähtavad nii OsmAnd armatuurlaual kui kaardi vidinas. Meeldetuletust saab lisada Androidi kalendrisse.
     Muuda kauguse mõõtmise ühikuid.
     Selleks, et reise kavandada ja punktide vahelist kaugust mõõta, loo teekondi kaardil koputades või olemasolevaid GPX-faile kasutades, Tulemusi saad salvestada GPX-failina, mida on hiljem võimalik juhendamiseks kasutada.
-    See lisa teeb seadme erivajadusega kasutajatele mõeldud funktsioonid otse OsmAndis kättesaadavaks. See lihtsustab nt. kõnesünteesi häälte kõnekiiruse reguleerimist, ekraanil navigeerimise suuna seadistamist, rulliku kasutamist suurenduse juhtimiseks või kõnesünteesi tagasisidet, näiteks oma asukoha automaatseks teatamiseks.
-    See lisa võimaldab OsmAnd abil OSM kaastöid teha, näiteks OSM huvipunkte luua või muuta, OSM märkmeid avada või kommenteerida ning salvestatud GPX faile lisada. OSM on kogukonna juhitud globaalne üldkasutatav kaardistamisprojekt. Üksikasju leiad https://openstreetmap.org. Aktiivset osalemist hinnatakse ja panust saab teha otse OsmAnd rakendusest, kui seadistada rakenduses oma isiklikud OSM kasutajatunnused.
-    See lisa kuvab arendus- ja silumisfunktsioonide sätteid nagu teekonna arvutamine, renderdamise jõudlus või hääljuhiste testimine ja simuleerimine. Need seaded on mõeldud arendajatele ja pole tavakasutaja jaoks vajalikud.
+    Teeb seadme erivajadusega kasutajatele mõeldud funktsioonid otse OsmAndis kättesaadavaks. See lihtsustab näiteks kõnesünteesi häälte kõnekiiruse reguleerimist, ekraanil navigeerimise suuna seadistamist, rulliku kasutamist suurenduse juhtimiseks või kõnesünteesi tagasisidet, näiteks oma asukoha automaatseks teatamiseks.
+    Tee OsmAnd\'i abil OSM\'i kaastöid, näiteks loo või muuda OSM\'i huvipunkte, ava või kommenteeri OSM\'i märkmeid ning lisa salvestatud GPX faile. Selleks sisesta oma OSM\'i kasutajanimi ja salasõna. OSM on kogukonna juhitud globaalne vaba litsentsi alusel avaldatud kaardistamisprojekt.
+    Arendus- ja silumisfunktsioonide seadistused, nagu teekonna simulatsioon, renderdamise jõudlus või hääljuhiste testimine. Need seaded on mõeldud arendajatele ja pole tavakasutaja jaoks vajalikud.
     Vali alternatiivne teekond, valides välditavad teed
     Kasuta riistvarakiirendatud OpenGL tuge (võib kasutada rohkem akut või mitte töötada väga vanades seadmetes).
     %1$s vajab seda luba ekraani välja lülitamiseks energiasäästu nimel.
@@ -3226,7 +3226,7 @@
 \n Enamik maailma riike üle on allalaadimiseks saadaval! 
 \n Hangi oma riigis usaldusväärne navigaator - olgu see siis Prantsusmaa, Saksamaa, Mehhiko, UK, Hispaania, Holland, USA, Venemaa, Brasiilia või mõni muu.
     OsmAnd + (OSM automatiseeritud navigeerimisjuhised) on kaardi- ja navigatsioonirakendus, millel on juurdepääs tasuta, ülemaailmsetele ja kvaliteetsetele OpenStreetMap (OSM) andmetele.
-\n Naudi hääl- ja optilist navigeerimist, HP-de (huvipunktide) vaatamist, GPX radade loomist ja haldamist, kasutades kõrgusjoonte visuaalset kuvamist ja kõrgusteavet, valikut autosõidu, jalgrattasõidu, jalakäijate režiimide, OSM redigeerimise ja palju muu vahel.
+\n Naudi hääl- ja optilist navigeerimist, HP-de (huvipunktide) vaatamist, GPX radade loomist ja haldamist, kasutades kõrgusjoonte visuaalset kuvamist ja kõrgusteavet, valikut autosõidu, jalgrattasõidu, jalakäijate režiimide, OSM\'i andmete muutmuise ja palju muu vahel.
 \n
 \n OsmAnd+ on rakenduse tasuline versioon. Selle ostmisega toetad projekti, rahastad uute funktsioonide arendamist ja saad kõige värskemaid uuendusi.
 \n
@@ -3267,19 +3267,19 @@
 \n • Valikuline reisi salvestamine ka taustrežiimis (kui seade on puhkeolekus)
 \n OsmAnd on aktiivselt arendatud avatud lähtekoodiga tarkvara. Kõik saavad rakendusse panustada, teatades vigadest, parandades tõlkeid või kodeerides uusi funktsioone. Lisaks toetub projekt rahalisele toetusele koodide kodeerimiseks ja uute funktsioonide testimiseks.
 \n
-    Ligikaudne kaardi leviala ja kvaliteet: 
-\n • Lääne-Euroopa: **** 
-\n • Ida-Euroopa: *** 
-\n • Venemaa: *** 
-\n • Põhja-Ameerika: *** 
-\n • Lõuna-Ameerika: ** 
-\n • Aasia: ** 
-\n • Jaapan ja Korea: *** 
-\n • Lähis-Ida: ** 
-\n • Aafrika: ** 
-\n • Antarktika: * 
-\n Enamik riike kogu maailmas on saadaval alla laadimiseks 
-\n Afganistanist Zimbabweni, Austraaliast USA-ni. Argentiina, Brasiilia, Kanada, Prantsusmaa, Saksamaa, Mehhiko, UK, Hispaania, …
+    Ligikaudne kaardi leviala ja kvaliteet:
+\n • Lääne-Euroopa: ****
+\n • Ida-Euroopa: ***
+\n • Venemaa: ***
+\n • Põhja-Ameerika: ***
+\n • Lõuna-Ameerika: **
+\n • Aasia: **
+\n • Jaapan ja Korea: ***
+\n • Lähis-Ida: **
+\n • Aafrika: **
+\n • Antarktika: *
+\n Enamike riikide andmed üle maailma on saadaval allalaadimiseks
+\n Afganistanist Zimbabweni, Austraaliast Ameerika Ühendriikideni. Argentina, Brasiilia, Kanada, Prantsusmaa, Saksamaa, Mehhiko, Suurbritannia, Hispaania, …
 \n
     Nimi sisaldab liiga palju suurtähti. Jätkata\?
     Proovi uuesti
@@ -3753,4 +3753,6 @@
 \n • Parandatud on profiili seadistuste impordi ja ekspordiga seotud vead
 \n
 \n
+    Peata teekonna salvestamine
+    Jätka teekonna salvestamist
 
\ No newline at end of file

From d73b02dc1d07302cbf334ba652c0eb65acd4236c Mon Sep 17 00:00:00 2001
From: Verdulo 
Date: Sun, 20 Sep 2020 15:32:38 +0000
Subject: [PATCH 0239/1366] Translated using Weblate (Esperanto)

Currently translated at 99.6% (3812 of 3824 strings)
---
 OsmAnd/res/values-eo/phrases.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml
index cc31985829..ac3f84fe04 100644
--- a/OsmAnd/res/values-eo/phrases.xml
+++ b/OsmAnd/res/values-eo/phrases.xml
@@ -831,7 +831,7 @@
     Rostilo
     Laborejo de agrokulturaj maŝinoj
     Laborejo de korbisto
-    Abelistejo
+    Abelejo
     Forĝejo
     Bierfarejo
     Boat-konstruejo
@@ -849,7 +849,7 @@
     Poŝ-horloĝistejo
     Varmizolaĵistejo
     Laborejo de juvelisto
-    Seruristejo
+    Laborejo de seruristo
     Ŝlosil-kopiistejo
     Laborejo de metal-konstruaĵisto
     Okulvitristejo
@@ -1852,7 +1852,7 @@
     Oficejo de konsilado
     Oficejo de kunlaborado
     Oficejo de arbarkultivo
-    Oficejo de provizarto
+    Oficejo de ekspedo
     Oficejo de paroĥo
     Oficejo de eldonisto
     benzino 91-oktannombra senplumba
@@ -3031,7 +3031,7 @@
     Bestonutrejo
     Okazaĵaj-provizoj-vendejo
     Elektraĵ-vendejo
-    Seruristejo
+    Laborejo de seruristo
     Prilumigad-aparata vendejo
     Loteri-bileta kiosko
     Hazardludejo
@@ -3719,7 +3719,7 @@
     Bakejo (ne vendejo)
     Laborejo de meblisto
     Pago
-    Dombesta beligejo
+    Hejmbesta beligejo
     Bankaŭtomato: jes
     Elpago de mono
     Elpago de mono: jes

From eb4fa3265a96bb71a70d3e846f05aa5da8ea9ddd Mon Sep 17 00:00:00 2001
From: Jeff Huang 
Date: Sun, 20 Sep 2020 02:04:45 +0000
Subject: [PATCH 0240/1366] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-zh-rTW/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml
index 33b644b362..c55a555aff 100644
--- a/OsmAnd/res/values-zh-rTW/strings.xml
+++ b/OsmAnd/res/values-zh-rTW/strings.xml
@@ -429,7 +429,7 @@
     選定的語言未被已安裝的 Android TTS(文字轉語音)引擎支援,其將會使用預先設定的 TTS 語言。要在市集中尋找其他 TTS 引擎嗎?
     資料遺失
     要轉到商店下載所選擇的語言嗎?
-    反轉 GPX 方向
+    反轉軌跡方向
     使用目前的目的地
     沿著整條軌跡往前
     此位置目前有向量地圖可以使用。

From 3eef30e12aa5c5472684a488757ed8c45d97317c Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Mon, 21 Sep 2020 11:54:13 +0300
Subject: [PATCH 0241/1366] Fix possible npe

---
 .../audionotes/AudioVideoNotesPlugin.java     | 32 ++++++++++---------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java
index 4f2c3fa11f..de3453550f 100644
--- a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java
@@ -1430,22 +1430,24 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
 		getMapActivity().getMyApplication().runInUIThread(new Runnable() {
 			@Override
 			public void run() {
-				if (!autofocus) {
-					cam.takePicture(null, null, new JpegPhotoHandler());
-				} else {
-					cam.autoFocus(new Camera.AutoFocusCallback() {
-						@Override
-						public void onAutoFocus(boolean success, Camera camera) {
-							try {
-								cam.takePicture(null, null, new JpegPhotoHandler());
-							} catch (Exception e) {
-								logErr(e);
-								closeRecordingMenu();
-								closeCamera();
-								finishRecording();
+				if (cam != null) {
+					if (!autofocus) {
+						cam.takePicture(null, null, new JpegPhotoHandler());
+					} else {
+						cam.autoFocus(new Camera.AutoFocusCallback() {
+							@Override
+							public void onAutoFocus(boolean success, Camera camera) {
+								try {
+									cam.takePicture(null, null, new JpegPhotoHandler());
+								} catch (Exception e) {
+									logErr(e);
+									closeRecordingMenu();
+									closeCamera();
+									finishRecording();
+								}
 							}
-						}
-					});
+						});
+					}
 				}
 			}
 		}, 200);

From 17351e2e88de4c9ffa194cb949713e3a4acea021 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Mon, 21 Sep 2020 12:17:45 +0300
Subject: [PATCH 0242/1366] Fix fav group image  npe

---
 OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java           | 1 +
 .../controllers/FavouritePointMenuController.java            | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java
index ad0eb9d359..6ebdaea6b4 100644
--- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java
+++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java
@@ -129,6 +129,7 @@ public class FavouritesDbHelper {
 		}
 	}
 
+	@Nullable
 	public Drawable getColoredIconForGroup(String groupName) {
 		String groupIdName = FavoriteGroup.convertDisplayNameToGroupIdName(context, groupName);
 		FavoriteGroup favoriteGroup = getGroup(groupIdName);
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
index a6a84bee67..d5a484f68f 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java
@@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable;
 import android.text.SpannableString;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.core.content.ContextCompat;
 import androidx.fragment.app.Fragment;
 
@@ -180,8 +181,8 @@ public class FavouritePointMenuController extends MenuController {
 			OsmandApplication app = mapActivity.getMyApplication();
 			FavouritesDbHelper helper = app.getFavorites();
 			String group = fav.getCategory();
-			if (helper.getGroup(group) != null) {
-				Drawable line2icon = helper.getColoredIconForGroup(group);
+			Drawable line2icon = helper.getGroup(group) != null ? helper.getColoredIconForGroup(group) : null;
+			if (line2icon != null) {
 				GravityDrawable gravityIcon = new GravityDrawable(line2icon);
 				gravityIcon.setBoundsFrom(line2icon);
 				return gravityIcon;

From 55dc6816001a8720361455d2cc644f5c20d28d74 Mon Sep 17 00:00:00 2001
From: Eugene <44466116+EugeneZmeuk@users.noreply.github.com>
Date: Mon, 21 Sep 2020 14:09:51 +0300
Subject: [PATCH 0243/1366] Update HelpActivity.java

---
 OsmAnd/src/net/osmand/plus/activities/HelpActivity.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java b/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
index da95de3931..667ee07614 100644
--- a/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
@@ -142,7 +142,7 @@ public class HelpActivity extends OsmandActionBarActivity implements AdapterView
 		contextMenuAdapter.addItem(createItem(R.string.travel_item, NULL_ID,
 				"feature_articles/travel.html"));
 		contextMenuAdapter.addItem(createItem(R.string.measure_distance_item, NULL_ID,
-				"feature_articles/measure-distance.html"));
+				"feature_articles/plan-route.html"));
 		contextMenuAdapter.addItem(createItem(R.string.radius_ruler_item, NULL_ID,
 				"feature_articles/ruler.html"));
 		contextMenuAdapter.addItem(createItem(R.string.quick_action_item, NULL_ID,

From ddf9e054153ddcdd50df365772f557d879a8ce5e Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Mon, 21 Sep 2020 17:05:19 +0300
Subject: [PATCH 0244/1366] Open my places from saved track dialog and fix
 check for points in plan route

---
 .../MeasurementToolFragment.java               |  4 ++--
 .../SavedTrackBottomSheetDialogFragment.java   | 18 +++++++++++++-----
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 8c6693a8b6..647353f9b7 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -628,7 +628,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			toolBarController.setTitle(getString(R.string.route_between_points));
 			mapActivity.refreshMap();
 
-			if (editingCtx.isNewData() || editingCtx.hasRoutePoints() || editingCtx.hasRoute() || editingCtx.getPointsCount() < 2) {
+			if (editingCtx.isNewData() || editingCtx.hasRoutePoints() || editingCtx.hasRoute() || editingCtx.getPointsCount() <= 2) {
 				RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
 						this, RouteBetweenPointsDialogType.WHOLE_ROUTE_CALCULATION,
 						editingCtx.getLastCalculationMode() == CalculationMode.NEXT_SEGMENT
@@ -1675,7 +1675,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 								break;
 							case SHOW_IS_SAVED_FRAGMENT:
 								SavedTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
-										toSave.getName());
+										toSave.getAbsolutePath());
 								dismiss(mapActivity);
 								break;
 							case SHOW_TOAST:
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SavedTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SavedTrackBottomSheetDialogFragment.java
index 12f2be4cc8..29d48411fb 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SavedTrackBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SavedTrackBottomSheetDialogFragment.java
@@ -1,21 +1,26 @@
 package net.osmand.plus.measurementtool;
 
 import android.app.Activity;
+import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
+import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 
+import net.osmand.plus.OsmandApplication;
 import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.activities.TrackActivity;
 import net.osmand.plus.base.MenuBottomSheetDialogFragment;
 import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemButton;
 import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
 import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
 import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem;
+import net.osmand.util.Algorithms;
 
 public class SavedTrackBottomSheetDialogFragment extends MenuBottomSheetDialogFragment {
 
@@ -34,7 +39,7 @@ public class SavedTrackBottomSheetDialogFragment extends MenuBottomSheetDialogFr
 		View mainView = View.inflate(UiUtilities.getThemedContext(getMyApplication(), nightMode),
 				R.layout.measure_track_is_saved, null);
 		TextView fileNameView = mainView.findViewById(R.id.file_name);
-		fileNameView.setText(fileName);
+		fileNameView.setText(Algorithms.getFileWithoutDirs(fileName));
 		items.add(new SimpleBottomSheetItem.Builder()
 				.setCustomView(mainView)
 				.create());
@@ -51,10 +56,13 @@ public class SavedTrackBottomSheetDialogFragment extends MenuBottomSheetDialogFr
 				.setOnClickListener(new View.OnClickListener() {
 					@Override
 					public void onClick(View v) {
-						Activity activity = getActivity();
-						if (activity instanceof MapActivity) {
-							MeasurementToolFragment.showInstance(((MapActivity) activity).getSupportFragmentManager(),
-									fileName);
+						FragmentActivity activity = getActivity();
+						if (activity != null && !Algorithms.isEmpty(fileName)) {
+							OsmandApplication app = ((OsmandApplication) activity.getApplication());
+							Intent newIntent = new Intent(activity, app.getAppCustomization().getTrackActivity());
+							newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, fileName);
+							newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+							activity.startActivity(newIntent);
 						}
 						dismiss();
 					}

From dcc3c09d75c1e291b8758067ad946f7542d05654 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Mon, 21 Sep 2020 17:07:05 +0300
Subject: [PATCH 0245/1366] Fix geocoding

---
 .../net/osmand/binary/GeocodingUtilities.java | 14 ++++----
 .../osmand/plus/CurrentPositionHelper.java    | 33 ++++++++++++++++---
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java b/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java
index 77357bac9b..a372f12aa1 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java
@@ -334,14 +334,16 @@ public class GeocodingUtilities {
 		boolean eqStreet = Algorithms.stringsEqual(gr1.streetName, gr2.streetName);
 		if (eqStreet) {
 			boolean sameObj = false;
-			if (gr1.building != null && gr2.building != null) {
-				if (Algorithms.stringsEqual(gr1.building.getName(), gr2.building.getName())) {
-					// same building
+			if (gr1.city != null && gr2.city != null) {
+				if (gr1.building != null && gr2.building != null) {
+					if (Algorithms.stringsEqual(gr1.building.getName(), gr2.building.getName())) {
+						// same building
+						sameObj = true;
+					}
+				} else if (gr1.building == null && gr2.building == null) {
+					// same street
 					sameObj = true;
 				}
-			} else if (gr1.building == null && gr2.building == null) {
-				// same street
-				sameObj = true;
 			}
 			if (sameObj) {
 				double cityDist1 = MapUtils.getDistance(gr1.searchPoint, gr1.city.getLocation());
diff --git a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java
index a50a345aa3..cbbd36162f 100644
--- a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java
+++ b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java
@@ -25,7 +25,6 @@ import org.apache.commons.logging.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
@@ -154,7 +153,7 @@ public class CurrentPositionHelper {
 
 	// single synchronized method
 	private synchronized void processGeocoding(@NonNull Location loc,
-											   @Nullable ResultMatcher geoCoding,
+											   @Nullable final ResultMatcher geoCoding,
 											   boolean storeFound,
 											   boolean allowEmptyNames,
 											   @Nullable final ResultMatcher result,
@@ -164,6 +163,21 @@ public class CurrentPositionHelper {
 											   boolean cancelPreviousSearch) {
 
 		if (cancelPreviousSearch && request != requestNumber.get()) {
+			if (geoCoding != null) {
+				app.runInUIThread(new Runnable() {
+					@Override
+					public void run() {
+						geoCoding.publish(null);
+					}
+				});
+			} else if (result != null) {
+				app.runInUIThread(new Runnable() {
+					@Override
+					public void run() {
+						result.publish(null);
+					}
+				});
+			}
 			return;
 		}
 
@@ -172,9 +186,18 @@ public class CurrentPositionHelper {
 		if (storeFound) {
 			lastAskedLocation = loc;
 			lastFound = gr == null || gr.isEmpty() ? null : gr.get(0).point.getRoad();
-		} else if(geoCoding != null) {
-			justifyResult(gr, geoCoding);
-		} else if(result != null) {
+		} else if (geoCoding != null) {
+			try {
+				justifyResult(gr, geoCoding);
+			} catch (Exception e) {
+				app.runInUIThread(new Runnable() {
+						@Override
+						public void run() {
+							geoCoding.publish(null);
+						}
+					});
+			}
+		} else if (result != null) {
 			app.runInUIThread(new Runnable() {
 				@Override
 				public void run() {

From 27345198225facfb778f0368de593bd97ac50a21 Mon Sep 17 00:00:00 2001
From: Nazar-Kutz 
Date: Mon, 21 Sep 2020 17:12:56 +0300
Subject: [PATCH 0246/1366] Fix CustomRadioButton in RTL

---
 OsmAnd/src/net/osmand/plus/UiUtilities.java   | 43 +++++++++++--------
 ...etweenPointsBottomSheetDialogFragment.java |  6 +--
 .../cards/NavigateTrackOptionsCard.java       | 16 +++----
 .../plus/srtmplugin/TerrainFragment.java      |  4 +-
 4 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java
index a435bd975e..5af06d9f23 100644
--- a/OsmAnd/src/net/osmand/plus/UiUtilities.java
+++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java
@@ -93,8 +93,8 @@ public class UiUtilities {
 	}
 
 	public enum CustomRadioButtonType {
-		LEFT,
-		RIGHT,
+		START,
+		END,
 	}
 
 	public UiUtilities(OsmandApplication app) {
@@ -459,26 +459,35 @@ public class UiUtilities {
 				? R.color.text_color_primary_dark
 				: R.color.text_color_primary_light);
 		int radius = AndroidUtils.dpToPx(app, 4);
+		boolean isLayoutRtl = AndroidUtils.isLayoutRtl(app);
 
-		TextView leftButtonText = buttonsView.findViewById(R.id.left_button);
-		View leftButtonContainer = buttonsView.findViewById(R.id.left_button_container);
-		TextView rightButtonText = buttonsView.findViewById(R.id.right_button);
-		View rightButtonContainer = buttonsView.findViewById(R.id.right_button_container);
+		TextView startButtonText = buttonsView.findViewById(R.id.left_button);
+		View startButtonContainer = buttonsView.findViewById(R.id.left_button_container);
+		TextView endButtonText = buttonsView.findViewById(R.id.right_button);
+		View endButtonContainer = buttonsView.findViewById(R.id.right_button_container);
 		GradientDrawable background = new GradientDrawable();
 		background.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f));
 		background.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(activeColor, 0.5f));
-		if (buttonType == CustomRadioButtonType.LEFT) {
-			background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius});
-			rightButtonContainer.setBackgroundColor(Color.TRANSPARENT);
-			rightButtonText.setTextColor(activeColor);
-			leftButtonContainer.setBackgroundDrawable(background);
-			leftButtonText.setTextColor(textColor);
+		if (buttonType == CustomRadioButtonType.START) {
+			if (isLayoutRtl) {
+				background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0});
+			} else {
+				background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius});
+			}
+			endButtonContainer.setBackgroundColor(Color.TRANSPARENT);
+			endButtonText.setTextColor(activeColor);
+			startButtonContainer.setBackgroundDrawable(background);
+			startButtonText.setTextColor(textColor);
 		} else {
-			background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0});
-			rightButtonContainer.setBackgroundDrawable(background);
-			rightButtonText.setTextColor(textColor);
-			leftButtonContainer.setBackgroundColor(Color.TRANSPARENT);
-			leftButtonText.setTextColor(activeColor);
+			if (isLayoutRtl) {
+				background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius});
+			} else {
+				background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0});
+			}
+			endButtonContainer.setBackgroundDrawable(background);
+			endButtonText.setTextColor(textColor);
+			startButtonContainer.setBackgroundColor(Color.TRANSPARENT);
+			startButtonText.setTextColor(activeColor);
 		}
 	}
 
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java
index 77f3909e62..8feb1ecf5c 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java
@@ -27,8 +27,8 @@ import org.apache.commons.logging.Log;
 import java.util.ArrayList;
 import java.util.List;
 
-import static net.osmand.plus.UiUtilities.CustomRadioButtonType.LEFT;
-import static net.osmand.plus.UiUtilities.CustomRadioButtonType.RIGHT;
+import static net.osmand.plus.UiUtilities.CustomRadioButtonType.START;
+import static net.osmand.plus.UiUtilities.CustomRadioButtonType.END;
 import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE;
 import static net.osmand.plus.measurementtool.SelectFileBottomSheet.BOTTOM_SHEET_HEIGHT_DP;
 
@@ -136,7 +136,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetBeha
 
 	public void updateModeButtons() {
 		UiUtilities.updateCustomRadioButtons(getMyApplication(), customRadioButton, nightMode,
-				defaultDialogMode == RouteBetweenPointsDialogMode.SINGLE ? LEFT : RIGHT);
+				defaultDialogMode == RouteBetweenPointsDialogMode.SINGLE ? START : END);
 		btnDescription.setText(getButtonDescr(defaultDialogMode));
 	}
 
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/NavigateTrackOptionsCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/NavigateTrackOptionsCard.java
index 4e3adfa29e..b2b819d269 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/NavigateTrackOptionsCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/NavigateTrackOptionsCard.java
@@ -11,8 +11,8 @@ import net.osmand.plus.activities.MapActivity;
 import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.LocalRoutingParameter;
 
 import static net.osmand.plus.UiUtilities.CustomRadioButtonType;
-import static net.osmand.plus.UiUtilities.CustomRadioButtonType.LEFT;
-import static net.osmand.plus.UiUtilities.CustomRadioButtonType.RIGHT;
+import static net.osmand.plus.UiUtilities.CustomRadioButtonType.START;
+import static net.osmand.plus.UiUtilities.CustomRadioButtonType.END;
 
 public class NavigateTrackOptionsCard extends BaseCard {
 
@@ -45,7 +45,7 @@ public class NavigateTrackOptionsCard extends BaseCard {
 		TextView description = parameterView.findViewById(R.id.description);
 
 		boolean enabled = passWholeRoute.isSelected(app.getSettings());
-		CustomRadioButtonType buttonType = enabled ? LEFT : RIGHT;
+		CustomRadioButtonType buttonType = enabled ? START : END;
 		UiUtilities.updateCustomRadioButtons(app, buttonsView, nightMode, buttonType);
 
 		leftButton.setText(R.string.start_of_the_track);
@@ -56,7 +56,7 @@ public class NavigateTrackOptionsCard extends BaseCard {
 			@Override
 			public void onClick(View v) {
 				if (!passWholeRoute.isSelected(app.getSettings())) {
-					applyParameter(parameterView, passWholeRoute, LEFT, true);
+					applyParameter(parameterView, passWholeRoute, START, true);
 				}
 			}
 		});
@@ -64,7 +64,7 @@ public class NavigateTrackOptionsCard extends BaseCard {
 			@Override
 			public void onClick(View v) {
 				if (passWholeRoute.isSelected(app.getSettings())) {
-					applyParameter(parameterView, passWholeRoute, RIGHT, false);
+					applyParameter(parameterView, passWholeRoute, END, false);
 				}
 			}
 		});
@@ -81,14 +81,14 @@ public class NavigateTrackOptionsCard extends BaseCard {
 		rightButton.setText(app.getRoutingHelper().getAppMode().toHumanString());
 
 		boolean enabled = navigationType.isSelected(app.getSettings());
-		CustomRadioButtonType buttonType = enabled ? RIGHT : LEFT;
+		CustomRadioButtonType buttonType = enabled ? END : START;
 		UiUtilities.updateCustomRadioButtons(app, buttonsView, nightMode, buttonType);
 
 		leftButton.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
 				if (navigationType.isSelected(app.getSettings())) {
-					applyParameter(parameterView, navigationType, LEFT, false);
+					applyParameter(parameterView, navigationType, START, false);
 				}
 			}
 		});
@@ -96,7 +96,7 @@ public class NavigateTrackOptionsCard extends BaseCard {
 			@Override
 			public void onClick(View v) {
 				if (!navigationType.isSelected(app.getSettings())) {
-					applyParameter(parameterView, navigationType, RIGHT, true);
+					applyParameter(parameterView, navigationType, END, true);
 				}
 			}
 		});
diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java
index f1517bbaea..b613d2ba13 100644
--- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java
+++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java
@@ -291,9 +291,9 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
 
 	private void adjustModeButtons(TerrainMode mode) {
 		if (mode == SLOPE) {
-			UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, RIGHT);
+			UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, END);
 		} else {
-			UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, LEFT);
+			UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, START);
 		}
 	}
 

From 7af6e0aa9e1d22e74ed7610bc9925caed0522680 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Mon, 21 Sep 2020 17:46:09 +0300
Subject: [PATCH 0247/1366] Upgrade appcompat to 1.2.0

---
 OsmAnd/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle
index 80c70c84b4..0e5734f212 100644
--- a/OsmAnd/build.gradle
+++ b/OsmAnd/build.gradle
@@ -523,7 +523,7 @@ dependencies {
 	implementation 'androidx.multidex:multidex:2.0.1'
 	implementation 'androidx.gridlayout:gridlayout:1.0.0'
 	implementation 'androidx.cardview:cardview:1.0.0'
-	implementation 'androidx.appcompat:appcompat:1.1.0'
+	implementation 'androidx.appcompat:appcompat:1.2.0'
 	implementation 'com.google.android.material:material:1.2.1'
 	implementation 'androidx.browser:browser:1.0.0'
 	implementation 'androidx.preference:preference:1.1.0'

From 7094c500e2dbc6ffadcd4904dd743593ed0b8bd0 Mon Sep 17 00:00:00 2001
From: Dmitry 
Date: Mon, 21 Sep 2020 18:27:51 +0300
Subject: [PATCH 0248/1366] Fix strings

---
 OsmAnd/res/values-ru/strings.xml | 2 +-
 OsmAnd/res/values-uk/strings.xml | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index f8ae3f5674..b9fb3e2dbc 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -3845,7 +3845,7 @@
     Маршрут трека
     Добавить файлы треков
     Импортируйте или запишите файлы треков
-    Добавить точку
+    Добавить путевую точку
     Добавить точку к треку
     Запись поездки
     Сохранить как файл трека
diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml
index d3a1ebd846..367b37541e 100644
--- a/OsmAnd/res/values-uk/strings.xml
+++ b/OsmAnd/res/values-uk/strings.xml
@@ -1031,7 +1031,7 @@
     Очистити проміжні точки
     Ви вже задали проміжні точки.
     Маршрут до
-    Напрямки від
+    Напрямок від
     До:
     Оголошувати…
     Налаштувати оголошення назв вулиць, дорожніх обмежень (вимушені зупинки, долішні (лежачі) поліцейські), попередження про камери контролю швидкості, обмеження швидкості.
@@ -3846,7 +3846,7 @@
     Додати шляхову точку треку
     Записування подорожі
     Зберегти як файл треку
-    Стежити за треком
+    Навігація за треком
     Виберіть файл треку для перегляду
     Виберіть файл треку для перегляду або імпортуйте його з пристрою.
     Обрати інший трек

From fc19e390048e4790bb7546c6c739d309eebb5f24 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Mon, 21 Sep 2020 19:23:10 +0300
Subject: [PATCH 0249/1366] Add followTrackMode to plan route menu

---
 .../MeasurementToolFragment.java              | 83 ++++++++++++-------
 .../FollowTrackFragment.java                  |  2 +-
 2 files changed, 56 insertions(+), 29 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 647353f9b7..bea960389d 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -138,6 +138,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	private boolean pointsListOpened;
 	private boolean planRouteMode = false;
 	private boolean directionMode = false;
+	private boolean followTrackMode = false;
 	private boolean approximationApplied = false;
 	private boolean portrait;
 	private boolean nightMode;
@@ -174,6 +175,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		this.directionMode = directionMode;
 	}
 
+	private void setFollowTrackMode(boolean followTrackMode) {
+		this.followTrackMode = followTrackMode;
+	}
+
 	@Override
 	public void onCreate(@Nullable Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
@@ -441,7 +446,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		toolBarController.setOnSaveViewClickListener(new OnClickListener() {
 			@Override
 			public void onClick(View v) {
-				saveChanges(FinalSaveAction.SHOW_SNACK_BAR_AND_CLOSE, false);
+				if (followTrackMode) {
+					startTrackNavigation();
+				} else {
+					saveChanges(FinalSaveAction.SHOW_SNACK_BAR_AND_CLOSE, false);
+				}
 			}
 		});
 		updateToolbar();
@@ -486,7 +495,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	}
 
 	public boolean isInEditMode() {
-		return !planRouteMode && !editingCtx.isNewData() && !directionMode;
+		return !planRouteMode && !editingCtx.isNewData() && !directionMode && !followTrackMode;
 	}
 
 	public void setFileName(String fileName) {
@@ -749,16 +758,23 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	private void runNavigation(final GPXFile gpx, final ApplicationMode appMode) {
 		MapActivity mapActivity = getMapActivity();
 		if (mapActivity != null) {
-			if (mapActivity.getMyApplication().getRoutingHelper().isFollowingMode()) {
-				mapActivity.getMapActions().stopNavigationActionConfirm(new Runnable() {
-					@Override
-					public void run() {
-						MapActivity mapActivity = getMapActivity();
-						if (mapActivity != null) {
-							mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpx, appMode, null, null, true, true, MenuState.HEADER_ONLY);
+			OsmandApplication app = mapActivity.getMyApplication();
+			if (app.getRoutingHelper().isFollowingMode()) {
+				if (followTrackMode) {
+					mapActivity.getMapActions().setGPXRouteParams(gpx);
+					app.getTargetPointsHelper().updateRouteAndRefresh(true);
+					app.getRoutingHelper().recalculateRouteDueToSettingsChange();
+				} else {
+					mapActivity.getMapActions().stopNavigationActionConfirm(new Runnable() {
+						@Override
+						public void run() {
+							MapActivity mapActivity = getMapActivity();
+							if (mapActivity != null) {
+								mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpx, appMode, null, null, true, true, MenuState.HEADER_ONLY);
+							}
 						}
-					}
-				});
+					});
+				}
 			} else {
 				mapActivity.getMapActions().stopNavigationWithoutConfirm();
 				mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpx, appMode, null, null, true, true, MenuState.HEADER_ONLY);
@@ -1843,7 +1859,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			cancelAddPointBeforeOrAfterMode();
 			return;
 		}
-		showQuitDialog(hidePointsListFirst);
+		if (followTrackMode) {
+			MapActivity mapActivity = getMapActivity();
+			if (mapActivity != null) {
+				mapActivity.getMapLayers().getMapControlsLayer().showRouteInfoControlDialog();
+				dismiss(mapActivity);
+			}
+		} else {
+			showQuitDialog(hidePointsListFirst);
+		}
 	}
 
 	private void showQuitDialog(boolean hidePointsListFirst) {
@@ -1909,11 +1933,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	}
 
 	public static boolean showInstance(FragmentManager fragmentManager, MeasurementEditingContext editingCtx,
-	                                   boolean planRoute, boolean directionMode) {
+	                                   boolean followTrackMode) {
 		MeasurementToolFragment fragment = new MeasurementToolFragment();
 		fragment.setEditingCtx(editingCtx);
-		fragment.setPlanRouteMode(planRoute);
-		fragment.setDirectionMode(directionMode);
+		fragment.setFollowTrackMode(followTrackMode);
 		return showFragment(fragment, fragmentManager);
 	}
 
@@ -2010,23 +2033,27 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		exitApproximationMode();
 		doAddOrMovePointCommonStuff();
 		updateSnapToRoadControls();
-		if (directionMode) {
+		if (directionMode || followTrackMode) {
 			directionMode = false;
-			MapActivity mapActivity = getMapActivity();
-			if (mapActivity != null) {
-				if (editingCtx.hasRoute()) {
-					String trackName = getSuggestedFileName();
-					GPXFile gpx = editingCtx.exportRouteAsGpx(trackName);
-					if (gpx != null) {
-						ApplicationMode appMode = editingCtx.getAppMode();
-						dismiss(mapActivity);
-						runNavigation(gpx, appMode);
-					} else {
-						Toast.makeText(mapActivity, getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_SHORT).show();
-					}
+			startTrackNavigation();
+		}
+	}
+
+	private void startTrackNavigation() {
+		MapActivity mapActivity = getMapActivity();
+		if (mapActivity != null) {
+			if (editingCtx.hasRoute()) {
+				String trackName = getSuggestedFileName();
+				GPXFile gpx = editingCtx.exportRouteAsGpx(trackName);
+				if (gpx != null) {
+					ApplicationMode appMode = editingCtx.getAppMode();
+					dismiss(mapActivity);
+					runNavigation(gpx, appMode);
 				} else {
 					Toast.makeText(mapActivity, getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_SHORT).show();
 				}
+			} else {
+				Toast.makeText(mapActivity, getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_SHORT).show();
 			}
 		}
 	}
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
index 4884fe616c..dcfa4fa6ef 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
@@ -542,7 +542,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
 			if (useAppMode) {
 				editingContext.setAppMode(app.getRoutingHelper().getAppMode());
 			}
-			MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), editingContext, true, true);
+			MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), editingContext, true);
 		}
 	}
 

From 9ae01e905e62a796d9b3c29d73df0f59254ee01d Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Mon, 21 Sep 2020 21:11:50 +0000
Subject: [PATCH 0250/1366] Translated using Weblate (Russian)

Currently translated at 100.0% (3484 of 3484 strings)
---
 OsmAnd/res/values-ru/strings.xml | 152 +++++++++++++++----------------
 1 file changed, 76 insertions(+), 76 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index f8ae3f5674..f63d7158b0 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -66,15 +66,15 @@
     Выберите улицу
     в %1$s
     Введите адрес
-    Введите город/населённый пункт/место
+    Город/место/район
     Введите почтовый индекс
     Ближайшие города
     Выберите город
     Поиск почтового индекса
-    Записать аудио
-    Записать видео
-    Сделать фото
-    Добавить заметку OSM
+    Аудиозаметка
+    Видеозаметка
+    Фотозаметка
+    OSM-заметка
     Функции парковки
     Благодарим вас за покупку платной версии OsmAnd.
     Не показывать сообщения при запуске
@@ -99,13 +99,13 @@
     Кнопка переключения автомасштабирования на основе скорости.
     Включение автомасштаба
     Выключение автомасштаба
-    Добавить точку маршрута
+    Пункт назначения
     Заменить пункт назначения
-    Добавить первую промежуточную точку
-    Кнопка для установки центра экрана пунктом назначения маршрута, любой ранее выбранный пункт назначения станет последним промежуточным пунктом.
-    Кнопка для установки центра экрана пунктом отправления. Затем будет предложено установить пункт назначения или запустить расчёт маршрута.
+    Первый промежуточный пункт
+    Установка центра экрана пунктом назначения; ранее выбранный пункт назначения станет последним промежуточным пунктом.
+    Кнопка для установки центра экрана пунктом отправления. Затем нужно будет выбрать пункт назначения или запустить расчёт маршрута.
     Кнопка для установки центра экрана пунктом назначения с заменой предыдущего (если был задан).
-    Кнопка для установки центра экрана первой промежуточной точкой маршрута.
+    Установка центра экрана первой промежуточной точкой маршрута.
     Нет покрытия
     Нет подложки
     Холмистый
@@ -148,7 +148,7 @@
     Переключатель, чтобы показать или скрыть избранные точки на карте.
     Переключатель, чтобы показать или скрыть POI на карте.
     Показать/скрыть избранные
-    Добавить категорию
+    Категория
     Действия
     Если оставить это поле пустым, то оно будет автоматически заполнено адресом или названием места.
     Это сообщение будет добавлено в комментарий.
@@ -219,8 +219,8 @@
     Тёмно-коричневый
     Цветовая гамма горизонталей
     Качество дорожного покрытия
-    Введите название города, адрес, POI
-    Введите имя для нового фильтра. Вы сможете его найти в списке «Категории».
+    Город, адрес, POI
+    Введите имя для нового фильтра. Он добавится в список «Категории».
     Транслитерация если имя на %1$s отсутствует
     Транслитерация названий
     Редактировать категории
@@ -233,7 +233,7 @@
     Сохранить фильтр
     Удалить фильтр
     Новый фильтр
-    Изменить положение
+    Изменить позицию
     Текущий путь
     Навигация OsmAnd Live
     Уровень заряда батареи
@@ -270,7 +270,7 @@
     Адрес не определён
     Около
     Местоположение
-    Редактировать POI
+    Изменить POI
     Заметка OSM открыта снова
     К заметке OSM добавлен комментарий
     Заметка OSM создана
@@ -286,7 +286,7 @@
     Удалённая OSM POI
     Отредактированная OSM POI
     Сохранить локально
-    Добавить заметку OSM
+    OSM-заметка
     Цвет трека GPX
     Толщина трека GPX
     Скопировано в буфер обмена
@@ -368,10 +368,10 @@
     Использовать онлайн-карты (загрузка и кеширование на SD-карте).
     Онлайн-карты
     Выберите источник онлайн или кешированных растровых карт.
-    Получение доступа ко множеству видов онлайн-карт (тайловых или растровых): от предопределённых тайловых OSM (как Mapnik), до спутниковых снимков и слоёв специального назначения, таких как карты погоды, климатические карты, геологические карты, слои затемнения высот и т. д. 
-\n 
-\n Любая из этих карт может быть использована в качестве основной (базовой) карты для отображения или в виде наложения или подложки к другой базовой карте (например стандартной локальной карте OsmAnd). Некоторые элементы векторной карты OsmAnd могут быть по желанию скрыты через меню «Настройки карты». 
-\n 
+    Доступ ко множеству онлайн-карт (т. н. тайловых или растровых): от встроенных OSM (как Mapnik), до спутниковых снимков и слоёв специального назначения, таких как карты погоды, климатические, геологические карты, затенения рельефа и др.
+\n
+\n Любая из этих карт может быть использована в качестве базовой либо как наложение или подложка к другой базовой карте (например стандартной локальной карте OsmAnd). Некоторые элементы векторной карты OsmAnd можно скрыть в меню «Настройки карты».
+\n
 \n Карты можно загрузить непосредственно из интернета или подготовить для использования в автономном режиме (и вручную скопировать в папку данных OsmAnd) в виде базы данных sqlite, которая может быть создана с помощью различных инструментов подготовки карт сторонних производителей.
     Показывает настройки для включения фонового отслеживания и навигации путём периодического пробуждения устройства GPS (с выключенным экраном).
     Добавляет поддержку специальных возможностей устройства непосредственно в OsmAnd. Это облегчает, например, регулировку скорости речи для синтезированного голоса, настройку направленности экрана навигации, управление масштабом при помощи трекбола или использование голосовых команд обратной связи для автоматической аннотации вашего местоположения.
@@ -466,7 +466,7 @@
     Неопределённо
     Текущий центр карты
     Начало:
-    Искать рядом
+    Поиск рядом
     Маршрут успешно сохранён в «%1$s».
     Имя файла: 
     Файл с таким именем уже существует.
@@ -563,7 +563,7 @@
     Координаты: %1$s\n%2$s
     Чтобы увидеть местоположение, перейдите по ссылке %1$s или Android-ссылке %2$s
     Отправить местоположение
-    Поделиться местоположением
+    Отправка геопозиции
     Путевая точка GPX «{0}» добавлена
     Добавить точку в записанный трек
     Административное
@@ -657,7 +657,7 @@
     фильтровать
     Дисплей высокого разрешения
     Не растягивать (с размытием) растровые карты на дисплеях высокого разрешения.
-    Искать общественный транспорт
+    Поиск транспорта
     Искать транспорт на остановке
     Результат поиска транспорта (нет пункта назначения):
     Результат поиска транспорта (до пункта {0}):
@@ -691,7 +691,7 @@
     POI…
     Источник карты
     Слои
-    Искать POI
+    Поиск POI
     Использовать трекбол для перемещения по карте.
     Использовать трекбол
     Устанавливает максимально допустимое время ожидания для каждого фонового фиксирования местоположения.
@@ -738,7 +738,7 @@
     Загрузить детальные карты регионов
     Поиск сигнала…
     Искать вокруг текущего центра карты
-    Искать рядом
+    Поиск рядом
     По умолчанию
     Портрет
     Ландшафт
@@ -768,7 +768,7 @@
     В данной области нет локальных POI
     Увеличение масштаба позволяет обновить POI
     Обновить POI
-    Вы хотите обновить локальные данные из интернета\?
+    Обновить локальные данные из интернета\?
     Город: {0}
     Улица: {0}, {1}
     Пересечение улиц: {0} x {1} в {2}
@@ -901,14 +901,14 @@
     Дом
     Пересечение улиц
     Обновить карту
-    Добавить POI
+    Создать POI
     Да
     Отмена
     Нет
     Название точки
     Избранная
     Точка «{0}» была успешно добавлена к избранным.
-    Редактировать место
+    Изменить
     Удалить из моих
     Удалить точку «%s» из избранных\?
     Точка {0} удалена.
@@ -1051,8 +1051,8 @@
     Запись места и времени парковки вашего авто.
 \nИ место, и время отображаются на панели управления или как виджет на карте. Можно добавить напоминание в календаре Android.
     Место парковки
-    Отметить парковку
-    Удалить метку места парковки
+    Место парковки
+    Удалить парковку
     Точка отправления слишком далеко от ближайшей дороги.
     Общие места
     Скорость моделирования маршрута:
@@ -1164,7 +1164,7 @@
     Привязка к дороге
     Промежуточный пункт %1$s слишком далеко от ближайшей дороги.
     Достигнут промежуточный пункт
-    Добавить промежуточный пункт
+    Промежуточный пункт
     Промежуточный пункт
     Конец маршрута слишком далеко от ближайшей дороги.
     Добавить тег
@@ -1176,8 +1176,8 @@
     Жильё
     Рестораны
     Достопримечательности
-    Добавить последним промежуточным пунктом
-    Добавить первым промежуточным пунктом
+    Последний промежуточный пункт
+    Первый промежуточный пункт
     Добавить последним промежуточным пунктом
     Добавить первым промежуточным пунктом
     Заменить пункт назначения
@@ -1281,7 +1281,7 @@
     Контурные линии
     Загрузка…
     Создание маршрутов по нажатию на карте, а также использование или изменение существующих файлов GPX, планирование поездки и измерение расстояния между точками. Результаты могут быть сохранены в виде файла GPX, который впоследствии может быть использован для навигации.
-    Сделать пунктом назначения
+    Пункт назначения
     Сначала установите город или улицу
     Пункт назначения %1$s
     Тип фокусировки камеры
@@ -1317,8 +1317,8 @@
     США
     Европа, Азия, Латинская Америка и тому подобное
     Великобритания, Индия и др.
-    Проложить маршрут
-    Пункт отправления
+    Маршрут сюда
+    Маршрут отсюда
     Канада
     Версия:
     Время действия (в минутах): %1$s
@@ -1739,7 +1739,7 @@
     Отменить выбор всех
     Поделиться
     Мои места
-    Избранные
+    Точки
     Треки
     Текущий трек
     Поделиться заметкой
@@ -1766,7 +1766,7 @@
     Посетить до
     Туристическая карта
     просрочено
-    Укажите время задержки на экране планирования маршрута.
+    Укажите время ожидания на экране планирования маршрута.
     Начать пошаговое ведение через…
     Поехали
     Расширяет возможности OsmAnd, делая доступными морские карты для катания на лодках, парусного спорта и других видов спорта.
@@ -2005,7 +2005,7 @@
     Как загрузить карты, установить основные настройки.
     Настройки навигации.
     Планирование поездки
-    Введите название страны
+    Страна
     Новая версия
     Первые шаги с OsmAnd
     Возможности
@@ -2027,7 +2027,7 @@
     Кнопка меню открывает панель управления, а не меню
     Доступ с карты
     Удалить путевую точку GPX\?
-    Редактировать путевую точку GPX
+    Изменить путевую точку GPX
     Без лестниц
     Избегать ступеней и лестниц
     Без пересечений границ
@@ -2137,7 +2137,7 @@
     Исключить из маршрута
     Публичное имя
     Поддерживаемый регион
-    Пожалуйста, введите публичное имя
+    Введите публичное имя
     Предлагается выбрать, прежде всего, управление приложением через гибкую панель управления или статическое меню. Ваш выбор всегда может быть изменён в настройках панели управления.
     Просмотр
     Добавьте маркеры на карте
@@ -2185,7 +2185,7 @@
     Поиск по координатам
     Расширенный поиск по координатам
     Вернуться в поиск
-    Удалить выбранные элементы из «Истории»\?
+    Удалить выбранные элементы из истории\?
     Показать %1$s на карте
     Искать за %1$s от местоположения
      поделились через OsmAnd
@@ -2257,15 +2257,15 @@
     Китайский (Гонконг)
     Быстрое действие
     Действие %d
-    Добавить маркер
-    Добавить POI
+    Маркер
+    POI
     Изменить стиль карты
     Стиль карты изменён на «%s».
-    Добавить место парковки
+    Место парковки
     Добавить действие
     Редактировать действие
-    Добавить в избранные
-    Добавить действие
+    В избранные
+    Добавить
     Удалить действие
     Вы уверены, что хотите удалить действие «%s»\?
     Показать избранные
@@ -2384,7 +2384,7 @@
     Экспорт маркеров в следующий файл GPX:
     Маркеры
     Изменить заметку
-    Изменить заметку OSM
+    Править OSM-заметку
     Добавить пункт отправления в качестве пункта назначения.
     Сделать маршрут круговым
     Использовать местоположение
@@ -2403,20 +2403,20 @@
     Дорога
     Показывать направляющие линии
     Тёмно-жёлтый
-    OsmAnd — это активно развивающийся проект с открытым исходным кодом. Благодаря открытости каждый может внести свой вклад в приложение сообщая об ошибках, улучшая перевод или кодируя новые функции. Проект находится в оживлённом состоянии непрерывного совершенствования всеми этими формами взаимодействия разработчиков и пользователей. Прогресс проекта также зависит от денежных взносов для финансирования написания и тестирования новых функций. 
-\n Примерная карта покрытия и качество: 
-\n • Западная Европа: **** 
-\n • Восточная Европа: *** 
-\n • Россия: *** 
-\n • Северная Америка: *** 
-\n • Южная Америка: ** 
-\n • Азия ** 
-\n • Япония и Корея: *** 
-\n • Ближний Восток: ** 
-\n • Африка: ** 
-\n • Антарктида: 
-\n Большинство стран по всему миру доступны для скачивания! 
-\n Получите надёжный навигатор в вашей стране — будь то Франция, Германия, Мексика, Великобритания, Испания, Нидерланды, США, Россия, Бразилия или любая другая.
+    OsmAnd — это активно развивающийся проект с открытым исходным кодом. Благодаря открытости, каждый может внести свой вклад в приложение, сообщая об ошибках, совершенствуя перевод или разрабатывая новые возможности. Кроме того, проект финансируется за счет денежных взносов с целью разработки и тестирования новых функций.
+\nПримерное покрытие и качество карт:
+\n • Западная Европа: ****
+\n • Восточная Европа: ***
+\n • Россия: ***
+\n • Северная Америка: ***
+\n • Южная Америка: **
+\n • Азия **
+\n • Япония и Корея: ***
+\n • Ближний Восток: **
+\n • Африка: **
+\n • Антарктида:
+\nДля скачивания доступно большинство стран мира!
+\n Получите надежный навигатор в своей стране — будь то Франция, Германия, Мексика, Великобритания, Испания, Нидерланды, США, Россия, Бразилия или любая другая.
     Примерная карта покрытия и качество: 
 \n • Западная Европа: **** 
 \n • Восточная Европа: *** 
@@ -2433,15 +2433,15 @@
 \n
     Временной буфер для онлайн-слежения
     Укажите временной буфер для хранения местоположений при отсутствии подключения к сети
-    Кнопка для добавления маркера карты в центр экрана.
-    Кнопка для добавления путевой точки GPX в центре экрана.
+    Добавление в центре экрана маркера на карту.
+    Добавление в центре экрана путевой точки GPX.
     Кнопка для добавления аудиозаметки в центре экрана.
     Кнопка для добавления видеозаметки в центре экрана.
     Кнопка для добавления фотозаметки в центре экрана.
-    Кнопка для добавления заметки OSM в центре экрана.
-    Кнопка для добавления POI в центре экрана.
+    Добавление в центре экрана OSM-заметки.
+    Добавление POI в центре экрана.
     Переключатель, чтобы включить или выключить голосовые подсказки во время навигации.
-    Кнопка для добавления парковочного места в центре экрана.
+    Добавление в центре экрана места парковки.
     Показывать промежуточный диалог
     Фотографии Mapillary доступны только онлайн.
     Неправильный формат
@@ -2577,7 +2577,7 @@
     " сохранено в "
     Повторить
     Добавить точки маршрута
-    Добавить путевую точку
+    Путевая точка
     Добавить линию
     Сохранить путевую точку GPX
     Сохранить точку маршрута
@@ -2758,7 +2758,7 @@
     Скачайте путеводители Викигида для просмотра статей о местах по всему миру без подключения к интернету.
     Доступно обновление
     Скачать файл
-    Свободный всемирный путеводитель, который может редактировать каждый.
+    Бесплатный путеводитель по всему миру, который может редактировать каждый.
     В настоящее время путеводители основаны на Викигиде. Проверьте бесплатно все функции во время открытого бета-тестирования. Впоследствии путеводители будут доступны подписчикам OsmAnd Unlimited и владельцам OsmAnd+.
     Вы можете изменять любую статью Викигида, более того, ваше участие в нашем проекте всячески приветствуется! Делитесь знаниями, опытом, талантами и своим вниманием.
     Начать редактирование
@@ -2861,7 +2861,7 @@
     Оставить пройденные маркеры на карте
     Больше транспорта доступно от этой остановки.
     Удалить маркер «%s»\?
-    Редактировать маркер
+    Изменить
     Стороннее приложение
     План и цены
     Ежемесячно
@@ -3231,8 +3231,8 @@
     Включить экран
     Карта во время навигации
     Карта во время навигации
-    Вес, высота, длина, скорость
-    Параметры автомобиля
+    Скорость движения, размеры, масса транспортного средства
+    Физические параметры
     Голосовые оповещения происходят только во время навигации.
     Навигационные инструкции и объявления
     Голосовые подсказки
@@ -3687,7 +3687,7 @@
 \n • Исправлены ошибки для языков, пишущихся справа налево 
 \n 
 \n
-    Доступ к этим действиям можно получить, нажав кнопку «%1$s».
+    Функции, доступные при нажатии кнопки «%1$s».
     Скрыть общественный транспорт
     Показать общественный транспорт
     Показать/скрыть общественный транспорт
@@ -3803,7 +3803,7 @@
     Добавить к треку
     Установите рабочие дни, чтобы продолжить
     Маршрут между точками
-    План маршрута
+    Составить маршрут
     Выберите нужный вариант разбиения: по времени или по расстоянию.
     Интервал между метками расстояния или времени на треке.
     Своё
@@ -3845,8 +3845,8 @@
     Маршрут трека
     Добавить файлы треков
     Импортируйте или запишите файлы треков
-    Добавить точку
-    Добавить точку к треку
+    Путевая точка
+    Путевая точка
     Запись поездки
     Сохранить как файл трека
     Следовать по маршруту

From 71fe5c80089514b1172bba475fd50ce268cb0982 Mon Sep 17 00:00:00 2001
From: Louis Garret 
Date: Mon, 21 Sep 2020 13:51:08 +0000
Subject: [PATCH 0251/1366] Translated using Weblate (French)

Currently translated at 100.0% (267 of 267 strings)

Translation: OsmAnd/Telegram
Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/fr/
---
 OsmAnd-telegram/res/values-fr/strings.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OsmAnd-telegram/res/values-fr/strings.xml b/OsmAnd-telegram/res/values-fr/strings.xml
index bc2bbd3d99..4397948508 100644
--- a/OsmAnd-telegram/res/values-fr/strings.xml
+++ b/OsmAnd-telegram/res/values-fr/strings.xml
@@ -266,4 +266,5 @@
     Cacher les contacts qui ne se sont pas déplacés depuis un temps donné.
     Définissez l\'heure à laquelle les contacts et groupes sélectionnés verront votre position en temps réel.
     OsmAnd connect
+    depuis
 
\ No newline at end of file

From 2e27035a1633d39cf39184ebf92509b9b8a176d5 Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Tue, 22 Sep 2020 10:55:16 +0300
Subject: [PATCH 0252/1366] Transparency seekbar on the map and UI are not
 synchronized

---
 OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java |  1 +
 .../osmand/plus/views/layers/MapControlsLayer.java    | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java
index 44d50db194..534c334aec 100644
--- a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java
+++ b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java
@@ -149,6 +149,7 @@ public class RasterMapMenu {
 						@Override
 						public boolean onIntegerValueChangedListener(int newValue) {
 							mapTransparencyPreference.set(newValue);
+							mapActivity.getMapLayers().getMapControlsLayer().updateTransparencySlider();
 							mapActivity.getMapView().refreshMap();
 							return false;
 						}
diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java
index 21277e2426..f1c3c1f13a 100644
--- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java
@@ -1068,6 +1068,17 @@ public class MapControlsLayer extends OsmandMapLayer {
 		}
 	}
 
+	public void updateTransparencySlider () {
+		LayerTransparencySeekbarMode seekbarMode = settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.get();
+		if (OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) != null) {
+			if (seekbarMode == LayerTransparencySeekbarMode.OVERLAY && settings.MAP_OVERLAY.get() != null) {
+				transparencySlider.setValue(settings.MAP_OVERLAY_TRANSPARENCY.get());
+			} else if (seekbarMode == LayerTransparencySeekbarMode.UNDERLAY && settings.MAP_UNDERLAY.get() != null) {
+				transparencySlider.setValue(settings.MAP_TRANSPARENCY.get());
+			}
+		}
+	}
+
 	public void showTransparencyBar(CommonPreference transparenPreference,
 	                                boolean isTransparencyBarEnabled) {
 		this.isTransparencyBarEnabled = isTransparencyBarEnabled;

From ff546e4f9e25242fad98fe304c0177753637d87c Mon Sep 17 00:00:00 2001
From: Eugene <44466116+EugeneZmeuk@users.noreply.github.com>
Date: Tue, 22 Sep 2020 11:01:05 +0300
Subject: [PATCH 0253/1366] Update HelpActivity.java

---
 OsmAnd/src/net/osmand/plus/activities/HelpActivity.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java b/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
index 667ee07614..ebeb14cb26 100644
--- a/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
@@ -141,7 +141,7 @@ public class HelpActivity extends OsmandActionBarActivity implements AdapterView
 				"feature_articles/map-markers.html"));
 		contextMenuAdapter.addItem(createItem(R.string.travel_item, NULL_ID,
 				"feature_articles/travel.html"));
-		contextMenuAdapter.addItem(createItem(R.string.measure_distance_item, NULL_ID,
+		contextMenuAdapter.addItem(createItem(R.string.plan_a_route_item, NULL_ID,
 				"feature_articles/plan-route.html"));
 		contextMenuAdapter.addItem(createItem(R.string.radius_ruler_item, NULL_ID,
 				"feature_articles/ruler.html"));

From 3c565905ca01d8a2cab414058758a63c38f2c24b Mon Sep 17 00:00:00 2001
From: Eugene <44466116+EugeneZmeuk@users.noreply.github.com>
Date: Tue, 22 Sep 2020 11:02:36 +0300
Subject: [PATCH 0254/1366] Update HelpActivity.java

---
 OsmAnd/src/net/osmand/plus/activities/HelpActivity.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java b/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
index ebeb14cb26..5cecc7b7ab 100644
--- a/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/HelpActivity.java
@@ -141,7 +141,7 @@ public class HelpActivity extends OsmandActionBarActivity implements AdapterView
 				"feature_articles/map-markers.html"));
 		contextMenuAdapter.addItem(createItem(R.string.travel_item, NULL_ID,
 				"feature_articles/travel.html"));
-		contextMenuAdapter.addItem(createItem(R.string.plan_a_route_item, NULL_ID,
+		contextMenuAdapter.addItem(createItem(R.string.plan_a_route, NULL_ID,
 				"feature_articles/plan-route.html"));
 		contextMenuAdapter.addItem(createItem(R.string.radius_ruler_item, NULL_ID,
 				"feature_articles/ruler.html"));

From 6d8b485c562e4bbd2c5679b596172a7d1a46eba0 Mon Sep 17 00:00:00 2001
From: sergosm 
Date: Tue, 22 Sep 2020 11:11:37 +0300
Subject: [PATCH 0255/1366] Length limit on the "Vehicle parameters" review

---
 .../settings/preferences/SizePreference.java     | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java b/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java
index 67120bf7c6..d950b56ed5 100644
--- a/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java
+++ b/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java
@@ -7,6 +7,9 @@ import androidx.preference.DialogPreference;
 import net.osmand.plus.R;
 import net.osmand.plus.settings.bottomsheets.VehicleSizeAssets;
 
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.Locale;
@@ -87,10 +90,13 @@ public class SizePreference extends DialogPreference {
 	public CharSequence getSummary() {
 		String summary = entries[0];
 		String persistedString = getValue();
-		if (!persistedString.equals(defaultValue)) {
+		if (StringUtils.isBlank(persistedString)) {
+			return summary;
+		}
+		if (!isPersistedStringEqualsZero(persistedString)) {
 			try {
 				final DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.US));
-				persistedString = df.format(Float.parseFloat(persistedString) + 0.01f);
+				persistedString = df.format(Double.parseDouble(persistedString) + 0.01d);
 				summary = String.format(getContext().getString(R.string.ltr_or_rtl_combine_via_space),
 						persistedString, getContext().getString(assets.getMetricShortRes()));
 			} catch (NumberFormatException e) {
@@ -100,7 +106,11 @@ public class SizePreference extends DialogPreference {
 		return summary;
 	}
 
-	public String getValue() {
+	private boolean isPersistedStringEqualsZero(String persistedString) {
+		return BigDecimal.ZERO.compareTo(new BigDecimal(persistedString)) == 0;
+	}
+
+	public String getValue () {
 		return getPersistedString(defaultValue);
 	}
 }

From 525ce78e003b8e62b860ceb0b067f80f4194fe0f Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 22 Sep 2020 12:21:14 +0300
Subject: [PATCH 0256/1366] Add sort types to available tracks screen

---
 .../plus/myplaces/AvailableGPXFragment.java   | 43 +++++++++----------
 .../plus/settings/backend/OsmandSettings.java | 29 +++++++++++--
 2 files changed, 46 insertions(+), 26 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 8432080bc8..136baa81b6 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -37,7 +37,6 @@ import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
@@ -63,6 +62,7 @@ import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
 import net.osmand.plus.GpxSelectionHelper;
 import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
 import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
+import net.osmand.plus.GpxSelectionHelper.SelectGpxTaskListener;
 import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
 import net.osmand.plus.OsmAndConstants;
 import net.osmand.plus.OsmAndFormatter;
@@ -82,6 +82,8 @@ import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
 import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
 import net.osmand.plus.osmedit.OsmEditingPlugin;
 import net.osmand.plus.settings.backend.OsmandSettings;
+import net.osmand.plus.settings.backend.OsmandSettings.TracksSortByMode;
+import net.osmand.plus.widgets.IconPopupMenu;
 
 import java.io.File;
 import java.text.Collator;
@@ -133,13 +135,13 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 	private View footerView;
 	private boolean importing = false;
 	private View emptyView;
-	private GpxSelectionHelper.SelectGpxTaskListener gpxTaskListener;
-	private boolean sortByName;
+	private SelectGpxTaskListener gpxTaskListener;
+	private TracksSortByMode sortByMode;
 
 	@Override
 	public void onCreate(@Nullable Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		gpxTaskListener = new GpxSelectionHelper.SelectGpxTaskListener() {
+		gpxTaskListener = new SelectGpxTaskListener() {
 			@Override
 			public void gpxSelectionInProgress() {
 				allGpxAdapter.notifyDataSetInvalidated();
@@ -160,13 +162,13 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 	}
 
 	@Override
-	public void onAttach(Context activity) {
+	public void onAttach(@NonNull Context activity) {
 		super.onAttach(activity);
 		this.app = (OsmandApplication) getActivity().getApplication();
-		sortByName = app.getSettings().SORT_TRACKS_BY_NAME.get();
+		sortByMode = app.getSettings().TRACKS_SORT_BY_MODE.get();
 		final Collator collator = Collator.getInstance();
 		collator.setStrength(Collator.SECONDARY);
-		currentRecording = new GpxInfo(getMyApplication().getSavingTrackHelper().getCurrentGpx(), getString(R.string.shared_string_currently_recording_track));
+		currentRecording = new GpxInfo(app.getSavingTrackHelper().getCurrentGpx(), getString(R.string.shared_string_currently_recording_track));
 		currentRecording.currentlyRecordingTrack = true;
 		asyncLoader = new LoadGpxTask();
 		selectedGpxHelper = ((OsmandApplication) activity.getApplicationContext()).getSelectedGpxHelper();
@@ -502,8 +504,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 					addTrack();
 				}else if (itemId == R.string.coordinate_input) {
 					openCoordinatesInput();
-				} else if (itemId == R.string.shared_string_sort) {
-					updateTracksSort();
 				}
 				return true;
 			}
@@ -521,8 +521,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 				.setIcon(R.drawable.ic_action_delete_dark).setListener(listener).createItem());
 		optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.shared_string_refresh, getActivity())
 				.setIcon(R.drawable.ic_action_refresh_dark).setListener(listener).createItem());
-		optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.shared_string_sort, getActivity())
-				.setIcon(getSortIconId(!sortByName)).setListener(listener).createItem());
 		OsmandPlugin.onOptionsMenuActivity(getActivity(), this, optionsMenuAdapter);
 		for (int j = 0; j < optionsMenuAdapter.length(); j++) {
 			final MenuItem item;
@@ -547,11 +545,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		}
 	}
 
-	@DrawableRes
-	private int getSortIconId(boolean sortByName) {
-		return sortByName ? R.drawable.ic_action_sort_by_name : R.drawable.ic_action_list_sort;
-	}
-
 	public void doAction(int actionResId) {
 		if (actionResId == R.string.shared_string_delete) {
 			operationTask = new DeleteGpxTask();
@@ -571,9 +564,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			ContextMenuItem contextMenuItem = optionsMenuAdapter.getItem(i);
 			if (itemId == contextMenuItem.getTitleId()) {
 				contextMenuItem.getItemClickListener().onContextMenuClick(null, itemId, i, false, null);
-				if (itemId == R.string.shared_string_sort) {
-					item.setIcon(getSortIconId(!sortByName));
-				}
 				return true;
 			}
 		}
@@ -973,14 +963,16 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			Arrays.sort(listFiles, new Comparator() {
 				@Override
 				public int compare(File f1, File f2) {
-					if (sortByName) {
+					if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) {
+						return f1.getName().compareTo(f2.getName());
+					} else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) {
 						return -f1.getName().compareTo(f2.getName());
 					} else {
 						// here we could guess date from file name '2017-08-30 ...' - first part date
 						if (f1.lastModified() == f2.lastModified()) {
 							return -f1.getName().compareTo(f2.getName());
 						}
-						return -Long.compare(f1.lastModified(), f2.lastModified());
+						return -((f1.lastModified() < f2.lastModified()) ? -1 : ((f1.lastModified() == f2.lastModified()) ? 0 : 1));
 					}
 				}
 			});
@@ -1078,15 +1070,20 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			Collections.sort(selected, new Comparator() {
 				@Override
 				public int compare(GpxInfo i1, GpxInfo i2) {
-					if (sortByName) {
+					if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) {
 						return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+					} else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) {
+						return -i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
 					} else {
+						if (i1.file == null || i2.file == null) {
+							return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+						}
 						long time1 = i1.file.lastModified();
 						long time2 = i2.file.lastModified();
 						if (time1 == time2) {
 							return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
 						}
-						return -Long.compare(time1, time2);
+						return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1));
 					}
 				}
 			});
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
index a860d4c65c..d8507abacd 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
@@ -2506,6 +2506,7 @@ public class OsmandSettings {
 	public final OsmandPreference SHOW_COORDINATES_WIDGET = new BooleanPreference("show_coordinates_widget", false).makeProfile().cache();
 
 	public final CommonPreference NOTES_SORT_BY_MODE = new EnumStringPreference<>("notes_sort_by_mode", NotesSortByMode.BY_DATE, NotesSortByMode.values());
+	public final CommonPreference TRACKS_SORT_BY_MODE = new EnumStringPreference<>("tracks_sort_by_mode", TracksSortByMode.BY_DATE, TracksSortByMode.values());
 
 	public final OsmandPreference ANIMATE_MY_LOCATION = new BooleanPreference("animate_my_location", true).makeProfile().cache();
 
@@ -3936,9 +3937,6 @@ public class OsmandSettings {
 	public final CommonPreference FAVORITES_TAB =
 			new IntPreference("FAVORITES_TAB", 0).makeGlobal().cache();
 
-	public final CommonPreference SORT_TRACKS_BY_NAME
-			= new BooleanPreference("sort_tracks_by_name", true).makeGlobal().cache();
-
 	public final CommonPreference OSMAND_THEME =
 			new IntPreference("osmand_theme", OSMAND_LIGHT_THEME) {
 				@Override
@@ -4105,6 +4103,31 @@ public class OsmandSettings {
 		}
 	}
 
+	public enum TracksSortByMode {
+		BY_DATE(R.drawable.ic_action_time_start),
+		BY_NAME_ASCENDING(R.drawable.ic_action_sort_by_name_ascending),
+		BY_NAME_DESCENDING(R.drawable.ic_action_sort_by_name_descending);
+
+		private final int iconId;
+
+		TracksSortByMode(int iconId) {
+			this.iconId = iconId;
+		}
+
+		public boolean isByName() {
+			return this == BY_NAME_ASCENDING || this == BY_NAME_DESCENDING;
+		}
+
+		public boolean isByDate() {
+			return this == BY_DATE;
+		}
+
+		@DrawableRes
+		public int getIconId() {
+			return iconId;
+		}
+	}
+
 	public enum MapMarkersMode {
 		TOOLBAR(R.string.shared_string_topbar),
 		WIDGETS(R.string.shared_string_widgets),

From 593112561d98ae9d1777578f6d82369bf01019a7 Mon Sep 17 00:00:00 2001
From: simon 
Date: Tue, 22 Sep 2020 13:02:19 +0300
Subject: [PATCH 0257/1366] exclude duplicated dialog fixed

---
 .../src/main/java/net/osmand/router/RoutingContext.java       | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java
index 922e225855..8809fc56ae 100644
--- a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java
+++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java
@@ -12,6 +12,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import gnu.trove.procedure.TObjectProcedure;
 import org.apache.commons.logging.Log;
 
 import gnu.trove.iterator.TIntObjectIterator;
@@ -289,7 +290,8 @@ public class RoutingContext {
 								if(excludeNotAllowed != null && !excludeNotAllowed.contains(ro.getId())) {
 									ts.add(ro);
 								}
-							} else if(excludeNotAllowed != null && ro.getId() > 0){
+							}
+							if(excludeNotAllowed != null && ro.getId() > 0){
 								excludeNotAllowed.add(ro.getId());
 								if(ts.excludedIds == null ){
 									ts.excludedIds = new TLongHashSet();

From 9cf447eab27258f58f61a30f5acacbd84c0e07bf Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 22 Sep 2020 13:02:34 +0300
Subject: [PATCH 0258/1366] Move sort button to toolbar

---
 OsmAnd/res/values/strings.xml                 |  3 ++
 .../base/OsmandExpandableListFragment.java    | 10 ++++--
 .../plus/myplaces/AvailableGPXFragment.java   | 32 +++++++++++++++----
 .../plus/settings/backend/OsmandSettings.java | 15 ++++++---
 4 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index c497ffda36..14e08c0176 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,9 @@
 	Thx - Hardy
 
 -->
+    Name: A – Z
+    Name: Z – A
+    Last modified
     
     • Updated "Plan a route" function: allows using different navigation types per segment and the inclusion of tracks\n\n
     • New "Appearance" menu for tracks: select color, thickness, display direction arrows, start/finish icons\n\n
diff --git a/OsmAnd/src/net/osmand/plus/base/OsmandExpandableListFragment.java b/OsmAnd/src/net/osmand/plus/base/OsmandExpandableListFragment.java
index 1db87051fa..90aabfac7c 100644
--- a/OsmAnd/src/net/osmand/plus/base/OsmandExpandableListFragment.java
+++ b/OsmAnd/src/net/osmand/plus/base/OsmandExpandableListFragment.java
@@ -88,10 +88,14 @@ public abstract class OsmandExpandableListFragment extends BaseOsmAndFragment
 
 	public MenuItem createMenuItem(Menu m, int id, int titleRes, int iconId, int menuItemType,
 	                               boolean flipIconForRtl) {
+		int color = isLightActionBar() ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark;
+		return createMenuItem(m, id, titleRes, iconId, menuItemType, false, color);
+	}
+
+	public MenuItem createMenuItem(Menu m, int id, int titleRes, int iconId, int menuItemType,
+	                               boolean flipIconForRtl, int iconColor) {
 		OsmandApplication app = requireMyApplication();
-		Drawable d = iconId == 0 ? null : app.getUIUtilities().getIcon(iconId, isLightActionBar() ?
-				R.color.active_buttons_and_links_text_light :
-				R.color.active_buttons_and_links_text_dark);
+		Drawable d = iconId == 0 ? null : app.getUIUtilities().getIcon(iconId, iconColor);
 		MenuItem menuItem = m.add(0, id, 0, titleRes);
 		if (d != null) {
 			if (flipIconForRtl) {
diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 136baa81b6..3c396eccf4 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -19,6 +19,7 @@ import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
+import android.view.SubMenu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
@@ -83,7 +84,6 @@ import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
 import net.osmand.plus.osmedit.OsmEditingPlugin;
 import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.settings.backend.OsmandSettings.TracksSortByMode;
-import net.osmand.plus.widgets.IconPopupMenu;
 
 import java.io.File;
 import java.text.Collator;
@@ -436,10 +436,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 	}
 
 	@Override
-	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+	public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
 		menu.clear();
-		MenuItem mi = createMenuItem(menu, SEARCH_ID, R.string.search_poi_filter, R.drawable.ic_action_search_dark, MenuItem.SHOW_AS_ACTION_ALWAYS
-						| MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
+		MenuItem mi = createMenuItem(menu, SEARCH_ID, R.string.search_poi_filter, R.drawable.ic_action_search_dark,
+				MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
 		SearchView searchView = new SearchView(getActivity());
 		FavoritesActivity.updateSearchView(getActivity(), searchView);
 		mi.setActionView(searchView);
@@ -475,6 +475,24 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 			}
 		});
 
+		menu.addSubMenu(Menu.NONE, R.string.shared_string_sort, Menu.NONE, R.string.shared_string_sort);
+		SubMenu sortMenu = menu.findItem(R.string.shared_string_sort).getSubMenu();
+		mi = sortMenu.getItem();
+		mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+		mi.setIcon(getIcon(R.drawable.ic_sort_waypoint_dark, isLightActionBar() ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark));
+
+		for (final TracksSortByMode mode : TracksSortByMode.values()) {
+			mi = createMenuItem(sortMenu, mode.getNameId(), mode.getNameId(), mode.getIconId(),
+					MenuItem.SHOW_AS_ACTION_ALWAYS, false, R.color.icon_color_default_light);
+			mi.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+				@Override
+				public boolean onMenuItemClick(MenuItem item) {
+					updateTracksSort(mode);
+					return false;
+				}
+			});
+		}
+
 		if (AndroidUiHelper.isOrientationPortrait(getActivity())) {
 			menu = ((FavoritesActivity) getActivity()).getClearToolbar(true).getMenu();
 		} else {
@@ -574,9 +592,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		((FavoritesActivity) getActivity()).addTrack();
 	}
 
-	private void updateTracksSort() {
-		sortByName = !sortByName;
-		app.getSettings().SORT_TRACKS_BY_NAME.set(sortByName);
+	private void updateTracksSort(TracksSortByMode sortByMode) {
+		this.sortByMode = sortByMode;
+		app.getSettings().TRACKS_SORT_BY_MODE.set(sortByMode);
 		reloadTracks();
 	}
 
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
index d8507abacd..e41c7d58df 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
@@ -4104,13 +4104,15 @@ public class OsmandSettings {
 	}
 
 	public enum TracksSortByMode {
-		BY_DATE(R.drawable.ic_action_time_start),
-		BY_NAME_ASCENDING(R.drawable.ic_action_sort_by_name_ascending),
-		BY_NAME_DESCENDING(R.drawable.ic_action_sort_by_name_descending);
+		BY_DATE(R.string.sort_last_modified, R.drawable.ic_action_time_start),
+		BY_NAME_ASCENDING(R.string.sort_name_ascending, R.drawable.ic_action_sort_by_name_ascending),
+		BY_NAME_DESCENDING(R.string.sort_name_descending, R.drawable.ic_action_sort_by_name_descending);
 
 		private final int iconId;
+		private final int nameId;
 
-		TracksSortByMode(int iconId) {
+		TracksSortByMode(int nameId, int iconId) {
+			this.nameId = nameId;
 			this.iconId = iconId;
 		}
 
@@ -4122,6 +4124,11 @@ public class OsmandSettings {
 			return this == BY_DATE;
 		}
 
+		@StringRes
+		public int getNameId() {
+			return nameId;
+		}
+
 		@DrawableRes
 		public int getIconId() {
 			return iconId;

From 69a93078e16435a94d227d6ecb95a69a846f462a Mon Sep 17 00:00:00 2001
From: simon 
Date: Tue, 22 Sep 2020 13:04:03 +0300
Subject: [PATCH 0259/1366] exclude duplicated dialog fixed

---
 OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java | 1 -
 1 file changed, 1 deletion(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java
index 8809fc56ae..3bfbaec0da 100644
--- a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java
+++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java
@@ -12,7 +12,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import gnu.trove.procedure.TObjectProcedure;
 import org.apache.commons.logging.Log;
 
 import gnu.trove.iterator.TIntObjectIterator;

From 459ffb228c728d94660f955ef1f2fc500fc7e30e Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 22 Sep 2020 14:12:56 +0300
Subject: [PATCH 0260/1366] Minor fixes

---
 .../MeasurementToolFragment.java               | 18 ++++++++++--------
 .../FollowTrackFragment.java                   |  4 +++-
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index bea960389d..6eced9d71b 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -479,7 +479,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		});
 		snapToRoadBtn.setVisibility(View.VISIBLE);
 
-		initMeasurementMode(gpxData);
+		initMeasurementMode(gpxData, savedInstanceState == null);
 
 		if (savedInstanceState == null) {
 			if (fileName != null) {
@@ -512,7 +512,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		updateSnapToRoadControls();
 	}
 
-	private void initMeasurementMode(GpxData gpxData) {
+	private void initMeasurementMode(GpxData gpxData, boolean addPoints) {
 		MapActivity mapActivity = getMapActivity();
 		if (mapActivity != null) {
 			editingCtx.getCommandManager().setMeasurementLayer(mapActivity.getMapLayers().getMeasurementToolLayer());
@@ -526,11 +526,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 						setAppMode(snapToRoadAppMode);
 					}
 				}
-				ActionType actionType = gpxData.getActionType();
-				if (actionType == ActionType.ADD_ROUTE_POINTS) {
-					displayRoutePoints();
-				} else if (actionType == ActionType.EDIT_SEGMENT) {
-					displaySegmentPoints();
+				if (addPoints) {
+					ActionType actionType = gpxData.getActionType();
+					if (actionType == ActionType.ADD_ROUTE_POINTS) {
+						displayRoutePoints();
+					} else if (actionType == ActionType.EDIT_SEGMENT) {
+						displaySegmentPoints();
+					}
 				}
 			}
 		}
@@ -1031,7 +1033,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
 		GpxData gpxData = new GpxData(gpxFile, rect, actionType, segment);
 		editingCtx.setGpxData(gpxData);
-		initMeasurementMode(gpxData);
+		initMeasurementMode(gpxData, true);
 		QuadRect qr = gpxData.getRect();
 		MapActivity mapActivity = getMapActivity();
 		if (mapActivity != null) {
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
index dcfa4fa6ef..544d073ca7 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
@@ -349,7 +349,9 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
 	@Override
 	public void onDestroyView() {
 		super.onDestroyView();
-		exitTrackAppearanceMode();
+		if (!editingTrack) {
+			exitTrackAppearanceMode();
+		}
 		onDismiss();
 	}
 

From 791f33095318646a3af122c4598ee3b61dd82c53 Mon Sep 17 00:00:00 2001
From: Victor Shcherb 
Date: Tue, 22 Sep 2020 13:27:19 +0200
Subject: [PATCH 0261/1366] Try to fix distance diff

---
 .../plus/measurementtool/MeasurementEditingContext.java   | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index d1dae05a6d..b3db049d39 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -250,8 +250,14 @@ public class MeasurementEditingContext {
 				RoadSegmentData data = this.roadSegmentData.get(pair);
 				if (data == null) {
 					if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE || !pair.first.lastPoint || !pair.second.firstPoint) {
-						distance += MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(),
+						double localDist = MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(),
 								pair.second.getLatitude(), pair.second.getLongitude());
+						if(!Double.isNaN(pair.first.ele) && !Double.isNaN(pair.second.ele) &&
+								pair.first.ele != 0 && pair.second.ele != 0) {
+							double h = Math.abs(pair.first.ele - pair.second.ele);
+							localDist = Math.sqrt(localDist * localDist + h * h);
+						}
+						distance += localDist;
 					}
 				} else {
 					distance += data.getDistance();

From fdea007118c475fc0c8174435ac839ffe0233fa7 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 14:37:52 +0300
Subject: [PATCH 0262/1366] Replace 'rename' to 'undo' after done button

---
 OsmAnd/src/net/osmand/FileUtils.java          |  64 ++++-
 .../osmand/plus/measurementtool/GpxData.java  |   7 +
 .../MeasurementToolFragment.java              | 224 ++++++++++++------
 3 files changed, 207 insertions(+), 88 deletions(-)

diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java
index 59fb36c88d..426c5c10c2 100644
--- a/OsmAnd/src/net/osmand/FileUtils.java
+++ b/OsmAnd/src/net/osmand/FileUtils.java
@@ -9,6 +9,7 @@ import android.widget.EditText;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
 
 import net.osmand.plus.GpxSelectionHelper;
@@ -19,6 +20,7 @@ import net.osmand.plus.SQLiteTileSource;
 import net.osmand.util.Algorithms;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.util.regex.Pattern;
 
@@ -121,33 +123,54 @@ public class FileUtils {
 		return null;
 	}
 
-	public static File renameGpxFile(OsmandApplication ctx, File source, String newName, boolean dirAllowed,
-									 RenameCallback callback) {
-		File dest = checkRenamePossibility(ctx, source, newName, dirAllowed);
+	public static File renameGpxFile(@NonNull OsmandApplication app, @NonNull File source,
+									 @NonNull String newName, boolean dirAllowed, @Nullable RenameCallback callback) {
+		File dest = checkRenamePossibility(app, source, newName, dirAllowed);
 		if (dest == null) {
 			return null;
 		}
+		File res = renameGpxFile(app, source, dest);
+		if (res != null) {
+			if (callback != null) {
+				callback.renamedTo(res);
+			}
+		} else {
+			Toast.makeText(app, R.string.file_can_not_be_renamed, Toast.LENGTH_LONG).show();
+		}
+		return res;
+	}
+
+	public static File renameGpxFile(@NonNull OsmandApplication app, @NonNull File src, @NonNull File dest) {
 		if (!dest.getParentFile().exists()) {
 			dest.getParentFile().mkdirs();
 		}
-		if (source.renameTo(dest)) {
-			GpxSelectionHelper helper = ctx.getSelectedGpxHelper();
-			SelectedGpxFile selected = helper.getSelectedFileByPath(source.getAbsolutePath());
-			ctx.getGpxDbHelper().rename(source, dest);
+		if (src.renameTo(dest)) {
+			GpxSelectionHelper helper = app.getSelectedGpxHelper();
+			SelectedGpxFile selected = helper.getSelectedFileByPath(src.getAbsolutePath());
+			app.getGpxDbHelper().rename(src, dest);
 			if (selected != null && selected.getGpxFile() != null) {
 				selected.getGpxFile().path = dest.getAbsolutePath();
 				helper.updateSelectedGpxFile(selected);
 			}
-			if (callback != null) {
-				callback.renamedTo(dest);
-			}
 			return dest;
-		} else {
-			Toast.makeText(ctx, R.string.file_can_not_be_renamed, Toast.LENGTH_LONG).show();
 		}
 		return null;
 	}
 
+	public static boolean removeGpxFile(@NonNull OsmandApplication app, @NonNull File file) {
+		if (file.exists()) {
+			GpxSelectionHelper helper = app.getSelectedGpxHelper();
+			SelectedGpxFile selected = helper.getSelectedFileByPath(file.getAbsolutePath());
+			file.delete();
+			app.getGpxDbHelper().remove(file);
+			if (selected != null && selected.getGpxFile() != null) {
+				helper.selectGpxFile(selected.getGpxFile(), false, false);
+			}
+			return true;
+		}
+		return false;
+	}
+
 	public static File checkRenamePossibility(OsmandApplication ctx, File source, String newName, boolean dirAllowed) {
 		if (Algorithms.isEmpty(newName)) {
 			Toast.makeText(ctx, R.string.empty_filename, Toast.LENGTH_LONG).show();
@@ -178,6 +201,23 @@ public class FileUtils {
 		return uniqueFileName;
 	}
 
+	public static File backupFile(@NonNull OsmandApplication app, @NonNull File src) {
+		if (!src.exists()) {
+			return null;
+		}
+		File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
+		if (!tempDir.exists()) {
+			tempDir.mkdirs();
+		}
+		File dest = new File(tempDir, src.getName());
+		try {
+			Algorithms.fileCopy(src, dest);
+		} catch (IOException e) {
+			return null;
+		}
+		return dest;
+	}
+
 	public interface RenameCallback {
 		void renamedTo(File file);
 	}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/GpxData.java b/OsmAnd/src/net/osmand/plus/measurementtool/GpxData.java
index 754964ea57..a59efe63dc 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/GpxData.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/GpxData.java
@@ -25,6 +25,13 @@ public class GpxData {
 		this.trkSegment = trkSegment;
 	}
 
+	public GpxData(GPXFile gpxFile, GpxData gpxData) {
+		this.gpxFile = gpxFile;
+		this.rect = gpxData.rect;
+		this.actionType = gpxData.actionType;
+		this.trkSegment = gpxData.trkSegment;
+	}
+
 	public GPXFile getGpxFile() {
 		return gpxFile;
 	}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index bea960389d..1afa0e8479 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -136,9 +136,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	private boolean wasCollapseButtonVisible;
 	private boolean progressBarVisible;
 	private boolean pointsListOpened;
-	private boolean planRouteMode = false;
-	private boolean directionMode = false;
-	private boolean followTrackMode = false;
+
+	private static final int PLAN_ROUTE_MODE = 0x1;
+	private static final int DIRECTION_MODE = 0x2;
+	private static final int FOLLOW_TRACK_MODE = 0x4;
+	private static final int UNDO_MODE = 0x8;
+	private int modes = 0x0;
+
 	private boolean approximationApplied = false;
 	private boolean portrait;
 	private boolean nightMode;
@@ -167,16 +171,30 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		this.initialPoint = initialPoint;
 	}
 
-	private void setPlanRouteMode(boolean planRouteMode) {
-		this.planRouteMode = planRouteMode;
+	private void setMode(int mode, boolean on) {
+		int modes = this.modes;
+		if (on) {
+			modes |= mode;
+		} else {
+			modes &= ~mode;
+		}
+		this.modes = modes;
 	}
 
-	private void setDirectionMode(boolean directionMode) {
-		this.directionMode = directionMode;
+	private boolean isPlanRouteMode() {
+		return (this.modes & PLAN_ROUTE_MODE) == PLAN_ROUTE_MODE;
 	}
 
-	private void setFollowTrackMode(boolean followTrackMode) {
-		this.followTrackMode = followTrackMode;
+	private boolean isDirectionMode() {
+		return (this.modes & DIRECTION_MODE) == DIRECTION_MODE;
+	}
+
+	private boolean isFollowTrackMode() {
+		return (this.modes & FOLLOW_TRACK_MODE) == FOLLOW_TRACK_MODE;
+	}
+
+	private boolean isUndoMode() {
+		return (this.modes & UNDO_MODE) == UNDO_MODE;
 	}
 
 	@Override
@@ -446,7 +464,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		toolBarController.setOnSaveViewClickListener(new OnClickListener() {
 			@Override
 			public void onClick(View v) {
-				if (followTrackMode) {
+				if (isFollowTrackMode()) {
 					startTrackNavigation();
 				} else {
 					saveChanges(FinalSaveAction.SHOW_SNACK_BAR_AND_CLOSE, false);
@@ -495,7 +513,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	}
 
 	public boolean isInEditMode() {
-		return !planRouteMode && !editingCtx.isNewData() && !directionMode && !followTrackMode;
+		return !isPlanRouteMode() && !editingCtx.isNewData() && !isDirectionMode() && !isFollowTrackMode();
 	}
 
 	public void setFileName(String fileName) {
@@ -519,11 +537,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			enterMeasurementMode();
 			updateSnapToRoadControls();
 			if (gpxData != null) {
-				List points = gpxData.getGpxFile().getRoutePoints();
-				if (!points.isEmpty()) {
-					ApplicationMode snapToRoadAppMode = ApplicationMode.valueOfStringKey(points.get(points.size() - 1).getProfileType(), null);
-					if (snapToRoadAppMode != null) {
-						setAppMode(snapToRoadAppMode);
+				if (!isUndoMode()) {
+					List points = gpxData.getGpxFile().getRoutePoints();
+					if (!points.isEmpty()) {
+						ApplicationMode snapToRoadAppMode = ApplicationMode.valueOfStringKey(points.get(points.size() - 1).getProfileType(), null);
+						if (snapToRoadAppMode != null) {
+							setAppMode(snapToRoadAppMode);
+						}
 					}
 				}
 				ActionType actionType = gpxData.getActionType();
@@ -533,6 +553,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 					displaySegmentPoints();
 				}
 			}
+			setMode(UNDO_MODE, false);
 		}
 	}
 
@@ -678,7 +699,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 				switch (resultCode) {
 					case SnapTrackWarningFragment.CANCEL_RESULT_CODE:
 						toolBarController.setSaveViewVisible(true);
-						directionMode = false;
+						setMode(DIRECTION_MODE, false);
 						exitApproximationMode();
 						updateToolbar();
 						break;
@@ -744,7 +765,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 							targetPointsHelper.clearAllPoints(false);
 							mapActions.enterRoutePlanningModeGivenGpx(gpx, appMode, null, null, true, true, MenuState.HEADER_ONLY);
 						} else {
-							directionMode = true;
+							setMode(DIRECTION_MODE, true);
 							enterApproximationMode(mapActivity);
 						}
 					}
@@ -760,7 +781,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		if (mapActivity != null) {
 			OsmandApplication app = mapActivity.getMyApplication();
 			if (app.getRoutingHelper().isFollowingMode()) {
-				if (followTrackMode) {
+				if (isFollowTrackMode()) {
 					mapActivity.getMapActions().setGPXRouteParams(gpx);
 					app.getTargetPointsHelper().updateRouteAndRefresh(true);
 					app.getRoutingHelper().recalculateRouteDueToSettingsChange();
@@ -1026,20 +1047,29 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	}
 
 	public void addNewGpxData(GPXFile gpxFile) {
-		QuadRect rect = gpxFile.getRect();
-		TrkSegment segment = gpxFile.getNonEmptyTrkSegment();
-		ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
-		GpxData gpxData = new GpxData(gpxFile, rect, actionType, segment);
-		editingCtx.setGpxData(gpxData);
+		GpxData gpxData = setupGpxData(gpxFile);
 		initMeasurementMode(gpxData);
-		QuadRect qr = gpxData.getRect();
 		MapActivity mapActivity = getMapActivity();
-		if (mapActivity != null) {
+		if (mapActivity != null && gpxData != null) {
+			QuadRect qr = gpxData.getRect();
 			mapActivity.getMapView().fitRectToMap(qr.left, qr.right, qr.top, qr.bottom,
 					(int) qr.width(), (int) qr.height(), 0);
 		}
 	}
 
+	@Nullable
+	private GpxData setupGpxData(@Nullable GPXFile gpxFile) {
+		GpxData gpxData = null;
+		if (gpxFile != null) {
+			QuadRect rect = gpxFile.getRect();
+			TrkSegment segment = gpxFile.getNonEmptyTrkSegment();
+			ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
+			gpxData = new GpxData(gpxFile, rect, actionType, segment);
+		}
+		editingCtx.setGpxData(gpxData);
+		return gpxData;
+	}
+
 	private void removePoint(MeasurementToolLayer measurementLayer, int position) {
 		if (measurementLayer != null) {
 			editingCtx.getCommandManager().execute(new RemovePointCommand(measurementLayer, position));
@@ -1172,7 +1202,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		if (gpx != null) {
 			List points = gpx.getRoutePoints();
 			if (measurementLayer != null) {
-				editingCtx.addPoints(points);
+				if (!isUndoMode()) {
+					editingCtx.addPoints(points);
+				}
 				adapter.notifyDataSetChanged();
 				updateDistancePointsText();
 			}
@@ -1182,7 +1214,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	private void displaySegmentPoints() {
 		MeasurementToolLayer measurementLayer = getMeasurementLayer();
 		if (measurementLayer != null) {
-			editingCtx.addPoints();
+			if (!isUndoMode()) {
+				editingCtx.addPoints();
+			}
 			adapter.notifyDataSetChanged();
 			updateDistancePointsText();
 		}
@@ -1510,7 +1544,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		new AsyncTask() {
 
 			private ProgressDialog progressDialog;
-			private File toSave;
+			private File backupFile;
+			private File outFile;
 			private GPXFile savedGpxFile;
 
 			@Override
@@ -1535,7 +1570,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 				TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
 				TrkSegment after = editingCtx.getAfterTrkSegmentLine();
 				if (gpxFile == null) {
-					toSave = new File(dir, fileName);
+					outFile = new File(dir, fileName);
 					String trackName = fileName.substring(0, fileName.length() - GPX_FILE_EXT.length());
 					GPXFile gpx = new GPXFile(Version.getFullVersion(app));
 					if (measurementLayer != null) {
@@ -1561,19 +1596,20 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 							gpx.addRoutePoints(points);
 						}
 					}
-					Exception res = GPXUtilities.writeGpxFile(toSave, gpx);
-					gpx.path = toSave.getAbsolutePath();
+					Exception res = GPXUtilities.writeGpxFile(outFile, gpx);
+					gpx.path = outFile.getAbsolutePath();
 					savedGpxFile = gpx;
 					if (showOnMap) {
-						app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
+						showGpxOnMap(app, gpx, true);
 					}
 					return res;
 				} else {
 					GPXFile gpx = gpxFile;
-					toSave = new File(gpx.path);
-					String trackName = Algorithms.getFileNameWithoutExtension(toSave);
+					outFile = new File(gpx.path);
+					backupFile = FileUtils.backupFile(app, outFile);
+					String trackName = Algorithms.getFileNameWithoutExtension(outFile);
 					if (measurementLayer != null) {
-						if (planRouteMode) {
+						if (isPlanRouteMode()) {
 							if (saveType == SaveType.LINE) {
 								TrkSegment segment = new TrkSegment();
 								if (editingCtx.hasRoute()) {
@@ -1635,21 +1671,25 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 					}
 					Exception res = null;
 					if (!gpx.showCurrentTrack) {
-						res = GPXUtilities.writeGpxFile(toSave, gpx);
+						res = GPXUtilities.writeGpxFile(outFile, gpx);
 					}
 					savedGpxFile = gpx;
 					if (showOnMap) {
-						SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
-						if (sf != null) {
-							if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) {
-								sf.processPoints(getMyApplication());
-							}
-						}
+						showGpxOnMap(app, gpx, false);
 					}
 					return res;
 				}
 			}
 
+			private void showGpxOnMap(OsmandApplication app, GPXFile gpx, boolean isNewGpx) {
+				SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
+				if (sf != null && !isNewGpx) {
+					if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) {
+						sf.processPoints(getMyApplication());
+					}
+				}
+			}
+
 			@Override
 			protected void onPostExecute(Exception warning) {
 				onGpxSaved(warning);
@@ -1665,7 +1705,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 				}
 				mapActivity.refreshMap();
 				if (warning == null) {
-					editingCtx.setChangesSaved();
 					if (editingCtx.isNewData() && savedGpxFile != null) {
 						QuadRect rect = savedGpxFile.getRect();
 						TrkSegment segment = savedGpxFile.getNonEmptyTrkSegment();
@@ -1674,30 +1713,66 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 						updateToolbar();
 					}
 					if (isInEditMode()) {
+						editingCtx.setChangesSaved();
 						dismiss(mapActivity);
 					} else {
 						switch (finalSaveAction) {
 							case SHOW_SNACK_BAR_AND_CLOSE:
 								final WeakReference mapActivityRef = new WeakReference<>(mapActivity);
 								snackbar = Snackbar.make(mapActivity.getLayout(),
-										MessageFormat.format(getString(R.string.gpx_saved_sucessfully), toSave.getName()),
+										MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getName()),
 										Snackbar.LENGTH_LONG)
-										.setAction(R.string.shared_string_rename, getRenameListener(mapActivityRef));
+										.setAction(R.string.shared_string_undo, new OnClickListener() {
+											@Override
+											public void onClick(View view) {
+												MapActivity mapActivity = mapActivityRef.get();
+												if (mapActivity != null) {
+													if (outFile != null) {
+														OsmandApplication app = mapActivity.getMyApplication();
+														FileUtils.removeGpxFile(app, outFile);
+														if (backupFile != null) {
+															FileUtils.renameGpxFile(app, backupFile, outFile);
+															GPXFile gpx = GPXUtilities.loadGPXFile(outFile);
+															setupGpxData(gpx);
+															if (showOnMap) {
+																showGpxOnMap(app, gpx, false);
+															}
+														} else {
+															setupGpxData(null);
+														}
+													}
+													setMode(UNDO_MODE, true);
+													MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(),
+															editingCtx, modes);
+												}
+											}
+										})
+										.addCallback(new Snackbar.Callback() {
+											@Override
+											public void onDismissed(Snackbar transientBottomBar, int event) {
+												if (event != DISMISS_EVENT_ACTION) {
+													editingCtx.setChangesSaved();
+												}
+												super.onDismissed(transientBottomBar, event);
+											}
+										});
 								snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_action)
 										.setAllCaps(false);
 								UiUtilities.setupSnackbar(snackbar, nightMode);
 								snackbar.show();
-								dismiss(mapActivity);
+								dismiss(mapActivity, false);
 								break;
 							case SHOW_IS_SAVED_FRAGMENT:
+								editingCtx.setChangesSaved();
 								SavedTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
-										toSave.getAbsolutePath());
+										outFile.getAbsolutePath());
 								dismiss(mapActivity);
 								break;
 							case SHOW_TOAST:
+								editingCtx.setChangesSaved();
 								if (!savedGpxFile.showCurrentTrack) {
 									Toast.makeText(mapActivity,
-											MessageFormat.format(getString(R.string.gpx_saved_sucessfully), toSave.getAbsolutePath()),
+											MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getAbsolutePath()),
 											Toast.LENGTH_LONG).show();
 								}
 						}
@@ -1706,22 +1781,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 					Toast.makeText(mapActivity, warning.getMessage(), Toast.LENGTH_LONG).show();
 				}
 			}
-
-			private OnClickListener getRenameListener(final WeakReference mapActivityRef) {
-				return new OnClickListener() {
-					@Override
-					public void onClick(View view) {
-						MapActivity mapActivity = mapActivityRef.get();
-						String parentFolder = toSave.getParentFile().getName();
-						if (GPX_INDEX_DIR.equals(parentFolder + File.separator)) {
-							parentFolder = null;
-						}
-						SaveAsNewTrackBottomSheetDialogFragment.showInstance(
-								mapActivity.getSupportFragmentManager(), null, parentFolder,
-								AndroidUtils.trimExtension(toSave.getName()), false, showOnMap);
-					}
-				};
-			}
 		}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 	}
 
@@ -1859,7 +1918,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			cancelAddPointBeforeOrAfterMode();
 			return;
 		}
-		if (followTrackMode) {
+		if (isFollowTrackMode()) {
 			MapActivity mapActivity = getMapActivity();
 			if (mapActivity != null) {
 				mapActivity.getMapLayers().getMapControlsLayer().showRouteInfoControlDialog();
@@ -1886,9 +1945,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		}
 	}
 
-	private void dismiss(MapActivity mapActivity) {
+	private void dismiss(@NonNull MapActivity mapActivity) {
+		dismiss(mapActivity, true);
+	}
+
+	private void dismiss(@NonNull MapActivity mapActivity, boolean clearContext) {
 		try {
-			editingCtx.clearSegments();
+			if (clearContext) {
+				editingCtx.clearSegments();
+			}
 			if (pointsListOpened) {
 				hidePointsList();
 			}
@@ -1914,21 +1979,21 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	public static boolean showInstance(FragmentManager fragmentManager, LatLon initialPoint) {
 		MeasurementToolFragment fragment = new MeasurementToolFragment();
 		fragment.setInitialPoint(initialPoint);
-		fragment.setPlanRouteMode(true);
+		fragment.setMode(PLAN_ROUTE_MODE, true);
 		return showFragment(fragment, fragmentManager);
 	}
 
 	public static boolean showInstance(FragmentManager fragmentManager, String fileName) {
 		MeasurementToolFragment fragment = new MeasurementToolFragment();
 		fragment.setFileName(fileName);
-		fragment.setPlanRouteMode(true);
+		fragment.setMode(PLAN_ROUTE_MODE, true);
 		return showFragment(fragment, fragmentManager);
 	}
 
 	public static boolean showInstance(FragmentManager fragmentManager, GPXFile gpxFile) {
 		MeasurementToolFragment fragment = new MeasurementToolFragment();
 		fragment.addNewGpxData(gpxFile);
-		fragment.setPlanRouteMode(true);
+		fragment.setMode(PLAN_ROUTE_MODE, true);
 		return showFragment(fragment, fragmentManager);
 	}
 
@@ -1936,7 +2001,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	                                   boolean followTrackMode) {
 		MeasurementToolFragment fragment = new MeasurementToolFragment();
 		fragment.setEditingCtx(editingCtx);
-		fragment.setFollowTrackMode(followTrackMode);
+		fragment.setMode(FOLLOW_TRACK_MODE, followTrackMode);
 		return showFragment(fragment, fragmentManager);
 	}
 
@@ -1948,7 +2013,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 
 	public static boolean showInstance(FragmentManager fragmentManager) {
 		MeasurementToolFragment fragment = new MeasurementToolFragment();
-		fragment.setPlanRouteMode(true);
+		fragment.setMode(PLAN_ROUTE_MODE, true);
+		return showFragment(fragment, fragmentManager);
+	}
+
+	private static boolean showInstance(FragmentManager fragmentManager, MeasurementEditingContext editingCtx, int modes) {
+		MeasurementToolFragment fragment = new MeasurementToolFragment();
+		fragment.setEditingCtx(editingCtx);
+		fragment.modes = modes;
 		return showFragment(fragment, fragmentManager);
 	}
 
@@ -2033,8 +2105,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 		exitApproximationMode();
 		doAddOrMovePointCommonStuff();
 		updateSnapToRoadControls();
-		if (directionMode || followTrackMode) {
-			directionMode = false;
+		if (isDirectionMode() || isFollowTrackMode()) {
+			setMode(DIRECTION_MODE, false);
 			startTrackNavigation();
 		}
 	}
@@ -2062,7 +2134,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 	public void onCancelGpxApproximation() {
 		editingCtx.getCommandManager().undo();
 		exitApproximationMode();
-		directionMode = false;
+		setMode(DIRECTION_MODE, false);
 		updateSnapToRoadControls();
 		updateToolbar();
 	}

From c24e8bba2d2e5d1ed677443b86083141ed45cb82 Mon Sep 17 00:00:00 2001
From: Dima-1 
Date: Tue, 22 Sep 2020 14:57:38 +0300
Subject: [PATCH 0263/1366] Add Sorting to Track Dialog

---
 .../bottom_sheet_plan_route_select_file.xml   |  76 ++++++++----
 OsmAnd/src/net/osmand/AndroidUtils.java       |   5 +
 ...veAsNewTrackBottomSheetDialogFragment.java |   3 +-
 .../SelectFileBottomSheet.java                | 108 ++++++++++++++++--
 .../plus/myplaces/AvailableGPXFragment.java   |   8 +-
 5 files changed, 161 insertions(+), 39 deletions(-)

diff --git a/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml b/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml
index 362dacf2c6..10de9cb667 100644
--- a/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml
+++ b/OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml
@@ -6,33 +6,59 @@
 	android:layout_height="wrap_content"
 	android:orientation="vertical">
 
-	
+		android:orientation="horizontal">
 
-	
+		
+
+			
+
+			
+		
+
+		
+	
 
 	 dirs = new ArrayList<>();
 		final File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
@@ -149,21 +194,66 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
 			@Override
 			public void onItemSelected(String item) {
 				selectedFolder = item;
-				updateFileList(item, folderAdapter);
+				updateFileList(folderAdapter);
 			}
 		});
 		items.add(new BaseBottomSheetItem.Builder().setCustomView(mainView).create());
-		updateFileList(selectedFolder, folderAdapter);
+		updateFileList(folderAdapter);
 	}
 
-	private void updateFileList(String folderName, HorizontalSelectionAdapter folderAdapter) {
-		List gpxInfoList = gpxInfoMap.get(folderName);
+	private void updateDescription(TextView descriptionView) {
+		String string = getString(tracksSortBy.getNameId());
+		descriptionView.setText(String.format(getString(R.string.ltr_or_rtl_combine_via_space),
+				getString(fragmentMode.description),
+				Character.toLowerCase(string.charAt(0)) + string.substring(1)));
+	}
+
+	public MenuItem createMenuItem(OsmandApplication app, Menu m, int id, int titleRes, int iconId, int menuItemType,
+	                               boolean flipIconForRtl, int iconColor) {
+		Drawable d = iconId == 0 ? null : app.getUIUtilities().getIcon(iconId, iconColor);
+		MenuItem menuItem = m.add(0, id, 0, titleRes);
+		if (d != null) {
+			if (flipIconForRtl) {
+				d = AndroidUtils.getDrawableForDirection(app, d);
+			}
+			menuItem.setIcon(d);
+		}
+		return menuItem;
+	}
+
+	private void updateFileList(HorizontalSelectionAdapter folderAdapter) {
+		sortFileList();
 		adapter.setShowFolderName(showFoldersName());
-		adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList());
 		adapter.notifyDataSetChanged();
 		folderAdapter.notifyDataSetChanged();
 	}
 
+	private void sortFileList() {
+		List gpxInfoList = gpxInfoMap.get(selectedFolder);
+		sortSelected(gpxInfoList);
+		adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList());
+	}
+
+	public void sortSelected(List gpxInfoList) {
+		Collections.sort(gpxInfoList, new Comparator() {
+			@Override
+			public int compare(GPXInfo i1, GPXInfo i2) {
+				if (tracksSortBy == TracksSortByMode.BY_NAME_ASCENDING) {
+					return i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase());
+				} else if (tracksSortBy == TracksSortByMode.BY_NAME_DESCENDING) {
+					return -i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase());
+				} else {
+					long time1 = i1.getLastModified();
+					long time2 = i2.getLastModified();
+					if (time1 == time2) {
+						return i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase());
+					}
+					return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1));
+				}
+			}
+		});
+	}
+
 	private boolean showFoldersName() {
 		return allFilesFolder.equals(selectedFolder);
 	}
diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 3c396eccf4..ef184307e6 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -476,11 +476,12 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 		});
 
 		menu.addSubMenu(Menu.NONE, R.string.shared_string_sort, Menu.NONE, R.string.shared_string_sort);
-		SubMenu sortMenu = menu.findItem(R.string.shared_string_sort).getSubMenu();
+		final SubMenu sortMenu = menu.findItem(R.string.shared_string_sort).getSubMenu();
 		mi = sortMenu.getItem();
 		mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
-		mi.setIcon(getIcon(R.drawable.ic_sort_waypoint_dark, isLightActionBar() ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark));
-
+		final int iconColorId = isLightActionBar() ? R.color.active_buttons_and_links_text_light
+				: R.color.active_buttons_and_links_text_dark;
+		mi.setIcon(getIcon(sortByMode.getIconId(), iconColorId));
 		for (final TracksSortByMode mode : TracksSortByMode.values()) {
 			mi = createMenuItem(sortMenu, mode.getNameId(), mode.getNameId(), mode.getIconId(),
 					MenuItem.SHOW_AS_ACTION_ALWAYS, false, R.color.icon_color_default_light);
@@ -488,6 +489,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
 				@Override
 				public boolean onMenuItemClick(MenuItem item) {
 					updateTracksSort(mode);
+					sortMenu.setIcon(getIcon(mode.getIconId(), iconColorId));
 					return false;
 				}
 			});

From d6e4bd5b8bb5866858c1f7cc0f7f4b9e40b91279 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 15:55:02 +0300
Subject: [PATCH 0264/1366] Fix appromination gpx mode

---
 .../plus/measurementtool/MeasurementEditingContext.java      | 5 +----
 .../osmand/plus/measurementtool/MeasurementToolFragment.java | 4 ++--
 .../command/ApplyGpxApproximationCommand.java                | 1 +
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index b3db049d39..99e16baa7b 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -749,7 +749,7 @@ public class MeasurementEditingContext {
 		return params;
 	}
 
-	public List getDistinctRoutePoints() {
+	public List getRoutePoints() {
 		List res = new ArrayList<>();
 		List points = new ArrayList<>(before.points);
 		points.addAll(after.points);
@@ -759,9 +759,6 @@ public class MeasurementEditingContext {
 			RoadSegmentData data = this.roadSegmentData.get(pair);
 			if (data != null) {
 				res.addAll(data.points);
-				if (i < size - 2) {
-					res.remove(res.size() - 1);
-				}
 			}
 		}
 		return res;
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index bfe5394260..520e8fb424 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -1579,7 +1579,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 						if (saveType == SaveType.LINE) {
 							TrkSegment segment = new TrkSegment();
 							if (editingCtx.hasRoute()) {
-								segment.points.addAll(editingCtx.getDistinctRoutePoints());
+								segment.points.addAll(editingCtx.getRoutePoints());
 							} else {
 								segment.points.addAll(before.points);
 								segment.points.addAll(after.points);
@@ -1615,7 +1615,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 							if (saveType == SaveType.LINE) {
 								TrkSegment segment = new TrkSegment();
 								if (editingCtx.hasRoute()) {
-									segment.points.addAll(editingCtx.getDistinctRoutePoints());
+									segment.points.addAll(editingCtx.getRoutePoints());
 								} else {
 									segment.points.addAll(before.points);
 									segment.points.addAll(after.points);
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/command/ApplyGpxApproximationCommand.java b/OsmAnd/src/net/osmand/plus/measurementtool/command/ApplyGpxApproximationCommand.java
index 99488a753e..5198faedc3 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/command/ApplyGpxApproximationCommand.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/command/ApplyGpxApproximationCommand.java
@@ -45,6 +45,7 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
 		if (command instanceof ApplyGpxApproximationCommand) {
 			ApplyGpxApproximationCommand approxCommand = (ApplyGpxApproximationCommand) command;
 			approximation = approxCommand.approximation;
+			mode = approxCommand.mode;
 			applyApproximation();
 			refreshMap();
 			return true;

From a577b26e7f167d92c0a1c1f419e1ee1af1f2ea69 Mon Sep 17 00:00:00 2001
From: Nazar-Kutz 
Date: Tue, 22 Sep 2020 16:00:37 +0300
Subject: [PATCH 0265/1366] Fix #9623

---
 .../net/osmand/plus/ContextMenuAdapter.java   | 19 ++++++-
 .../osmand/plus/dashboard/DashboardOnMap.java | 27 +++++++++-
 .../osmand/plus/dialogs/ConfigureMapMenu.java | 50 ++++++++++++++++---
 .../osmand/plus/render/RendererRegistry.java  | 31 +++++++++++-
 .../fragments/ConfigureMenuItemsFragment.java |  2 +-
 .../fragments/ConfigureMenuRootFragment.java  |  2 +-
 6 files changed, 119 insertions(+), 12 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java
index 7263f119bd..3ea7eee4d7 100644
--- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java
@@ -65,6 +65,7 @@ public class ContextMenuAdapter {
 	@LayoutRes
 	private int DEFAULT_LAYOUT_ID = R.layout.list_menu_item_native;
 	List items = new ArrayList<>();
+	private ArrayAdapter arrayAdapter;
 	private boolean profileDependent = false;
 	private boolean nightMode;
 	private ConfigureMapMenu.OnClickListener changeAppModeListener = null;
@@ -100,6 +101,15 @@ public class ContextMenuAdapter {
 		return items.get(position);
 	}
 
+	public ContextMenuItem getItemById(@NonNull String id) {
+		for (ContextMenuItem item : items) {
+			if (id.equals(item.getId())) {
+				return item;
+			}
+		}
+		return null;
+	}
+
 	public List getItems() {
 		return items;
 	}
@@ -192,8 +202,9 @@ public class ContextMenuAdapter {
 			}
 		}
 		items.removeAll(itemsToRemove);
-		return new ContextMenuArrayAdapter(activity, layoutId, R.id.title,
+		this.arrayAdapter = new ContextMenuArrayAdapter(activity, layoutId, R.id.title,
 				items.toArray(new ContextMenuItem[items.size()]), app, lightTheme, changeAppModeListener);
+		return this.arrayAdapter;
 	}
 
 	public class ContextMenuArrayAdapter extends ArrayAdapter {
@@ -616,6 +627,12 @@ public class ContextMenuAdapter {
 		return visible;
 	}
 
+	public void notifyDataSetChanged() {
+		if (this.arrayAdapter != null) {
+			this.arrayAdapter.notifyDataSetChanged();
+		}
+	}
+
 	public static OnItemDeleteAction makeDeleteAction(final OsmandPreference... prefs) {
 		return new OnItemDeleteAction() {
 			@Override
diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java
index 4c9b2a2c2b..74d61c7479 100644
--- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java
+++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java
@@ -130,6 +130,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
 
 	private ArrayAdapter listAdapter;
 	private OnItemClickListener listAdapterOnClickListener;
+	private DashboardStateListener dashboardStateListener;
 
 	private boolean visible = false;
 	private DashboardType visibleType;
@@ -567,7 +568,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
 		boolean appModeChanged = currentAppMode != previousAppMode;
 
 		boolean refresh = this.visibleType == type && !appModeChanged;
-		previousAppMode = currentAppMode;
+		this.previousAppMode = currentAppMode;
 		this.visibleType = type;
 		DashboardOnMap.staticVisible = visible;
 		DashboardOnMap.staticVisibleType = type;
@@ -657,9 +658,21 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
 				settings.MAPILLARY_FIRST_DIALOG_SHOWN.set(true);
 			}
 		}
+		notifyDashboardVisibilityStateListener(visible);
 		mapActivity.updateStatusBarColor();
 	}
 
+	private void notifyDashboardVisibilityStateListener(boolean visible) {
+		if (dashboardStateListener != null) {
+			if (visible) {
+				dashboardStateListener.onShowDashboard();
+			} else {
+				dashboardStateListener.onHideDashboard();
+				dashboardStateListener = null;
+			}
+		}
+	}
+
 	public void updateDashboard() {
 		if (visibleType == DashboardType.ROUTE_PREFERENCES) {
 			refreshContent(false);
@@ -705,7 +718,9 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
 		if (visibleType == DashboardType.CONFIGURE_SCREEN) {
 			cm = mapActivity.getMapLayers().getMapWidgetRegistry().getViewConfigureMenuAdapter(mapActivity);
 		} else if (visibleType == DashboardType.CONFIGURE_MAP) {
-			cm = new ConfigureMapMenu().createListAdapter(mapActivity);
+			ConfigureMapMenu configureMapMenu = new ConfigureMapMenu(mapActivity);
+			dashboardStateListener = configureMapMenu;
+			cm = configureMapMenu.createListAdapter(mapActivity);
 		} else if (visibleType == DashboardType.LIST_MENU) {
 			cm = mapActivity.getMapActions().createMainOptionsMenu();
 		} else if (visibleType == DashboardType.ROUTE_PREFERENCES) {
@@ -1315,4 +1330,12 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
 	@Override
 	public void routeWasFinished() {
 	}
+
+	public interface DashboardStateListener {
+
+		void onShowDashboard();
+
+		void onHideDashboard();
+
+	}
 }
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java
index 647eebeb4c..900ada6a20 100644
--- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java
+++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java
@@ -37,9 +37,11 @@ import net.osmand.plus.R;
 import net.osmand.plus.UiUtilities;
 import net.osmand.plus.activities.MapActivity;
 import net.osmand.plus.activities.SettingsActivity;
+import net.osmand.plus.dashboard.DashboardOnMap;
 import net.osmand.plus.inapp.InAppPurchaseHelper;
 import net.osmand.plus.poi.PoiUIFilter;
 import net.osmand.plus.render.RendererRegistry;
+import net.osmand.plus.render.RendererRegistry.OnChangeRenderingRuleListener;
 import net.osmand.plus.settings.backend.OsmandSettings;
 import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
 import net.osmand.plus.settings.backend.OsmandSettings.ListStringPreference;
@@ -98,8 +100,9 @@ import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_DETAI
 import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_HIDE;
 import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_ROUTES;
 
-public class ConfigureMapMenu {
+public class ConfigureMapMenu implements DashboardOnMap.DashboardStateListener {
 	private static final Log LOG = PlatformUtil.getLog(ConfigureMapMenu.class);
+	public static final String TAG = ConfigureMapMenu.class.getName();
 	public static final String HIKING_ROUTES_OSMC_ATTR = "hikingRoutesOSMC";
 	public static final String CURRENT_TRACK_COLOR_ATTR = "currentTrackColor";
 	public static final String CURRENT_TRACK_WIDTH_ATTR = "currentTrackWidth";
@@ -110,10 +113,17 @@ public class ConfigureMapMenu {
 	private int selectedLanguageIndex;
 	private boolean transliterateNames;
 
+	private MapActivity mapActivity;
+	private ContextMenuAdapter contextMenuAdapter;
+
 	public interface OnClickListener {
 		void onClick();
 	}
 
+	public ConfigureMapMenu(MapActivity mapActivity) {
+		this.mapActivity = mapActivity;
+	}
+
 	public ContextMenuAdapter createListAdapter(final MapActivity ma) {
 		OsmandApplication app = ma.getMyApplication();
 		boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
@@ -136,6 +146,7 @@ public class ConfigureMapMenu {
 		adapter.setNightMode(nightMode);
 		createLayersItems(customRules, adapter, ma, themeRes, nightMode);
 		createRenderingAttributeItems(customRules, adapter, ma, themeRes, nightMode);
+		this.contextMenuAdapter = adapter;
 		return adapter;
 	}
 
@@ -273,13 +284,17 @@ public class ConfigureMapMenu {
 		final OsmandSettings settings = app.getSettings();
 		final int selectedProfileColorRes = settings.APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode);
 		final int selectedProfileColor = ContextCompat.getColor(app, selectedProfileColorRes);
+		RendererRegistry rr = app.getRendererRegistry();
+		RenderingRulesStorage storage = rr.getCurrentSelectedRenderer();
+		String renderDescr = getRenderDescr(activity, storage);
 
 		adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_map_rendering, activity)
 				.setId(MAP_RENDERING_CATEGORY_ID)
 				.setCategory(true).setLayout(R.layout.list_group_title_with_switch).createItem());
 		adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_renderer, activity)
 				.setId(MAP_STYLE_ID)
-				.setDescription(getRenderDescr(activity)).setLayout(R.layout.list_item_single_line_descrition_narrow)
+				.setDescription(renderDescr)
+				.setLayout(R.layout.list_item_single_line_descrition_narrow)
 				.setIcon(R.drawable.ic_map).setListener(new ContextMenuAdapter.ItemClickListener() {
 					@Override
 					public boolean onContextMenuClick(final ArrayAdapter ad, int itemId,
@@ -942,13 +957,11 @@ public class ConfigureMapMenu {
 		dialog.show();
 	}
 
-	protected String getRenderDescr(final MapActivity activity) {
-		RendererRegistry rr = activity.getMyApplication().getRendererRegistry();
-		RenderingRulesStorage storage = rr.getCurrentSelectedRenderer();
+	protected String getRenderDescr(Context ctx, RenderingRulesStorage storage) {
 		if (storage == null) {
 			return "";
 		}
-		String translation = RendererRegistry.getTranslatedRendererName(activity, storage.getName());
+		String translation = RendererRegistry.getTranslatedRendererName(ctx, storage.getName());
 		return translation == null ? storage.getName() : translation;
 	}
 
@@ -1109,6 +1122,31 @@ public class ConfigureMapMenu {
 		}
 	}
 
+	@Override
+	public void onShowDashboard() {
+		getMyApplication().getRendererRegistry()
+				.addOnChangeRenderingRuleListener(TAG, new OnChangeRenderingRuleListener() {
+					@Override
+					public void onRenderingRuleChanged(RenderingRulesStorage currentSelectedRender) {
+						if (contextMenuAdapter != null) {
+							ContextMenuItem item = contextMenuAdapter.getItemById(MAP_STYLE_ID);
+							String renderDescr = getRenderDescr(mapActivity, currentSelectedRender);
+							item.setDescription(renderDescr);
+							contextMenuAdapter.notifyDataSetChanged();
+						}
+					}
+				});
+	}
+
+	@Override
+	public void onHideDashboard() {
+		getMyApplication().getRendererRegistry().removeOnChangeRenderingRuleListener(TAG);
+	}
+
+	private OsmandApplication getMyApplication() {
+		return mapActivity.getMyApplication();
+	}
+
 	private static class StringSpinnerArrayAdapter extends ArrayAdapter {
 
 		private boolean nightMode;
diff --git a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java
index 17dc572bc4..e20d90c27a 100644
--- a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java
+++ b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java
@@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -49,6 +50,7 @@ public class RendererRegistry {
 
 	private RenderingRulesStorage defaultRender = null;
 	private RenderingRulesStorage currentSelectedRender = null;
+	private Map onChangeRenderingRuleListeners = new HashMap<>();
 	
 	private Map externalRenderers = new LinkedHashMap();
 	private Map internalRenderers = new LinkedHashMap();
@@ -334,8 +336,22 @@ public class RendererRegistry {
 		return currentSelectedRender;
 	}
 	
-	public void setCurrentSelectedRender(RenderingRulesStorage currentSelectedRender) {
+	public void setCurrentSelectedRender(final RenderingRulesStorage currentSelectedRender) {
 		this.currentSelectedRender = currentSelectedRender;
+		notifyChangeRenderRuleListeners();
+	}
+
+	public void notifyChangeRenderRuleListeners() {
+		app.runInUIThread(new Runnable() {
+			@Override
+			public void run() {
+				for (OnChangeRenderingRuleListener listener : onChangeRenderingRuleListeners.values()) {
+					if (listener != null) {
+						listener.onRenderingRuleChanged(currentSelectedRender);
+					}
+				}
+			}
+		});
 	}
 
     public void setRendererLoadedEventListener(IRendererLoadedEventListener listener) {
@@ -361,4 +377,17 @@ public class RendererRegistry {
 	public Map getExternalRenderers() {
 		return externalRenderers;
 	}
+
+	public void addOnChangeRenderingRuleListener(@NonNull String key,
+	                                             @NonNull OnChangeRenderingRuleListener listener) {
+		onChangeRenderingRuleListeners.put(key, listener);
+	}
+
+	public void removeOnChangeRenderingRuleListener(@NonNull String key) {
+		onChangeRenderingRuleListeners.remove(key);
+	}
+
+	public interface OnChangeRenderingRuleListener {
+		void onRenderingRuleChanged(RenderingRulesStorage currentSelectedRender);
+	}
 }
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java
index 44fb4bf7f6..43cd0d59eb 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java
@@ -197,7 +197,7 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment
 					contextMenuAdapter = ((MapActivity) activity).getMapActions().createMainOptionsMenu();
 					break;
 				case CONFIGURE_MAP:
-					ConfigureMapMenu configureMapMenu = new ConfigureMapMenu();
+					ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity)activity);
 					contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity);
 					break;
 				case CONTEXT_MENU_ACTIONS:
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java
index 330f1c0a18..b47a761e8b 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java
@@ -285,7 +285,7 @@ public class ConfigureMenuRootFragment extends BaseOsmAndFragment {
 						contextMenuAdapter = mapActivityActions.createMainOptionsMenu();
 						break;
 					case CONFIGURE_MAP:
-						ConfigureMapMenu configureMapMenu = new ConfigureMapMenu();
+						ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity) activity);
 						contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity);
 						break;
 					case CONTEXT_MENU_ACTIONS:

From a5610b73520e8125ae3f095e0f2432306234d5cc Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 22 Sep 2020 16:13:40 +0300
Subject: [PATCH 0266/1366] Minor fixes in plan route and follow track

---
 .../MeasurementToolFragment.java              | 20 ++++++++++---------
 .../FollowTrackFragment.java                  | 15 ++++++++++++--
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 520e8fb424..7d6818a9d6 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -536,7 +536,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 			editingCtx.getCommandManager().setMeasurementLayer(mapActivity.getMapLayers().getMeasurementToolLayer());
 			enterMeasurementMode();
 			updateSnapToRoadControls();
-			if (gpxData != null) {
+			if (gpxData != null && addPoints) {
 				if (!isUndoMode()) {
 					List points = gpxData.getGpxFile().getRoutePoints();
 					if (!points.isEmpty()) {
@@ -546,13 +546,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 						}
 					}
 				}
-				if (addPoints) {
-					ActionType actionType = gpxData.getActionType();
-					if (actionType == ActionType.ADD_ROUTE_POINTS) {
-						displayRoutePoints();
-					} else if (actionType == ActionType.EDIT_SEGMENT) {
-						displaySegmentPoints();
-					}
+				ActionType actionType = gpxData.getActionType();
+				if (actionType == ActionType.ADD_ROUTE_POINTS) {
+					displayRoutePoints();
+				} else if (actionType == ActionType.EDIT_SEGMENT) {
+					displaySegmentPoints();
 				}
 			}
 			setMode(UNDO_MODE, false);
@@ -807,7 +805,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
 
 	@Override
 	public void saveChangesOnClick() {
-		saveChanges(FinalSaveAction.SHOW_TOAST, true);
+		if (isFollowTrackMode()) {
+			startTrackNavigation();
+		} else {
+			saveChanges(FinalSaveAction.SHOW_TOAST, true);
+		}
 	}
 
 	@Override
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
index 544d073ca7..6507ff8d2d 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
@@ -63,6 +63,7 @@ import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
 import net.osmand.plus.routing.RoutingHelper;
 import net.osmand.plus.settings.backend.ApplicationMode;
 import net.osmand.plus.views.layers.MapControlsLayer;
+import net.osmand.util.Algorithms;
 
 import org.apache.commons.logging.Log;
 
@@ -185,8 +186,18 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
 
 				setupTracksCard();
 			} else {
-				File file = new File(gpxFile.path);
-				GPXInfo gpxInfo = new GPXInfo(gpxFile.path, file.lastModified(), file.length());
+				String fileName = null;
+				File file = null;
+				if (!Algorithms.isEmpty(gpxFile.path)) {
+					file = new File(gpxFile.path);
+					fileName = file.getName();
+				} else if (!Algorithms.isEmpty(gpxFile.tracks)) {
+					fileName = gpxFile.tracks.get(0).name;
+				}
+				if (Algorithms.isEmpty(fileName)) {
+					fileName = app.getString(R.string.shared_string_gpx_track);
+				}
+				GPXInfo gpxInfo = new GPXInfo(fileName, file != null ? file.lastModified() : 0, file != null ? file.length() : 0);
 				TrackEditCard importTrackCard = new TrackEditCard(mapActivity, gpxInfo);
 				importTrackCard.setListener(this);
 				cardsContainer.addView(importTrackCard.build(mapActivity));

From 5acf6e27f7bac41c75ea67a18f71d07b435bf5a3 Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 22 Sep 2020 16:55:01 +0300
Subject: [PATCH 0267/1366] Hide extra description and remove unnecessary
 changes

---
 .../net/osmand/plus/activities/MapActivityActions.java   | 4 +---
 .../plus/routepreparationmenu/MapRouteInfoMenu.java      | 9 +++++++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 5414b9c0f7..dbd0f133fa 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -525,9 +525,7 @@ public class MapActivityActions implements DialogProvider {
 				TargetPointsHelper tg = mapActivity.getMyApplication().getTargetPointsHelper();
 				tg.clearStartPoint(false);
 				Location finishLoc = ps.get(ps.size() - 1);
-				PointDescription point = new PointDescription(PointDescription.POINT_TYPE_LOCATION, result.path, "");
-				point.setName(PointDescription.getSearchAddressStr(mapActivity));
-				tg.navigateToPoint(new LatLon(finishLoc.getLatitude(), finishLoc.getLongitude()), false, -1, point);
+				tg.navigateToPoint(new LatLon(finishLoc.getLatitude(), finishLoc.getLongitude()), false, -1);
 			}
 		}
 	}
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
index f0216f1c9d..69bed394cc 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
@@ -1760,8 +1760,13 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
 			if (routeParams != null) {
 				TargetPoint target = app.getTargetPointsHelper().getPointToNavigate();
 				if (target != null) {
-					PointDescription pointDescription = target.getOriginalPointDescription();
-					return pointDescription != null && routeParams.getFile().path.equals(pointDescription.getTypeName());
+					List points = routeParams.getPoints(app);
+					if (!Algorithms.isEmpty(points)) {
+						Location loc = points.get(points.size() - 1);
+						LatLon latLon = new LatLon(loc.getLatitude(), loc.getLongitude());
+						LatLon targetLatLon = new LatLon(target.getLatitude(), target.getLongitude());
+						return latLon.equals(targetLatLon);
+					}
 				}
 			}
 		}

From e6a7f5f22857409486a3ef94196050a0547de16c Mon Sep 17 00:00:00 2001
From: Vitaliy 
Date: Tue, 22 Sep 2020 17:13:51 +0300
Subject: [PATCH 0268/1366] Fix check for attach route card

---
 .../osmand/plus/routepreparationmenu/FollowTrackFragment.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
index 6507ff8d2d..ee2bf6b38e 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
@@ -218,7 +218,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
 						reverseTrackCard.setListener(this);
 						cardsContainer.addView(reverseTrackCard.build(mapActivity));
 					}
-					if (!gpxFile.hasRtePt()) {
+					if (!gpxFile.hasRtePt() && !gpxFile.hasRoute()) {
 						cardsContainer.addView(buildDividerView(cardsContainer, true));
 
 						AttachTrackToRoadsCard attachTrackCard = new AttachTrackToRoadsCard(mapActivity);

From e64b8645833a1731b58bf0447c46b3fa226e4020 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 17:21:06 +0300
Subject: [PATCH 0269/1366] Fix exported route when opened by plan route

---
 .../plus/measurementtool/MeasurementEditingContext.java       | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index 99e16baa7b..c8e0ff043b 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -474,6 +474,10 @@ public class MeasurementEditingContext {
 			List segments = routeImporter.importRoute();
 			List routePoints = gpxData.getGpxFile().getRoutePoints();
 			int prevPointIndex = 0;
+			if (routePoints.isEmpty() && points.size() > 1) {
+				routePoints.add(points.get(0));
+				routePoints.add(points.get(points.size() - 1));
+			}
 			for (int i = 0; i < routePoints.size() - 1; i++) {
 				Pair pair = new Pair<>(routePoints.get(i), routePoints.get(i + 1));
 				int startIndex = pair.first.getTrkPtIndex();

From 5252d179d0e1174d06ce751ae5470d5576e0e9d7 Mon Sep 17 00:00:00 2001
From: simon 
Date: Tue, 22 Sep 2020 17:32:18 +0300
Subject: [PATCH 0270/1366] test added

---
 .../java/net/osmand/router/RouteTestingTest.java | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java b/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
index b4f343da62..cf43602528 100644
--- a/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
+++ b/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
@@ -15,6 +15,7 @@ import java.util.TreeSet;
 
 import net.osmand.binary.BinaryMapIndexReader;
 
+import net.osmand.data.LatLon;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -62,9 +63,20 @@ public class RouteTestingTest {
 		RandomAccessFile raf = new RandomAccessFile(fl, "r");
 		RoutePlannerFrontEnd fe = new RoutePlannerFrontEnd();
 
-		BinaryMapIndexReader[] binaryMapIndexReaders = { new BinaryMapIndexReader(raf, new File(fl)) };
+		BinaryMapIndexReader[] binaryMapIndexReaders;// = { new BinaryMapIndexReader(raf, new File(fl)) };
 		RoutingConfiguration.Builder builder = RoutingConfiguration.getDefault();
 		Map params = te.getParams();
+		if (params.containsKey("map")){
+			String fl1 = "src/test/resources/" + params.get("map");
+			RandomAccessFile raf1 = new RandomAccessFile(fl1, "r");
+			binaryMapIndexReaders = new BinaryMapIndexReader[]{
+					new BinaryMapIndexReader(raf1, new File(fl1)),
+					new BinaryMapIndexReader(raf, new File(fl))
+			};
+		}
+		else {
+			binaryMapIndexReaders = new BinaryMapIndexReader[]{new BinaryMapIndexReader(raf, new File(fl))};
+		}
 		RoutingConfiguration config = builder.build(params.containsKey("vehicle") ? params.get("vehicle") : "car",
 				RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, params);
 		RoutingContext ctx = fe.buildRoutingContext(config, null, binaryMapIndexReaders,
@@ -102,6 +114,4 @@ public class RouteTestingTest {
 
 	}
 
-
-
 }

From 71827daeea1c379262ff173621d1ed5cef9da44e Mon Sep 17 00:00:00 2001
From: simon 
Date: Tue, 22 Sep 2020 17:32:25 +0300
Subject: [PATCH 0271/1366] test added

---
 .../net/osmand/router/RouteTestingTest.java   | 53 +++++++++----------
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java b/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
index cf43602528..06e6ef8fda 100644
--- a/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
+++ b/OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
@@ -30,34 +30,34 @@ public class RouteTestingTest {
 	private TestEntry te;
 
 
-    public RouteTestingTest(String name, TestEntry te) {
-        this.te = te;
-    }
+	public RouteTestingTest(String name, TestEntry te) {
+		this.te = te;
+	}
 
-    @BeforeClass
-    public static void setUp() throws Exception {
-        RouteResultPreparation.PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
-    }
+	@BeforeClass
+	public static void setUp() throws Exception {
+		RouteResultPreparation.PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
+	}
 
-    @Parameterized.Parameters(name = "{index}: {0}")
-    public static Iterable data() throws IOException {
-        String fileName = "/test_routing.json";
-        Reader reader = new InputStreamReader(RouteTestingTest.class.getResourceAsStream(fileName));
-        Gson gson = new GsonBuilder().setPrettyPrinting().create();
-        TestEntry[] testEntries = gson.fromJson(reader, TestEntry[].class);
-        ArrayList arrayList = new ArrayList<>();
-        for(TestEntry te : testEntries) {
-        	if(te.isIgnore()) {
-        		continue;
-        	}
-        	arrayList.add(new Object[] {te.getTestName(), te});
-        }
-        reader.close();
-        return arrayList;
+	@Parameterized.Parameters(name = "{index}: {0}")
+	public static Iterable data() throws IOException {
+		String fileName = "/test_routing.json";
+		Reader reader = new InputStreamReader(RouteTestingTest.class.getResourceAsStream(fileName));
+		Gson gson = new GsonBuilder().setPrettyPrinting().create();
+		TestEntry[] testEntries = gson.fromJson(reader, TestEntry[].class);
+		ArrayList arrayList = new ArrayList<>();
+		for (TestEntry te : testEntries) {
+			if (te.isIgnore()) {
+				continue;
+			}
+			arrayList.add(new Object[]{te.getTestName(), te});
+		}
+		reader.close();
+		return arrayList;
 
-    }
+	}
 
-    @Test
+	@Test
 	public void testRouting() throws Exception {
 		String fl = "src/test/resources/Routing_test.obf";
 		RandomAccessFile raf = new RandomAccessFile(fl, "r");
@@ -66,15 +66,14 @@ public class RouteTestingTest {
 		BinaryMapIndexReader[] binaryMapIndexReaders;// = { new BinaryMapIndexReader(raf, new File(fl)) };
 		RoutingConfiguration.Builder builder = RoutingConfiguration.getDefault();
 		Map params = te.getParams();
-		if (params.containsKey("map")){
+		if (params.containsKey("map")) {
 			String fl1 = "src/test/resources/" + params.get("map");
 			RandomAccessFile raf1 = new RandomAccessFile(fl1, "r");
 			binaryMapIndexReaders = new BinaryMapIndexReader[]{
 					new BinaryMapIndexReader(raf1, new File(fl1)),
 					new BinaryMapIndexReader(raf, new File(fl))
 			};
-		}
-		else {
+		} else {
 			binaryMapIndexReaders = new BinaryMapIndexReader[]{new BinaryMapIndexReader(raf, new File(fl))};
 		}
 		RoutingConfiguration config = builder.build(params.containsKey("vehicle") ? params.get("vehicle") : "car",

From 77f75dd08a11d5acc6d55614695bf1213b33eef0 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 18:03:41 +0300
Subject: [PATCH 0272/1366] Fix invisible alert dialog buttons when no
 animation

---
 OsmAnd/res/values/styles.xml | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values/styles.xml b/OsmAnd/res/values/styles.xml
index e52dbdfd56..ea305b19d2 100644
--- a/OsmAnd/res/values/styles.xml
+++ b/OsmAnd/res/values/styles.xml
@@ -355,12 +355,12 @@
     
 
     
 
     
 
     
 
-    
 
-    
 

From f1b754760913593187f35c6260c924e0e5cfc6d7 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 18:03:41 +0300
Subject: [PATCH 0273/1366] Fix invisible alert dialog buttons when no
 animation

---
 OsmAnd/res/values/styles.xml | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/OsmAnd/res/values/styles.xml b/OsmAnd/res/values/styles.xml
index e52dbdfd56..ea305b19d2 100644
--- a/OsmAnd/res/values/styles.xml
+++ b/OsmAnd/res/values/styles.xml
@@ -355,12 +355,12 @@
     
 
     
 
     
 
     
 
-    
 
-    
 

From 201245090238d2d523ae0734109ac5cb803ec0f3 Mon Sep 17 00:00:00 2001
From: Ldm Public 
Date: Tue, 22 Sep 2020 12:27:10 +0000
Subject: [PATCH 0274/1366] Translated using Weblate (French)

Currently translated at 99.9% (3486 of 3487 strings)
---
 OsmAnd/res/values-fr/strings.xml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml
index 408aa58e53..bfe4fe6318 100644
--- a/OsmAnd/res/values-fr/strings.xml
+++ b/OsmAnd/res/values-fr/strings.xml
@@ -3880,4 +3880,7 @@
     Modifier le type d’itinéraire après
     Seule la ligne d\'itinéraire sera enregistrée, les points de passage seront supprimés.
     Rétablir
+    Dernière modification
+    Nom : Z – A
+    Nom : A – Z
 
\ No newline at end of file

From 93fd2265f9d748355a89f10e8158aaf7e66930fd Mon Sep 17 00:00:00 2001
From: Deelite <556xxy@gmail.com>
Date: Tue, 22 Sep 2020 14:50:25 +0000
Subject: [PATCH 0275/1366] Translated using Weblate (Russian)

Currently translated at 99.9% (3484 of 3487 strings)
---
 OsmAnd/res/values-ru/strings.xml | 42 +++++++++++++++-----------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index baa3bce085..d77acfa3aa 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -185,7 +185,7 @@
     Старый поиск
     Показывать старый поиск
     Добавить старый поиск в меню.
-    Использовать автомагистрали
+    Разрешить автомагистрали
     Разрешает автомагистрали.
     Статьи Википедии рядом
     Город или регион
@@ -309,16 +309,16 @@
     Формат вывода видео
     Использовать системное приложение для записи видео.
     Использовать системную программу
-    Установка настроек аудио и видео.
+    Параметры записи звука и видео.
     Ошибка записи
     Камера недоступна
-    Аудио/видео записывается. Для остановки нажмите виждет AV.
+    Идёт запись медиа. Для остановки нажмите на виджет AV.
     Проигрывается аудио.\n%1$s
     Открыть внешний проигрыватель
     Удалить эту запись?
     недоступно
-    Записать аудио
-    Записать видео
+    Аудиозаметка
+    Видеозаметка
     Слой аудиозаписей
     Запись не может быть воспроизведена.
     Удалить запись
@@ -330,8 +330,8 @@
     Измерение расстояний
     Нажмите «Использовать местоположение…» чтобы добавить заметку к данному местоположению.
     Аудиозаметки
-    Делайте аудио/фото/видеозаметки во время поездки, используя либо кнопку на карте, либо контекстное меню местоположения.
-    Аудио/видеозаметки
+    Создавайте аудио-, видео- и фотозаметки в поездке, используя виджет или контекстное меню.
+    Медиазаметки
     частей
     Линии высот
     Контурные линии
@@ -1203,13 +1203,13 @@
     Просмотр
     Сделать фото
     Сделать фото
-    Синхронизация треков и видео/аудиозаметок с вашим аккаунтом Dropbox.
+    Синхронизация треков и медиазаметок с вашим аккаунтом Dropbox.
     Плагин Dropbox
     Плагин обеспечивает наложение контурных линии и (рельефа) затемняющего слоя, которые будут отображаться поверх стандартных карт OsmAnd. Эта функция высоко оценится спортсменами, туристами, путешественниками и всеми, кто заинтересован в рельефной структуре ландшафта.
 \n 
 \nГлобальные данные (между 70° на севере и 70° на юге) основываются на измерениях SRTM (Shuttle Radar Topography Mission) и ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer), инструментом визуализации Terra, флагманского спутника Земли системы наблюдения NASA. ASTER является результатом совместных усилий NASA, министерства экономики Японии, торговли и промышленности (METI), космических систем Японии (J-spacesystems).
     Фото %1$s %2$s
-    Аудио/видеоданные
+    Медиаданные
     Остановить навигацию\?
     Вы уверены, что хотите удалить пункт назначения (и промежуточные пункты)?
     Точный маршрут (альфа)
@@ -1317,8 +1317,8 @@
     США
     Европа, Азия, Латинская Америка и тому подобное
     Великобритания, Индия и др.
-    Маршрут сюда
-    Маршрут отсюда
+    Маршрут до этой точки
+    Маршрут от этой точки
     Канада
     Версия:
     Время действия (в минутах): %1$s
@@ -2624,7 +2624,7 @@
     Нажатие на маркер на карте переместит его на первое место в списке активных маркеров, не открывая контекстное меню.
     Активация одним нажатием
     Делайте заметки!
-    Добавьте аудио-, видео- или фотозаметку в любую точку на карте, используя виджет или контекстное меню.
+    Добавьте аудио-, видео- или фотозаметки в любую точку на карте, используя виджет или контекстное меню.
     Заметки по дате
     По дате
     По типу
@@ -3061,7 +3061,7 @@
     Нет, спасибо
     Разрешить
     Имя профиля
-    Тип навигации
+    Режим навигации
     Такси
     Метро
     Лошадь
@@ -3071,8 +3071,8 @@
     Лыжи
     Тип: %s
     Базовый профиль
-    Выберите тип навигации
-    Выберите тип навигации для нового профиля
+    Выберите режим навигации
+    Выберите режим навигации для нового профиля
     Введите имя профиля
     Сначала необходимо указать имя профиля.
     Уже есть профиль с таким именем
@@ -3087,7 +3087,7 @@
     Вы действительно хотите удалить профиль «%s»
     Выберите профиль для начала
     Основывайте свой пользовательский профиль на одном из профилей приложения по умолчанию, это определяет базовые настройки, такие как видимость виджетов по умолчанию и выбор единиц измерения скорости и расстояния. Ниже перечислены профили приложений по умолчанию, а также примеры пользовательских профилей, на которые они могут быть расширены:
-    Выберите тип навигации
+    Выберите режим навигации
     Автомобиль, грузовик, мотоцикл
     Горный велосипед, мопед, лошадь
     Прогулки, пеший туризм, бег
@@ -3238,7 +3238,7 @@
     Голосовые подсказки
     Экранные оповещения
     Настройка параметров маршрута
-    Параметры маршрута
+    Маршрутизация
     Буфер Logcat
     Настройки плагинов
     Язык и вывод
@@ -3349,7 +3349,7 @@
     Выберите цвет
     Вы не можете удалить стандартные профили OsmAnd, но вы можете отключить их на предыдущем экране или переместить вниз.
     Редактировать профили
-    «Тип навигации» определяет способ расчета маршрутов.
+    Режим навигации определяет правила расчета маршрутов.
     Внешний вид профиля
     Значок, цвет и имя
     Редактировать список профилей
@@ -3828,9 +3828,7 @@
     Профиль будет применён только к следующему сегменту.
     Следующий сегмент
     Весь трек
-    Для использования данной возможности OsmAnd необходимо привязать ваш трек по дорогам.
-\n
-\nНа следующем шаге необходимо выбрать профиль навигации для определения разрешённых дорог и пороговое расстояние, чтобы приблизительно привязать маршрут к дорогам.
+    Далее необходимо выбрать профиль навигации для определения порогового расстояния и привязки маршрута к ближайшей разрешённой дороге.
     Выберите способ соединения точек прямой линией или рассчитайте маршрут между ними, как указано ниже.
     При обратном направлении
     Все изменения будут утеряны.
@@ -3900,4 +3898,4 @@
 \n • Исправлены проблемы с импортом/экспортом настроек профиля
 \n
 \n
-
+
\ No newline at end of file

From 28031b3665750c6a5916b664a302af81189d0e02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Tue, 22 Sep 2020 12:43:39 +0000
Subject: [PATCH 0276/1366] Translated using Weblate (Turkish)

Currently translated at 100.0% (3487 of 3487 strings)
---
 OsmAnd/res/values-tr/strings.xml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml
index 88d2ecc725..9713a69b10 100644
--- a/OsmAnd/res/values-tr/strings.xml
+++ b/OsmAnd/res/values-tr/strings.xml
@@ -3856,4 +3856,7 @@
 \n • Profil ayarlarının içe/dışa aktarımıyla ilgili sorunlar düzeltildi
 \n
 \n
+    Son değiştirme
+    İsim: Z – A
+    İsim: A – Z
 
\ No newline at end of file

From 7cb6a947db6e3808d3b1b6b4ab8ce94c37cab1c7 Mon Sep 17 00:00:00 2001
From: Yaron Shahrabani 
Date: Tue, 22 Sep 2020 14:01:57 +0000
Subject: [PATCH 0277/1366] Translated using Weblate (Hebrew)

Currently translated at 100.0% (3487 of 3487 strings)
---
 OsmAnd/res/values-iw/strings.xml | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml
index afc41fbb36..7f556c9926 100644
--- a/OsmAnd/res/values-iw/strings.xml
+++ b/OsmAnd/res/values-iw/strings.xml
@@ -3838,9 +3838,7 @@
     כל המסלול יחושב מחדש באמצעות הפרופיל הנבחר.
     רק המקטע הבא יחושב מחודש באמצעות הפרופיל הנבחר.
     נא לבחור כיצד לחבר נקודות, בקו ישר, או לחבר מסלול ביניהן כפי שצוין להלן.
-    כדי להשתמש באפשרות זו על OsmAnd להצמיד את המסלול שלך לדרכים שעל המפה.
-\n
-\n בשלב הבא יהיה עליך לבחור בפרופיל ניווט כדי לזהות את הדרכים המורשות ואת סף המרחק כדי להעריך את המסלול שלך ביחס לדרכים.
+    בשלב הבא עליך להצמיד את הדרך המורשית הקרובה ביותר לאחד מפרופילי הניווט שלך כדי להשתמש באפשרות הזו.
     תמונות ברמת רחוב
     להתעלם מהשינויים במסלול המתוכנן על ידי סגירתו\?
     במקרה של כיוון הפוך
@@ -3893,4 +3891,22 @@
     נשמר
     נא להוסיף שתי נקודות לפחות.
     ביצוע מחדש
+    • פונקציית תכנון המסלול עודכנה: מאפשרת שימוש בסוגי ניווט שונים לפי מקטע והכללת מסלולית
+\n
+\n • תפריט מראה חדש למסלולים: ניתן לבחור צבע, עובי, להציג חצי כיוון, סמלי התחלה/סיום
+\n
+\n • אופן הצגת שבילי האופניים השתפר.
+\n
+\n • אפשר לגעת במסלולים, יש להם גם תפריט הקשר עם מידע בסיסי.
+\n
+\n • אלגוריתמי החיפוש השתפרו
+\n
+\n • אפשרות המעקב אחר המסלול בניווט השתפרה
+\n
+\n • תוקנו תקלות בייבוא/ייצוא הגדרות פרופיל
+\n
+\n
+    שינוי אחרון
+    שם: ת – א
+    שם: א – ת
 
\ No newline at end of file

From 9e31931b9ddc0d4014f7a8cd0b55ec25939065dd Mon Sep 17 00:00:00 2001
From: Franco 
Date: Tue, 22 Sep 2020 12:37:36 +0000
Subject: [PATCH 0278/1366] Translated using Weblate (Spanish (Argentina))

Currently translated at 100.0% (3487 of 3487 strings)
---
 OsmAnd/res/values-es-rAR/strings.xml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml
index 6b55481e6e..99f789d362 100644
--- a/OsmAnd/res/values-es-rAR/strings.xml
+++ b/OsmAnd/res/values-es-rAR/strings.xml
@@ -1129,7 +1129,7 @@
     El idioma elegido es incompatible con el motor TTS (texto a voz) instalado en Android, se usará el idioma TTS predefinido. ¿Buscar otro motor TTS en la tienda de aplicaciones\?
     Faltan datos
     ¿Ir a la tienda de aplicaciones para descargar el idioma elegido?
-    Invertir la dirección GPX
+    Invertir la dirección de la traza
     Usar destino actual
     Pasar a lo largo de la traza completa
     Mapa vectorial presente para esta ubicación. 
@@ -3904,4 +3904,7 @@
 \n • Se han solucionado los problemas de la importación y exportación en los ajustes de los perfiles
 \n
 \n
+    Último modificado
+    Nombre: Z – A
+    Nombre: A – Z
 
\ No newline at end of file

From 15240ccef463f7d91d10bbae97ad67794a0f9b94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= 
Date: Tue, 22 Sep 2020 13:12:34 +0000
Subject: [PATCH 0279/1366] Translated using Weblate (Turkish)

Currently translated at 62.8% (2405 of 3824 strings)
---
 OsmAnd/res/values-tr/phrases.xml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml
index ce16c3b5ef..76b5305843 100644
--- a/OsmAnd/res/values-tr/phrases.xml
+++ b/OsmAnd/res/values-tr/phrases.xml
@@ -2406,4 +2406,14 @@
     Küçük elektrikli aletler
     Kalkış bilgileri panosu
     İçme suyu doldurma
+    İstihkam türü: dairesel hendek
+    İstihkam türü: küçük set
+    İstihkam türü: limes
+    İstihkam türü: tepe kalesi
+    Megalit türü: geçit mezar
+    Megalit türü: taş çember
+    Megalit türü: nuraghe
+    Megalit türü: dolmen
+    Megalit türü: menhir
+    Toprak işi
 
\ No newline at end of file

From c65e91561f2267705d151249fcb1c9dd9f663ba0 Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 19:53:19 +0300
Subject: [PATCH 0280/1366] Fix initial search radius for nearest POIs

---
 .../java/net/osmand/search/core/SearchCoreFactory.java | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
index 360fafbdf9..e5c791a780 100644
--- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
+++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
@@ -923,6 +923,7 @@ public class SearchCoreFactory {
 
 	public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
 		private static final int BBOX_RADIUS = 10000;
+		private static final int BBOX_RADIUS_NEAREST = 1000;
 		private SearchAmenityTypesAPI searchAmenityTypesAPI;
 		private MapPoiTypes types;
 		private AbstractPoiType unselectedPoiType;
@@ -1007,7 +1008,14 @@ public class SearchCoreFactory {
 			}
 			this.nameFilter = nameFilter;
 			if (poiTypeFilter != null) {
-				QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS);
+				int radius = BBOX_RADIUS;
+				if (phrase.getRadiusLevel() == 1 && poiTypeFilter instanceof CustomSearchPoiFilter) {
+					String name = ((CustomSearchPoiFilter) poiTypeFilter).getFilterId();
+					if ("std_null".equals(name)) {
+						radius = BBOX_RADIUS_NEAREST;
+					}
+				}
+				QuadRect bbox = phrase.getRadiusBBoxToSearch(radius);
 				List offlineIndexes = phrase.getOfflineIndexes();
 				Set searchedPois = new TreeSet<>();
 				for (BinaryMapIndexReader r : offlineIndexes) {

From 02faad80aeba0745f1b45a2f397dda6fdc95abbe Mon Sep 17 00:00:00 2001
From: max-klaus 
Date: Tue, 22 Sep 2020 19:53:19 +0300
Subject: [PATCH 0281/1366] Fix initial search radius for nearest POIs

---
 .../java/net/osmand/search/core/SearchCoreFactory.java | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
index 360fafbdf9..e5c791a780 100644
--- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
+++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java
@@ -923,6 +923,7 @@ public class SearchCoreFactory {
 
 	public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
 		private static final int BBOX_RADIUS = 10000;
+		private static final int BBOX_RADIUS_NEAREST = 1000;
 		private SearchAmenityTypesAPI searchAmenityTypesAPI;
 		private MapPoiTypes types;
 		private AbstractPoiType unselectedPoiType;
@@ -1007,7 +1008,14 @@ public class SearchCoreFactory {
 			}
 			this.nameFilter = nameFilter;
 			if (poiTypeFilter != null) {
-				QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS);
+				int radius = BBOX_RADIUS;
+				if (phrase.getRadiusLevel() == 1 && poiTypeFilter instanceof CustomSearchPoiFilter) {
+					String name = ((CustomSearchPoiFilter) poiTypeFilter).getFilterId();
+					if ("std_null".equals(name)) {
+						radius = BBOX_RADIUS_NEAREST;
+					}
+				}
+				QuadRect bbox = phrase.getRadiusBBoxToSearch(radius);
 				List offlineIndexes = phrase.getOfflineIndexes();
 				Set searchedPois = new TreeSet<>();
 				for (BinaryMapIndexReader r : offlineIndexes) {

From 709f91ab0aa2f69d838792cc6ff25f55feae7e4b Mon Sep 17 00:00:00 2001
From: Dmitriy Prodchenko 
Date: Wed, 23 Sep 2020 10:23:52 +0300
Subject: [PATCH 0282/1366] Update 3-bug-report.md

---
 .github/ISSUE_TEMPLATE/3-bug-report.md | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md
index ecf870be10..c30c5ccaf7 100644
--- a/.github/ISSUE_TEMPLATE/3-bug-report.md
+++ b/.github/ISSUE_TEMPLATE/3-bug-report.md
@@ -22,25 +22,25 @@ Please give us the following information so that we can try to **reproduce** you
 
 🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
 
-# 🐞 bug report
+## 🐞 Bug report
 
-### Is this a regression?
+##### Is this a regression?
 
 
  Yes, the previous version in which this bug was not present was: ....
 
-### Description
+##### Description
 
 
 
-## 🔬 Minimal Reproduction
+##### Minimal Reproduction
 
 
  1. Open app, and click on ...
 
-## 🔥 Exception or Error
+##### Exception or Error
 
 

 
@@ -48,7 +48,7 @@ If the bug is reproducible, please describe steps below:
 
 
-## 🌍 Your Environment +##### Your Environment **OsmAnd Version:** From b2e705f21c6f1a20e07aa3e39662fc5698ad8141 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Wed, 23 Sep 2020 10:31:19 +0300 Subject: [PATCH 0283/1366] Update 3-bug-report.md --- .github/ISSUE_TEMPLATE/3-bug-report.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md index c30c5ccaf7..aac6f3b299 100644 --- a/.github/ISSUE_TEMPLATE/3-bug-report.md +++ b/.github/ISSUE_TEMPLATE/3-bug-report.md @@ -29,18 +29,18 @@ Please give us the following information so that we can try to **reproduce** you Yes, the previous version in which this bug was not present was: .... -##### Description +### Description -##### Minimal Reproduction +##### How to reproduce? 1. Open app, and click on ... -##### Exception or Error +### Exception or Error

 
@@ -48,9 +48,9 @@ If the bug is reproducible, please describe steps below:
 
 
-##### Your Environment +### Your Environment -**OsmAnd Version:** +OsmAnd Version:

 
@@ -58,7 +58,11 @@ If the bug is reproducible, please describe steps below:
 
 
-**Device and Android/iOS version:** +Device and Android/iOS version: + + +Android/iOS version: + **Maps used (online or offline):** From 96edf0f0e1f7fe88db06811bf5bc6c36e73be633 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Wed, 23 Sep 2020 10:38:06 +0300 Subject: [PATCH 0284/1366] Update 3-bug-report.md --- .github/ISSUE_TEMPLATE/3-bug-report.md | 56 +------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md index aac6f3b299..05f1de2b1c 100644 --- a/.github/ISSUE_TEMPLATE/3-bug-report.md +++ b/.github/ISSUE_TEMPLATE/3-bug-report.md @@ -3,73 +3,19 @@ name: "\U0001F41E Bug report" about: Report a bug in OsmAnd --- - - -## 🐞 Bug report - -##### Is this a regression? - - - Yes, the previous version in which this bug was not present was: .... - ### Description - -##### How to reproduce? +### How to reproduce? - - 1. Open app, and click on ... - -### Exception or Error - -

-
-
-
-
### Your Environment - OsmAnd Version: - -

-
-
-
-
- Device and Android/iOS version: - - Android/iOS version: **Maps used (online or offline):** - - - - [ ] Offline maps offered within the OsmAnd app for download. - [ ] Online (tile / raster) maps - -**Anything else relevant?** From c39782e7ca869c2b49e1d629f0d5a0989dbc5199 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Wed, 23 Sep 2020 10:40:59 +0300 Subject: [PATCH 0285/1366] Update 3-bug-report.md --- .github/ISSUE_TEMPLATE/3-bug-report.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md index 05f1de2b1c..80e7025212 100644 --- a/.github/ISSUE_TEMPLATE/3-bug-report.md +++ b/.github/ISSUE_TEMPLATE/3-bug-report.md @@ -15,7 +15,5 @@ Device and Android/iOS version: Android/iOS version: -**Maps used (online or offline):** -- [ ] Offline maps offered within the OsmAnd app for download. - -- [ ] Online (tile / raster) maps +**Maps used (online or offline):** +If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date. From c9d24fc7f57b0012258d72ddb697e6a24eac94c3 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Wed, 23 Sep 2020 11:15:50 +0300 Subject: [PATCH 0286/1366] Update 3-bug-report.md --- .github/ISSUE_TEMPLATE/3-bug-report.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md index 80e7025212..0fd8c3e5ff 100644 --- a/.github/ISSUE_TEMPLATE/3-bug-report.md +++ b/.github/ISSUE_TEMPLATE/3-bug-report.md @@ -11,9 +11,8 @@ about: Report a bug in OsmAnd ### Your Environment OsmAnd Version: -Device and Android/iOS version: Android/iOS version: - +Device model: **Maps used (online or offline):** If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date. From 0f0c0870023f170245010f85766d28d38fd44761 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 23 Sep 2020 11:42:28 +0300 Subject: [PATCH 0287/1366] Fix UI track sort by --- OsmAnd/res/layout/popup_menu_item.xml | 2 + OsmAnd/res/menu/track_sort_menu_item.xml | 9 +++ .../plus/SimplePopUpMenuItemAdapter.java | 13 ++++ OsmAnd/src/net/osmand/plus/UiUtilities.java | 17 ++++- .../SelectFileBottomSheet.java | 61 ++++++--------- .../plus/myplaces/AvailableGPXFragment.java | 74 ++++++++++++------- 6 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 OsmAnd/res/menu/track_sort_menu_item.xml diff --git a/OsmAnd/res/layout/popup_menu_item.xml b/OsmAnd/res/layout/popup_menu_item.xml index 66509ffa4d..9e160fcc14 100644 --- a/OsmAnd/res/layout/popup_menu_item.xml +++ b/OsmAnd/res/layout/popup_menu_item.xml @@ -22,7 +22,9 @@ android:textColor="?android:textColorPrimary" android:layout_gravity="center_vertical" android:paddingLeft="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" android:paddingRight="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" android:paddingTop="@dimen/content_padding_small" android:paddingBottom="@dimen/content_padding_small" android:textSize="@dimen/default_list_text_size" diff --git a/OsmAnd/res/menu/track_sort_menu_item.xml b/OsmAnd/res/menu/track_sort_menu_item.xml new file mode 100644 index 0000000000..8344782092 --- /dev/null +++ b/OsmAnd/res/menu/track_sort_menu_item.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/SimplePopUpMenuItemAdapter.java b/OsmAnd/src/net/osmand/plus/SimplePopUpMenuItemAdapter.java index 4619e6a3e9..a646b7a416 100644 --- a/OsmAnd/src/net/osmand/plus/SimplePopUpMenuItemAdapter.java +++ b/OsmAnd/src/net/osmand/plus/SimplePopUpMenuItemAdapter.java @@ -12,6 +12,8 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.AndroidUtils; + import static net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem; import java.util.List; @@ -50,6 +52,10 @@ public class SimplePopUpMenuItemAdapter } else { ivIcon.setVisibility(View.GONE); } + if (item.selected) { + convertView.setBackgroundColor(UiUtilities.getColorWithAlpha( + AndroidUtils.getColorFromAttr(getContext(), R.attr.active_color_basic), 0.1f)); + } } return convertView; } @@ -64,6 +70,7 @@ public class SimplePopUpMenuItemAdapter private CharSequence title; private Drawable icon; private View.OnClickListener onClickListener; + boolean selected; public SimplePopUpMenuItem(CharSequence title, Drawable icon) { this.title = title; @@ -75,6 +82,12 @@ public class SimplePopUpMenuItemAdapter this.onClickListener = onClickListener; } + public SimplePopUpMenuItem(CharSequence title, Drawable icon, View.OnClickListener onClickListener, + boolean selected) { + this(title, icon, onClickListener); + this.selected = selected; + } + public CharSequence getTitle() { return title; } diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 5af06d9f23..f818716730 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -784,7 +784,7 @@ public class UiUtilities { titles.add(String.valueOf(item.getTitle())); hasIcon = hasIcon || item.getIcon() != null; } - float itemWidth = AndroidUtils.getTextMaxWidth(defaultListTextSize, titles) + contentPadding; + float itemWidth = AndroidUtils.getTextMaxWidth(defaultListTextSize, titles) + contentPadding * 2; float iconPartWidth = hasIcon ? standardIconSize + contentPaddingHalf : 0; int totalWidth = (int) (Math.max(itemWidth, minWidth) + iconPartWidth); @@ -808,4 +808,19 @@ public class UiUtilities { }); return listPopupWindow; } + + public static void showPopUpMenu(View v, final List items) { + UiUtilities.createListPopupWindow( + v.getContext(), v, v.getWidth(), items, new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (position < items.size()) { + View.OnClickListener listener = items.get(position).getOnClickListener(); + if (listener != null) { + listener.onClick(view); + } + } + } + }).show(); + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index cd84845584..d808f8f5e6 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -3,8 +3,6 @@ package net.osmand.plus.measurementtool; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; @@ -19,6 +17,7 @@ import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; import net.osmand.plus.base.BottomSheetBehaviourDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.helpers.GpxTrackAdapter; @@ -26,7 +25,6 @@ import net.osmand.plus.helpers.GpxTrackAdapter.OnItemClickListener; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; -import net.osmand.plus.widgets.IconPopupMenu; import java.io.File; import java.util.ArrayList; @@ -36,6 +34,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static net.osmand.plus.SimplePopUpMenuItemAdapter.*; import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo; import static net.osmand.plus.settings.backend.OsmandSettings.*; import static net.osmand.util.Algorithms.collectDirs; @@ -73,7 +72,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { private Mode fragmentMode; private String selectedFolder; private String allFilesFolder; - TracksSortByMode tracksSortBy = TracksSortByMode.BY_DATE; + TracksSortByMode sortByMode = TracksSortByMode.BY_DATE; public void setFragmentMode(Mode fragmentMode) { this.fragmentMode = fragmentMode; @@ -105,30 +104,29 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { ? R.color.inactive_buttons_and_links_bg_dark : R.color.inactive_buttons_and_links_bg_light); AndroidUtils.setBackground(sortButton, background); - sortButton.setImageResource(tracksSortBy.getIconId()); + sortButton.setImageResource(sortByMode.getIconId()); sortButton.setVisibility(View.VISIBLE); sortButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - IconPopupMenu popup = new IconPopupMenu(v.getContext(), v); - final Menu menu = popup.getMenu(); - MenuItem mi; + final List items = new ArrayList<>(); for (final TracksSortByMode mode : TracksSortByMode.values()) { - mi = createMenuItem(app, menu, mode.getNameId(), mode.getNameId(), mode.getIconId(), - MenuItem.SHOW_AS_ACTION_ALWAYS, false, R.color.icon_color_default_light); - mi.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - tracksSortBy = mode; - sortButton.setImageResource(mode.getIconId()); - updateDescription(descriptionView); - sortFileList(); - adapter.notifyDataSetChanged(); - return false; - } - }); + items.add(new SimplePopUpMenuItem( + getString(mode.getNameId()), + app.getUIUtilities().getThemedIcon(mode.getIconId()), + new View.OnClickListener() { + @Override + public void onClick(View v) { + sortByMode = mode; + sortButton.setImageResource(mode.getIconId()); + updateDescription(descriptionView); + sortFileList(); + adapter.notifyDataSetChanged(); + } + }, sortByMode == mode + )); } - popup.show(); + UiUtilities.showPopUpMenu(v, items); } }); } @@ -202,25 +200,12 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { } private void updateDescription(TextView descriptionView) { - String string = getString(tracksSortBy.getNameId()); + String string = getString(sortByMode.getNameId()); descriptionView.setText(String.format(getString(R.string.ltr_or_rtl_combine_via_space), getString(fragmentMode.description), Character.toLowerCase(string.charAt(0)) + string.substring(1))); } - public MenuItem createMenuItem(OsmandApplication app, Menu m, int id, int titleRes, int iconId, int menuItemType, - boolean flipIconForRtl, int iconColor) { - Drawable d = iconId == 0 ? null : app.getUIUtilities().getIcon(iconId, iconColor); - MenuItem menuItem = m.add(0, id, 0, titleRes); - if (d != null) { - if (flipIconForRtl) { - d = AndroidUtils.getDrawableForDirection(app, d); - } - menuItem.setIcon(d); - } - return menuItem; - } - private void updateFileList(HorizontalSelectionAdapter folderAdapter) { sortFileList(); adapter.setShowFolderName(showFoldersName()); @@ -238,9 +223,9 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { Collections.sort(gpxInfoList, new Comparator() { @Override public int compare(GPXInfo i1, GPXInfo i2) { - if (tracksSortBy == TracksSortByMode.BY_NAME_ASCENDING) { + if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { return i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase()); - } else if (tracksSortBy == TracksSortByMode.BY_NAME_DESCENDING) { + } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { return -i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase()); } else { long time1 = i1.getLastModified(); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index ef184307e6..47e4343a31 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -19,7 +19,6 @@ import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.SubMenu; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; @@ -70,7 +69,7 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; -import net.osmand.plus.SimplePopUpMenuItemAdapter; +import net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; @@ -475,24 +474,26 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } }); - menu.addSubMenu(Menu.NONE, R.string.shared_string_sort, Menu.NONE, R.string.shared_string_sort); - final SubMenu sortMenu = menu.findItem(R.string.shared_string_sort).getSubMenu(); - mi = sortMenu.getItem(); +// menu.addSubMenu(Menu.NONE, R.string.shared_string_sort, Menu.NONE, R.string.shared_string_sort); + inflater.inflate(R.menu.track_sort_menu_item, menu); + mi = menu.findItem(R.id.action_sort); +// mi = sortMenu.getItem(); mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - final int iconColorId = isLightActionBar() ? R.color.active_buttons_and_links_text_light + int iconColorId = isLightActionBar() ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark; mi.setIcon(getIcon(sortByMode.getIconId(), iconColorId)); + final List items = new ArrayList<>(); for (final TracksSortByMode mode : TracksSortByMode.values()) { - mi = createMenuItem(sortMenu, mode.getNameId(), mode.getNameId(), mode.getIconId(), - MenuItem.SHOW_AS_ACTION_ALWAYS, false, R.color.icon_color_default_light); - mi.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - updateTracksSort(mode); - sortMenu.setIcon(getIcon(mode.getIconId(), iconColorId)); - return false; - } - }); +// mi = createMenuItem(sortMenu, mode.getNameId(), mode.getNameId(), mode.getIconId(), +// MenuItem.SHOW_AS_ACTION_ALWAYS, false, R.color.icon_color_default_light); +// mi.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { +// @Override +// public boolean onMenuItemClick(MenuItem item) { +// updateTracksSort(mode); +// sortMenu.setIcon(getIcon(mode.getIconId(), iconColorId)); +// return false; +// } +// }); } if (AndroidUiHelper.isOrientationPortrait(getActivity())) { @@ -578,7 +579,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { int itemId = item.getItemId(); for (int i = 0; i < optionsMenuAdapter.length(); i++) { ContextMenuItem contextMenuItem = optionsMenuAdapter.getItem(i); @@ -587,6 +588,29 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement return true; } } + if (itemId == R.id.action_sort) { + Activity activity = getActivity(); + if (activity != null) { + View menuSortItemView = getActivity().findViewById(R.id.action_sort); + final List items = new ArrayList<>(); + for (final TracksSortByMode mode : TracksSortByMode.values()) { + items.add(new SimplePopUpMenuItem( + getString(mode.getNameId()), + app.getUIUtilities().getThemedIcon(mode.getIconId()), + new View.OnClickListener() { + @Override + public void onClick(View v) { + updateTracksSort(mode); + int iconColorId = isLightActionBar() ? R.color.active_buttons_and_links_text_light + : R.color.active_buttons_and_links_text_dark; + item.setIcon(getIcon(mode.getIconId(), iconColorId)); + } + }, sortByMode == mode + )); + } + UiUtilities.showPopUpMenu(menuSortItemView, items); + } + } return super.onOptionsItemSelected(item); } @@ -1492,10 +1516,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } private void openPopUpMenu(View v, final GpxInfo gpxInfo) { - final List items = new ArrayList<>(); + final List items = new ArrayList<>(); UiUtilities iconsCache = getMyApplication().getUIUtilities(); - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.shared_string_show_on_map), iconsCache.getThemedIcon(R.drawable.ic_show_on_map), new View.OnClickListener() { @@ -1509,7 +1533,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement GPXTrackAnalysis analysis; if ((analysis = getGpxTrackAnalysis(gpxInfo, app, null)) != null) { if (analysis.totalDistance != 0 && !gpxInfo.currentlyRecordingTrack) { - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.analyze_on_map), iconsCache.getThemedIcon(R.drawable.ic_action_info_dark), new View.OnClickListener() { @@ -1522,7 +1546,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } } - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.shared_string_move), iconsCache.getThemedIcon(R.drawable.ic_action_folder_stroke), new View.OnClickListener() { @@ -1533,7 +1557,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } )); - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.shared_string_rename), iconsCache.getThemedIcon(R.drawable.ic_action_edit_dark), new View.OnClickListener() { @@ -1551,7 +1575,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement )); Drawable shareIcon = iconsCache.getThemedIcon((R.drawable.ic_action_gshare_dark)); - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.shared_string_share), AndroidUtils.getDrawableForDirection(app, shareIcon), new View.OnClickListener() { @@ -1569,7 +1593,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement final OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getEnabledPlugin(OsmEditingPlugin.class); if (osmEditingPlugin != null && osmEditingPlugin.isActive()) { - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.shared_string_export), iconsCache.getThemedIcon(R.drawable.ic_action_export), new View.OnClickListener() { @@ -1581,7 +1605,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement )); } - items.add(new SimplePopUpMenuItemAdapter.SimplePopUpMenuItem( + items.add(new SimplePopUpMenuItem( getString(R.string.shared_string_delete), iconsCache.getThemedIcon(R.drawable.ic_action_delete_dark), new View.OnClickListener() { From c5415febeb264cb6bdccdb2551f03af0be7d4ad1 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 23 Sep 2020 11:54:21 +0300 Subject: [PATCH 0288/1366] Fix UI track sort by --- .../plus/myplaces/AvailableGPXFragment.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 47e4343a31..9596bafb89 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -474,27 +474,12 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } }); -// menu.addSubMenu(Menu.NONE, R.string.shared_string_sort, Menu.NONE, R.string.shared_string_sort); inflater.inflate(R.menu.track_sort_menu_item, menu); mi = menu.findItem(R.id.action_sort); -// mi = sortMenu.getItem(); mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); int iconColorId = isLightActionBar() ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark; mi.setIcon(getIcon(sortByMode.getIconId(), iconColorId)); - final List items = new ArrayList<>(); - for (final TracksSortByMode mode : TracksSortByMode.values()) { -// mi = createMenuItem(sortMenu, mode.getNameId(), mode.getNameId(), mode.getIconId(), -// MenuItem.SHOW_AS_ACTION_ALWAYS, false, R.color.icon_color_default_light); -// mi.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { -// @Override -// public boolean onMenuItemClick(MenuItem item) { -// updateTracksSort(mode); -// sortMenu.setIcon(getIcon(mode.getIconId(), iconColorId)); -// return false; -// } -// }); - } if (AndroidUiHelper.isOrientationPortrait(getActivity())) { menu = ((FavoritesActivity) getActivity()).getClearToolbar(true).getMenu(); From 1f65840dd4334f2f29e16007015668773d076bf1 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 23 Sep 2020 16:29:16 +0300 Subject: [PATCH 0289/1366] Fix button width in plan route and divider in follow track --- OsmAnd/res/layout/fragment_measurement_tool.xml | 6 ++++-- .../plus/routepreparationmenu/FollowTrackFragment.java | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/layout/fragment_measurement_tool.xml b/OsmAnd/res/layout/fragment_measurement_tool.xml index fe1ba9b1d7..d4b7f7ea57 100644 --- a/OsmAnd/res/layout/fragment_measurement_tool.xml +++ b/OsmAnd/res/layout/fragment_measurement_tool.xml @@ -216,10 +216,12 @@ + android:minWidth="@dimen/measurement_tool_button_width" /> + diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index ee2bf6b38e..42ff2f94e6 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -205,7 +205,6 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca SelectTrackCard selectTrackCard = new SelectTrackCard(mapActivity); selectTrackCard.setListener(this); cardsContainer.addView(selectTrackCard.build(mapActivity)); - cardsContainer.addView(buildDividerView(cardsContainer, false)); ApplicationMode mode = app.getRoutingHelper().getAppMode(); @@ -213,13 +212,16 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca GPXRouteParamsBuilder rparams = routingHelper.getCurrentGPXRoute(); boolean osmandRouter = mode.getRouteService() == RouteProvider.RouteService.OSMAND; if (rparams != null && osmandRouter) { - if (!gpxFile.hasRoute() || gpxFile.hasRtePt()) { + boolean showReverseCard = !gpxFile.hasRoute() || gpxFile.hasRtePt(); + if (showReverseCard) { + cardsContainer.addView(buildDividerView(cardsContainer, false)); + ReverseTrackCard reverseTrackCard = new ReverseTrackCard(mapActivity, rparams.isReverse()); reverseTrackCard.setListener(this); cardsContainer.addView(reverseTrackCard.build(mapActivity)); } if (!gpxFile.hasRtePt() && !gpxFile.hasRoute()) { - cardsContainer.addView(buildDividerView(cardsContainer, true)); + cardsContainer.addView(buildDividerView(cardsContainer, showReverseCard)); AttachTrackToRoadsCard attachTrackCard = new AttachTrackToRoadsCard(mapActivity); attachTrackCard.setListener(this); From 915dc9800b2dcb8e58f0de58443e013430ceca66 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 23 Sep 2020 18:32:46 +0300 Subject: [PATCH 0290/1366] Add configure profile, switch profile aidl ID --- .../aidlapi/OsmAndCustomizationConstants.java | 2 ++ .../plus/activities/MapActivityActions.java | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java index 2e1543321a..af48552bc4 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java @@ -4,6 +4,8 @@ public interface OsmAndCustomizationConstants { // Navigation Drawer: String DRAWER_ITEM_ID_SCHEME = "drawer.action."; + String DRAWER_SWITCH_PROFILE_ID = DRAWER_ITEM_ID_SCHEME + "switch_profile"; + String DRAWER_CONFIGURE_PROFILE_ID = DRAWER_ITEM_ID_SCHEME + "configure_profile"; String DRAWER_DASHBOARD_ID = DRAWER_ITEM_ID_SCHEME + "dashboard"; String DRAWER_MAP_MARKERS_ID = DRAWER_ITEM_ID_SCHEME + "map_markers"; String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places"; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index dbd0f133fa..0bd66f8a6f 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -91,6 +91,7 @@ import java.util.Map; import static net.osmand.IndexConstants.GPX_FILE_EXT; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_MAP_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_PROFILE_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_SCREEN_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DASHBOARD_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DIRECTIONS_ID; @@ -104,6 +105,7 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_OSMAND_LIVE import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_PLUGINS_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SEARCH_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SWITCH_PROFILE_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_TRAVEL_GUIDES_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_ADD_GPX_WAYPOINT; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_ADD_ID; @@ -145,7 +147,7 @@ public class MapActivityActions implements DialogProvider { private static final int DIALOG_RELOAD_TITLE = 103; private static final int DIALOG_SAVE_DIRECTIONS = 106; - + private static final int DRAWER_MODE_NORMAL = 0; private static final int DRAWER_MODE_SWITCH_PROFILE = 1; @@ -476,7 +478,7 @@ public class MapActivityActions implements DialogProvider { mapActivity.showQuickSearch(latitude, longitude); } else if (standardId == R.string.context_menu_item_directions_from) { //if (OsmAndLocationProvider.isLocationPermissionAvailable(mapActivity)) { - enterDirectionsFromPoint(latitude, longitude); + enterDirectionsFromPoint(latitude, longitude); //} else { // ActivityCompat.requestPermissions(mapActivity, // new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, @@ -535,17 +537,17 @@ public class MapActivityActions implements DialogProvider { } public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, LatLon from, PointDescription fromName, - boolean useIntermediatePointsByDefault, boolean showMenu) { + boolean useIntermediatePointsByDefault, boolean showMenu) { enterRoutePlanningModeGivenGpx(gpxFile, from, fromName, useIntermediatePointsByDefault, showMenu, MapRouteInfoMenu.DEFAULT_MENU_STATE); } public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, LatLon from, PointDescription fromName, - boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { + boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { enterRoutePlanningModeGivenGpx(gpxFile, null, from, fromName, useIntermediatePointsByDefault, showMenu, menuState); } public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, ApplicationMode appMode, LatLon from, PointDescription fromName, - boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { + boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { settings.USE_INTERMEDIATE_POINTS_NAVIGATION.set(useIntermediatePointsByDefault); OsmandApplication app = mapActivity.getMyApplication(); TargetPointsHelper targets = app.getTargetPointsHelper(); @@ -727,7 +729,7 @@ public class MapActivityActions implements DialogProvider { private ContextMenuAdapter createSwitchProfileOptionsMenu(final OsmandApplication app, ContextMenuAdapter optionsMenuHelper, boolean nightMode) { drawerMode = DRAWER_MODE_NORMAL; createProfilesController(app, optionsMenuHelper, nightMode, true); - + List activeModes = ApplicationMode.values(app); ApplicationMode currentMode = app.getSettings().APPLICATION_MODE.get(); @@ -759,7 +761,7 @@ public class MapActivityActions implements DialogProvider { }) .createItem()); } - + int activeColorPrimaryResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item) .setColor(activeColorPrimaryResId) @@ -778,7 +780,7 @@ public class MapActivityActions implements DialogProvider { } private ContextMenuAdapter createNormalOptionsMenu(final OsmandApplication app, ContextMenuAdapter optionsMenuHelper, boolean nightMode) { - + createProfilesController(app, optionsMenuHelper, nightMode, false); optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.home, mapActivity) @@ -1055,6 +1057,7 @@ public class MapActivityActions implements DialogProvider { int icArrowResId = listExpanded ? R.drawable.ic_action_arrow_drop_up : R.drawable.ic_action_arrow_drop_down; final int nextMode = listExpanded ? DRAWER_MODE_NORMAL : DRAWER_MODE_SWITCH_PROFILE; optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_switch_profile) + .setId(DRAWER_SWITCH_PROFILE_ID) .setIcon(currentMode.getIconRes()) .setSecondaryIcon(icArrowResId) .setColor(currentMode.getIconColorInfo().getColor(nightMode)) @@ -1070,6 +1073,7 @@ public class MapActivityActions implements DialogProvider { }) .createItem()); optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_configure_profile) + .setId(DRAWER_CONFIGURE_PROFILE_ID) .setColor(currentMode.getIconColorInfo().getColor(nightMode)) .setTitle(getString(R.string.configure_profile)) .setListener(new ItemClickListener() { @@ -1084,8 +1088,8 @@ public class MapActivityActions implements DialogProvider { } private String getProfileDescription(OsmandApplication app, ApplicationMode mode, - Map profilesObjects, String defaultDescription){ - String description = defaultDescription; + Map profilesObjects, String defaultDescription) { + String description = defaultDescription; String routingProfileKey = mode.getRoutingProfile(); if (!Algorithms.isEmpty(routingProfileKey)) { From e6231e2166f08b1e19e080bb690e0fcad3b945e5 Mon Sep 17 00:00:00 2001 From: sergosm Date: Wed, 23 Sep 2020 19:32:25 +0300 Subject: [PATCH 0291/1366] fix "Nearby wikipedia articles" so the settings are applied --- .../plus/mapcontextmenu/MenuBuilder.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index d197ae51e6..00d0a8cc20 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -53,6 +53,7 @@ import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; +import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.views.layers.POIMapLayer; @@ -992,18 +993,10 @@ public class MenuBuilder { if (showNearestWiki && latLon != null) { QuadRect rect = MapUtils.calculateLatLonBbox( latLon.getLatitude(), latLon.getLongitude(), 250); - nearestWiki = app.getResourceManager().searchAmenities( - new BinaryMapIndexReader.SearchPoiTypeFilter() { - @Override - public boolean accept(PoiCategory type, String subcategory) { - return type != null && type.isWiki(); - } + PoiUIFilter wikiPoiFilter = app.getPoiFilters().getTopWikiPoiFilter(); + + nearestWiki = getAmenities(rect, wikiPoiFilter); - @Override - public boolean isEmpty() { - return false; - } - }, rect.top, rect.left, rect.bottom, rect.right, -1, null); Collections.sort(nearestWiki, new Comparator() { @Override @@ -1016,8 +1009,7 @@ public class MenuBuilder { Long id = objectId; List wikiList = new ArrayList<>(); for (Amenity wiki : nearestWiki) { - String lng = wiki.getContentLanguage("content", preferredMapAppLang, "en"); - if (wiki.getId().equals(id) || (!lng.equals("en") && !lng.equals(preferredMapAppLang))) { + if (wiki.getId().equals(id)) { wikiList.add(wiki); } } @@ -1027,6 +1019,11 @@ public class MenuBuilder { return false; } + private List getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) { + return wikiPoiFilter.searchAmenities(rect.top, rect.left, + rect.bottom, rect.right, -1, null); + } + @SuppressWarnings("unchecked") public static

void execute(AsyncTask task, P... requests) { task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); From 911ce59533dd1753ab2914cb417882c27daa61dd Mon Sep 17 00:00:00 2001 From: josep constanti Date: Wed, 23 Sep 2020 15:50:03 +0000 Subject: [PATCH 0292/1366] Translated using Weblate (Catalan) Currently translated at 96.6% (3370 of 3487 strings) --- OsmAnd/res/values-ca/strings.xml | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index ce8fda7ac6..be291b8d7b 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -2911,10 +2911,10 @@ Abasta l\'àrea: %1$s x %2$s Totes les cruïlles Tipus de carretera Sortida a - Mostra/amaga traces GPX - Un botó per mostrar o amagar les traces GPX seleccionades al mapa. - Amaga les traces GPX - Mostra les traces GPX + Mostra/amaga traces + Un botó per mostrar o amagar les traces seleccionades al mapa. + Amaga les traces + Mostra les traces Pugeu a la parada • Nova pantalla \'Adreces\': Mostra els botons de destinació Casa i Feina, drecera de \'ruta anterior\', llista de traces GPX i marcadors actius, historial de cerca \n @@ -3169,7 +3169,7 @@ Abasta l\'àrea: %1$s x %2$s Fora de pista Ovni Monocicle - Mogueu la mà a la part superior de la pantalla per a activar-la durant la navegació. + Si moveu la vostra mà per pantalla s\'activarà. Grau 1 Grau 2 Grau 3 @@ -3333,7 +3333,7 @@ Abasta l\'àrea: %1$s x %2$s Estadístiques Mostra el mapa a la pantalla de blocat durant la navegació. Configuració per la navegació en el perfil seleccionat \"%1$s\". - Hora d\'activació + Retard des de l\'activació Unitats i formats Aparença Aparença del mapa @@ -3352,7 +3352,7 @@ Abasta l\'àrea: %1$s x %2$s Activa la pantalla Mapa durant la navegació Mapa durant la navegació - Pes, alçada, velocitat + Pes, alçada, llargada, velocitat Paràmetres del vehicle Els missatges de veu només es produeixen navegant. Instruccions de navegació i anuncis @@ -3415,7 +3415,7 @@ Abasta l\'àrea: %1$s x %2$s Perfil seleccionat Un botó per establir el punt central de la pantalla com el punt de sortida. Llavors, demanarà seleccionar-la destinació o iniciar el càlcul de la ruta. Memòria intermèdia del Logcat - Prement %1$s es perdran tots els vostres canvis. + Prement %1$s es perden tots els vostres canvis. Restableix tota la configuració del perfil als valors predeterminats de la instal·lació. Voleu restablir la configuració de tots els perfils\? %1$s %2$s @@ -3607,7 +3607,7 @@ Abasta l\'àrea: %1$s x %2$s Amagat Aquests elements no es mostren al menú, però les opcions o els connectors que representen continuaran funcionant. Si s\'amaga la configuració es restablirà al seus valors originals. - Les accions principals només contenen 4 botons. + Només hi han 4 botons. Accions principals Només podeu moure els elements dins d\'aquesta categoria. Connector per a desenvolupadors @@ -3819,4 +3819,17 @@ Abasta l\'àrea: %1$s x %2$s Traces Importa o enregistra fitxers de traces Trieu un fitxer de traces a seguir o importeu-lo des del dispositiu. + L’autorització s’ha realitzat correctament + So de l\'obturador de la càmera + Utilitza l\'aplicació del sistema + Restableix la configuració predeterminada del complement + Desplaçament mínim + Precisió mínima + Velocitat mínima + Notificació + Especifiqueu l\'adreça web amb la sintaxi de paràmetres: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitud={4}, velocitat={5}, càrrega={6}. + Adreça web + Darrera modificació + Nom: Z - A + Nom: A - Z \ No newline at end of file From ed6f68f54b64d2f52f55a3e133767f5eceb3c31e Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 22 Sep 2020 16:00:35 +0000 Subject: [PATCH 0293/1366] Translated using Weblate (German) Currently translated at 99.9% (3486 of 3487 strings) --- OsmAnd/res/values-de/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index ba12de339b..fa4dbe5c06 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -1324,7 +1324,7 @@ Tags Beschreibung Aufzeichnung mit der Schaltfläche \'GPX\' oder unter \'Erweiterungen → Streckenaufzeichnung → Einstellungen\'. - GPX-Route umkehren + Trackrichtung umkehren Derzeitiges Ziel verwenden Gesamten Track durchlaufen Keine GPX-Dateien im Ordner tracks gefunden @@ -3907,4 +3907,7 @@ \n • Probleme beim Import/Export von Profileinstellungen behoben \n \n + Zuletzt geändert + Name: Z – A + Name: A – Z \ No newline at end of file From afed30d9a22128c6e7b58e13b160e38a767d4d7b Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Wed, 23 Sep 2020 14:53:05 +0000 Subject: [PATCH 0294/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 125 ++++++++++++++++--------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index d77acfa3aa..3ef0d51e37 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -40,10 +40,10 @@ Увеличить радиус поиска Ничего не найдено Изменить запрос или увеличить радиус поиска. - Показать/скрыть заметки OSM - Показать заметки OSM - Скрыть заметки OSM - Переключатель, чтобы показать или скрыть заметки OSM на карте. + Показать/скрыть OSM-заметки + Показать OSM-заметки + Скрыть OSM-заметки + Переключатель отображения OSM-заметок на карте. Отсортировано по расстоянию Поиск в избранных Загрузите карту «Наложение затенения рельефа» для отображения вертикального затенения (отмывки) рельефа. @@ -71,8 +71,8 @@ Ближайшие города Выберите город Поиск почтового индекса - Аудиозаметка - Видеозаметка + Аудио⁣заметка + Видео⁣заметка Фотозаметка OSM-заметка Функции парковки @@ -99,22 +99,22 @@ Кнопка переключения автомасштабирования на основе скорости. Включение автомасштаба Выключение автомасштаба - Пункт назначения + Добавить пункт назначения Заменить пункт назначения Первый промежуточный пункт - Установка центра экрана пунктом назначения; ранее выбранный пункт назначения станет последним промежуточным пунктом. + Добавление нового пункта назначения в центре экрана. Ранее выбранный пункт назначения станет последним промежуточным пунктом. Кнопка для установки центра экрана пунктом отправления. Затем нужно будет выбрать пункт назначения или запустить расчёт маршрута. Кнопка для установки центра экрана пунктом назначения с заменой предыдущего (если был задан). Установка центра экрана первой промежуточной точкой маршрута. Нет покрытия Нет подложки - Холмистый - Менее холмистый - Равнинный + Гористый + Сглаженный + Ровный Короткие маршруты Сбалансированный Предпочитать переулки - Предпочтительный рельеф: равнинный или холмистый. + Выберите предпочтительный рельеф. Склон Добавить новую папку Точки удалены. @@ -140,7 +140,7 @@ Время Длина маршрута Стиль езды - Выберите пересечённость местности + Колебания высоты ландшафта Использовать данные о высотах Фактор рельефа местности (по данным SRTM, ASTER и EU-DEM). Действие переименовано в %1$s, чтобы избежать дублирования. @@ -185,8 +185,8 @@ Старый поиск Показывать старый поиск Добавить старый поиск в меню. - Разрешить автомагистрали - Разрешает автомагистрали. + Разрешить магистрали + Разрешает движение по автомагистралям. Статьи Википедии рядом Город или регион Сверните на %1$d съезд @@ -301,8 +301,8 @@ \nГлобальные данные (между 70° на севере и 70° на юге) основываются на измерениях SRTM (Shuttle Radar Topography Mission) и ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer) — инструментом визуализации Terra, флагманского спутника Системы Наблюдения Земли NASA. ASTER является результатом совместных усилий NASA, министерства экономики Японии, торговли и промышленности (METI), а также Космических Систем Японии (J-spacesystems). Рассмотрите возможность покупки плагина «Линии высот» в Google Play, чтобы поддержать последующую разработку. Линии высот - Запись видео - Запись аудио + Видео⁣заметка + Аудио⁣заметка Действие по умолчанию для виджета: Действие по умолчанию для виджета Формат вывода видео: @@ -325,7 +325,7 @@ Проиграть Запись %1$s %3$s %2$s Запись - Аудиозаметки + Медиазаметки OsmAnd-плагин для линий высот Измерение расстояний Нажмите «Использовать местоположение…» чтобы добавить заметку к данному местоположению. @@ -406,7 +406,7 @@ Отправить изменения в OSM Удалить правку Локальное дополнение: - OSM POI/заметки на устройстве + POI и OSM-заметки на устройстве Просмотр и управление OSM POI/заметками в локальной базе данных. Укажите интервал онлайн-слежения. Интервал онлайн-слежения @@ -467,11 +467,11 @@ Текущий центр карты Начало: Поиск рядом - Маршрут успешно сохранён в «%1$s». + Маршрут сохранён в «%1$s». Имя файла: Файл с таким именем уже существует. Отправить файлы GPX в сообщество OSM. Они будут использованы для улучшения карты. - %1$d из %2$d объектов успешно отправлены. + %1$d из %2$d объектов отправлено. Отправить в OSM Детализированная карта Показывать детали (дороги и др.), начиная с мелких масштабов. @@ -488,9 +488,9 @@ \n \nУдерживайте для вызова настроек" Загружено - %1$d из %2$d объектов успешно архивированы. - %1$d из %2$d объектов успешно удалены. - %1$d из %2$d объектов успешно активированы. + %1$d из %2$d объектов архивировано. + %1$d из %2$d объектов удалено. + %1$d из %2$d объектов восстановлено. Нет объектов, чтобы %1$s Вы собираетесь %1$s %2$s объектов. Вы уверены? Управление картами. @@ -611,7 +611,7 @@ Невозможно найти указанную папку. Папка хранилища данных У вас установлена предыдущая версия OsmAnd. Все локальные данные поддерживаются новой версией. Однако избранные точки нужно выгрузить из предыдущей версии приложения и загрузить в новую. - Сборка {0} успешно установлена ({1}). + Сборка {0} установлена ({1}). Загружается сборка… Установить OsmAnd — {0} из {1} {2} МБ\? Не удалось получить список сборок OsmAnd @@ -646,7 +646,7 @@ Не удалось нарисовать выбранную область. Ошибка : недостаточно памяти процесса, чтобы отобразить карту Контекстное меню… - Стиль успешно загружен + Стиль загружен Не удалось загрузить отрисовщик. Векторный отрисовщик Выберите внешний вид отрисовки @@ -675,7 +675,7 @@ Выравнивание карты: Ориентация карты Детали маршрута - Избранные точки успешно импортированы + Избранные точки импортированы GPX-файл с сохранёнными точками отсутствует в {0} Точки сохранены в {0} Нет избранных точек для сохранения @@ -687,7 +687,7 @@ Спасибо Яндексу за предоставление информации о пробках. Яндекс.Пробки Маршрут - Заметки OSM (онлайн) + OSM-заметки (онлайн) POI… Источник карты Слои @@ -762,7 +762,7 @@ Показывать остановки общественного транспорта на карте. Показать остановки транспорта Навигационное приложение OsmAnd - Данные POI были успешно обновлены ({0} объектов загружено) + Данные POI обновлены ({0} объектов загружено) Не удалось обновить локальный список POI. Не удалось загрузить данные с сервера. В данной области нет локальных POI @@ -907,7 +907,7 @@ Нет Название точки Избранная - Точка «{0}» была успешно добавлена к избранным. + Точка «{0}» добавлена к избранным. Изменить Удалить из моих Удалить точку «%s» из избранных\? @@ -1201,7 +1201,7 @@ Настройки аудио и видео Изменить порядок Просмотр - Сделать фото + Фотозаметка Сделать фото Синхронизация треков и медиазаметок с вашим аккаунтом Dropbox. Плагин Dropbox @@ -1239,7 +1239,7 @@ Укажите адрес Выбор избранной Модификации OSM - По запросу\? + Выбирать OsmAnd карты и навигация OsmAnd+ карты и навигация Уменьшает «шум» компаса, но добавляет инерцию. @@ -1351,7 +1351,7 @@ Избегать автомагистралей Без автомагистралей Предпочитать автомагистрали - Предпочитать автомагистрали + Предпочитать магистрали Без платных дорог Избегать платных дорог Без грунтовых дорог @@ -1484,7 +1484,7 @@ Старт навигации автоматически Сохранить как группу избранных Задать точки маршрута - Метки точек + Названия точек " \n \nУдерживайте для просмотра на карте" @@ -1731,7 +1731,7 @@ Сегменты трека Точки трека дней назад - Заметки + Медиазаметки Выбранные выбранные Нет @@ -1926,7 +1926,7 @@ Жирный контур Рабочие дни Избранные - Успешно сохранён в: %1$s + Сохранён в %1$s POI будут удалены после того как вы отправите ваши изменения удалить Недавние места @@ -2121,8 +2121,8 @@ Недостаточно места! \nНеобходимо {3} МБ временного хранилища и {1} МБ постоянного. \n(Доступно только {2} МБ) - Отправьте свою заметку OSM анонимно или используя свой профиль OpenStreetMap.org. - Отправить заметку OSM + Отправьте OSM-заметку анонимно или используя свой профиль OpenStreetMap.org. + Отправить OSM-заметку Использовать меню Использовать панель управления Панель управления или меню @@ -2204,7 +2204,7 @@ Не проверять информацию о новых версиях и скидках от OsmAnd. Не показывать новые версии Обновить все карты сейчас? - Очистить всю плитку + Удалить из кеша Снижать расход топлива Использование топливо-сберегающего пути (обычно короче). Вы уверены, что хотите заменить избранные %1$s\? @@ -2227,9 +2227,10 @@ Не удалось определить местоположение OsmAnd определит ваше местоположение и предложит загрузить карты для этой области. Поиск карт… - Выберите другой регион + Другой регион Пропустить загрузку карт - У вас нет загруженных карт. Вы можете выбрать карту из списка или загрузить её позже с помощью «Меню — %1$s». + У вас нет загруженных карт. Вы можете выбрать карту из списка или скачать позже (Меню — %1$s). Для использования без интернета скачайте карту заранее. +\nДля работы с картами онлайн включите плагин «Онлайн-карты». Мили/метры Получить за %1$s Получить @@ -2616,7 +2617,7 @@ \n OsmAnd это активно развивающееся программное обеспечение с открытым исходным кодом. Каждый может внести свой вклад в приложение, сообщая об ошибках, улучшая переводы или кодируя новые функции. Кроме того, проект опирается на финансовые взносы для финансирования разработки и тестирования новых функциональных возможностей. \n Создать или изменить объекты OSM - Создавайте или изменяйте OSM POI, открывайте или комментируйте заметки OSM, а также отправляйте записанные файлы GPX. + Добавляйте и редактируйте POI, сообщайте о неточностях на карте в OSM-заметках, делитесь записанными треками. Удалено Отредактировано Добавлено @@ -2680,7 +2681,7 @@ Выберите тип файла Экспортировать в виде POI, заметок OSM или обоих вариантов. Все данные - Заметки OSM + OSM-заметки Впереди туннель Туннели Сделать отправной точкой @@ -2777,7 +2778,7 @@ Платное приложение Платный плагин Команда OsmAnd - На основе сохранённых вами статей мы рекомендуем вам скачать следующие карты: + Рекомендации на основе ваших закладок: Нужные вам карты Перезапуск Вы отменили подписку OsmAnd Live @@ -2907,9 +2908,9 @@ пересадки пешком Показывать вдоль маршрута - Поверхность + Покрытие Тип дороги - Крутость + Крутизна Добавить дом Добавить работу Работа @@ -3200,7 +3201,7 @@ Пример Изменить настройки Отменить изменение - Применить только к «%1$s» + Применить только к профилю «%1$s» Применить ко всем профилям Сообщение при запуске Аналитика @@ -3304,7 +3305,7 @@ Предпочитать грунтовые дороги Предпочитать грунтовые дороги. Вы уверены, что хотите обновить все карты (%1$d)\? - Вы можете применить это изменение ко всем профилям или только к выбранному в данный момент. + Вы можете применить это ко всем или только к выбранному профилю. Общий Переключатель, показывающая или скрывающая контурные линии на карте. Показать контурные линии @@ -3465,7 +3466,7 @@ Вы можете выбрать дополнительные данные для экспорта вместе с профилем. Приложение по умолчанию (%s) Не перестраивать - Минимальное отклонение для перестроения маршрута + Отклонение для пересчёта Маршрут будет пересчитан, если расстояние до него больше заданного параметра Пользовательский профиль Угол: %s° @@ -3498,14 +3499,14 @@ Онлайн-отслеживание Точность ведения журнала Ваши записанные треки находятся в %1$s или папке OsmAnd. - Ваши заметки OSM находятся в %1$s. + Ваши OSM-заметки находятся в %1$s. Видеозаметки Фотозаметки Пересчёт маршрута Имя пользователя и пароль Эти настройки применяются ко всем профилям. Редактирование OSM - Просмотр ваших исправлений или ошибок OSM, ещё не отправленных в %1$s. Отправленные точки больше не будут отображаться. + Ваши правки и баги OSM, ещё не отправленные в %1$s. Отправленные точки больше не будут отображаться. OSM Значок, отображаемый во время навигации или движения. Значок, отображаемый в состоянии покоя. @@ -3549,8 +3550,8 @@ Объекты добавлены Импорт завершён Все данные из %1$s импортированы, вы можете использовать кнопки ниже, чтобы открыть соответствующий раздел приложения для управления ими. - Маршрут будет пересчитан, если расстояние от маршрута до текущего местоположения больше выбранного значения. - Выберите расстояние, после которого маршрут будет пересчитан. + При уходе с маршрута на расстояние, превышающее это значение, маршрут будет перестроен автоматически. + Отклонение, при котором маршрут будет пересчитан. Легенда Невозможно разобрать геоссылку «%s». Для отображения затенения рельефа на карте необходимы дополнительные карты. @@ -3796,15 +3797,15 @@ Скачать карты Википедии Эндуро мотоцикл Мотороллер - Закрытая заметка OSM + Закрытая OSM-заметка Инвалидная коляска - В карту + Карт Инвалидное кресло впереди Добавить к треку - Установите рабочие дни, чтобы продолжить + Для продолжения задайте рабочие дни Маршрут между точками Составить маршрут - Выберите нужный вариант разбиения: по времени или по расстоянию. + Выберите способ разбиения: по времени или по расстоянию. Интервал между метками расстояния или времени на треке. Своё Добавленная точка не будет видна на карте, так как выбранная группа скрыта, найти её можно в «%s». @@ -3812,11 +3813,11 @@ Выберите ширину Стрелки направления Сплошной - Последнее изменение + Дата изменения Импортировать трек Открыть существующий трек Создать новый маршрут - Выберите файл трека для открытия. + Выберите файл трека. Готово Перезаписать трек Выбрать трек, к которому будет добавлен новый сегмент. @@ -3824,12 +3825,12 @@ Предельная дистанция Сохранить как новый трек Обратный маршрут - Профиль будет примёнен ко всему маршруту. - Профиль будет применён только к следующему сегменту. + Пересчёт всего маршрута согласно выбранному профилю. + Расчёт маршрута для ближайшего сегмента. Следующий сегмент Весь трек Далее необходимо выбрать профиль навигации для определения порогового расстояния и привязки маршрута к ближайшей разрешённой дороге. - Выберите способ соединения точек прямой линией или рассчитайте маршрут между ними, как указано ниже. + Выберите, как соединять точки: прямой линией или строить маршрут по заданному профилю. При обратном направлении Все изменения будут утеряны. Уличная фотосъёмка From 0cf1eb76d2652b40fea8ed392497696aad06095c Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Wed, 23 Sep 2020 13:31:09 +0000 Subject: [PATCH 0295/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 3ef0d51e37..5f89b31530 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3899,4 +3899,7 @@ \n • Исправлены проблемы с импортом/экспортом настроек профиля \n \n + Последнее изменение + Имя: Я - А + Имя: А - Я \ No newline at end of file From 3ff58e29412fb6c5ad2f9f184b2ac061cb43b0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Tue, 22 Sep 2020 16:22:17 +0000 Subject: [PATCH 0296/1366] Translated using Weblate (Hungarian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-hu/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index 519a8cce66..97f76c0623 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -3893,4 +3893,7 @@ \n • Javítva a profilbeállítások importálásával / exportálásával kapcsolatos problémák \n \n + Utolsó módosítás + Név: Z–A + Név: A–Z \ No newline at end of file From c9fea9a3c48b452778f21ee09185831c73944d51 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Tue, 22 Sep 2020 17:07:29 +0000 Subject: [PATCH 0297/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-uk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 367b37541e..905af29b00 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -3896,4 +3896,7 @@ \n• Виправлено вади перенесення налаштувань профілю \n \n + Востаннє змінено + За назвою: Я — А + За назвою: А — Я \ No newline at end of file From 00b332ef9b48eb44c34b1c90f7d1087ad83693d6 Mon Sep 17 00:00:00 2001 From: ace shadow Date: Tue, 22 Sep 2020 18:49:46 +0000 Subject: [PATCH 0298/1366] Translated using Weblate (Slovak) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-sk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 379b112de9..a9fbf672f4 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -3899,4 +3899,7 @@ \n • Opravené problému s importom a exportom nastavení profilov \n \n + Naposledy zmenené + Názov: Z – A + Názov: A – Z \ No newline at end of file From 242cdfd3de0732c60c3483475d25f5c571cc02e5 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 23 Sep 2020 16:28:11 +0000 Subject: [PATCH 0299/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 4c30071193..c747a366f1 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1611,7 +1611,7 @@ \n \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. البحث قرب مركز الخريطة الحالية - العلامات النشطة + عدد خطوط التوجيه المباشر علامات الخريطة تخطي الحدود حدد الطرق التي تريد تجنبها أثناء التنقل. @@ -2499,8 +2499,8 @@ لإيقاف تشغيل الخريطة المتحركة. إبقاء القياس على الخريطة خروج بدون الحفظ؟ - خط إلى العلامة - سهم متجه إلى العلامة + رسم خط توجيه + سهم متجه للهدف عرض المتجاوز إخفاء المتجاوز إزالة من \"علامات الخريطة\" @@ -2592,7 +2592,7 @@ توقفت عند حدد مفضلة لإضافتها إلى العلامات. مجموعة مفضلة - علامتان + خطين علامة التعديلات %1$s, المبلغ %2$s mBTC مساهمي OSM المستفيدون @@ -2839,14 +2839,14 @@ \n• مباشر أوسماند الاشتراك الآن يدعم جميع أوسماند الميزات \n \n - نقرة لتنشيط العلامة + انقر لتنشيط توجيه الهدف إضافة ملاحظة صوتية أو فيديو أو صورة لكل نقطة على الخريطة، باستخدام قائمة السياق أو القطعة. ابحث عن المسارات مع نقاط الطريق حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق). نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر العلامة. يمكنك استيراد المجموعات المفضلة أو نقاط المسار كعلامات. ستظهر العلامات التي تم تجاوزها على هذه الشاشة. - خط مباشر من موقعك إلى العلامة النشطة. + خط مباشر من موقعك إلى الهدف. عرض سهم واحد أو اثنين ليشير إلى اتجاه العلامة النشطة. طريقة عرض المسافة من موقعي إلى العلامات النشطة. عدد الأسهم تجاه العلامات النشطة ( للملاحة في الصحراء). From 9cfeee848bbaeaf05940416e90a73dc083151338 Mon Sep 17 00:00:00 2001 From: nasr pen Date: Wed, 23 Sep 2020 16:19:41 +0000 Subject: [PATCH 0300/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 84 ++++++++++++++++---------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index c747a366f1..cec757522c 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -434,7 +434,7 @@ الموقع لم يحدد. تعديل الشفافية (0 - شفاف ، 255 - معتم ) إلغاء التحميل؟ - نشكرك على استخدام أوسماند. الكثير من مميزات هذا البرنامج بحاجة إلى بعض البيانات الإقليمية التي يمكنك تحميلها عبر \'إعدادات\'→ \'إدارة البيانات\'. بعد ذلك سوف تكون قادرا على عرض الخرائط، و تحديد العناوين ، والبحث عن النقاط المهمة ، والعثور على وسائل النقل العام . + نشكرك على استخدام أوسماند. الكثير من مميزات هذا البرنامج بحاجة إلى بعض البيانات الإقليمية التي يمكنك تحميلها عبر \'إعدادات\'← \'إدارة البيانات\'. بعد ذلك سوف تكون قادرا على عرض الخرائط، و تحديد العناوين ، والبحث عن النقاط المهمة ، والعثور على وسائل النقل العام . خريطة العالم العامة مطلوبة لعمل التطبيق بشكل سليم، وقد حددت للتحميل. لم يتم العثور على شيء. إذا لم تتمكن من إيجاد منطقتك، يمكنك صنعها بنفسك (انظر http://osmand.net ). إلى مدى قريب \"١٠٠م\" @@ -721,9 +721,9 @@ عكس اتجاه المسار استخدم الوجهة الحالية يمر على طول المسار باكمله - خريطة التنقل المتوفرة حاليا لهذا الموقع. -\n -\nلتفعليها \'القائمة\' → \'تكوين الخريطة\' → \'مصدر الخريطة ...\' → \'خرائط متجهة بدون اتصال\'. + خريطة التنقل متوفرة حالياً لهذا الموقع. +\n +\nلتفعليها \'القائمة\' ← \'ضبط الخريطة\' ← \'مصدر الخريطة\' ← \'الخريطة المحملة\'. مصدر التوجيه الصوتي اختيار قناة لتشغيل التوجيه الصوتي. صوت المكالمة الهاتفية ( كما يحاول قطع ستريو بلوتوث السيارة ) @@ -972,7 +972,7 @@ المفضلة المسارات إخفاء - إعداد الخريطة + ضبط الخريطة مصدر الخريطة… مصدر الخريطة عرض أسماء المفضلة @@ -1905,7 +1905,7 @@ فشل في الحصول على قائمة إصدارات التطبيق عملية تحميل إصدارات التطبيق جارية … حدد إصدار التطبيق للتثبيت - التوجيهات الصوتية غير متوفرة، يرجى الذهاب إلى \"إعدادات\" ← \"عامة\" ← \"التوجيه الصوتي\" وحدد أو حمل حزمة صوت. + التوجيهات الصوتية غير متوفرة، يرجى الذهاب إلى \"إدارة الخرائط\" ← \"تحميلات متاحة\" ← \"التوجيه الصوتي\" وحدد أو حمل حزمة صوت. اختيار قاعدة تحويل وضع نهار/ ليل. تحميل {0} ملف ({1} مب)؟ {0} عنصر محدد @@ -2131,7 +2131,7 @@ إخفاء %1$s إضافة فئة إنشاء عناصر - إعداد الخريطة + ضبط الخريطة الملاحة رسالة حدد الفئة لحفظ المفضلة فيها: @@ -2753,7 +2753,7 @@ اختر العنصر المناسب لا تفعل افعل - صور المقالة يمكن تحمل للاستخدام بدون اتصال. + صور المقالة يمكن تحملها للاستخدام بدون اتصال. \nدائماً متوفرة في \'اكتشف\'←\'خيارات\'. الصفحة متاحة على الإنترنت فقط. فتح في متصفح الويب؟ الصور المؤقتة @@ -3044,20 +3044,20 @@ تفضيل الطرق الغير معبدة. تحديث كل الخرائط هل أنت متأكد من رغبتك بتحديث (%1$d) خريطة؟ - • تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل. -\n -\n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط -\n -\n • إصلاحات للنمط الليلي -\n -\n • إصلاح العديد من مشاكل التوجيه في جميع أنحاء العالم -\n -\n • خريطة الأساس المحدثة مع شبكة طرق أكثر تفصيلا -\n -\n • تحديث المناطق التي غمرتها الفيضانات في جميع أنحاء العالم -\n -\n • توجيه التزلج: إضافة ملف تعريف الارتفاع وتعقيد المسار إلى تفاصيل المسار -\n + • تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل. +\n +\n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط +\n +\n • إصلاحات للنمط الليلي +\n +\n • إصلاح العديد من مشاكل التوجيه في جميع أنحاء العالم +\n +\n • خريطة الأساس المحدثة مع شبكة طرق أكثر تفصيلا +\n +\n • تحديث المناطق التي غمرتها الفيضانات في جميع أنحاء العالم +\n +\n • توجيه التزلج: إضافة وضع الارتفاع وتعقيد المسار إلى تفاصيل المسار +\n \n • إصلاحات أخرى \n \n @@ -3075,7 +3075,7 @@ إخفاء التضاريس إظهار/إخفاء التضاريس لا يمكن بدء تشغيل أداة تحويل النص إلى كلام. - تصدير الملف الشخصي + تصدير الوضع وضع أوسماند: %1$s الوضع \'%1$s\' موجود بالفعل، هل تريد استبداله؟ لا يمكن تصدير الوضع. @@ -3143,7 +3143,7 @@ إدارة أوضاع التطبيق … لكامل التطبيق الإعدادات - نسخة من ملف تعريف آخر + نسخ من وضع آخر قم بتشغيل الشاشة خريطة أثناء التنقل خريطة أثناء التنقل @@ -3191,7 +3191,7 @@ السرعة الافتراضية تغيير إعدادات السرعة الافتراضية تعيين حد السرعة الأدنى/الأعلى - ملف تعريف جديد + وضع جديد خروج مفاجئ فشل العملية الأخيرة لأوسماند. الرجاء مساعدتنا في التحسين من خلال مشاركة رسالة الخطأ. • أوضاع التطبيق: قم بإنشاء وضع مخصص لاحتياجاتك الخاصة ، باستخدام رمز ولون مخصصين @@ -3260,9 +3260,9 @@ عرض الإحداثيات سياسة الخصوصية ساعدنا في جعل أوسماند أفضل - السماح ل OsmAnd بجمع ومعالجة بيانات استخدام التطبيق المجهول. لا يتم جمع بيانات حول موقعك أو المواقع التي تعرضها على الخريطة. -\n -\nقم بإعدادها في أي وقت لاحق في \'الإعدادات\' → \'الخصوصية والأمان\'. + السماح ل OsmAnd بجمع ومعالجة بيانات استخدام التطبيق المجهول. لا يتم جمع بيانات حول موقعك أو المواقع التي تعرضها على الخريطة. +\n +\nقم بإعدادها في أي وقت لاحق في \'الإعدادات\' ← \'الخصوصية والأمان\'. اختر نوع البيانات التي تريد مشاركتها: الخرائط التي تم تنزيلها الشاشات المزارة @@ -3301,7 +3301,7 @@ لايمكن حذف الأوضاع الأساسية حفظ التغييرات احفظ تغييرات الوضع أولاً - حذف الملف الشخصي + حذف الوضع هل تريد حذف الوضع \"%s\" حدد وضع أساسي إسناد الوضع المخصص الخاص بك إلى أحد أوضاع التطبيق الافتراضية ، يحدد الإعداد الأساسي مثل الرؤية الافتراضية لعناصر واجهة المستخدم ووحدات السرعة والمسافة. وهذه هي أوضاع التطبيق الافتراضية ، إلى جانب أمثلة لأوضاع مخصصة يمكن تمديدها إلى: @@ -3384,7 +3384,7 @@ مظهر الوضع اختر الايقونة واللون والاسم تحرير قائمة الأوضاع - الملف الشخصي المحدد + الوضع المحدد بالضغط على %1$s، ستفقد كل تغييراتك. سيتم إعادة ضبط جميع إعدادات الوضع إلى الحالة الافتراضية بعد التثبيت. استعادة الضبط الافتراضي؟ @@ -3506,7 +3506,7 @@ تعطيل إعادة الحساب الحد الأدنى من المسافة لإعادة حساب المسار سيتم إعادة حساب المسار إذا كانت المسافة إلى المسار أطول من المعلمة المحددة - ملف تعريف مخصص + وضع مخصص الزاوية: %s° زاوية سيتم عرض جزء مستقيم إضافي بين موقعي والمسار المحسوب حتى يتم إعادة حساب المسار @@ -3533,9 +3533,9 @@ أسلوب التقديم استيراد ملف الrendering ستتم استعادة كافة إعدادات الوضع إلى حالتها الأصلية بعد إنشاء/استيراد هذا الوضع. - استعادة جميع إعدادات الملف الشخصي؟ - حفظ ملف تعريف جديد - لا يمكن عمل نسخة احتياطية من الملف الشخصي. + استعادة جميع إعدادات الوضع؟ + حفظ الوضع الجديد + لا يمكن عمل نسخة احتياطية لهذا الوضع. هل أنت متأكد من أنك تريد مسح البيانات المسجلة؟ استيراد البيانات من %1$s استيراد @@ -3579,7 +3579,7 @@ الثلج ملحق مخصص استبدل نقطة أخرى بالحالية. - تم تطبيق التغييرات على %1$s ملف تعريف. + تم تطبيق التغييرات على %1$s وضع. لايمكن قراءة %1$s. لايمكن كتابة %1$s. تعذر استيراد %1$s. @@ -3657,7 +3657,7 @@ اشتراك أوسماند لايف مشتريات أوسماند دليل رموز الخريطة. - الملفات الشخصية للملاحة + أوضاع الملاحة • خرائط جديدة للمنحدرات غير المتصلة بالإنترنت \n \n • التخصيص الكامل للمفضلات ونقاط الطرق GPX - الألوان المخصصة والأيقونات والأشكال @@ -3689,8 +3689,8 @@ استعادة ترتيب العناصر الافتراضية عودة إلى التحرير سيتم تبديل زر الإجراء التسجيل بين التشكيلات الجانبية المحددة. - إضافة ملف تعريف - تغيير ملف تعريف التطبيق + إضافة وضع + تغيير الوضع لم يتم العثور على الأوضاع المحددة لهذا الإجراء. خريطة عامة للعالم (تفصيلية) نوع غير معتمد @@ -3809,7 +3809,7 @@ حدد المسار للفتح. تم الكتابة فوق المسار - ملف تعريف التنقل + وضع التنقل حدد ملف المسار الذي سيتم إضافة مقطع جديد إليه. حفظ كمسار جديد عكس الطريق @@ -3818,7 +3818,7 @@ حدد كيفية توصيل النقاط، بخط مستقيم، أو حساب مسار بينها على النحو المحدد أدناه. مسار كامل المقطع التالي - بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد ملفات تعريف التنقل الخاصة بك لاستخدام هذا الخيار. + بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد أوضاع التنقل الخاصة بك لاستخدام هذا الخيار. بداية المسافة صور للشارع هل أنت متأكد أنك تريد إغلاق مسار الخطة دون حفظ؟ سوف تفقد كل التغييرات؟ @@ -3864,8 +3864,8 @@ المقطع السابق جميع المقاطع السابقة سيتم إعادة حساب المقطع المحدد فقط باستخدام الوضع المحدد. - سيتم إعادة حساب كافة الشرائح اللاحقة باستخدام ملف التعريف المحدد. - سيتم إعادة حساب كافة الشرائح السابقة باستخدام ملف التعريف المحدد. + سيتم إعادة حساب كافة الشرائح اللاحقة باستخدام الوضع المحدد. + سيتم إعادة حساب كافة الشرائح السابقة باستخدام الوضع المحدد. فتح المسار المحفوظ محفوظ مسار مبسط From be68c841134633a657aa075acb98fcff76d69941 Mon Sep 17 00:00:00 2001 From: Softmap Date: Tue, 22 Sep 2020 20:55:48 +0000 Subject: [PATCH 0301/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index cec757522c..a15f23f5ec 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3888,4 +3888,7 @@ \n• تم إصلاح المشكلات المتعلقة باستيراد/تصدير الأوضاع الشخصية \n \n + آخر تعديل + الاسم: أ – ي + الاسم: أ – ي \ No newline at end of file From bf1ea5d18a10ee3cd63d6ad59ead58ed73005fef Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Wed, 23 Sep 2020 14:19:35 +0000 Subject: [PATCH 0302/1366] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 4ce78f580e..a2c4186817 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -3896,4 +3896,7 @@ \n • Problemas corrigidos com importação/exportação de configurações de perfil \n \n" + Última modificação + Nome: Z – A + Nome: A – Z \ No newline at end of file From f3a971bd6b9047b6c68096d1be8420894c18bdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 22 Sep 2020 16:14:00 +0000 Subject: [PATCH 0303/1366] Translated using Weblate (Estonian) Currently translated at 99.3% (3466 of 3487 strings) --- OsmAnd/res/values-et/strings.xml | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index f05f7fbf4c..47d430d832 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -1581,7 +1581,7 @@ Paigalda versioon Kohanda rakenduse välimust. Rakenduse teema - Puudega kasutamise valikud + Erivajadusega kasutamise valikud Määra aadress Vali lemmik OSM täiendused @@ -1849,7 +1849,7 @@ Kuva joonlaud Teave Tagasi asukohta - Puudega kasutamise režiim + Erivajadusega kasutamise režiim Lülitab puudega kasutajatele mõeldud funktsioonid. Android süsteemi seadete kohaselt Tagasi menüüle @@ -1892,7 +1892,7 @@ Käivita automaatne teavitamine Lõpeta automaatne teavitamine Olen siin - Puudega kasutamise eelistused. + Erivajadusega kasutamisega seotud eelistused. Vara Normaalne Hilja @@ -3211,20 +3211,20 @@ \n • Lae GPX rajad OSM keskkonda üles otse rakendusest \n • Lisa huvipunkte ja lae need kohe üles OSM keskkonda (või hiljem internetühenduse tekkides) \n - OsmAnd on aktiivselt arendatud avatud lähtekoodiga tarkvara. Kõik saavad rakendusse panustada, teatades vigadest, parandades tõlkeid või kodeerides uusi funktsioone. Lisaks toetub projekt rahalisele toetusele koodide kodeerimiseks ja uute funktsioonide testimiseks. -\n Ligikaudne kaardi leviala ja kvaliteet: -\n • Lääne-Euroopa: **** -\n • Ida-Euroopa: *** -\n • Venemaa: *** -\n • Põhja-Ameerika: *** -\n • Lõuna-Ameerika: ** -\n • Aasia: ** -\n • Jaapan ja Korea: *** -\n • Lähis-Ida: ** -\n • Aafrika: ** -\n • Antarktika: * -\n Enamik maailma riike üle on allalaadimiseks saadaval! -\n Hangi oma riigis usaldusväärne navigaator - olgu see siis Prantsusmaa, Saksamaa, Mehhiko, UK, Hispaania, Holland, USA, Venemaa, Brasiilia või mõni muu. + OsmAnd on aktiivselt arendatud avatud lähtekoodiga tarkvara. Kõik saavad rakendusse panustada, teatades vigadest, parandades tõlkeid või luues uut funktsioonaalsust. Lisaks kasutab projekt rahalisele toetuset programmerimiseks ja uute funktsioonide testimiseks. +\n Ligikaudne kaardi leviala ja kvaliteet: +\n • Lääne-Euroopa: **** +\n • Ida-Euroopa: *** +\n • Venemaa: *** +\n • Põhja-Ameerika: *** +\n • Lõuna-Ameerika: ** +\n • Aasia: ** +\n • Jaapan ja Korea: *** +\n • Lähis-Ida: ** +\n • Aafrika: ** +\n • Antarktika: * +\n Enamik maailma riike on allalaadimiseks saadaval! +\n Hangi oma riigi jaoks usaldusväärne kaardirakendus - olgu see siis Prantsusmaa, Saksamaa, Mehhiko, Suurbritannia, Hispaania, Holland, Ameerika Ühendriigid, Venemaa, Brasiilia või mõni muu maa. OsmAnd + (OSM automatiseeritud navigeerimisjuhised) on kaardi- ja navigatsioonirakendus, millel on juurdepääs tasuta, ülemaailmsetele ja kvaliteetsetele OpenStreetMap (OSM) andmetele. \n Naudi hääl- ja optilist navigeerimist, HP-de (huvipunktide) vaatamist, GPX radade loomist ja haldamist, kasutades kõrgusjoonte visuaalset kuvamist ja kõrgusteavet, valikut autosõidu, jalgrattasõidu, jalakäijate režiimide, OSM\'i andmete muutmuise ja palju muu vahel. \n @@ -3755,4 +3755,11 @@ \n Peata teekonna salvestamine Jätka teekonna salvestamist + Režiim erivajadusega kasutajatele on sinu Android\'i seadmes välja lülitatud. + Muuda loendi järjestust ja peida kategooriaid. Kõiki muudatusi saad importida või eksportida koos profiilidega. + Valides ühe või mitu kategooriat võid lisada uue kohandatud kategooria. + Marsruutimine + Viimati muudetud + Nimi: Z – A + Nimi: A – Z \ No newline at end of file From 644a6f232b84b0ba1732e518f794aad957640f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 22 Sep 2020 17:48:00 +0000 Subject: [PATCH 0304/1366] Translated using Weblate (Turkish) Currently translated at 63.5% (2432 of 3824 strings) --- OsmAnd/res/values-tr/phrases.xml | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index 76b5305843..ed3292f096 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -674,8 +674,8 @@ Manastır Tarihi Manastır Dini alan - Wayside haçı - Yolkenarı tapınağı + Yol kenarı haçı + Yol kenarı türbesi Bilgilendirme Saat Seyahat acentesi @@ -2416,4 +2416,31 @@ Megalit türü: dolmen Megalit türü: menhir Toprak işi + Sıcaklık + Tür: gulag + Tür: nazi + Tür: çalışma kampı + Tür: savaş esiri kampı + Tür: toplama kampı + Eski hapishane kampı + Zirve haçı: evet + Haç + Bina türü: türbe + Bina türü: sinagog + Bina türü: bazilika + Bina türü: manastır + Bina türü: katedral + Bina türü: tapınak + Bina türü: cami + Bina türü: şapel + Bina türü: kilise + Heykeltıraş + Sanatçı + Meydan + Tarihi demiryolu + Tarihi darağacı + Tarihi harman yeri + Tarihi tren istasyonu + Tarihi çiftlik + Pa (müstahkem maori yerleşimi) \ No newline at end of file From a5b32a37f339771233023231d77ef8fdaf19cb1d Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 23 Sep 2020 02:17:42 +0000 Subject: [PATCH 0305/1366] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index c55a555aff..b12cc12a51 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3896,4 +3896,7 @@ \n • 修復設定檔的匯入/匯出問題 \n \n + 最後修改時間 + 名稱:Z – A + 名稱:A – Z \ No newline at end of file From 95af82e531b5b00083072a0682a11ca0d25bdd4d Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 23 Sep 2020 23:18:44 +0300 Subject: [PATCH 0306/1366] Select current navigation profile in attach roads --- .../src/main/java/net/osmand/util/Algorithms.java | 8 +++++--- OsmAnd/src/net/osmand/AndroidUtils.java | 10 ---------- OsmAnd/src/net/osmand/plus/MapMarkersHelper.java | 3 +-- .../measurementtool/GpxApproximationFragment.java | 15 ++++++++++++--- .../measurementtool/MeasurementToolFragment.java | 8 ++++++-- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index ea2869aaa3..bff9377ec3 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -119,9 +119,11 @@ public class Algorithms { } public static String getFileNameWithoutExtension(String name) { - int i = name.lastIndexOf('.'); - if (i >= 0) { - name = name.substring(0, i); + if (name != null) { + int index = name.lastIndexOf('.'); + if (index != -1) { + return name.substring(0, index); + } } return name; } diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index 740c826ab5..0efdd133f3 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -153,16 +153,6 @@ public class AndroidUtils { R.color.icon_color_default_light, R.color.wikivoyage_active_dark); } - public static String trimExtension(String src) { - if (src != null) { - int index = src.lastIndexOf('.'); - if (index != -1) { - return src.substring(0, index); - } - } - return src; - } - public static String addColon(OsmandApplication app, @StringRes int stringRes) { return app.getString(R.string.ltr_or_rtl_combine_via_colon, app.getString(stringRes), "").trim(); } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 636fcddb72..c168047ba9 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -8,7 +8,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; -import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; @@ -526,7 +525,7 @@ public class MapMarkersHelper { private MapMarkersGroup createGPXMarkerGroup(File fl) { return new MapMarkersGroup(getMarkerGroupId(fl), - AndroidUtils.trimExtension(fl.getName()), + Algorithms.getFileNameWithoutExtension(fl.getName()), MapMarkersGroup.GPX_TYPE); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java index 87edaaf71b..924cea3ab0 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/GpxApproximationFragment.java @@ -298,13 +298,15 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment return (menuState & (MenuState.HEADER_ONLY | MenuState.HALF_SCREEN)) != 0; } - public static void showInstance(@NonNull FragmentManager fm, @Nullable Fragment targetFragment, @NonNull LocationsHolder locationsHolder) { + public static void showInstance(@NonNull FragmentManager fm, @Nullable Fragment targetFragment, + @NonNull LocationsHolder locationsHolder, @Nullable ApplicationMode appMode) { try { if (!fm.isStateSaved()) { GpxApproximationFragment fragment = new GpxApproximationFragment(); fragment.setRetainInstance(true); fragment.setTargetFragment(targetFragment, REQUEST_CODE); fragment.setLocationsHolder(locationsHolder); + fragment.setSnapToRoadAppMode(appMode); fm.beginTransaction() .replace(R.id.fragmentContainer, fragment, TAG) .addToBackStack(TAG) @@ -348,12 +350,19 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment @Override public void onProfileSelect(ApplicationMode applicationMode) { - if (snapToRoadAppMode != applicationMode) { - snapToRoadAppMode = applicationMode; + if (setSnapToRoadAppMode(applicationMode)) { calculateGpxApproximation(); } } + public boolean setSnapToRoadAppMode(ApplicationMode appMode) { + if (appMode != null && snapToRoadAppMode != appMode) { + snapToRoadAppMode = appMode; + return true; + } + return false; + } + public LocationsHolder getLocationsHolder() { return locationsHolder; } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 7d6818a9d6..42b176201b 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -706,8 +706,12 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route case SnapTrackWarningFragment.CONTINUE_RESULT_CODE: MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { + ApplicationMode mode = editingCtx.getAppMode(); + if (mode == ApplicationMode.DEFAULT || "public_transport".equals(mode.getRoutingProfile())) { + mode = null; + } GpxApproximationFragment.showInstance(mapActivity.getSupportFragmentManager(), - this, new LocationsHolder(editingCtx.getPoints())); + this, new LocationsHolder(editingCtx.getPoints()), mode); } break; } @@ -1522,7 +1526,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date()); displayedName = FileUtils.createUniqueFileName(requireMyApplication(), suggestedName, GPX_INDEX_DIR, GPX_FILE_EXT); } else { - displayedName = AndroidUtils.trimExtension(new File(gpxData.getGpxFile().path).getName()); + displayedName = Algorithms.getFileNameWithoutExtension(new File(gpxData.getGpxFile().path).getName()); } return displayedName; } From 8a59bfe127fac273200bc38a91328dc9655fe52a Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 24 Sep 2020 11:07:28 +0300 Subject: [PATCH 0307/1366] Use a new arrow for track direction --- .../views/layers/geometry/GpxGeometryWay.java | 4 +-- .../geometry/GpxGeometryWayContext.java | 2 +- .../layers/geometry/GpxGeometryWayDrawer.java | 36 ++++++++++--------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java index 76bee7cdf2..24d49df0b1 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java @@ -132,7 +132,7 @@ public class GpxGeometryWay extends GeometryWay { - private static final float DIRECTION_ARROW_CIRCLE_MULTIPLIER = 1.5f; - public GpxGeometryWayDrawer(GpxGeometryWayContext context) { super(context); } @@ -33,16 +30,23 @@ public class GpxGeometryWayDrawer extends GeometryWayDrawer arrowsWayStyle.getTrackWidth()) { - Paint paint = context.getPaintIcon(); - paint.setColor(arrowsWayStyle.getTrackColor()); - paint.setStrokeWidth(arrowWidth * DIRECTION_ARROW_CIRCLE_MULTIPLIER); - canvas.drawPoint(x, y, paint); - } + float newWidth = arrowsWayStyle.getTrackWidth() / 2f; + float paintH2 = bitmap.getHeight() / 2f; + float paintW2 = newWidth / 2f; + + Matrix matrix = getMatrix(); + matrix.reset(); + matrix.postScale(newWidth / bitmap.getWidth(), 1); + matrix.postRotate((float) angle, paintW2, paintH2); + matrix.postTranslate(x - paintW2, y - paintH2); + + Paint paint = context.getPaintIconCustom(); + Integer pointColor = style.getPointColor(); + paint.setColorFilter(new PorterDuffColorFilter(pointColor, PorterDuff.Mode.SRC_IN)); + canvas.drawBitmap(bitmap, matrix, paint); } - super.draw(canvas, context); } } -} +} \ No newline at end of file From 2e388a060658fd52c3ad3e3e630fc446cdcf9b6d Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 24 Sep 2020 11:17:40 +0300 Subject: [PATCH 0308/1366] Fix #9623 part 2 (Refactoring) --- .../net/osmand/plus/ContextMenuAdapter.java | 8 ++-- .../osmand/plus/activities/MapActivity.java | 4 ++ .../osmand/plus/dashboard/DashboardOnMap.java | 35 +++++++--------- .../osmand/plus/dialogs/ConfigureMapMenu.java | 41 +++++++------------ .../osmand/plus/render/RendererRegistry.java | 27 +----------- 5 files changed, 38 insertions(+), 77 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 3ea7eee4d7..795bc7224c 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -202,9 +202,9 @@ public class ContextMenuAdapter { } } items.removeAll(itemsToRemove); - this.arrayAdapter = new ContextMenuArrayAdapter(activity, layoutId, R.id.title, + arrayAdapter = new ContextMenuArrayAdapter(activity, layoutId, R.id.title, items.toArray(new ContextMenuItem[items.size()]), app, lightTheme, changeAppModeListener); - return this.arrayAdapter; + return arrayAdapter; } public class ContextMenuArrayAdapter extends ArrayAdapter { @@ -628,8 +628,8 @@ public class ContextMenuAdapter { } public void notifyDataSetChanged() { - if (this.arrayAdapter != null) { - this.arrayAdapter.notifyDataSetChanged(); + if (arrayAdapter != null) { + arrayAdapter.notifyDataSetChanged(); } } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index e23e596dcf..2816e7d5b0 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -1466,6 +1466,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven } protected void onPostExecute(Void result) { + DashboardOnMap dashboard = getDashboard(); + if (dashboard != null) { + dashboard.onMapSettingsUpdated(); + } } }.executeOnExecutor(singleThreadExecutor, (Void) null); diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index 74d61c7479..127837c7be 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -96,6 +96,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_STYLE_ID; + public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInformationListener { private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(DashboardOnMap.class); @@ -130,7 +132,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo private ArrayAdapter listAdapter; private OnItemClickListener listAdapterOnClickListener; - private DashboardStateListener dashboardStateListener; + private ConfigureMapMenu configureMapMenu; private boolean visible = false; private DashboardType visibleType; @@ -657,20 +659,14 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo fragment.show(mapActivity.getSupportFragmentManager(), MapillaryFirstDialogFragment.TAG); settings.MAPILLARY_FIRST_DIALOG_SHOWN.set(true); } + + deleteTmpReferences(); } - notifyDashboardVisibilityStateListener(visible); mapActivity.updateStatusBarColor(); } - private void notifyDashboardVisibilityStateListener(boolean visible) { - if (dashboardStateListener != null) { - if (visible) { - dashboardStateListener.onShowDashboard(); - } else { - dashboardStateListener.onHideDashboard(); - dashboardStateListener = null; - } - } + private void deleteTmpReferences() { + configureMapMenu = null; } public void updateDashboard() { @@ -718,8 +714,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo if (visibleType == DashboardType.CONFIGURE_SCREEN) { cm = mapActivity.getMapLayers().getMapWidgetRegistry().getViewConfigureMenuAdapter(mapActivity); } else if (visibleType == DashboardType.CONFIGURE_MAP) { - ConfigureMapMenu configureMapMenu = new ConfigureMapMenu(mapActivity); - dashboardStateListener = configureMapMenu; + configureMapMenu = new ConfigureMapMenu(mapActivity); cm = configureMapMenu.createListAdapter(mapActivity); } else if (visibleType == DashboardType.LIST_MENU) { cm = mapActivity.getMapActions().createMainOptionsMenu(); @@ -1047,6 +1042,12 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo } } + public void onMapSettingsUpdated() { + if (configureMapMenu != null) { + configureMapMenu.updateMenuItem(MAP_STYLE_ID); + } + } + public void updateLocation(final boolean centerChanged, final boolean locationChanged, final boolean compassChanged) { if (inLocationUpdate) { @@ -1330,12 +1331,4 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo @Override public void routeWasFinished() { } - - public interface DashboardStateListener { - - void onShowDashboard(); - - void onHideDashboard(); - - } } diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 900ada6a20..a48421e373 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -37,11 +37,9 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SettingsActivity; -import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.render.RendererRegistry; -import net.osmand.plus.render.RendererRegistry.OnChangeRenderingRuleListener; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings.ListStringPreference; @@ -100,7 +98,7 @@ import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_DETAI import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_HIDE; import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_ROUTES; -public class ConfigureMapMenu implements DashboardOnMap.DashboardStateListener { +public class ConfigureMapMenu { private static final Log LOG = PlatformUtil.getLog(ConfigureMapMenu.class); public static final String TAG = ConfigureMapMenu.class.getName(); public static final String HIKING_ROUTES_OSMC_ATTR = "hikingRoutesOSMC"; @@ -284,9 +282,7 @@ public class ConfigureMapMenu implements DashboardOnMap.DashboardStateListener { final OsmandSettings settings = app.getSettings(); final int selectedProfileColorRes = settings.APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode); final int selectedProfileColor = ContextCompat.getColor(app, selectedProfileColorRes); - RendererRegistry rr = app.getRendererRegistry(); - RenderingRulesStorage storage = rr.getCurrentSelectedRenderer(); - String renderDescr = getRenderDescr(activity, storage); + String renderDescr = getRenderDescr(app); adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_map_rendering, activity) .setId(MAP_RENDERING_CATEGORY_ID) @@ -957,11 +953,13 @@ public class ConfigureMapMenu implements DashboardOnMap.DashboardStateListener { dialog.show(); } - protected String getRenderDescr(Context ctx, RenderingRulesStorage storage) { + protected String getRenderDescr(OsmandApplication app) { + RendererRegistry rr = app.getRendererRegistry(); + RenderingRulesStorage storage = rr.getCurrentSelectedRenderer(); if (storage == null) { return ""; } - String translation = RendererRegistry.getTranslatedRendererName(ctx, storage.getName()); + String translation = RendererRegistry.getTranslatedRendererName(app, storage.getName()); return translation == null ? storage.getName() : translation; } @@ -1122,25 +1120,16 @@ public class ConfigureMapMenu implements DashboardOnMap.DashboardStateListener { } } - @Override - public void onShowDashboard() { - getMyApplication().getRendererRegistry() - .addOnChangeRenderingRuleListener(TAG, new OnChangeRenderingRuleListener() { - @Override - public void onRenderingRuleChanged(RenderingRulesStorage currentSelectedRender) { - if (contextMenuAdapter != null) { - ContextMenuItem item = contextMenuAdapter.getItemById(MAP_STYLE_ID); - String renderDescr = getRenderDescr(mapActivity, currentSelectedRender); - item.setDescription(renderDescr); - contextMenuAdapter.notifyDataSetChanged(); - } - } - }); - } + public void updateMenuItem(String itemId) { + OsmandApplication app = getMyApplication(); + if (app == null) return; - @Override - public void onHideDashboard() { - getMyApplication().getRendererRegistry().removeOnChangeRenderingRuleListener(TAG); + if (MAP_STYLE_ID.equals(itemId) && contextMenuAdapter != null) { + ContextMenuItem item = contextMenuAdapter.getItemById(MAP_STYLE_ID); + String renderDescr = getRenderDescr(app); + item.setDescription(renderDescr); + contextMenuAdapter.notifyDataSetChanged(); + } } private OsmandApplication getMyApplication() { diff --git a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java index e20d90c27a..b96a2dbd5e 100644 --- a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java +++ b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java @@ -25,7 +25,6 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; @@ -50,8 +49,7 @@ public class RendererRegistry { private RenderingRulesStorage defaultRender = null; private RenderingRulesStorage currentSelectedRender = null; - private Map onChangeRenderingRuleListeners = new HashMap<>(); - + private Map externalRenderers = new LinkedHashMap(); private Map internalRenderers = new LinkedHashMap(); @@ -338,20 +336,6 @@ public class RendererRegistry { public void setCurrentSelectedRender(final RenderingRulesStorage currentSelectedRender) { this.currentSelectedRender = currentSelectedRender; - notifyChangeRenderRuleListeners(); - } - - public void notifyChangeRenderRuleListeners() { - app.runInUIThread(new Runnable() { - @Override - public void run() { - for (OnChangeRenderingRuleListener listener : onChangeRenderingRuleListeners.values()) { - if (listener != null) { - listener.onRenderingRuleChanged(currentSelectedRender); - } - } - } - }); } public void setRendererLoadedEventListener(IRendererLoadedEventListener listener) { @@ -378,15 +362,6 @@ public class RendererRegistry { return externalRenderers; } - public void addOnChangeRenderingRuleListener(@NonNull String key, - @NonNull OnChangeRenderingRuleListener listener) { - onChangeRenderingRuleListeners.put(key, listener); - } - - public void removeOnChangeRenderingRuleListener(@NonNull String key) { - onChangeRenderingRuleListeners.remove(key); - } - public interface OnChangeRenderingRuleListener { void onRenderingRuleChanged(RenderingRulesStorage currentSelectedRender); } From 7534f8b28bcdaf24006e6e3caff2f88316effc0d Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 24 Sep 2020 11:25:04 +0300 Subject: [PATCH 0309/1366] Fix #9623 part 3 (delete useless code) --- OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java | 1 - OsmAnd/src/net/osmand/plus/render/RendererRegistry.java | 4 ---- .../plus/settings/fragments/ConfigureMenuItemsFragment.java | 2 +- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index a48421e373..44699c2451 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -100,7 +100,6 @@ import static net.osmand.render.RenderingRuleStorageProperties.UI_CATEGORY_ROUTE public class ConfigureMapMenu { private static final Log LOG = PlatformUtil.getLog(ConfigureMapMenu.class); - public static final String TAG = ConfigureMapMenu.class.getName(); public static final String HIKING_ROUTES_OSMC_ATTR = "hikingRoutesOSMC"; public static final String CURRENT_TRACK_COLOR_ATTR = "currentTrackColor"; public static final String CURRENT_TRACK_WIDTH_ATTR = "currentTrackWidth"; diff --git a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java index b96a2dbd5e..d382fa9882 100644 --- a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java +++ b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java @@ -361,8 +361,4 @@ public class RendererRegistry { public Map getExternalRenderers() { return externalRenderers; } - - public interface OnChangeRenderingRuleListener { - void onRenderingRuleChanged(RenderingRulesStorage currentSelectedRender); - } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java index 43cd0d59eb..731ffc2c38 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java @@ -197,7 +197,7 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment contextMenuAdapter = ((MapActivity) activity).getMapActions().createMainOptionsMenu(); break; case CONFIGURE_MAP: - ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity)activity); + ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity) activity); contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity); break; case CONTEXT_MENU_ACTIONS: From 80edc693c220bb9e1914cc226db72066752c9aae Mon Sep 17 00:00:00 2001 From: sergosm Date: Thu, 24 Sep 2020 11:29:08 +0300 Subject: [PATCH 0310/1366] '.gpx' extension --- .../SaveAsNewTrackBottomSheetDialogFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java index 231182be8b..64eee7f8ee 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java @@ -298,7 +298,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial if (folderName != null && !dir.getName().equals(folderName)) { source = new File(dir, folderName); } - source = new File(source, fileName + IndexConstants.GPX_FILE_EXT); + source = new File(source, fileName); return source; } From b8a10322956cf1fbe8349bc0767c958b45166120 Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 24 Sep 2020 11:29:49 +0300 Subject: [PATCH 0311/1366] Fix #9623 part 4 (remove tautology) --- .../src/net/osmand/plus/dashboard/DashboardOnMap.java | 2 +- .../src/net/osmand/plus/dialogs/ConfigureMapMenu.java | 10 +++++----- .../settings/fragments/ConfigureMenuItemsFragment.java | 2 +- .../settings/fragments/ConfigureMenuRootFragment.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index 127837c7be..4c2c4a6a8d 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -715,7 +715,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo cm = mapActivity.getMapLayers().getMapWidgetRegistry().getViewConfigureMenuAdapter(mapActivity); } else if (visibleType == DashboardType.CONFIGURE_MAP) { configureMapMenu = new ConfigureMapMenu(mapActivity); - cm = configureMapMenu.createListAdapter(mapActivity); + cm = configureMapMenu.createListAdapter(); } else if (visibleType == DashboardType.LIST_MENU) { cm = mapActivity.getMapActions().createMainOptionsMenu(); } else if (visibleType == DashboardType.ROUTE_PREFERENCES) { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 44699c2451..d9a60adff3 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -110,7 +110,7 @@ public class ConfigureMapMenu { private int selectedLanguageIndex; private boolean transliterateNames; - private MapActivity mapActivity; + private MapActivity ma; private ContextMenuAdapter contextMenuAdapter; public interface OnClickListener { @@ -118,10 +118,10 @@ public class ConfigureMapMenu { } public ConfigureMapMenu(MapActivity mapActivity) { - this.mapActivity = mapActivity; + this.ma = mapActivity; } - public ContextMenuAdapter createListAdapter(final MapActivity ma) { + public ContextMenuAdapter createListAdapter() { OsmandApplication app = ma.getMyApplication(); boolean nightMode = app.getDaynightHelper().isNightModeForMapControls(); int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; @@ -134,7 +134,7 @@ public class ConfigureMapMenu { adapter.setChangeAppModeListener(new OnClickListener() { @Override public void onClick() { - ma.getDashboard().updateListAdapter(createListAdapter(ma)); + ma.getDashboard().updateListAdapter(createListAdapter()); } }); List customRules = getCustomRules(app, @@ -1132,7 +1132,7 @@ public class ConfigureMapMenu { } private OsmandApplication getMyApplication() { - return mapActivity.getMyApplication(); + return ma.getMyApplication(); } private static class StringSpinnerArrayAdapter extends ArrayAdapter { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java index 731ffc2c38..926264aceb 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java @@ -198,7 +198,7 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment break; case CONFIGURE_MAP: ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity) activity); - contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity); + contextMenuAdapter = configureMapMenu.createListAdapter(); break; case CONTEXT_MENU_ACTIONS: MapContextMenu menu = ((MapActivity) activity).getContextMenu(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java index b47a761e8b..f7b2dda412 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java @@ -286,7 +286,7 @@ public class ConfigureMenuRootFragment extends BaseOsmAndFragment { break; case CONFIGURE_MAP: ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity) activity); - contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity); + contextMenuAdapter = configureMapMenu.createListAdapter(); break; case CONTEXT_MENU_ACTIONS: MapContextMenu menu = ((MapActivity) activity).getContextMenu(); From 4af66bf010528c756175f84d600cebff647bc542 Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Wed, 23 Sep 2020 23:50:22 +0000 Subject: [PATCH 0312/1366] Translated using Weblate (Japanese) Currently translated at 98.7% (3443 of 3487 strings) --- OsmAnd/res/values-ja/strings.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 7193842fe5..80f0b62286 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -7,7 +7,7 @@ 見つからないデータ 選択された言語用のデータはインストールされて いません。マーケットに行ってインストールしますか? - GPXルートを反転 + 経路を反転 現在の目的地を使用 経路全体を通過する メニューの[マップダウンロード]などから、この場所のオフラインベクターマップをダウンロードするか『オンラインマップ』プラグインを有効にしてください。 @@ -3842,7 +3842,7 @@ POIの更新は利用できません 経路ファイルを記録、またはインポートします 経路・経由地点を追加 経路・経由地点を追加 - 道路に貼り付ける + 道路に沿わせる 旅程の記録 経路ファイルとして保存 経路を辿る @@ -3897,4 +3897,7 @@ POIの更新は利用できません (最近使用したアプリを介して) OsmAndを終了すると、GPXの記録が一時停止されます(バックグラウンドサービスインジケーターがAndroid通知バーから消えます。) 一般的な経路記録の記録間隔を定義します(マップ画面の\'GPX\'ボタンを使用) 保存されました + 最終更新日 + 名称: 降順(Z-A) + 名称: 昇順(A-Z) \ No newline at end of file From 482b5db5045bfd281e4e96158b7453458a24cefb Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Thu, 24 Sep 2020 07:51:49 +0000 Subject: [PATCH 0313/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 5f89b31530..035ea9609b 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -2065,7 +2065,7 @@ Разбиение на клипы Использовать разбиение на клипы Циклическая перезапись клипов при превышении заданного объёма хранилища. - Обратить пункты отправления и назначения + Поменять местами пункты отправления и назначения Удалить Подземные объекты Данные недоступны From 05b29d05bbb6238e360f394d7b8f07e24d5d3d70 Mon Sep 17 00:00:00 2001 From: Mirco Zorzo Date: Wed, 23 Sep 2020 20:42:38 +0000 Subject: [PATCH 0314/1366] Translated using Weblate (Italian) Currently translated at 90.2% (3146 of 3487 strings) --- OsmAnd/res/values-it/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 018ca3edb1..e806eff554 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -3900,4 +3900,7 @@ \n \n Traccia semplificata + Ultimo modificato + Nome: Z – A + Nome: A – Z \ No newline at end of file From a8ddbeb4e39fdd0c9c15a3f9ce96e2f9fc06e20b Mon Sep 17 00:00:00 2001 From: Viktar Vauchkevich Date: Wed, 23 Sep 2020 20:22:02 +0000 Subject: [PATCH 0315/1366] Translated using Weblate (Belarusian) Currently translated at 99.9% (3486 of 3487 strings) --- OsmAnd/res/values-be/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index 0696333fe4..2ac856d032 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -3954,4 +3954,7 @@ \n • Выпраўлены праблемы з імпартам / экспартам налад профілю \n \n + Апошняя змена + Назва: Я — А + Назва: А — Я \ No newline at end of file From aab5c85dbf49a67ce0c46d9c53c9aae531bbb881 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Thu, 24 Sep 2020 10:15:37 +0000 Subject: [PATCH 0316/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 70 ++++++++++++++++---------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index a15f23f5ec..944fa1130e 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1140,7 +1140,7 @@ ترتيب حسب المسافة ترتيب حسب الاسم عرض أزرار التقريب أثناء الملاحة. - حدد الوجهات + حدد الوجهة إحداثية أرقام المنازل غير مسموح استخدام تحذيرات كاميرا السرعة بالقانون في العديد من البلدان (ألمانيا وفرنسا، وإيطاليا، وغيرها). أوسماند لا تتحمل أي مسؤولية إذا كنت تنتهك القانون. الرجاء انقر فوق \"نعم\" فقط إذا كنت مؤهلاً استخدام هذه الميزة. @@ -1390,7 +1390,7 @@ قطار المسار الحالي مستوى البطارية - تغيير موقع العلامة + تغيير موقع التوجيه المباشر تابعنا اتجاه صدى الصوت الملاحة عبر أوسماند لايف @@ -1411,7 +1411,7 @@ وضع الخريطة رقيقة متوسط - لم تضف علامات على الخريطة + لم تضف توجيه مباشر على الخريطة لم يتم العثور على نقاط الطريق التقرير سمح الآن للتطبيق بالكتابة على وحدة التخزين الخارجية. الرجاء إعادة تشغيله يدويا. @@ -1472,7 +1472,7 @@ يحتوي اسم الملف على حرف غير قانوني تقرير عن خرائط العالم - حرك الخريطة لتغيير مكان العلامة + حرك الخريطة لتغيير مكان التوجيه المباشر إشارة صوتية عند اتجاه نقطة الوصول. اشر عن اتجاه نقطة الهدف بالاهتزاز. @@ -1591,7 +1591,7 @@ حرك للاسفل اسم مستخدم و كلمة سر OSM نحن بحاجة اليه لكي نوفر لك معلومات حول المساهمات. - حدد علامة الخريطة + حدد توجيه مباشر عرض شريط الشفافية لا توجد مساحة كافية! \n {3} MB مطلوب مؤقتا ، {1} ميجا بايت بشكل دائم. @@ -1607,12 +1607,12 @@ انعطف يسارا واذهب هذا الملحق يوفير خرائط بحرية للزوارق والمراكب الشراعية وأنواع أخرى من الرياضات المائية. \n -\nخريطة خاصة إضافية للتطبيق ستقدم كل علامات الملاحة البحرية سواء داخلية أو شاطئية وكذلك جدول للرموز. وصف كل علامة ملاحة يوفر التفاصيل اللازمة للتعرف عليها ومعانيها (الفئة، الشكل، اللون، التسلسل، المرجع...إلخ.). +\nخريطة خاصة إضافية للتطبيق ستقدم كل علامات الملاحة البحرية سواء داخلية أو شاطئية وكذلك جدول للرموز. وصف كل وجهة ملاحة يوفر التفاصيل اللازمة للتعرف عليها ومعانيها (الفئة، الشكل، اللون، التسلسل، المرجع...إلخ.). \n \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. البحث قرب مركز الخريطة الحالية عدد خطوط التوجيه المباشر - علامات الخريطة + التوجيه المباشر تخطي الحدود حدد الطرق التي تريد تجنبها أثناء التنقل. الفئات @@ -1630,10 +1630,10 @@ الخرائط الموجودة انتقال للأعلى التعديلات %1$s ، الرتبة %2$s ، مجموع التعديلات %3$s - العلامة الأولى للخريطة - العلامة الثانية للخريطة - إضافة إلى علامات الخريطة - حذف كافة العلامات النشطة على الخريطة؟ + التوجيه المباشرالأول للخريطة + التوجيه المباشرالثاني للخريطة + إضافة إلى التوجيه المباشر + حذف كافة التوجيه المباشرالنشط على الخريطة؟ علامة على الخريطة عرض المضلعات الحالة @@ -1750,7 +1750,7 @@ خطأ تحيين القائمة المحلية لPOI. تحيين الPOI قم بتحميل مذكرة OSM الخاصة بك دون الكشف عن هويتك أو باستخدام ملف تعريف OpenStreetMap.org . - إضافة جميع النقاط إلى علامات الخريطة؟ + إضافة جميع النقاط إلى التوجيه المباشر؟ مسح السجلات ؟ إظهار مسارات الدراجة الجبلية يمكنك إزالة التحديثات المحملة والرجوع إلى الإصدار الأصلي للخريطة @@ -2312,7 +2312,7 @@ إظهار نقاط ومعالم العمق. بدء مقطع جديدة بعد فارق 6 دقائق، مسار جديد بعد فارق 2 ساعة، أو ملف جديد بعد فارق أطول إذا تغير التاريخ. متوقف مؤقتاً - قد يكون المسار طويلا جداً للحساب. يرجى إضافة وجهات وسطى إذا لم يتم العثور على نتيجة خلال 10 دقائق. + قد يكون المسار طويلا جدا للحساب. يرجى إضافة وجهات وسطى إذا لم يتم العثور على نتيجة خلال 10 دقائق. أوسماند(توجيهات OSM للتنقل الآلية) تطبيق خريطة وتنقل مع إمكانية الوصول إلى بيانات (OSM) مجاناً وفي جميع أنحاء العالم، وبجودة عالية \n \n. استمتع بمستكشف بالصوت والصورة، وعرض POI (نقاط الاهتمام)، إنشاء وإدارة مسارات GPX، استخدام عرض ارتفاع بيانات الخطوط المحيطية (عن طريق الملحق)، اختيار بين نمط القيادة، ركوب الدراجات والمشاة، التعديل على الموقع وغيرها. @@ -2482,12 +2482,12 @@ عتبة توجيه الخريطة حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'. تم نقل جميع العلامات إلى السجل - تم نقل العلامة إلى السجل - العلامة نقلت كنشطه + تم نقل التوجيه المباشرإلى السجل + انتقل التوجيه المباشر نشط قائمة مجموعات آخر استخدام : %1$s - تنشيط العلامة + تنشيط التوجيه المباشر اليوم أمس آخر ٧ أيام @@ -2503,12 +2503,12 @@ سهم متجه للهدف عرض المتجاوز إخفاء المتجاوز - إزالة من \"علامات الخريطة\" + إزالة من \"التوجيه المباشر\" تنازلي تصاعدي تاريخ الإضافة ترتيب حسب: - حدد كيفية الإشارة إلى المسافة والاتجاه لعلامات الخريطة على شاشة الخريطة: + حدد كيفية الإشارة إلى المسافة والاتجاه للتوجيه المباشر على شاشة الخريطة: استخدم الموقع أضف موقعك كنقطة أولى لتخطيط طريق مثالي. موقعي @@ -2536,12 +2536,12 @@ أظهر الخريطة تم حساب المسار رحلة ذهاب وإياب - يجب عليك إضافة علامة واحدة على الأقل لاستخدام هذه الوظيفة. + يجب عليك إضافة توجيه مباشر واحد على الأقل لاستخدام هذه الوظيفة. تنسيق خاطئ أدخل اسم جديد عودة عرض - تمت إضافة نقاط الطريق إلى علامات الخريطة + تمت إضافة نقاط الطريق إلى التوجيه المباشر للخريطة إدخال خاطئ يمكن استيرادها كنقاط مفضلة، أو كملف GPX. استيراد كملف GPX @@ -2549,15 +2549,15 @@ استيراد ملف نقرة على الخريطة ستفعل أزرار التحكم والويدجت. شاشة كاملة - علامة مُجتازة + توجيه مباشر مجتاز إنشاء أو تعديل عناصر OSM قم بإنشاء أو تعديل نقاط الاهتمام OSM ، وفتح ملاحظات OSM أو التعليق عليها ، والمساهمة في ملفات GPX المسجلة. حذف مُعدلة تمت الإضافة تعديل طلب البحث. - تم تنشيط العلامة %s. - انقر على العلامة في الخريطة لجعلها أعلى العلامات النشطة بدون فتح القائمة. + تم تنشيط التوجيه المباشر%s. + انقر على التوجيه المباشر في الخريطة لجعله الاعلى بدون فتح القائمة. تدوين ملاحظات! بدون حد زمني اقرأ المقال كاملا @@ -2570,22 +2570,22 @@ يفتح أبوابه على إجراءات إضافية إجراءات - علامة + خط الملاحظات حسب التاريخ حسب التاريخ حسب النوع المزيد - العلامة + المظهر على الخريطة نقاط المسار إضافة مجموعة - قم بإنشاء علامات على الخريطة ! + قم بإنشاء التوجيه المباشر على الخريطة ! استيراد مجموعات عدد الأرقام اليمين اليسار لصق الانتقال إلى الحقل التالي - تعديل تسمية العلامة + إعادة تسمية التوجيه المباشر مجموع التبرعات تسميات POI بدون اسم @@ -2593,7 +2593,7 @@ حدد مفضلة لإضافتها إلى العلامات. مجموعة مفضلة خطين - علامة + التوجيه المباشر التعديلات %1$s, المبلغ %2$s mBTC مساهمي OSM المستفيدون الشتاء و التزحلق @@ -2693,7 +2693,7 @@ تنزيل الكل إعادة تشغيل التطبيق إشارة مرجعية - نقاط بالطريق تم إزالتها من علامات الخريطة + نقاط بالطريق تم إزالتها من التوجيه المباشر للخريطة بواسطة أوسماند الأسعار والاشتراك شهري @@ -2708,14 +2708,14 @@ يجدد سنويا حدد فترة الدفع المناسبة لك: تبرعات مساعدة صندوق رسم الخرائط OSM. - حذف العلامة \'%s\'؟ - تعديل العلامة + حذف التوجيه المباشر \'%s\'؟ + تعديل التوجيه المباشر بحث عن شارع اختر المدينة أولاً استعادة تطبيق من طرف ثالث - عند التفعيل ستبقى العلامات المضافة من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"علامة مُجتازة\". إذا كانت المجموعة غير نشطة ستختفي العلامات من الخريطة. - إبقاء العلامات المتجاوزة على الخريطة + عند التفعيل سيبقى التوجيه المباشر المضاف من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز التوجيه المباشر\". إذا كانت المجموعة غير نشطة ستختفي الوجهات المباشرة من الخريطة. + إبقاء التوجيه المباشر المتجاوز على الخريطة هناك المزيد من وسائل النقل في هذا الموقف. يرجى إعطاء إذن تحديد الموقع للتطبيق لكي يواصل. شكرا على الرد @@ -2843,11 +2843,11 @@ إضافة ملاحظة صوتية أو فيديو أو صورة لكل نقطة على الخريطة، باستخدام قائمة السياق أو القطعة. ابحث عن المسارات مع نقاط الطريق حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق). - نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر العلامة. + نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر التوجيه المباشر. يمكنك استيراد المجموعات المفضلة أو نقاط المسار كعلامات. ستظهر العلامات التي تم تجاوزها على هذه الشاشة. خط مباشر من موقعك إلى الهدف. - عرض سهم واحد أو اثنين ليشير إلى اتجاه العلامة النشطة. + عرض سهم واحد أو اثنين ليشير إلى الوجهة النشطة. طريقة عرض المسافة من موقعي إلى العلامات النشطة. عدد الأسهم تجاه العلامات النشطة ( للملاحة في الصحراء). أسود From b21b2dceeff2303255883063449f8baec9cef116 Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Thu, 24 Sep 2020 00:28:12 +0000 Subject: [PATCH 0317/1366] Translated using Weblate (Japanese) Currently translated at 99.2% (3795 of 3824 strings) --- OsmAnd/res/values-ja/phrases.xml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-ja/phrases.xml b/OsmAnd/res/values-ja/phrases.xml index 43277a41ea..2165c6fca4 100644 --- a/OsmAnd/res/values-ja/phrases.xml +++ b/OsmAnd/res/values-ja/phrases.xml @@ -456,7 +456,7 @@ モニュメント・記念碑 水族館 観光名所 - チャリティーストア + チャリティーショップ 写真屋 セーリング 遊園地の乗り物 @@ -1248,12 +1248,12 @@ 許可 洗濯機 洗濯機:無し - 洗車場:無し + 無し エアーコンプレッサー 有り エアーコンプレッサー:無し セルフサービス式 - セルフサービスではない + 無し 掃除機 有り 掃除機:無し @@ -1974,7 +1974,7 @@ アイスクリーム SIMカード 有り - 無し + 横断補助音:無し 歩行許可時のみ 保養地、援助施設 望遠鏡の種類 @@ -3804,7 +3804,14 @@ 水位:平均水位より低め 水位:平均水位より高め 水位:浮遊物 - 飲料水補充ネットワーク(所属) + 給水スポットネットワーク 飲料水の補充:不可 - 飲料水の補充:可 + + ブース + 小型電化製品 + 運行掲示板・時刻表 + 給水スポットネットワークへの参加有無 + 触覚矢印 + 振動装置 + 公称圧力 \ No newline at end of file From 9e76a6a9600f4e04e7b5bd5a561e0e8eedb7b565 Mon Sep 17 00:00:00 2001 From: Franco Date: Thu, 24 Sep 2020 01:03:23 +0000 Subject: [PATCH 0318/1366] Translated using Weblate (Spanish (American)) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-es-rUS/strings.xml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-es-rUS/strings.xml b/OsmAnd/res/values-es-rUS/strings.xml index bb6fe37c9e..a7750a3b93 100644 --- a/OsmAnd/res/values-es-rUS/strings.xml +++ b/OsmAnd/res/values-es-rUS/strings.xml @@ -1129,7 +1129,7 @@ El idioma elegido es incompatible con el motor TTS (texto a voz) instalado en Android, se usará el idioma TTS predefinido. ¿Buscar otro motor TTS en la tienda de aplicaciones\? Faltan datos ¿Ir a la tienda de aplicaciones para descargar el idioma elegido? - Invertir la dirección GPX + Invertir la dirección de la traza Usar destino actual Pasar a lo largo de la traza completa Mapa vectorial presente para esta ubicación. @@ -3838,7 +3838,7 @@ Recalcular toda la traza usando el perfil elegido. A continuación, ajusta la traza al camino permitido más cercano con un perfil de navegación. Recalcular sólo el siguiente segmento usando el perfil elegido. - Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos con el perfil elegido. + Marca cómo conectar los puntos, con una línea recta o calcular una ruta entre ellos como se detalla a continuación. Elige un archivo de traza al que se añadirá un nuevo segmento. Ruta inversa Añadir punto de referencia de la traza @@ -3886,13 +3886,13 @@ Añadir dirección Ingresar dirección Rehacer - • Se ha actualizado el modo «Planificar ruta»: ahora permite usar diferentes tipos de navegación para cada segmento y adjunta cualquier traza a los caminos + • Se ha actualizado la función «Planificar ruta»: permite utilizar diferentes tipos de navegación por segmento y la inclusión de trazas \n -\n • Nuevas opciones en el aspecto de las trazas: elegir el color, cambiar el grosor de las flechas de dirección y las marcas de inicio/fin. +\n • Nuevo menú con el aspecto de las trazas: elegir el color, el grosor, mostrar las flechas de dirección y los iconos de inicio/fin. \n -\n • Mejoras en la visibilidad de los nodos de bicicleta +\n • Mejoras en la visibilidad de los nodos de bicicleta. \n -\n • Menú contextual con información básica para las trazas +\n • Las trazas ahora se pueden pulsar, contiene un menú contextual con información básica. \n \n • Algoritmos de búsqueda mejorados \n @@ -3901,4 +3901,7 @@ \n • Se han solucionado los problemas de la importación y exportación en los ajustes de los perfiles \n \n + Nombre: Z – A + Nombre: A – Z + Último modificado \ No newline at end of file From d2f2fbafb5510e8c51e2312a6a4d90405d6a3207 Mon Sep 17 00:00:00 2001 From: Franco Date: Thu, 24 Sep 2020 01:10:06 +0000 Subject: [PATCH 0319/1366] Translated using Weblate (Spanish (American)) Currently translated at 100.0% (3824 of 3824 strings) --- OsmAnd/res/values-es-rUS/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-es-rUS/phrases.xml b/OsmAnd/res/values-es-rUS/phrases.xml index d12ccb5eef..25786f2488 100644 --- a/OsmAnd/res/values-es-rUS/phrases.xml +++ b/OsmAnd/res/values-es-rUS/phrases.xml @@ -3849,4 +3849,6 @@ Tablero de partidas: no Con retraso Tablero de partidas + Frutos secos + Panal de abejas \ No newline at end of file From 5be447c66e195bce7090baef42a14947ae7dacb1 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Wed, 23 Sep 2020 22:31:34 +0000 Subject: [PATCH 0320/1366] Translated using Weblate (Esperanto) Currently translated at 98.6% (3441 of 3487 strings) --- OsmAnd/res/values-eo/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 304dea0021..fc643544e6 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -3865,4 +3865,7 @@ Tondi post Ŝanĝi specon de vojo antaŭ Ŝanĝi specon de vojo post + Antaŭe modifita + Nomo: Z – A + Nomo: A – Z \ No newline at end of file From 54b99404a7748688403daee90e3de140915e68e6 Mon Sep 17 00:00:00 2001 From: sergosm Date: Thu, 24 Sep 2020 11:29:08 +0300 Subject: [PATCH 0321/1366] '.gpx' extension --- .../SaveAsNewTrackBottomSheetDialogFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java index 231182be8b..64eee7f8ee 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java @@ -298,7 +298,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial if (folderName != null && !dir.getName().equals(folderName)) { source = new File(dir, folderName); } - source = new File(source, fileName + IndexConstants.GPX_FILE_EXT); + source = new File(source, fileName); return source; } From ef343e5423a50e9e63bf7e0484a5a5e95963a0bb Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Thu, 24 Sep 2020 13:47:22 +0200 Subject: [PATCH 0322/1366] Fix issue --- .../SaveAsNewTrackBottomSheetDialogFragment.java | 2 +- .../osmand/plus/routepreparationmenu/ChooseRouteFragment.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java index 64eee7f8ee..231182be8b 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java @@ -298,7 +298,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial if (folderName != null && !dir.getName().equals(folderName)) { source = new File(dir, folderName); } - source = new File(source, fileName); + source = new File(source, fileName + IndexConstants.GPX_FILE_EXT); return source; } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java index 004f5c4d2b..407f65295f 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java @@ -487,7 +487,7 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date()); fileName = FileUtils.createUniqueFileName(app, suggestedName, IndexConstants.GPX_INDEX_DIR, GPX_FILE_EXT); } else { - fileName = new File(paramsBuilder.getFile().path).getName(); + fileName = AndroidUtils.trimExtension(new File(paramsBuilder.getFile().path).getName()); } SaveAsNewTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), ChooseRouteFragment.this, null, fileName, From 0747bb5320036da3681f2067138d0a496bb3f3df Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Thu, 24 Sep 2020 13:47:22 +0200 Subject: [PATCH 0323/1366] Fix issue --- .../SaveAsNewTrackBottomSheetDialogFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java index 64eee7f8ee..231182be8b 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java @@ -298,7 +298,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial if (folderName != null && !dir.getName().equals(folderName)) { source = new File(dir, folderName); } - source = new File(source, fileName); + source = new File(source, fileName + IndexConstants.GPX_FILE_EXT); return source; } From 3e350cbb43b1c75c62ba35ae31e1c64495babf98 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Thu, 24 Sep 2020 13:59:11 +0200 Subject: [PATCH 0324/1366] Fix bad naming --- .../SaveAsNewTrackBottomSheetDialogFragment.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java index 231182be8b..5b4058f339 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java @@ -105,7 +105,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial @Override public void afterTextChanged(Editable s) { - checkEmptyName(s.toString()); + updateFileNameFromEditText(s.toString()); } }); BaseBottomSheetItem editFileName = new BaseBottomSheetItem.Builder() @@ -215,7 +215,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial folderName = item; EditText editText = nameTextBox.getEditText(); if (editText != null) { - checkEmptyName(editText.getText().toString()); + updateFileNameFromEditText(editText.getText().toString()); } } }; @@ -307,7 +307,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial return rightButtonEnabled; } - private void checkEmptyName(String name) { + private void updateFileNameFromEditText(String name) { rightButtonEnabled = false; String text = name.trim(); if (text.isEmpty()) { From 493bce784472ab0655bc8d6158dac91abc4e493f Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 24 Sep 2020 15:18:07 +0300 Subject: [PATCH 0325/1366] Fix multi context menu npe --- .../net/osmand/plus/mapcontextmenu/MenuTitleController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java index 523ce5fef4..f676c5812e 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java @@ -25,8 +25,8 @@ public abstract class MenuTitleController { private AddressLookupRequest addressLookupRequest; - protected String searchAddressStr; - protected String addressNotFoundStr; + protected String searchAddressStr = ""; + protected String addressNotFoundStr = ""; @Nullable public abstract MapActivity getMapActivity(); From 685d2db529ef20b2d7107cae1c5336793e37b2bd Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 24 Sep 2020 15:32:08 +0300 Subject: [PATCH 0326/1366] Fix SelectFileBottomSheet npe --- .../osmand/plus/measurementtool/SelectFileBottomSheet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index d808f8f5e6..31502bea57 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -215,7 +215,9 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { private void sortFileList() { List gpxInfoList = gpxInfoMap.get(selectedFolder); - sortSelected(gpxInfoList); + if (gpxInfoList != null) { + sortSelected(gpxInfoList); + } adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList()); } From 8d70ba97feafb05b235f269d2a31236c2fe2d8cb Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 24 Sep 2020 15:18:07 +0300 Subject: [PATCH 0327/1366] Fix multi context menu npe --- .../net/osmand/plus/mapcontextmenu/MenuTitleController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java index 523ce5fef4..f676c5812e 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuTitleController.java @@ -25,8 +25,8 @@ public abstract class MenuTitleController { private AddressLookupRequest addressLookupRequest; - protected String searchAddressStr; - protected String addressNotFoundStr; + protected String searchAddressStr = ""; + protected String addressNotFoundStr = ""; @Nullable public abstract MapActivity getMapActivity(); From 32218bb48192e155adf2326425fbb011a06b4bc9 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 24 Sep 2020 15:32:08 +0300 Subject: [PATCH 0328/1366] Fix SelectFileBottomSheet npe --- .../osmand/plus/measurementtool/SelectFileBottomSheet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index d808f8f5e6..31502bea57 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -215,7 +215,9 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { private void sortFileList() { List gpxInfoList = gpxInfoMap.get(selectedFolder); - sortSelected(gpxInfoList); + if (gpxInfoList != null) { + sortSelected(gpxInfoList); + } adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList()); } From 2581bcb4e5d26ad48b4f293638f33ad861a3a378 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 24 Sep 2020 17:04:07 +0300 Subject: [PATCH 0329/1366] Get temp dir refactoring --- OsmAnd/src/net/osmand/FileUtils.java | 13 +++++++++---- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 8 +++----- .../src/net/osmand/plus/helpers/ImportHelper.java | 8 +++----- .../fragments/ExportProfileBottomSheet.java | 13 +++---------- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java index 426c5c10c2..65ea676356 100644 --- a/OsmAnd/src/net/osmand/FileUtils.java +++ b/OsmAnd/src/net/osmand/FileUtils.java @@ -205,10 +205,7 @@ public class FileUtils { if (!src.exists()) { return null; } - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } + File tempDir = getTempDir(app); File dest = new File(tempDir, src.getName()); try { Algorithms.fileCopy(src, dest); @@ -218,6 +215,14 @@ public class FileUtils { return dest; } + public static File getTempDir(OsmandApplication app) { + File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + return tempDir; + } + public interface RenameCallback { void renamedTo(File file); } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 07c545a424..58dbdd1559 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -26,6 +26,7 @@ import com.google.gson.reflect.TypeToken; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; +import net.osmand.FileUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; @@ -2350,11 +2351,8 @@ public class OsmandAidlApi { } private int copyFileImpl(String fileName, byte[] filePartData, long startTime, boolean done, String destinationDir) { - File file = app.getAppPath(IndexConstants.TEMP_DIR + fileName); - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } + File tempDir = FileUtils.getTempDir(app); + File file = new File(tempDir, fileName); File destFile = app.getAppPath(destinationDir + fileName); long currentTime = System.currentTimeMillis(); try { diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index c57f53a0fa..e3dcb9cd2d 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -21,6 +21,7 @@ import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; +import net.osmand.FileUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; @@ -715,17 +716,14 @@ public class ImportHelper { @Override protected String doInBackground(Void... voids) { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } + File tempDir = FileUtils.getTempDir(app); File dest = new File(tempDir, name); return copyFile(app, dest, uri, true); } @Override protected void onPostExecute(String error) { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); + File tempDir = FileUtils.getTempDir(app); final File file = new File(tempDir, name); if (error == null && file.exists()) { app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java index a09a8ba435..40fa4e290c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java @@ -21,6 +21,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; @@ -329,7 +330,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { if (app != null) { exportingProfile = true; showExportProgressDialog(); - File tempDir = getTempDir(); + File tempDir = FileUtils.getTempDir(app); String fileName = profile.toHumanString(); app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), prepareSettingsItemsForExport(), true); } @@ -391,19 +392,11 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { } private File getExportFile() { - File tempDir = getTempDir(); + File tempDir = FileUtils.getTempDir(app); String fileName = profile.toHumanString(); return new File(tempDir, fileName + IndexConstants.OSMAND_SETTINGS_FILE_EXT); } - private File getTempDir() { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } - return tempDir; - } - private void shareProfile(@NonNull File file, @NonNull ApplicationMode profile) { try { final Intent sendIntent = new Intent(); From cdaac54d24ab2f829c0602b8ee11df6857b0813e Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 24 Sep 2020 18:06:02 +0200 Subject: [PATCH 0330/1366] Update build.gradle --- OsmAnd/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 0e5734f212..91b0b8022f 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -45,10 +45,10 @@ android { defaultConfig { minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15 targetSdkVersion 28 - versionCode 370 + versionCode 390 versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode multiDexEnabled true - versionName "3.7.0" + versionName "3.9.0" versionName System.getenv("APK_VERSION")? System.getenv("APK_VERSION").toString(): versionName versionName System.getenv("APK_VERSION_SUFFIX")? versionName + System.getenv("APK_VERSION_SUFFIX").toString(): versionName // Stops the Gradle plugin’s automatic rasterization of vectors From 3a17a14e6f086ed0b69c7247b64669defed846ec Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Thu, 24 Sep 2020 15:38:51 +0000 Subject: [PATCH 0331/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 035ea9609b..5e2d0c47f7 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -331,7 +331,7 @@ Нажмите «Использовать местоположение…» чтобы добавить заметку к данному местоположению. Аудиозаметки Создавайте аудио-, видео- и фотозаметки в поездке, используя виджет или контекстное меню. - Медиазаметки + Аудио/видеозаметки частей Линии высот Контурные линии @@ -2134,7 +2134,7 @@ Переместить ↑ Переместить ↓ Завершить навигацию - Исключить из маршрута + Избегать дорог Публичное имя Поддерживаемый регион Введите публичное имя @@ -2885,14 +2885,14 @@ Гуарани Вы используете {0} карту, которая поставляется OsmAnd. Хотите запустить полную версию Osmand\? Запустить OsmAnd\? - Добавить точку маршрута + Задать пункт назначения Добавить промежуточный пункт Установить отправную точку Путь Точки интереса (POI) Расчёт маршрута… Общественный транспорт - Укажите на карте или в списке ниже, каких дорог следует избегать при навигации: + Выберите дорогу на карте или из списка ниже, которую вы хотите избежать во время навигации: Моделировать навигацию Выберите файл трека для следования Голосовые подсказки @@ -3068,7 +3068,7 @@ Лошадь Вертолёт Вы можете добавить собственную модифицированную версию routing.xml в ..osmand/routing - Значок + Выберите значок Лыжи Тип: %s Базовый профиль @@ -3233,13 +3233,13 @@ Карта во время навигации Карта во время навигации Скорость движения, размеры, масса транспортного средства - Физические параметры + Параметры транспортного средства Голосовые оповещения происходят только во время навигации. Навигационные инструкции и объявления Голосовые подсказки Экранные оповещения Настройка параметров маршрута - Маршрутизация + Параметры маршрута Буфер Logcat Настройки плагинов Язык и вывод @@ -3574,7 +3574,7 @@ Добавить описание Категории Квадрат - Форма + Выберите форму Круг Восьмиугольник Сообщение о доступности @@ -3820,7 +3820,7 @@ Выберите файл трека. Готово Перезаписать трек - Выбрать трек, к которому будет добавлен новый сегмент. + Выберите трек, к которому будет добавлен новый сегмент. Профиль Предельная дистанция Сохранить как новый трек From deba0bc228bfda94753e4e9ec5d1317f1dc0c046 Mon Sep 17 00:00:00 2001 From: nasr pen Date: Fri, 25 Sep 2020 06:46:52 +0000 Subject: [PATCH 0332/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 944fa1130e..64699588d6 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -980,7 +980,7 @@ التفاصيل الوقت الحالي اتجاه الخريطة - حسب اتجاه الحركة + اتجاه الحركة في الأعلى الشمال في الأعلى حسب البوصلة إشارة توقف @@ -3122,7 +3122,7 @@ يتم تحديد هذا الاعداد بشكل افتراضي للأوضاع: %s تغيير الإعدادات تجاهل التغيير - تطبيق علي كافة الأوضاع + تطبيق على كافة الأوضاع رسالة البدء تحليل إظهار الخريطة على شاشة القفل أثناء التنقل. From b5219c440d57e66941b2aafa32fbe1ef59961fb9 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Fri, 25 Sep 2020 03:59:33 +0000 Subject: [PATCH 0333/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 66 ++++++++++++++++---------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 64699588d6..d8d136ed73 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -68,7 +68,7 @@ خدمات التسجيل لا طريق إزالة وجهة - توجد وجهة سابقة تعمل حالياً : + توجد وجهة سابقة تعمل حاليا : الوجهات الوضع المتقدم… موقف سيارات @@ -195,7 +195,7 @@ من : استعراض الوضع الافتراضي - تعيينه وجهة + تعيينه كوجهة اختر المدينة أو الشارع الأول حذف نقطة الوقت @@ -216,7 +216,7 @@ أخرى النسخة الكاملة إيقاف التوجيه - امح الهدف + حذف الهدف واي فاي غير متصل حالياً. هل تريد متابعة التحميل بواسطة اتصال الإنترنت الحالي؟ اسم الشارع رقم البيت @@ -271,7 +271,7 @@ إعدادات التطبيق حفظ المسار الحالي الإعدادات - تكبير الخريطة + حجم الخريطة خريطة العالم العامة الانتهاء (دقائق): %1$s قابل للتحميل: %1$s @@ -342,7 +342,7 @@ إضافتها كأول وجهة وسطى الوجهة %1$s بعيدة جدا من أقرب طريق. تم الوصول - إضافة كوجهة + إضافة كوجهة وسيطة وجهة وسطى نقطة الوصول بعيدة جدا عن أقرب طريق. إضافة وسم @@ -367,7 +367,7 @@ مواقيت الشروق والغروب سمات التقديم نمط الخريطة - عرض/إخفاء العدادات + عرض/إخفاء الاختصارات طرق فلورية مسطرة عرض الاتجاه @@ -376,7 +376,7 @@ \n التطبيق في الخلفية إيقاف \n التشغيل في الخلفية - عرض/إخفاء العدادات + عرض/إخفاء الاختصارات أين أنا اقفل الشاشة البوصلة @@ -992,7 +992,7 @@ تسجيل المسار اختر الفاصل الزمني لتسجيل المسار أثناء الملاحة صوت مسج - التوجيه + الملاحة والتوجيه استخدام الموقع… مفضلة نقاط مفضلة مجاورة @@ -1031,7 +1031,7 @@ الطرق فقط ذاكرة الجهاز تعديل مجموعة - إزالة العلامة + إزالة الوسم حالة GPS إنارة الشوارع البروكسي @@ -1229,7 +1229,7 @@ احسب قسم طريق أوسماند بدون إنترنت احسب طريق أوسماند لأول وآخر قسمين في الطريق استخدام المسار المعروض للملاحة؟ - إضافتها كوجهة لاحقاً + إضافتها كوجهة لاحقا اختر GPX… حدد الوجهة تفضيل طرق الدراجات النارية @@ -1306,7 +1306,7 @@ نقل نهاري ليلي - الشروق/الغروب + تلقائي مستشعر الضوء تحميل الخريطة حدد أقصى تقريب للتحميل المسبق @@ -1335,7 +1335,7 @@ بحث بدون اتصال اختر خدمة الملاحة عبر أو بدون ربط بالإنترنت. لا يمكن الوصول لمجلد البيانات على الذاكرة! - حدد الوجهة أولاً + حدد الوجهة أولا جار تحميل قائمة المناطق المتاحة… لم يتم تحميل قائمة المناطق من osmand.net. خطأ أثناء حفظ GPX. @@ -1379,7 +1379,7 @@ شكرا لدعمكم أوسماند! \nلتنشيط جميع الميزات الجديدة ، تحتاج إلى إعادة تشغيل أوسماند. إعدادات الاشتراك - عدادات + شريط جانبي الرمز البريدي من بحث @@ -1408,7 +1408,7 @@ غير مثبت وسع فرز - وضع الخريطة + مظهرالخريطة رقيقة متوسط لم تضف توجيه مباشر على الخريطة @@ -1436,7 +1436,7 @@ رفع كمستخدم مجهول رفع ملاحظة OSM شريط الأدوات - حدد علامة على الخريطة + حدد توجيه مباشرعلى الخريطة ترتيب عكسي تفعيل ميزة العلامات. الأسترية @@ -1475,7 +1475,7 @@ حرك الخريطة لتغيير مكان التوجيه المباشر إشارة صوتية عند اتجاه نقطة الوصول. - اشر عن اتجاه نقطة الهدف بالاهتزاز. + حدد اتجاه النقطة المستهدفة بالاهتزاز. تمكين الملاحة لتعديلات أوسماند لايف (تجريبي). لا تغير المسار عندما تكون خارج الطريق منع إعادة الحساب التلقائي للمسار عندما تبتعد قليلا عن الطريق الصحيح. @@ -1611,7 +1611,7 @@ \n \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. البحث قرب مركز الخريطة الحالية - عدد خطوط التوجيه المباشر + عدد خطوط التوجيه التوجيه المباشر تخطي الحدود حدد الطرق التي تريد تجنبها أثناء التنقل. @@ -1634,7 +1634,7 @@ التوجيه المباشرالثاني للخريطة إضافة إلى التوجيه المباشر حذف كافة التوجيه المباشرالنشط على الخريطة؟ - علامة على الخريطة + توجيه مباشر على الخريطة عرض المضلعات الحالة حفظ التعديلات @@ -2087,10 +2087,10 @@ وسط منخفض إخفاء المياه - زر الإجراء السريع + زر الاختصار السريع إجراء %d شاشة %d - إضافة العلامة + إضافة توجيه مباشر للخريطة إضافة POI نمط الخريطة نمط الخرائط تغير ل \"%s\". @@ -2165,7 +2165,7 @@ تقسيم المسارات آلياً إلى أجزاء بعد كل فراغ تقصير رمز التموضع المفتوح \n يُرجى تقديم رمزٍ كامل - اسم الإجراء السريع مكرر + اسم الاختصار السريع مكرر سوف تكون تتمة هذه الرسالة تلقائية في المجال المخصص للتعليق. مجلد جديد النقاط المهمة في هذا الطريق @@ -2285,8 +2285,8 @@ لمشاهدة خطوط التضاريس على الخريطة، يجب تحميل الملحق أولاً. تمكين استقراء موقعي أثناء الفقد المؤقت للموقع وذلك لإصلاحه. زر تشغيل أو إيقاف التكبير التلقائي وفقاً لسرعتك. - زر توسيط في وجهة الطريق ، مما يجعل الوجهة المحددة مسبقاً تصبح الوجهة الوسيطة الأخيرة. - زر لجعل الشاشة مركز الوجهة الجديدة ، مع استبدال الوجهة المحددة مسبقاً (إن وجدت). + زر توسيط في وجهة الطريق ، مما يجعل الوجهة المحددة مسبقا تصبح الوجهة الوسيطة الأخيرة. + زر لجعل الشاشة مركز الوجهة الجديدة ، مع استبدال الوجهة المحددة مسبقا (إن وجدت). يمكنك التقاط صور خاصة بك أو سلسلة من الصور وإرفاقها إلى هذا الموقع من الخريطة. للقيام بذلك تحتاج إلى تثبيت تطبيق مابيلاري من Google play. تحتاج إلى تحميل خريطة تراكب التلال لهذه المنطقة. لمشاهدة التضاريس على الخريطة، تحتاج إلى شراء وتثبيت برنامج الخطوط المحيطية المساعد. @@ -2416,7 +2416,7 @@ \nأوسماند ذو المصدر المفتوح، وجاري تطويره . يمكن للجميع أن يساهم بالإبلاغ عن الأخطاء، تحسين الترجمات أو برمجة ميزات جديدة. هذا المشروع خاضع للتحسين المستمر بشتى أشكال تفاعل المطورين والمستخدمين. التقدم المحرز في المشروع يعتمد أيضا على المساهمات المالية لتمويل البرمجة واختبار التحديثات الجديدة \n الاسم يحتوي على الكثير من الأحرف الكبيرة . هل تريد الاستمرار؟ - اسم الإجراء السريع المحدد قيد الاستخدام، لقد تم تغييره إلى %1$s لتجنب التكرار. + اسم الاختصار السريع المحدد قيد الاستخدام، لقد تم تغييره إلى %1$s لتجنب التكرار. الضغط على زر الإجراء سيطبق أحد الأنماط من القائمة أدناه. تنقلاتك على هذا الطريق OLC الصالحة بالكامل\nتمثل المنطقة: %1$s x %2$s @@ -2483,7 +2483,7 @@ حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'. تم نقل جميع العلامات إلى السجل تم نقل التوجيه المباشرإلى السجل - انتقل التوجيه المباشر نشط + التوجيه المباشر انتقل كنشط قائمة مجموعات آخر استخدام : %1$s @@ -2575,7 +2575,7 @@ حسب التاريخ حسب النوع المزيد - المظهر على الخريطة + التوجيه المباشر نقاط المسار إضافة مجموعة قم بإنشاء التوجيه المباشر على الخريطة ! @@ -2593,7 +2593,7 @@ حدد مفضلة لإضافتها إلى العلامات. مجموعة مفضلة خطين - التوجيه المباشر + خط التعديلات %1$s, المبلغ %2$s mBTC مساهمي OSM المستفيدون الشتاء و التزحلق @@ -2715,7 +2715,7 @@ استعادة تطبيق من طرف ثالث عند التفعيل سيبقى التوجيه المباشر المضاف من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز التوجيه المباشر\". إذا كانت المجموعة غير نشطة ستختفي الوجهات المباشرة من الخريطة. - إبقاء التوجيه المباشر المتجاوز على الخريطة + إبقاء التوجيه المباشر المتجاوز هناك المزيد من وسائل النقل في هذا الموقف. يرجى إعطاء إذن تحديد الموقع للتطبيق لكي يواصل. شكرا على الرد @@ -2848,8 +2848,8 @@ ستظهر العلامات التي تم تجاوزها على هذه الشاشة. خط مباشر من موقعك إلى الهدف. عرض سهم واحد أو اثنين ليشير إلى الوجهة النشطة. - طريقة عرض المسافة من موقعي إلى العلامات النشطة. - عدد الأسهم تجاه العلامات النشطة ( للملاحة في الصحراء). + طريقة عرض المسافة من موقعي إلى الوجهات النشطة. + عدد الأسهم تجاه الوجهات النشطة ( للملاحة في الصحراء). أسود تشغيل الغوارانية @@ -2920,7 +2920,7 @@ %s وضع تجنب أنواع النقل… المشي - اختصر طول العلامة \"%s\" إلى أقل من 255 حرف. + اختصر طول الوسم\"%s\" إلى أقل من 255 حرف. درجات مللي راديان وحدات القياس الزاوي @@ -3321,7 +3321,7 @@ توجيه جهة خارجية حدد الأوضاع لتكون مرئية في التطبيق. أوضاع التطبيق - أضف عنصراً واحداً على الأقل إلى القائمة في إعدادات \"الإجراء السريع\" + أضف عنصراً واحداً على الأقل إلى القائمة في إعدادات \"الاختصار السريع\" جبال الألب/التزلج علي المنحدرات التزلج على جبال الألب أو الانحدار. التزلج عبر البلاد / الشمال @@ -3734,7 +3734,7 @@ مهلة الشاشة الافتراضية يمكنك تصدير أو استيراد إجراءات سريعة باستخدام ملفات بروفايل التطبيق . حذف الكل؟ - هل أنت متأكد من رغبتك في حذف الإجراءات السريعة %d نهائيًا؟ + هل أنت متأكد من رغبتك في حذف الاختصارات السريعة %d نهائيًا؟ مهلة الشاشة نغمات أدل بعرض مركبتك، قد يتم تطبيق بعض القيود على المركبات العريضة. From 8cf78547e4411e16817ecb3d4dc958e2b9928447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1ns?= Date: Fri, 25 Sep 2020 00:31:18 +0000 Subject: [PATCH 0334/1366] Translated using Weblate (Galician) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-gl/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml index 18e88d4dab..628e97198e 100644 --- a/OsmAnd/res/values-gl/strings.xml +++ b/OsmAnd/res/values-gl/strings.xml @@ -3925,4 +3925,7 @@ Lon %2$s Gravar A gravación da pista deterase ó pechar a aplicación (mediante aplicacións recentes). (A indicación de fondo do OsmAnd, desaparecerá da barra de notificacións do Android.) Especifica o intre de gravación xeral para pistas (habilitado a través do trebello de gravación no mapa). + Última modificación + Nome: Z – A + Nome: A – Z \ No newline at end of file From b69b30a03034483912a16abe1887ecf34bf0232c Mon Sep 17 00:00:00 2001 From: max-klaus Date: Fri, 25 Sep 2020 11:47:46 +0300 Subject: [PATCH 0335/1366] Fix countWords npe --- .../java/net/osmand/search/core/SearchPhrase.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java index f1b5b45b05..2a3fc59521 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java @@ -229,12 +229,14 @@ public class SearchPhrase { } public int countWords(String w) { - String[] ws = w.split(ALLDELIMITERS); int cnt = 0; - for (int i = 0; i < ws.length; i++) { - String wd = ws[i].trim(); - if (wd.length() > 0) { - cnt++; + if (!Algorithms.isEmpty(w)) { + String[] ws = w.split(ALLDELIMITERS); + for (int i = 0; i < ws.length; i++) { + String wd = ws[i].trim(); + if (wd.length() > 0) { + cnt++; + } } } return cnt; From a0005dccbbd2e36d4722cf78577b3f173af293b1 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Fri, 25 Sep 2020 11:47:46 +0300 Subject: [PATCH 0336/1366] Fix countWords npe --- .../java/net/osmand/search/core/SearchPhrase.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java index f1b5b45b05..2a3fc59521 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java @@ -229,12 +229,14 @@ public class SearchPhrase { } public int countWords(String w) { - String[] ws = w.split(ALLDELIMITERS); int cnt = 0; - for (int i = 0; i < ws.length; i++) { - String wd = ws[i].trim(); - if (wd.length() > 0) { - cnt++; + if (!Algorithms.isEmpty(w)) { + String[] ws = w.split(ALLDELIMITERS); + for (int i = 0; i < ws.length; i++) { + String wd = ws[i].trim(); + if (wd.length() > 0) { + cnt++; + } } } return cnt; From bd10c798f817b9b60df5c7e2b8b26c88cd7eeea3 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 25 Sep 2020 13:14:38 +0300 Subject: [PATCH 0337/1366] Fix track name and select app mode from gpx in follow track --- .../MeasurementToolFragment.java | 12 ++++++++-- .../ChooseRouteFragment.java | 2 +- .../FollowTrackFragment.java | 22 +++++++++++-------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 42b176201b..8089d3a012 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -1521,8 +1521,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route private String getSuggestedFileName() { GpxData gpxData = editingCtx.getGpxData(); - String displayedName; - if (gpxData == null) { + String displayedName = null; + if (gpxData != null) { + GPXFile gpxFile = gpxData.getGpxFile(); + if (!Algorithms.isEmpty(gpxFile.path)) { + displayedName = Algorithms.getFileNameWithoutExtension(new File(gpxFile.path).getName()); + } else if (!Algorithms.isEmpty(gpxFile.tracks)) { + displayedName = gpxFile.tracks.get(0).name; + } + } + if (gpxData == null || displayedName == null) { String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date()); displayedName = FileUtils.createUniqueFileName(requireMyApplication(), suggestedName, GPX_INDEX_DIR, GPX_FILE_EXT); } else { diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java index 407f65295f..62827e1e67 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java @@ -487,7 +487,7 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date()); fileName = FileUtils.createUniqueFileName(app, suggestedName, IndexConstants.GPX_INDEX_DIR, GPX_FILE_EXT); } else { - fileName = AndroidUtils.trimExtension(new File(paramsBuilder.getFile().path).getName()); + fileName = Algorithms.getFileNameWithoutExtension(new File(paramsBuilder.getFile().path).getName()); } SaveAsNewTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), ChooseRouteFragment.this, null, fileName, diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index 42ff2f94e6..8937f4ce5d 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -25,6 +25,7 @@ import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.TrkSegment; +import net.osmand.GPXUtilities.WptPt; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.ValueHolder; @@ -433,14 +434,11 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca if (mapActivity != null) { if (card instanceof ImportTrackCard) { importTrack(); - } else if (card instanceof TrackEditCard) { - openPlanRoute(true); + } else if (card instanceof TrackEditCard || card instanceof AttachTrackToRoadsCard) { + openPlanRoute(); close(); } else if (card instanceof SelectTrackCard) { updateSelectionMode(true); - } else if (card instanceof AttachTrackToRoadsCard) { - openPlanRoute(false); - close(); } else if (card instanceof ReverseTrackCard || card instanceof NavigateTrackOptionsCard) { updateMenu(); @@ -488,6 +486,14 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { this.gpxFile = gpxFile; + List points = gpxFile.getRoutePoints(); + if (!points.isEmpty()) { + ApplicationMode mode = ApplicationMode.valueOfStringKey(points.get(0).getProfileType(), null); + if (mode != null) { + app.getRoutingHelper().setAppMode(mode); + app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); + } + } mapActivity.getMapActions().setGPXRouteParams(gpxFile); app.getTargetPointsHelper().updateRouteAndRefresh(true); app.getRoutingHelper().recalculateRouteDueToSettingsChange(); @@ -544,7 +550,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca } } - public void openPlanRoute(boolean useAppMode) { + public void openPlanRoute() { MapActivity mapActivity = getMapActivity(); if (mapActivity != null && gpxFile != null) { editingTrack = true; @@ -554,9 +560,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca GpxData gpxData = new GpxData(gpxFile, rect, actionType, segment); MeasurementEditingContext editingContext = new MeasurementEditingContext(); editingContext.setGpxData(gpxData); - if (useAppMode) { - editingContext.setAppMode(app.getRoutingHelper().getAppMode()); - } + editingContext.setAppMode(app.getRoutingHelper().getAppMode()); MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), editingContext, true); } } From 41e4654a626bf8d034ef9bb6daf2a7898beb83b9 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 25 Sep 2020 13:44:45 +0300 Subject: [PATCH 0338/1366] Fix saved track name --- .../routepreparationmenu/ChooseRouteFragment.java | 15 +++++++++++---- .../RouteOptionsBottomSheet.java | 11 +++++++++-- .../routepreparationmenu/cards/TracksCard.java | 10 ++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java index 62827e1e67..5c283c670d 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java @@ -37,6 +37,7 @@ import androidx.viewpager.widget.ViewPager; import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; @@ -482,12 +483,18 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements ContextMe OsmandApplication app = mapActivity.getMyApplication(); GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute(); - String fileName; - if (paramsBuilder == null || paramsBuilder.getFile() == null || paramsBuilder.getFile().path == null) { + String fileName = null; + if (paramsBuilder != null && paramsBuilder.getFile() != null) { + GPXFile gpxFile = paramsBuilder.getFile(); + if (!Algorithms.isEmpty(gpxFile.path)) { + fileName = Algorithms.getFileNameWithoutExtension(new File(gpxFile.path).getName()); + } else if (!Algorithms.isEmpty(gpxFile.tracks)) { + fileName = gpxFile.tracks.get(0).name; + } + } + if (Algorithms.isEmpty(fileName)) { String suggestedName = new SimpleDateFormat("EEE dd MMM yyyy", Locale.US).format(new Date()); fileName = FileUtils.createUniqueFileName(app, suggestedName, IndexConstants.GPX_INDEX_DIR, GPX_FILE_EXT); - } else { - fileName = Algorithms.getFileNameWithoutExtension(new File(paramsBuilder.getFile().path).getName()); } SaveAsNewTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), ChooseRouteFragment.this, null, fileName, diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java index 0d23e78673..d18537bfb8 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java @@ -16,6 +16,7 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.StateChangedListener; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; @@ -47,6 +48,7 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.router.GeneralRouter; +import net.osmand.util.Algorithms; import java.io.File; import java.util.Arrays; @@ -342,14 +344,19 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { private BaseBottomSheetItem createGpxRoutingItem(final LocalRoutingParameter optionsItem) { RouteProvider.GPXRouteParamsBuilder routeParamsBuilder = mapActivity.getRoutingHelper().getCurrentGPXRoute(); - String description; + String description = null; int descriptionColorId; if (routeParamsBuilder == null) { descriptionColorId = nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light; description = mapActivity.getString(R.string.follow_track_descr); } else { descriptionColorId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; - description = new File(routeParamsBuilder.getFile().path).getName(); + GPXFile gpxFile = routeParamsBuilder.getFile(); + if (!Algorithms.isEmpty(gpxFile.path)) { + description = new File(gpxFile.path).getName(); + } else if (!Algorithms.isEmpty(gpxFile.tracks)) { + description = gpxFile.tracks.get(0).name; + } } return new BottomSheetItemWithDescription.Builder() diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java index 78bd52085e..3312371a56 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java @@ -12,6 +12,7 @@ import androidx.appcompat.view.ContextThemeWrapper; import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; import net.osmand.plus.GPXDatabase.GpxDataItem; @@ -19,6 +20,7 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.plus.settings.backend.ApplicationMode; import java.io.File; import java.util.ArrayList; @@ -115,6 +117,14 @@ public class TracksCard extends BaseCard { v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + List points = item.file.getRoutePoints(); + if (!points.isEmpty()) { + ApplicationMode mode = ApplicationMode.valueOfStringKey(points.get(0).getProfileType(), null); + if (mode != null) { + app.getRoutingHelper().setAppMode(mode); + app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); + } + } mapActivity.getMapActions().setGPXRouteParams(item.file); app.getTargetPointsHelper().updateRouteAndRefresh(true); } From db17418c4f7013e852ad3b29cfbf31910f6ac69b Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 25 Sep 2020 14:41:02 +0300 Subject: [PATCH 0339/1366] Fix reverse track availability --- .../osmand/plus/routepreparationmenu/FollowTrackFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index 8937f4ce5d..fd0d22f6fc 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -213,7 +213,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca GPXRouteParamsBuilder rparams = routingHelper.getCurrentGPXRoute(); boolean osmandRouter = mode.getRouteService() == RouteProvider.RouteService.OSMAND; if (rparams != null && osmandRouter) { - boolean showReverseCard = !gpxFile.hasRoute() || gpxFile.hasRtePt(); + boolean showReverseCard = !routingHelper.isCurrentGPXRouteV2(); if (showReverseCard) { cardsContainer.addView(buildDividerView(cardsContainer, false)); From d8cd611c7e782fd1d78c9b34e8d5794bc5f580c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric?= Date: Fri, 25 Sep 2020 15:42:43 +0000 Subject: [PATCH 0340/1366] Translated using Weblate (French) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-fr/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index bfe4fe6318..e88760ed72 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3786,7 +3786,7 @@ Itinéraire entre points Planifier un itinéraire Ajouter à une trace - Douane + Personnalisé Le point ajouté ne sera pas visible sur la carte car le groupe sélectionné est masqué. Vous pouvez le trouver dans \"%s\". Sélectionnez l\'intervalle d\'affichage sur la trace des marques de distance ou de durée. Sélectionner l\'option de découpage : durée ou distance. @@ -3859,13 +3859,13 @@ Segment précédent Tous les segments précédents Seul le segment sélectionné sera recalculé avec le profil sélectionné. - • Mise à jour du mode de planification d\'itinéraire autorisant différents types de navigation pour chaque segment et permettant de déplacer n\'importe quelle trace sur les routes + • Mise à jour du mode de planification d\'itinéraire : il autorise différents types de navigation par segment et permet d\'inclure les traces \n -\n• Nouvelles options pour l\'apparence des traces : choix de la couleur et de l\'épaisseur des flèches de direction et affichage des marques de départ et d\'arrivée +\n• Nouveau menu pour l\'apparence des traces : choix de la couleur, épaisseur, affichage des flèches de direction et icônes de départ et d\'arrivée \n -\n• Amélioration de \"bicycle nodes visibility\" +\n• Amélioration de la visibilité des nœuds relatifs aux infrastructures cyclistes \n -\n• Nouveau menu contextuel pour les traces affichant des informations basiques +\n• Les traces peuvent être \"tapées\" pour afficher un menu contextuel avec des informations basiques \n \n• Amélioration de l\'algorithme de recherche \n From e542620ff162d0fb11396a3f98d5d5affd43a0b6 Mon Sep 17 00:00:00 2001 From: josep constanti Date: Fri, 25 Sep 2020 11:02:39 +0000 Subject: [PATCH 0341/1366] Translated using Weblate (Catalan) Currently translated at 97.2% (3392 of 3487 strings) --- OsmAnd/res/values-ca/strings.xml | 50 ++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index be291b8d7b..5e8a7c8286 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -3449,12 +3449,12 @@ Abasta l\'àrea: %1$s x %2$s La icona es mostra en repòs. Valida i comparteix enregistraments detallats de l\'aplicació Reorganitza les categories - Canvia el criteri d\'ordenació de la llista, amaga categories innecessàries. Podeu importar i exportar tots els canvis amb els perfils. - Podeu afegir una nova categoria personalitzada seleccionant-ne una o, si cal, alguna categoria més. + Canvia el criteri d\'ordenació de la llista, amaga categories. Podeu importar o exportar tots els canvis amb els perfils. + Podeu afegir una nova categoria personalitzada seleccionant una o més categories. Disponible Afegeix una categoria personalitzada Mostra només de nit - Tots els ajustaments dels connectors s\'han restaurat a l\'estat predeterminat. + Tota la configuració dels connectors s\'ha restablert per defecte. Trineu Esborra les dades registrades Copia les coordenades @@ -3469,15 +3469,15 @@ Abasta l\'àrea: %1$s x %2$s Esquí de muntanya Cal donar permís per a utilitzar aquesta opció. \'Restableix els valors predeterminats\' recuperarà l\'ordenació inicial desprès de la instal·lació. - Totes les configuracions dels perfils s\'han tornat als valors predeterminats. + Totes les configuracions dels perfils s\'han restablert per defecte. %1$s/%2$s Ocàs %1$s Sol ixent %1$s - El mode accessible està desactivat al vostre sistema. - Respecta l\'aturada de pantalla automàtica - Inactiu d\'inici, mentre OsmAnd s\'executa en primer terme la pantalla no s\'apaga. + El mode d\'accessibilitat està desactivat al vostre sistema Android. + Segueix l\'aturada de pantalla automàtica + Inactiu d\'inici, mentre OsmAnd s\'executi en primer terme la pantalla no es desactivarà. \n -\nSi s\'activa, OsmAnd respectarà els paràmetres d\'aturada de pantalla automàtica. +\nSi s\'activa, OsmAnd utilitzarà la configuració d\'aturada del sistema. • Perfils: ara podeu canviar-ne l\'ordre, establir la icona al mapa, canviar tota la configuració dels perfils bàsics i restablir-los als valors predefinits \n \n • S\'ha afegit el número de sortida en la navegació @@ -3507,7 +3507,7 @@ Abasta l\'àrea: %1$s x %2$s Càlcul de rutes Estil personalitzat de representació Inclou dades addicionals - El perfil importat conté dades addicionals. Cliqueu a Importa per triar entre importar només les dades del perfil o seleccionar també les dades addicionals. + El perfil importat conté dades addicionals. Cliqueu \"Importa\" per importar només les dades del perfil o seleccioneu dades addicionals. Podeu seleccionar dades addicionals per exportar juntament amb el perfil. Aplicació predeterminada (%s) Sense recàlcul @@ -3698,7 +3698,7 @@ Abasta l\'àrea: %1$s x %2$s Importa una traça Obre una traça existent Crea una ruta nova - Seleccioneu un fitxer de traça per obrir-lo. + Seleccioneu un fitxer de traça a obrir. Fet Substitueix la traça Proporcioneu l\'amplada del vostre vehicle, pot haver-hi rutes restringides als vehicles amples. @@ -3707,20 +3707,20 @@ Abasta l\'àrea: %1$s x %2$s El punt afegit no serà visible al mapa, perquè el grup seleccionat és ocult, el podeu trobar a \"%s\". Cadira de rodes Nota d\'OSM tancada - Heu d\'indicar els dies laborals abans de continuar + Indiqueu els dies laborals abans de continuar Ruta entre dos punts Planejar una ruta - Afegir a una ruta - Mostrar icones d\'inici final + Afegeix a una ruta + Mostra icones d\'inici i final Triar amplària Trieu un arxiu de ruta al qual s\'afegirà un nou segment. Per usar aquesta opció OsmAnd ha d\'ajustar la seua ruta a les vies del mapa. \n \nEn el pas següent cal que elegiu el perfil de navegació per detectar vies permeses i el llindar de distància per aproximar la ruta a les vies. - Trieu com connectar els punts, amb una línia recta, o calcular la ruta entre ells d\'acord amb el perfil seleccionat. + Trieu com connectar els punts, amb una línia recta, o calcular la ruta entre ells segons s\'indica a continuació. Trieu l\'interval a què les marques de distància o temps sobre la ruta es mostraran. Personalitzat - Desar com a una ruta nova + Desa com una traça nova Ruta inversa La ruta sencera serà recalculada fent ús del perfil seleccionat. Només el següent segment serà recalculat fent ús del perfil seleccionat. @@ -3802,7 +3802,7 @@ Abasta l\'àrea: %1$s x %2$s Torna a fer Manté la pantalla desactivada Moto enduro - Esteu segur que voleu tancar la ruta planificada sense desar-la\? Perdreu tots els canvis. + Esteu segur que voleu descartar totes les modificacions de la ruta planificada en tancar-la\? Afegeix a un fitxer de traces Traces Enregistra el trajecte a un fitxer GPX @@ -3832,4 +3832,22 @@ Abasta l\'àrea: %1$s x %2$s Darrera modificació Nom: Z - A Nom: A - Z + Traces + Prement el botó d\'activació del dispositiu s\'activarà la pantalla mostrant OsmAnd ja la pantalla blocada. + Botó d\'activació + • S\'ha actualitzat la funció Planifica una ruta: permet utilitzar diferents tipus de navegació per segments i afegir traces +\n +\n • Nou menú Aspecte per les traces: seleccioneu color, gruix, representació de les fletxes de direcció, icones inici/fi +\n +\n • S\'ha millorat la visibilitat dels nodes ciclistes. +\n +\n • Ara les traces es poden seleccionar, tenen un menú contextual amb informació bàsica. +\n +\n • S\'han millorat els algoritmes de Cerca +\n +\n • S\'ha millorat les opcions de Segueix traces a Navegació +\n +\n • S\'han corregit problemes en la importació/exportació de la configuració dels perfils +\n +\n \ No newline at end of file From 749ef5644886401696fe08c17fd69c5f277fc293 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Fri, 25 Sep 2020 15:43:46 +0000 Subject: [PATCH 0342/1366] Translated using Weblate (French) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index e88760ed72..91daebce7f 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3869,7 +3869,7 @@ \n \n• Amélioration de l\'algorithme de recherche \n -\n• Amélioration du suivi des traces lors de la Navigation +\n• Amélioration du suivi des traces pendant la Navigation \n \n• Correction de l\'import / export des profils \n From fba9b797afa1c9ab1cf1904c4d834c6adafaeeac Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Fri, 25 Sep 2020 09:13:34 +0000 Subject: [PATCH 0343/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 5e2d0c47f7..4252cf122c 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -72,7 +72,7 @@ Выберите город Поиск почтового индекса Аудио⁣заметка - Видео⁣заметка + Записать видео Фотозаметка OSM-заметка Функции парковки @@ -301,8 +301,8 @@ \nГлобальные данные (между 70° на севере и 70° на юге) основываются на измерениях SRTM (Shuttle Radar Topography Mission) и ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer) — инструментом визуализации Terra, флагманского спутника Системы Наблюдения Земли NASA. ASTER является результатом совместных усилий NASA, министерства экономики Японии, торговли и промышленности (METI), а также Космических Систем Японии (J-spacesystems). Рассмотрите возможность покупки плагина «Линии высот» в Google Play, чтобы поддержать последующую разработку. Линии высот - Видео⁣заметка - Аудио⁣заметка + Запись видео + Запись аудио Действие по умолчанию для виджета: Действие по умолчанию для виджета Формат вывода видео: @@ -325,7 +325,7 @@ Проиграть Запись %1$s %3$s %2$s Запись - Медиазаметки + Аудиозаметки OsmAnd-плагин для линий высот Измерение расстояний Нажмите «Использовать местоположение…» чтобы добавить заметку к данному местоположению. @@ -1201,7 +1201,7 @@ Настройки аудио и видео Изменить порядок Просмотр - Фотозаметка + Сделать фото Сделать фото Синхронизация треков и медиазаметок с вашим аккаунтом Dropbox. Плагин Dropbox @@ -2227,10 +2227,9 @@ Не удалось определить местоположение OsmAnd определит ваше местоположение и предложит загрузить карты для этой области. Поиск карт… - Другой регион + Выберите другой регион Пропустить загрузку карт - У вас нет загруженных карт. Вы можете выбрать карту из списка или скачать позже (Меню — %1$s). Для использования без интернета скачайте карту заранее. -\nДля работы с картами онлайн включите плагин «Онлайн-карты». + У вас нет загруженных карт. Вы можете загрузить карту из списка или сделать это позже («Меню — %1$s»). Мили/метры Получить за %1$s Получить @@ -2671,7 +2670,7 @@ Текущий Добавляет промежуточную остановку Добавляет начальную остановку - Добавляет в конец точку в качестве нового пункта назначения + Перемещает пункт назначения и создаёт промежуточную точку Показать закрытые заметки Показать/скрыть заметки OSM на карте. GPX — подходит для экспорта в JOSM и другие OSM редакторы. @@ -2778,7 +2777,7 @@ Платное приложение Платный плагин Команда OsmAnd - Рекомендации на основе ваших закладок: + На основе сохранённых вами статей мы рекомендуем вам скачать следующие карты: Нужные вам карты Перезапуск Вы отменили подписку OsmAnd Live @@ -3201,7 +3200,7 @@ Пример Изменить настройки Отменить изменение - Применить только к профилю «%1$s» + Применить только к «%1$s» Применить ко всем профилям Сообщение при запуске Аналитика @@ -3466,7 +3465,7 @@ Вы можете выбрать дополнительные данные для экспорта вместе с профилем. Приложение по умолчанию (%s) Не перестраивать - Отклонение для пересчёта + Минимальное отклонение для перестроения маршрута Маршрут будет пересчитан, если расстояние до него больше заданного параметра Пользовательский профиль Угол: %s° @@ -3550,7 +3549,7 @@ Объекты добавлены Импорт завершён Все данные из %1$s импортированы, вы можете использовать кнопки ниже, чтобы открыть соответствующий раздел приложения для управления ими. - При уходе с маршрута на расстояние, превышающее это значение, маршрут будет перестроен автоматически. + Маршрут будет пересчитан, если расстояние от маршрута до текущего местоположения больше выбранного значения. Отклонение, при котором маршрут будет пересчитан. Легенда Невозможно разобрать геоссылку «%s». @@ -3813,7 +3812,7 @@ Выберите ширину Стрелки направления Сплошной - Дата изменения + Последнее изменение Импортировать трек Открыть существующий трек Создать новый маршрут From 34556590c0770cde2bfb07346072131c4ae6a1cc Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Fri, 25 Sep 2020 14:07:44 +0000 Subject: [PATCH 0344/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 106 +++++++++++++++---------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index d8d136ed73..4395b39ccb 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -27,7 +27,7 @@ إدارة الخرائط تفضل الطرق السريعة فضّل… - فضّل الطرق السريعة. + فضل الطرق السريعة. بدون فتح خرائط الاتحاد الأوروبي بيانات الصوت / الفيديو @@ -46,15 +46,15 @@ تسجيل إيقاف بدء - إضافة أوسماند المحلي للخطوط المحيطية + ملحق الخطوط الكنتورية دون اتصال قياس المسافة الملاحظة صوتية أجزاء - الخطوط المحيطية (الكنتورية) - الخطوط المحيطية + الخطوط الكنتورية + الخطوط الكنتورية خرائط أخرى الطرق فقط - خرائط الخطوط المحيطية (الكنتورية) + خرائط الخطوط الكنتورية الخرائط العادية الحدود حد السرعة @@ -71,7 +71,7 @@ توجد وجهة سابقة تعمل حاليا : الوجهات الوضع المتقدم… - موقف سيارات + موقف السيارة حالة طوارئ وسائل النقل العام تسلية @@ -93,7 +93,7 @@ لفتح قفل الشاشة اضغط على أيقونة القفل اسم الشارع إعادة التعيين إلى الافتراضي - موقف سيارات + موقف السيارة السرعة الوجهة الارتفاع @@ -115,7 +115,7 @@ خاص الزم اليسار الزم اليمين - أظهر الخطوط المحيطية (الكنتورية) + أظهر الخطوط الكنتورية أظهر المزيد من تفاصيل الخريطة زيادة كمية خريطة التفصيل هو مبين. بيانات التوجيه @@ -367,7 +367,7 @@ مواقيت الشروق والغروب سمات التقديم نمط الخريطة - عرض/إخفاء الاختصارات + الاختصارات طرق فلورية مسطرة عرض الاتجاه @@ -376,7 +376,7 @@ \n التطبيق في الخلفية إيقاف \n التشغيل في الخلفية - عرض/إخفاء الاختصارات + الاختصارات أين أنا اقفل الشاشة البوصلة @@ -410,8 +410,8 @@ مرشح كالمان تشغيل صوت التقاط الصورة استخدم الاستشعار المغناطيسي - عمل الودجة الافتراضي: - عمل الودجة الافتراضي + إجراء الأداة الافتراضي: + إجراء الأداة الافتراضي مكان موقف سيارتك. %1$s أخذ السيارة عند: مساء @@ -503,13 +503,13 @@ \n  * اضغط على أداة القياس لمعرفة المزيد من الإجراءات. طبقة التضاريس طبقة التضاريس - بيانات الخطوط المحيطية - من فضلك فكر في شراء ملحق الخطوط المحيطية من Google Play لدعم المزيد من التطوير. - الخطوط المحيطية + بيانات الخطوط الكنتورية + من فضلك فكر في شراء ملحق الخطوط الكنتورية من Google Play لدعم المزيد من التطوير. + الخطوط الكنتورية جار تشغيل صوت من التّسجيل المحدد. \n%1$s برنامج ZXing للبحث عن الباركود غيرُ مثبّت. بحث في السّوق ؟ - مستوى تكبير الخطوط المحيطية: + مستوى تكبير الخطوط الكنتورية: الأيسر الخلفي إلى اليسار الأيسر الأمامي @@ -560,7 +560,7 @@ يوفر هذا الملحق طبقة خط كنتوري وطبقة للتضاريس ظاهرة على الخريطة الأساسية للتطبيق. هذه الوظيفة ستكون محل تقدير من طرف الرياضيين، المتنزهين، الرحالة، وكل من هو مهتم بجمال ورخاء الطبيعة. \n \nالبيانات العالمية (بين 70 درجة شمالا و70 جنوبا) مبنية حسب قياسات SRTM (مكوك رادار البعثة الطبوغرافية) وASTER (المكوك المتقدم الخاص بالانبعاث الحراري والانعكاس الإشعاعي)، أداة تصوير على متن Terra، القمر الصناعي الرئيسي لنظام رصد الأرض التابع لناسا. ASTER هو جهد تعاوني فيما بين وكالة ناسا، وزارة الاقتصاد اليابانية، التجارة والصناعة (METI)، و أنظمة الفضاء اليابانية (J-spacesystems). - يوفر هذا الملحق خطوط محيطية وطبقة تضاريس (طبيعية) تظهر على خرائط أوسماند. هذه الوظيفة ستعجب كثيرا الرياضيين، المتجولين، الرحالة، و كل من تهمه بنية التضاريس الطبيعية (يرجى ملاحظة أن بيانات الخطوط المحيطية/أو المساعدة منفصلة ، وتتوفر تنزيلات إضافية بعد تنشيط الملحق.) + يوفر هذا الملحق خطوط كنتورية وطبقة تضاريس (طبيعية) تظهر على خرائط أوسماند. هذه الوظيفة ستعجب كثيرا الرياضيين، المتجولين، الرحالة، و كل من تهمه بنية التضاريس الطبيعية (يرجى ملاحظة أن بيانات الخطوط الكنتورية/أو المساعدة منفصلة ، وتتوفر تنزيلات إضافية بعد تنشيط الملحق.) \nالبيانات العالمية (ما بين 70 درجة شمالاً و70 جنوباً) مبنية على مقاييس SRTM (مكوك رادار البعثة الطبوغرافية) و ASTER (الانبعاث الحراري الفضائي المتقدم والإنعكاس الإشعاعي)، أداة التصوير على متن Terra، القمر الصناعي الرئيسي لنظام رصد الأرض التابع لناسا. \n ASTER هو جهد تعاوني بين كل من وكالة ناسا، وزارة الاقتصاد اليابانية، التجارة والصناعة (METI)، ونظم الفضاء اليابانية (J-spacesystems). أوسماند (اتجاهات التنقل الآلية OSM) @@ -599,9 +599,9 @@ \n - تشغيل كامل دون إنترنت( خزن خرائط التوجيه أو الخرائط الجزئية المنزلة في ذاكرة الجهاز) \n - خرائط التوجيه المدمجة للعالم ككل متاحة لتعمل دون إنترنت \n - تحميل غير محدود لخرائط البلدان أو المناطق مباشرة من التطبيق -\n - ميزة ويكيبيديا المحلية ( قم بتحميل POI لويكيبيديا)، الأمثل لمشاهدة المعالم الأثرية -\n - يمكن تراكب عدة طبقات للخرائط، ك GPX أو مسارات الملاحة، مواقع ذات الاهتمام (POI)، الأماكن المفضلة، الحدود المحيطية، أماكن توقف النقل العمومي، خرائط إضافية بشفافية قابلة للتعديل -\n - البحث عن العناوين والأماكن (POI) دون إنترنت +\n - ميزة ويكيبيديا المحلية ( قم بتحميل نقاط الاهتمام لويكيبيديا)، الأمثل لمشاهدة المعالم الأثرية +\n - يمكن تراكب عدة طبقات للخرائط، ك GPX أو مسارات الملاحة، مواقع ذات الاهتمام ، الأماكن المفضلة، الحدود الكنتورية، أماكن توقف النقل العمومي، خرائط إضافية بشفافية قابلة للتعديل +\n - البحث عن العناوين وأماكن الاهتمام دون إنترنت \n - تحديد الطريق لمسافات متوسطة المدى \n - وضع السيارة، الدراجة والمشاة متوفر مع: \n - تبديل اختياري آلي لوضع الرؤية في الليل/النهار @@ -992,7 +992,7 @@ تسجيل المسار اختر الفاصل الزمني لتسجيل المسار أثناء الملاحة صوت مسج - الملاحة والتوجيه + التوجيه مع الطرق استخدام الموقع… مفضلة نقاط مفضلة مجاورة @@ -1071,10 +1071,10 @@ تجنب الطرق… طرق السكك الحديدية خطوط الترام - الطرق + المسارات الرياضية وسائل المواصلات سمات أخرى للخريطة - العناصر المتبقية + العناصر الاخرى شريط المعلومات العدادات على اليمين العدادات على اليسار @@ -1177,7 +1177,7 @@ مطب كاميرا مراقبة السرعة تنبيه مروري - نقاط الاهتمام المجاورة + نقاط الاهتمام القريبة تنبيهات مرورية تسجيل المسار حسب الطلب حمّل الخرائط المفقودة %1$s (%2$d MB)؟ @@ -1432,7 +1432,7 @@ يُتيحُ لك هذا الاشتراك الحصول على التحديثات كُل ساعة لجميع الخرائط حول العالم. \nجزء من الدخل سيعود إلى مجتمع OSM ويُدفَع لكل مساهمة. \nإن كنت تحب أوسماند وOSM وترغب في الدّعم، هذه هي الطريقة المُثلى للقيام بذلك. - علامات أخرى + وجهات أخرى رفع كمستخدم مجهول رفع ملاحظة OSM شريط الأدوات @@ -1848,7 +1848,7 @@ وضع علامة تشير إلى بدء تشغيل التطبيق الأولي، أبق جميع الإعدادات الأخرى دون تغيير. خرائط على مستوى المنطقة طبقة التضاريس غير مفعلة - الخطوط المحيطية معطلة + الخطوط الكنتورية معطلة ميل بحري ميل بحري/س إجراء محاكاة تخيلية باستخدام توجيه نشط أو مسار مسجل. @@ -1925,14 +1925,14 @@ أدخل موضوع البحث لإيجاد POI شكراً Yandex على معلومات حركة المرور. حركة مرور Yandex - نقاط الاهتمام POI… + نقاط الاهتمام… بحث عن نقاط الاهتمام استخدم كرة التتبع لتحريك الخريطة. استخدم كرة التعقب %1$s محطة توقف قبل مفتاح الخريطة هل حقا تريد تحميل خريطة الطرق فقط، على الرغم من أنه لديك الخريطة (كاملة)؟ - يجب تفعيل ملحق الخطوط المحيطية + يجب تفعيل ملحق الخطوط الكنتورية مسار رحلة مسبق مسافة مسبقة المسافة اللاحقة @@ -2040,15 +2040,15 @@ فئات فرعية أسماء بترجمة حرفية ترجمة حرفية اذا كانت %1$s من الاسم مفقودة - أدخل المدينة، العنوان أو اسم POI + أدخل المدينة، العنوان أو نقاط الاهتمام في ارتقاب عطل عيد الميلاد ورأس السنة الجديدة، يمكنك اختيار عرض POI المرتبطة بعيد الميلاد: أشجار عيد الميلاد، أسواق...الخ. عرض POI عيد الميلاد ؟ بني فاتح بني غامق - نظام ألوان الخطوط المحيطية + نظام ألوان الخطوط الكنتورية سلامة سطح الطرق POI عيد الميلاد - لون الخطوط المحيطية + لون الخطوط الكنتورية تسجيل السرعة الأدنى مرشح: لا تسجيل نقاط أقل من هذه السرعة. تسجيل كشف الحركة @@ -2079,8 +2079,8 @@ الصربية (اللاتينية) الصينية (هونج كونج) ماء - عرض الخطوط المحيطية - عرض الخطوط المحيطية + عرض الخطوط الكنتورية + عرض الخطوط الكنتورية كثافة الخط المحيطي كثافة الخط المحيطي عالي @@ -2199,7 +2199,7 @@ زيادة نصف قطر البحث بحث في المفضلة ملحق - لون الخطوط المحيطية + لون الخطوط الكنتورية اسم المجموعة تعديل اللون إعادة تسمية @@ -2278,7 +2278,7 @@ الوجهة الخاص بك تقع في منطقة ذات ولوج خاص. هل تسمح بالدخول إلى الطرق الخاصة لهذه الرحلة؟ زر يظهر أو يخفي ملاحظات OSM على الخريطة. إخفاء من مستوى التكبير/التصغير - يجب تحميل خريطة الخطوط المحيطية (الكنتورية) لهذه المنطقة لعرضها. + يجب تحميل خريطة الخطوط الكنتورية لهذه المنطقة لعرضها. العرض بدءا من مستوى التكبير عرض مستوى التكبير: %1$s استقراء موقعي @@ -2289,12 +2289,12 @@ زر لجعل الشاشة مركز الوجهة الجديدة ، مع استبدال الوجهة المحددة مسبقا (إن وجدت). يمكنك التقاط صور خاصة بك أو سلسلة من الصور وإرفاقها إلى هذا الموقع من الخريطة. للقيام بذلك تحتاج إلى تثبيت تطبيق مابيلاري من Google play. تحتاج إلى تحميل خريطة تراكب التلال لهذه المنطقة. - لمشاهدة التضاريس على الخريطة، تحتاج إلى شراء وتثبيت برنامج الخطوط المحيطية المساعد. + لمشاهدة التضاريس على الخريطة، تحتاج إلى شراء وتثبيت برنامج الخطوط الكنتورية المساعد. زر لجعل مركز الشاشة أول وجهة وسيطة. بدون طبقة بدون طبقة اشترك في قائمة البريد الإلكتروني لدينا فيما يخص الخصومات والحصول على 3 تنزيلات خرائط إضافية! - مجموعة من الخرائط التي تحوي نقاط أعماق البحر وخطوطه المحيطية. + مجموعة من الخرائط التي تحوي نقاط أعماق البحر وخطوطه الكنتورية. شكرا لشراء معالم أعماق البحار معالم العمق البحري معالم أعماق البحار في نصف الكرة الجنوبي @@ -2315,7 +2315,7 @@ قد يكون المسار طويلا جدا للحساب. يرجى إضافة وجهات وسطى إذا لم يتم العثور على نتيجة خلال 10 دقائق. أوسماند(توجيهات OSM للتنقل الآلية) تطبيق خريطة وتنقل مع إمكانية الوصول إلى بيانات (OSM) مجاناً وفي جميع أنحاء العالم، وبجودة عالية \n -\n. استمتع بمستكشف بالصوت والصورة، وعرض POI (نقاط الاهتمام)، إنشاء وإدارة مسارات GPX، استخدام عرض ارتفاع بيانات الخطوط المحيطية (عن طريق الملحق)، اختيار بين نمط القيادة، ركوب الدراجات والمشاة، التعديل على الموقع وغيرها. +\n. استمتع بمستكشف بالصوت والصورة، وعرض (نقاط الاهتمام)، إنشاء وإدارة مسارات GPX، استخدام عرض ارتفاع بيانات الخطوط الكنتورية(عن طريق الملحق)، اختيار بين نمط القيادة، ركوب الدراجات والمشاة، التعديل على الموقع وغيرها. التنقل عبر GPS \n• يمكنك أن تختار بين وضع دون اتصال (لا رسوم تجوال عندما تكون في الخارج) أو بالإنترنت (أسرع) \n• التوجيه الصوتي بالتفصيل يوجهك طوال الطريق (مسجل أو مدرج) @@ -2344,7 +2344,7 @@ \n• التنقل في وضع ركوب الدراجات تقترح لك مسار دراجات \n• يمكنك مشاهدة سرعتك وارتفاعك \n• خيار تسجيل GPX يتيح لك تسجيل رحلتك ومشاركتها -\n• عبر ملحق إضافي يمكنك عرض الخطوط المحيطية والتضاريس +\n• عبر ملحق إضافي يمكنك عرض الخطوط الكنتورية والتضاريس المشي، التنزه، جولة في المدينة \n• الخريطة تظهر لك ممرات المشي والتنزه \n• ويكيبيديا سيخبرك الكثير اثناء جولتك وبلغتك المفضلة @@ -2367,7 +2367,7 @@ \nمعظم البلدان في جميع أنحاء العالم متاحة للتحميل! \nاحصل على برنامج تنقل موثوق به في بلدك - سواءاً في فرنسا، ألمانيا، المكسيك، المملكة المتحدة، إسبانيا، هولندا، الولايات المتحدة الأمريكية، روسيا، البرازيل أو أي دولة أخرى. أوسماند بلس (توجيهات OSM للملاحة الآلية) تطبيق خريطة وملاحة مع إمكانية الوصول إلى بيانات الموقع مجاناً وفي جميع أنحاء العالم، وبجودة عالية. -\nاستمتع بالملاحة بصوت والصورة، عرض النقاط المهمة حولك (POI)، وإنشاء وإدارة مسارات GPX باستخدام معلومات عن تصور وعلو الخطوط المحيطية، خياراً بين القيادة، ركوب الدراجات، وضع المشاة، التعديل على OSM وأكثر من ذلك بكثير. +\nاستمتع بالملاحة بصوت والصورة، عرض النقاط المهمة حولك (POI)، وإنشاء وإدارة مسارات GPX باستخدام معلومات عن تصور وعلو الخطوط الكنتورية، خياراً بين القيادة، ركوب الدراجات، وضع المشاة، التعديل على OSM وأكثر من ذلك بكثير. \n \nأوسماند بلس هو إصدار للتطبيق مدفوع الأجر. قبل شرائه، ادعم المشروع، بتمويل لتطوير الميزات الجديدة والحصول على آخر التحديثات. \n @@ -2407,7 +2407,7 @@ \n • محطات نقل عام اختيارية (حافلات، الترامواي، القطار) بما في ذلك أسماء خطوط النقل \n • تسجيل رحلة اختياري إلى ملف GPX محلي أو لخدمة على الإنترنت \n • عرض اختياري للسرعة والارتفاع -\n • عرض الخطوط المحيطية والتضاريس (عن طريق برامج ملحق إضافي) +\n • عرض الخطوط الكنتورية والتضاريس (عن طريق برامج ملحق إضافي) المساهمة مباشرة في OSM \n• الابلاغ عن الأخطاء في البرنامج \n• رفع مسارات GPX إلى OSM مباشرة من التطبيق @@ -2519,7 +2519,7 @@ تصدير علاماتك إلى ملف يمكنك تحديده هنا: نقل إلى السجل سيتم إزالة المجموعة بعد إعادة تشغيل التطبيق. - العلامات + التوجيه المباشر نمط الإحداثيات لوحة مفاتيح النظام اختر نسق إدخال الأحداثيات. يمكنك دائماً تغييره بالنقر على خيارات. @@ -2570,7 +2570,7 @@ يفتح أبوابه على إجراءات إضافية إجراءات - خط + توجيه مباشر الملاحظات حسب التاريخ حسب التاريخ حسب النوع @@ -2666,7 +2666,7 @@ ويكي الرحلات دون اتصال تحميلات غير محدودة ويكيبيديا دون اتصال - الخطوط المحيطية والتضاريس + الخطوط الكنتورية والتضاريس على الواي فاي فقط تنزيل الصور على الواي فاي فقط @@ -2822,7 +2822,7 @@ للملاحة البحرية. ميزات العوامات ، المنارات ، مجاري الأنهار ، الممرات البحرية وعلامات ، الموانئ ، خدمات علامة مائية ، وملامح العمق. للتزلج. يتميز بمناطق التزلج ومصاعد التزلج ومسارات التزلج على الجليد وما إلى ذلك. يعتم كائنات الخريطة الثانوية. أسلوب قيادة بسيط. الوضع الليلي اللطيف ، وخطوط الكنتور ، مقارنة بالطرق ذات اللون البرتقالي ، يعتم الكائنات في الخريطة الثانوية. - على النقيض من نمط مصممة أساسا للمشي والتنزه وركوب الدراجات في الطبيعة. قراءة جيدة في الإضاءة الخارجية المعقدة. الميزات الرئيسية: مقارنة الطرق والأجسام الطبيعية، أنواع مختلفة من طرق، والخطوط المحيطية مع إعدادات متقدمة، تفاصيل أكثر في مستويات التكبير/التصغير المقابلة من النمط الافتراضي. يسمح الخيار تكامل سطحي التمييز بين نوعية سطح الطريق. لا يوجد وضع ليلي. + على النقيض من نمط مصممة أساسا للمشي والتنزه وركوب الدراجات في الطبيعة. قراءة جيدة في الإضاءة الخارجية المعقدة. الميزات الرئيسية: مقارنة الطرق والأجسام الطبيعية، أنواع مختلفة من طرق، والخطوط الكنتورية مع إعدادات متقدمة، تفاصيل أكثر في مستويات التكبير/التصغير المقابلة من النمط الافتراضي. يسمح الخيار تكامل سطحي التمييز بين نوعية سطح الطريق. لا يوجد وضع ليلي. الستايل القديم Mapnik الافتراضي جعل ستايل.السمات الرئيسية: الوان متشابهة إلى Mapnik \'الأسلوب. أسلوب الملاحة مع التباين العالي والحد الأعلى من التفاصيل. يتضمن كل خيارات النمط الافتراضي أوسماند، مع عرض أكبر قدر ممكن من التفاصيل ، ولا سيما الطرق والمسارات وطرق السفر الأخرى. التمييز الواضح بين \"جولة الأطلس\" بين أنواع الطرق. مناسبة للاستخدام النهاري والليلي وفي الهواء الطلق. أسلوب الغرض العام. تقديم نظافة مبسطة في المدن المكتظة بالسكان. الملامح الرئيسية: خطوط الكنتور ، والطرق ، وجودة السطح ، والقيود المفروضة على الوصول ، ودروع الطريق ، والمسارات التي تظهر وفقاً لمقياس SAC ، وميزات رياضة الماء الأبيض. @@ -2962,7 +2962,7 @@ \n تمكين تغييرات النقل العام أوسماند لايف. أوسماند لايف وسائل النقل العام - تجنب الحصى والطرق المرصوفة + عدم تجنب الحصى والطرق المرصوفة تجنب الحصى والطرق المرصوفة بدون قطارات تجنب القطارات @@ -3018,7 +3018,7 @@ لصق مسار مجلد بيانات أوسماند تغيير مجلد التخزين ؟ نقل للموقع الجديد - تجنب بعض الطرق، أو بعض أنواع الطرق + تجنب بعض الطرق جنبًا إلى جنب طريق تلفريك اتصال @@ -3039,7 +3039,7 @@ المستخدم %1$s GB تم استخدام %1$s MB تم استخدام %1$s kB - الخطوط المحيطية والتضاريس + الخطوط الكنتورية والتضاريس تفضيل الطرق الغير معبدة تفضيل الطرق الغير معبدة. تحديث كل الخرائط @@ -3066,10 +3066,10 @@ تفضيل الطرق الغير معبدة تفضيل الطرق غير المعبدة عند التوجيه. تحرير خرائط OSM - لإظهار أو إخفاء الخطوط المحيطية على الخريطة. - إظهار الخطوط المحيطية - إخفاء الخطوط المحيطية - إظهار/إخفاء الخطوط المحيطية + لإظهار أو إخفاء الخطوط الكنتورية على الخريطة. + إظهار الخطوط الكنتورية + إخفاء الخطوط الكنتورية + إظهار/إخفاء الخطوط الكنتورية لإظهار وإخفاء التضاريس على الخريطة. إظهار التضاريس إخفاء التضاريس @@ -3804,7 +3804,7 @@ صلب التعديل الأخير استيراد المسار - فتح المسار الموجود + فتح مسار موجود إنشاء مسار جديد حدد المسار للفتح. تم From b5c82c1d162f87922f001fb54900e69d0da2c738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Fri, 25 Sep 2020 07:42:17 +0000 Subject: [PATCH 0345/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 15.5% (542 of 3487 strings) --- OsmAnd/res/values-nb/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index 683e185d58..32c34dd961 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -3744,4 +3744,7 @@ har blitt lagret Legg til minst to punkter. Gjør om + Sist endret + Navn: Å - A + Navn: A - Å \ No newline at end of file From 5f3f16e14513a0f08e6e3300bdd8d75998fb2f01 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Fri, 25 Sep 2020 18:33:48 +0000 Subject: [PATCH 0346/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 4395b39ccb..2d2a7b8cf6 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -2482,7 +2482,7 @@ عتبة توجيه الخريطة حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'. تم نقل جميع العلامات إلى السجل - تم نقل التوجيه المباشرإلى السجل + تم نقل التوجيه المباشر إلى السجل التوجيه المباشر انتقل كنشط قائمة مجموعات @@ -2556,7 +2556,7 @@ مُعدلة تمت الإضافة تعديل طلب البحث. - تم تنشيط التوجيه المباشر%s. + تم تنشيط التوجيه المباشر %s. انقر على التوجيه المباشر في الخريطة لجعله الاعلى بدون فتح القائمة. تدوين ملاحظات! بدون حد زمني From 1a165d54285328a7c6fb2d04ceff999e69f00c05 Mon Sep 17 00:00:00 2001 From: josep constanti Date: Fri, 25 Sep 2020 22:35:46 +0000 Subject: [PATCH 0347/1366] Translated using Weblate (Catalan) Currently translated at 97.3% (3394 of 3487 strings) --- OsmAnd/res/values-ca/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index 5e8a7c8286..79432f1703 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -89,7 +89,7 @@ Utilitza mapes en línia (les tessel·les es baixen i es desen a la tarja de memòria). Mapes en línia Seleccioneu les fonts de mapes de tessel·les en línia o a la memòria cau. - "Aquest connector fa disponible directament des OsmAnd les característiques d\'accessibilitat del dispositiu. Us permet, per exemple, ajustar la velocitat de la veu en la síntesi TTS , configurar la pantalla de navegació, utilitzar un ratolí de bola per controla el zoom o la veu sintetitzada, anunciant automàticament la vostra posició." + "Fa disponible directament des OsmAnd les característiques d\'accessibilitat del dispositiu. Us permet, per exemple, ajustar la velocitat de la veu sintetitzada, configurar la navegació amb cursors, utilitzant un ratolí de bola per controlar el zoom o rebre notificacions amb veu sintetitzada, per exemple per anunciar automàticament la vostra posició." Gestor de connectors Cerca de PDI (punt d\'interès) Gestor de connectors @@ -701,7 +701,7 @@ Transport públic Emergències Restaurants - "Amb aquest connector d\'OsmAnd es poden fer contribucions a OSM com la creació o modificació de PDIs d\'OSM, obrir o comentar anotacions OSM o contribuir amb fitxers GPX enregistrats. OSM és un projecte gestionat per una comunitat, de domini públic i de cartografia global,. Per més detalls dirigiu-vos a https://openstreetmap.org. La participació activa s\'agraeix i aquestes contribucions es poden fer directament des OsmAnd, si heu indicat les vostres credencials personals d\'OSM a l\'aplicació." + "Permet fer contribucions a OSM com la creació o modificació de PDIs d\'OSM, obrir o comentar anotacions OSM i aportar fitxers enregistrats GPX amb OsmAnd en subministrar el vostre usuari i contrasenya. OpenStreetMap.org és un projecte gestionat per una comunitat, de domini públic i de cartografia global." "La llengua seleccionada no està suportada per el motor de TTS (text a veu) d\'Android instal·lat, s\'usarà la llengua del TTS per defecte. Voleu buscar un altre motor TTS a la botiga\?" Comparteix l\'ubicació usant Format de mapa «{0}» obsolet, no s\'admet From 444ffc80c8cd16c2e3c00ffcc4c27c559074ef0f Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 26 Sep 2020 10:52:51 +0000 Subject: [PATCH 0348/1366] Translated using Weblate (German) Currently translated at 99.9% (3486 of 3487 strings) --- OsmAnd/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index fa4dbe5c06..319e1c4f6f 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3457,7 +3457,7 @@ Sie können eine neue benutzerdefinierte Kategorie hinzufügen, indem Sie eine oder mehrere Kategorien auswählen. Nur nachts anzeigen Alle Plugin-Einstellungen wurden auf den Standardzustand zurückgesetzt. - Alle Profileinstellungen werden auf die Standardeinstellungen zurückgesetzt. + Alle Profileinstellungen auf Standard zurückgesetzt. Ankündigung Symbol, das im Ruhezustand angezeigt wird. System-App verwenden From 476e8152a50073a2c3f8e5a1e13cb660a3b4fd29 Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Sat, 26 Sep 2020 16:11:40 +0000 Subject: [PATCH 0349/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 4252cf122c..42c016b76d 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -359,7 +359,7 @@ Прервать загрузку\? Для работы большинства основных возможностей приложения требуются детальные карты регионов, которые можно загрузить из интернета с помощью пункта меню «Настройки» → «Управление файлами карт». После загрузки вы сможете просматривать карты, осуществлять поиск адресов, POI и общественного транспорта. Карта мира, необходимая для обеспечения базовой функциональности, находится в очереди загрузки. - Ничего не было найдено. Вы можете создать карту самостоятельно (смотрите на osmand.net). + Ничего не найдено. Если для вашего региона нет карты, вы можете создать её (см. osmand.net). Онлайн и кешированные карты (растровые) Стандартные карты (векторные) Загрузка и управление локальными файлами карт на вашем устройстве. @@ -776,7 +776,7 @@ Избранное Отправка данных… Отправка… - По вашему запросу ничего не найдено + Ничего не найдено Поиск… Поиск адреса… Поиск адреса в OSM Nominatim @@ -868,7 +868,7 @@ Растровые карты Источник карты Использовать интернет - Показать ваше местоположение + Показать вашу позицию Показать координаты GPS на карте Использовать интернет для загрузки недостающих участков карты Навигационное приложение @@ -1043,7 +1043,7 @@ Добавить напоминание в календарь Время стоянки ограничено Время стоянки неограниченно - Расположение припаркованного автомобиля. %1$s + Расположение припаркованного транспортного средства. %1$s Забрать автомобиль в: PM AM @@ -2710,7 +2710,7 @@ Использовать двузначную долготу Путеводитель Путевые точки удалены из маркеров карты - Ничего не найдено: + Ничего нет в радиусе Добавьте все путевые точки трека или выберите отдельные категории. Всего Результат @@ -2813,7 +2813,7 @@ Мир Ваш поисковый запрос будет отправлен: «%1$s», вместе с вашим местоположением. \n -\nПерсональная информация не собирается, собираются только поисковые данные, необходимые для улучшения поиска. +\nПерсональная информация не собирается, требуются только данные поиска, с целью усовершенствовать поиск. Нет результатов? \nРасскажите нам об этом. Отправить поисковый запрос? @@ -3342,11 +3342,11 @@ %1$s • %2$s %1$s, %2$s Для пустынь и других малонаселённых районов. Более детально. - Положение значка при движении - Положение значка в состоянии покоя + Значок местоположения при движении + Значок местоположения в состоянии покоя После нажатия кнопки «Применить» удалённые профили будут полностью потеряны. Базовый профиль - Выберите цвет + Цвет Вы не можете удалить стандартные профили OsmAnd, но вы можете отключить их на предыдущем экране или переместить вниз. Редактировать профили Режим навигации определяет правила расчета маршрутов. @@ -3493,8 +3493,8 @@ Навигация, точность ведения журнала Размер изображения, качество звука и видео Логин, пароль, локальное редактирование - Выберите значок, цвет и имя - Позволяет обмениваться текущим местоположением с помощью записи поездки. + Значок, цвет и название профиля + Возможность отправки текущего местоположения при записи поездки. Онлайн-отслеживание Точность ведения журнала Ваши записанные треки находятся в %1$s или папке OsmAnd. @@ -3526,7 +3526,7 @@ Прямо-к-точке Сортировать по категории Антарктида - Дополнительный прямой отрезок между моим местоположением и рассчитанным маршрутом будет отображаться до тех пор, пока маршрут не будет пересчитан + Прямой отрезок между текущим местоположением и рассчитанным маршрутом будет отображаться, пока маршрут не будет пересчитан Стиль отрисовки Импорт файла отрисовки Все настройки профиля будут восстановлены в исходное состояние после создания/импорта этого профиля. From 9f3ac4e9424ff9caeae23d242e65bb06a7560b50 Mon Sep 17 00:00:00 2001 From: Roberto GEB Date: Sat, 26 Sep 2020 10:21:08 +0000 Subject: [PATCH 0350/1366] Translated using Weblate (Spanish) Currently translated at 97.3% (3394 of 3487 strings) --- OsmAnd/res/values-es/strings.xml | 228 +++++++++++++++++++++---------- 1 file changed, 155 insertions(+), 73 deletions(-) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 9f7e110378..8c6fad630e 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -445,7 +445,7 @@ Distancia total %1$s, tiempo de viaje %2$d h %3$d min. Servicios de navegación con o sin conexión. Servicio de navegación - ¡Carpeta de almacenamiento de datos en la tarjeta de memoria inaccesible! + ¡La carpeta de almacenamiento en la tarjeta de memoria es inaccesible! ¿Descargar {0} - {1} ? Ya existen datos descargados ({1}) para {0}. ¿Actualizarlos ({2})? Dirección @@ -612,13 +612,13 @@ Usa mapas en línea (descarga y guarda teselas en la tarjeta de memoria). Mapas en línea Elige las fuentes de teselas de mapas en línea o en caché. - Este complemento puede acceder a muchos tipos de mapas en línea (llamados teselas o ráster), desde teselas predefinidas de OpenStreetMap (como Mapnik) a imágenes satelitales y capas de propósito especial como mapas del tiempo, mapas del clima, mapas geológicos, capas de sombreado, etc. -\n -\nCualquiera de estos mapas puede ser usado como el mapa (base) principal que se mostrará en el mapa de OsmAnd, o como una superposición o subyacencia de otro mapa base (como los mapas estándar de OsmAnd en línea). Para hacer más visible cualquier mapa subyacente, ciertos elementos de los mapas vectoriales OsmAnd se pueden ocultar fácilmente a través del menú «Configurar mapa» cuando lo desees. -\n -\nLos mapas de teselas se pueden obtener directamente a través de fuentes en línea, o se pueden preparar para tu uso sin conexión (y copiar manualmente en la carpeta de datos OsmAnd) como una base de datos SQLite que puede ser producida por una variedad de herramientas de preparación de mapas de terceros. + "Accede a muchos tipos de mapas en línea (llamados teselas o ráster), desde teselas predefinidas de OpenStreetMap (como Mapnik) a imágenes satelitales y capas de propósito especial como mapas meteorológicos, mapas del clima, mapas geológicos, capas de sombreado, etc. +\n +\nCualquiera de estos mapas puede mostrarse como el mapa (base) principal, o como una superposición o subyacencia de otro mapa base (como los mapas estándar de OsmAnd sin conexión). Ciertos elementos de los mapas vectoriales OsmAnd se pueden ocultar a través del menú «Configurar mapa» para hacer más visible cualquier mapa subyacente. +\n +\nDescarga los mapas de teselas directamente a través de fuentes en línea, o prepararlos para tu uso sin conexión (copiándolos manualmente en la carpeta de datos OsmAnd) como una base de datos SQLite que puede generarse con varias herramientas de preparación de mapas de terceros." Muestra los ajustes para activar en modo reposo el seguimiento y la navegación, activando periódicamente el dispositivo GPS (con la pantalla apagada). - Este complemento activa las funciones de accesibilidad del dispositivo, directamente en OsmAnd. Facilita por ejemplo, el ajuste de la velocidad de la voz para voces de texto a voz, la configuración de navegación de pantalla con el panel direccional, usando la rueda de desplazamiento para el control del zoom, o la retroalimentación de texto a voz, por ejemplo, para anunciar la ubicación automáticamente. + Activa las funciones de accesibilidad del dispositivo directamente en OsmAnd. Facilita por ejemplo, el ajuste de la velocidad de la voz para voces de texto a voz, la configuración de navegación de pantalla con el panel direccional, usando la rueda de desplazamiento para el control del zoom, o la retroalimentación de texto a voz, por ejemplo, para anunciar la ubicación automáticamente. Este complemento muestra los ajustes de funciones de desarrollo y depuración para probar la simulación de rutas, el rendimiento del renderizado, o las indicaciones por voz. Estos ajustes están destinados para los desarrolladores y no son necesarios para el usuario general. Complementos Los complementos activan ajustes avanzados y funcionalidades adicionales. @@ -1249,7 +1249,7 @@ Más detalles Menos detalles Restricciones de acceso - Restricciones de acceso y peajes + Mostrar restricciones de acceso y peajes Calidad de los caminos Superficie de los caminos Rutas ciclistas @@ -2634,11 +2634,11 @@ cerrado Invierno y esquí GPX - adecuado para exportar a JOSM u otros editores OSM. - OSC - adecuado para exportar a OpenStreetMap. + OSC - adecuado para exportar a OSM. Archivo GPX Archivo OSC Elegir tipo de archivo - Elige el tipo de exportación: notas de OSM, PDI o ambos. + Exporta como notas OSM, PDIs o ambos. Todos los datos Notas de OSM Vista turística @@ -2844,7 +2844,7 @@ Renovar anualmente %1$.2f %2$s Frecuencia de pago: - Las donaciones ayudan a financiar la cartografía de OpenStreetMap. + Las donaciones ayudan a financiar la cartografía de OSM. Por OsmAnd Suscripciones Sólo mostrar imágenes en 360° @@ -2896,10 +2896,10 @@ Tipos de caminos Bajarse en Esperar en la parada - Mostrar/ocultar trazas GPX - Un botón que muestra u oculta las trazas GPX elegidas en el mapa. - Ocultar trazas GPX - Mostrar trazas GPX + Mostrar/ocultar trazas + Un botón que muestra u oculta las trazas elegidas en el mapa. + Ocultar trazas + Mostrar trazas • Nueva pantalla «Direcciones»: Muestra los botones de destino «Casa» y «Trabajo», el atajo de la «ruta anterior», la lista de trazas, marcadores GPX activos y el historial de búsqueda. \n \n • Información adicional en «Detalles de la ruta»: Tipos de caminos, superficie, pendiente y suavidad @@ -3104,7 +3104,7 @@ Automóvil, camión, motocicleta Bicicleta de montaña, ciclomotor, caballo Caminata, senderismo, correr - Todos los tipos de transporte público + Tipos de transporte público Barco, remo, vela Avión, ala delta Línea recta @@ -3153,7 +3153,7 @@ Despertar en giros Define durante cuánto tiempo debe estar encendida la pantalla. Usar sensor de proximidad - Mueve la mano sobre la parte superior de la pantalla para encenderla mientras navegas. + Agitando tu mano sobre la pantalla lo encenderá. Grado 1 Grado 2 Grado 3 @@ -3225,7 +3225,7 @@ Análisis Mostrar el mapa en la pantalla de bloqueo durante la navegación. Ajustes para la navegación del perfil elegido «%1$s». - Duración del encendido + Tiempo de espera después de despertar Unidades y formatos Aspecto Apariencia del mapa @@ -3247,9 +3247,9 @@ Mapa durante la navegación Mapa durante la navegación Otros - Peso, altura, velocidad + Peso, altura, longitud, velocidad Parámetros del vehículo - Los anuncios de voz solo se realizan durante la navegación. + Los anuncios de voz solo se hacen durante la navegación. Instrucciones de navegación y anuncios Indicaciones por voz Alertas en pantalla @@ -3261,7 +3261,7 @@ Descarga el mapa detallado de «%s», para ver esta área. Carpeta… Mover al nuevo destino - Cambiar la carpeta de almacenamiento de datos + Cambiar la carpeta de almacenamiento Parque de nieve Trineo Trineo @@ -3311,8 +3311,8 @@ Usado %1$s GB Usado %1$s MB Usado %1$s kB - Preferir caminos sin pavimentar - Prefiere caminos sin pavimentar. + Preferir carreteras sin pavimentar + Prefiere carreteras sin pavimentar. Actualizar todos los mapas ¿Estás seguro de que quieres actualizar todos los (%1$d) mapas\? Ingresa la ruta a la carpeta @@ -3332,8 +3332,8 @@ Curvas de nivel y sombreado Puedes aplicar este cambio a todos los perfiles o sólo al marcado actualmente. Compartido - Preferir caminos sin pavimentar - Prefiere caminos sin pavimentar. + Preferir carreteras sin pavimentar + Prefiere carreteras sin pavimentar sobre las pavimentadas para el enrutamiento. Ediciones de OSM Un botón que muestra u oculta las curvas de nivel en el mapa. Mostrar curvas de nivel @@ -3349,16 +3349,16 @@ \'%1$s\' ya existe. ¿Sobrescribir\? No se pudo exportar el perfil. Importar perfil - Para importar un perfil, elige el archivo en el dispositivo y ábrelo con OsmAnd. + Añade un perfil abriendo su archivo con OsmAnd. Error de importación de %1$s: %2$s %1$s importados. Blanco Alternar %1$s y %2$s Punto de partida - Se utiliza para estimar la hora de llegada en el caso de los tipos de caminos desconocido y para limitar la velocidad en todos los caminos (podría cambiarse la ruta) + Estima la hora de llegada para tipos de vías desconocidos y límites de velocidad en todas las vías (puede afectar al enrutado) Esquí de travesía Simular la ubicación usando una traza GPX grabada. - Nombre del archivo vacío + El nombre de archivo está vacío Traza guardada Revertir Un botón para centrar en la pantalla el punto de partida y calcular la ruta hacia el destino o abre un cuadro de diálogo para elegir el destino si el marcador no está en el mapa. @@ -3387,20 +3387,20 @@ Descargando %s Grueso Para desiertos y otras zonas escasamente pobladas. Más detallado. - Elegir icono de navegación - Elegir icono de mapa - Al pulsar en «Aplicar», los perfiles borrados se perderán completamente. + Icono de posición en movimiento + Icono de posición en reposo + Al tocar \'Aplicar\' se eliminan los perfiles borrados de forma permanente. Perfil principal Elegir el color - No puedes borrar los perfiles de OsmAnd predefinidos, pero puedes desactivarlos en la pantalla anterior, o moverlos a la parte inferior. + Los perfiles predefinidos de OsmAnd no pueden borrarse , pero sí desactivarse (en la pantalla anterior), o moverse a la parte inferior. Editar perfiles El \'tipo de navegación\' domina como se calculan las ruta. Apariencia del perfil Icono, color y nombre - Editar la lista de perfiles + Editar lista de perfiles Perfil seleccionado - Tocando en %1$s, descartarás todos tus cambios. - Todos los ajustes del perfil se restablecerán al estado después de la instalación. + Tocando en %1$s, descartas todos tus cambios. + Restablece todas las configuraciones de perfil a los valores predeterminados de instalación. ¿Restablecer todos los ajustes del perfil\? %1$s %2$s %1$s: %2$s @@ -3417,7 +3417,7 @@ Te permite compartir la ubicación actual utilizando la grabación del viaje. Seguimiento en línea Precisión de registro - Puedes encontrar todas las trazas grabadas en %1$s o en la carpeta OsmAnd utilizando el administrador de archivos. + Tus trazas grabadas están en %1$s, o en la carpeta de OsmAnd. Puedes encontrar todas tus notas en %1$s. Notas de video Notas de foto @@ -3472,21 +3472,21 @@ Éste es un filtro de corte de baja velocidad para no registrar puntos por debajo de cierta velocidad. Esto puede hacer que las pistas grabadas sean más suaves cuando se ven en el mapa. Recomendación: Intenta usar primero la detección de movimiento a través del filtro de desplazamiento mínimo (B), puede producir mejores resultados, y perderás menos datos. Si tus trazas siguen siendo ruidosas a bajas velocidades, prueba con valores distintos de cero aquí. Ten en cuenta que algunas mediciones pueden no informar de ningún valor de velocidad (algunos métodos basados en la red), en cuyo caso no se registraría nada. Observación: comprobación de velocidad > 0: La mayoría de los chips de GPS reportan un valor de velocidad sólo si el algoritmo determina que estás en movimiento, y ninguno si no lo estás. Por lo tanto, usar el ajuste > 0 en este filtro en cierto sentido utiliza la detección de movimiento de los chips del GPS. Pero incluso si no se filtra aquí en el momento de la grabación, seguimos utilizando esta característica en nuestro análisis de GPX para determinar la distancia corregida, es decir, el valor mostrado en ese campo es la distancia registrada miestras está en movimiento. - Esto registrará sólo los puntos medidos con una precisión mínima indicada (en metros/pies, según lo informado por Android para tu conjunto de chips). La precisión se refiere a la dispersión de las mediciones repetidas, y no está directamente relacionada con la precisión, lo que define lo cerca que están tus mediciones a tu verdadera posición. + Esto registrará sólo los puntos medidos con una exactitud mínima indicada (en metros/pies, según lo informado por Android para tu conjunto de chips). La exactitud es la proximidad de las mediciones a la posición real y no está directamente relacionada con la precisión, que es la dispersión de las mediciones repetidas. Reorganizar categorías - Puedes añadir categorías personalizadas, ocultar las categorías que no te parezcan necesarias y cambiar el criterio de ordenación de la lista. La lista puede ser importada y exportada con perfiles. - Puedes añadir una nueva categoría personalizada seleccionando una o varias categorías necesarias. - Restablecer valores predeterminados restablecerá el orden de clasificación al estado predeterminado tras la instalación. + Cambia el criterio de ordenación de listas, oculta categorías. Puedes importar o exportar todos los cambios en perfiles. + Puedes añadir una nueva categoría personalizada seleccionando una o más categorías. + \"Restablecer valores predeterminados\" restablecerá el orden de clasificación al valor predeterminado de la instalación. Disponible Añadir categoría personalizada Mostrar sólo por la noche - Todos los ajustes del complemento se restauraron al estado predeterminado. - Todos los ajustes del perfil se restauran al estado predeterminado. + Todos los ajustes del complemento se restauraron a lo predeterminado. + Todos los ajustes del perfil se restauran a lo predeterminado. %1$s/%2$s Ocaso a las %1$s Amanece a las %1$s - Modo de accesibilidad desactivado en el sistema. - Usar el tiempo de espera de la pantalla del sistema + Elmodo de accesibilidad está desactivado en tu sistema Android. + Usar el tiempo de apagado de pantalla del sistema Desactivado por defecto, si OsmAnd se ejecuta en primer plano, la pantalla no se apaga. \n \nSi está activada, OsmAnd utilizará los ajustes de tiempo de espera del sistema. @@ -3503,7 +3503,7 @@ %1$s — %2$s — %3$s Enrutado Incluir datos adicionales - El perfil importado contiene datos adicionales. Pulsa en Importar para importar solo datos de perfil o seleccione datos adicionales para importar. + El perfil importado contiene datos adicionales. Pulsa \"Importar\" para importar solo datos de perfil o seleccione datos adicionales. Puedes seleccionar datos adicionales para exportar junto con el perfil. Perfiles Acciones rápidas @@ -3518,7 +3518,7 @@ Importar archivo de renderizado Terreno Mapa de sombreado utilizando tonos oscuros para mostrar pendientes, picos y tierras bajas. - Pendiente es visualizaciones coloreadas en el terreno. + Pendiente utiliza colores para visualizar la inclinación del terreno. Establezca los niveles de zoom mínimo y máximo en los que se mostrará la capa. Se necesitan mapas adicionales para ver Sombreado en el mapa. Se necesitan mapas adicionales para ver Pendientes en el mapa. @@ -3542,7 +3542,7 @@ Recalcular ruta en caso de desvío %1$s de %2$s Cuestas - Mostrar/esconder terreno + Mostrar / esconder terreno Esconder terreno Mostrar terreno Un botón para mostrar o esconder una capa de terreno en el mapa. @@ -3560,19 +3560,19 @@ Idioma Todos los idiomas Se necesitan mapas adicionales para ver los puntos de interés de Wikipedia en el mapa. - • Nuevos mapas sin conexión de las pendientes + • Nuevos mapas de Pendientes sin conexión \n -\n • Personalización más completa de los favoritos y puntos de referencia GPX (colores personalizados, iconos, formas) +\n • Personalización completa de Favoritos y Puntos de referencia GPX - colores personalizados, iconos, formas \n -\n • Nueva personalización en el orden de los elementos en Configurar mapa, menú contextual y menú lateral +\n • Personalización en el orden de los elementos en Configurar mapa, menú contextual y menú lateral \n \n • Wikipedia ahora se visualiza como una capa separada en Configurar mapa, elige sólo los idiomas necesarios \n -\n • Crea tu propio filtro/mapas de puntos de interés, con total flexibilidad +\n • Crea tu propios filtros/mapas de PDI con total flexibilidad \n \n • Se añadieron opciones para restablecer los ajustes de los perfiles personalizados \n -\n • Las rutas GPX para la navegación, ahora admiten los carriles de tráfico y completan las instrucciones de giro +\n • Las rutas GPX para la navegación admiten los carriles de tráfico e instrucciones de giro completas \n \n • Se ha corregido el tamaño de la interfaz en las tabletas \n @@ -3581,10 +3581,10 @@ \n Suscripción - OsmAnd Live Compras en OsmAnd - Un botón que muestra u oculta el transporte público en el mapa. + Botón que muestra u oculta el transporte público en el mapa. Regresar a editar Cambiar el perfil de la aplicación - Los perfiles seleccionados para esta acción no se han encontrado. + No se pudo encontrar ninguno de esos perfiles. Mapas extras OsmAnd + Mapillary Viaje (Wikivoyage y Wikipedia) @@ -3594,7 +3594,7 @@ Mostrar/ocultar transporte público Ocultar transporte público Mostrar transporte público - Crear/Editar POI + Crear / Editar POI Agregar / Editar Favorito Agregar perfil Aragones @@ -3606,9 +3606,9 @@ OsmAnd ya tiene elementos con los mismos nombres que los importados. \n \nSelecciona una acción. - Personalice la cantidad de elementos en el cajón, configure el mapa y el menú contextual. + Personaliza la cantidad de elementos en el cajón, configure el mapa y el menú contextual. \n -\nPuede desactivar los complementos no utilizados para ocultar todos sus controles de la aplicación. %1$s. +\nDesactiva los complementos no utilizados para ocultar todos sus controles de la aplicación. %1$s. Ocultar ajustes los restablece a su estado original. Panyabí Napolitano @@ -3628,13 +3628,13 @@ \nPuede administrar y cancelar sus suscripciones yendo a la configuración de Google Play. Combina tipos de POI de diferentes categorías. Toque \"Cambiar\" para seleccionar todo, toque el lado izquierdo para la selección de categoría. Restaurar pedido de artículos predeterminado - El botón de acción de grabación cambiará entre los perfiles seleccionados. + El botón de acción cambia los perfiles seleccionados. Antártida Ordenar por categoría Estilo de renderizado La ruta se volverá a calcular si la distancia a la ruta es mayor que el parámetro especificado Distancia mínima para recalcular ruta - Desactivar recálculo + Sin recálculo Seleccione los datos a importar. Algunos artículos ya existen Los elementos importados se agregarán con el prefijo @@ -3657,7 +3657,7 @@ Divisor Oculto Estos elementos están ocultos en el menú, pero las opciones o complementos representados continuarán funcionando. - \'Acciones principales\' solo contiene 4 botones. + Solo tiene cuatro botones. Acciones principales Puede acceder a estas acciones tocando el botón “%1$s”. Puede mover elementos solo dentro de esta categoría. @@ -3666,7 +3666,7 @@ Motonieve Complemento OsmAnd personalizado Artículos - Seleccione los idiomas en los que aparecerán los artículos de Wikipedia en el mapa. Puede cambiar entre todos los idiomas disponibles mientras lee el artículo. + Selecciona los idiomas para los artículos de Wikipedia en el mapa. Cambia a cualquier idioma disponible mientras lees el artículo. Es posible que algunos artículos de Wikipedia no estén disponibles en su idioma. Cantonés Tártaro @@ -3680,13 +3680,13 @@ Acción %1$s no admitida Mapa general del mundo (detallado) Tipo no admitido - Proporciona la anchura de tu vehículo, algunas restricciones de rutas pueden aplicarse para los vehículos anchos. - Proporciona la altura de tu vehículo, algunas restricciones de rutas pueden aplicarse para los vehículos altos. - Proporciona el peso de tu vehículo, algunas restricciones de rutas pueden aplicarse para los vehículos pesados. + Proporciona la anchura de tu vehículo, algunas restricciones de ruta pueden aplicarse para vehículos anchos. + Proporciona la altura de tu vehículo, algunas restricciones de ruta pueden aplicarse para vehículos altos. + Proporciona el peso de tu vehículo, algunas restricciones de ruta pueden aplicarse para vehículos pesados. OsmAnd GPX no está bien formado, por favor ponte en contacto con el equipo de soporte para investigar más a fondo. Siempre Control de pantalla - Apaga la pantalla después del tiempo de apagado de la pantalla definido en el sistema. + Apaga la pantalla según el tiempo de espera del sistema. Usar el tiempo de apagado de la pantalla del sistema Selecciona las opciones de activación de la pantalla (asegúrate de que OsmAnd esté en primer plano cuando se bloquee el dispositivo): Cada instrucción de navegación encenderá la pantalla. @@ -3706,20 +3706,20 @@ Tiempo de expiración Proyección de Mercator Formato de almacenamiento - Fija el nivel de zoom mínimo y máximo en el que se mostrará o cargará el mapa en línea. - Tiempo de expiración en minutos. Las teselas almacenadas se volverán a cargar después del tiempo especificado. Deja este campo vacío para que no se actualicen nunca las teselas de esta fuente. + Establece un nivel de zoom mínimo y máximo para mostrar o cargar el mapa en línea. + Las teselas almacenadas se volverán a cargar después del tiempo especificado. Deja este campo vacío para que no se actualicen nunca las teselas de esta fuente. \n \nUn día son 1.440 minutos. \nUna semana son 10.080 minutos. \nUn mes son 43.829 minutos. Elige cómo se guardarán las teselas descargadas. - Puedes Exportar o Importar acciones rápidas con perfiles de aplicación. + Puede exportar o importar acciones rápidas con perfiles de aplicación. ¿Eliminar todo\? ¿Estás seguro de que deseas eliminar irrevocablemente% d acciones rápidas\? Tiempo de apagado de la pantalla - Si la opción \"%1$s\" está habilitada, el tiempo de actividad dependerá de ella. + Si \"%1$s\" está encendido, el tiempo de actividad dependerá de ello. metros - Controla la visibilidad de los detalles adicionales mostrados en el mapa + Muestra u oculta detalles adicionales del mapa Mapa nocturno No pude analizar la geointención \"%s\". División de grabación @@ -3778,14 +3778,14 @@ Límite de longitud Rumbo %1$s eliminado - Es necesario reiniciar para eliminar completamente los datos de las cámaras de velocidad. + Reinicia la aplicación para borrar todos los datos de los radares de velocidad. Desinstalar y reiniciar Este dispositivo no tiene cámaras de velocidad. Patines en línea - Permite controlar el nivel de zoom del mapa con los botones de volumen del dispositivo. + Controla el nivel de zoom del mapa usando los botones de volumen. Botones de volumen como zoom Proporcione la longitud de su vehículo, se pueden aplicar algunas restricciones de rutas para vehículos largos. - Eliminar el siguiente punto de destino + Eliminar el punto de destino más cercano Por favor, proporcione un nombre para el punto El punto de destino actual de la ruta será borrado. Si se trata del destino, la navegación se detendrá. Descargar mapas de Wikipedia @@ -3815,4 +3815,86 @@ Abrir traza guardada está guardada Añade al menos dos puntos. + Seleccionar anchura + Grabar automáticamente la traza durante la navegación + Consigue información sobre puntos de interés en Wikipedia. Es tu guía de bolsillo sin conexión. Sólo tienes que activar el complemento de Wikipedia y disfrutar de los artículos sobre los objetos que te rodean. + El punto agregado no será visible en el mapa, ya que el grupo seleccionado está oculto, puedes encontrarlo en \"% s\". + Motocicleta de enduro + Moto scooter + Silla de ruedas + Silla de ruedas hacia adelante + Go-cart + Nota OSM cerrada + Establece los días laborables para continuar + Ruta entre puntos + Añadir a una traza + Mostrar los iconos de inicio y fin + Selecciona el intervalo con el que se mostrarán las marcas con la distancia o el tiempo sobre la traza. + Selecciona la opción de división deseada: por tiempo o por distancia. + Personalizado + Flechas de dirección + Sólido + Ultimo editado + Importar traza + Selecciona un archivo de traza para abrirlo. + Sobrescribir traza + Guardar como nueva traza + Ruta inversa + La traza completa será recalculada utilizando el perfil seleccionado. + Sólo el siguiente segmento será recalculado usando el perfil seleccionado. + Selecciona cómo conectar puntos, con línea recta, o calcula una ruta entre ellos como se especifica a continuación. + Traza completa + Siguiente segmento + A continuación, ajusta tu traza a la carretera permitida más cercana con uno de tus perfiles de navegación para usar esta opción. + Distancia umbral + Perfil de navegación + Selecciona un archivo de traza al que agregar el nuevo segmento. + Imágenes a pie de calle + ¿Estás seguro de que quieres descartar todos los cambios en la ruta planeada cerrándola\? + En caso de dirección contraria + Guardar como nuevo archivo de traza + Añadir a un archivo de traza + Trazas + Trazas + Trazas + Registrar traza en archivo GPX + Ruta de traza + Añadir archivos de traza + Importa o graba archivos de trazas + Añadir punto de ruta de la traza + Añadir punto de ruta de la traza + Grabación de viaje + Guardar como archivo de traza + Seguir traza + Elige el archivo de la traza a seguir + Elige el archivo de traza a seguir o impórtalo desde tu dispositivo. + Selecciona otra traza + Navegar desde mi ubicación a la traza + Apuntar a la traza para navegar + Inicio de la traza + Punto más cercano + Adherir a las carreteras + Recortar antes de + Recortar después de + Cambiar el tipo de ruta después de + Pausará el registro de trazas cuando se mate la aplicación (a través de aplicaciones recientes). (La indicación OsmAnd de fondo desaparece de la barra de notificaciones de Android.) + Rehacer + - Función actualizada de Planificar una ruta: permite utilizar diferentes tipos de navegación por segmento y la inclusión de trazas +\n +\n - Nuevo menú Apariencia para las trazas: selecciona el color, el grosor, muestra las flechas de dirección, los iconos de inicio/fin +\n +\n - Mejorada la visibilidad de los nodos de bicicleta. +\n +\n - Las trazas son ahora tocables, tienen un menú contextual con información básica. +\n +\n - Algoritmos de búsqueda mejorados +\n +\n - Mejoradas las opciones de seguimiento de trazas en Navegación +\n +\n - Solucionados los problemas con configuración de los perfiles de importación/exportación +\n +\n + Último modificado + Nombre: Z – A + Nombre: A - Z \ No newline at end of file From d1dc69dc204d1f79bfc4c2e3f97e19454a2d2ac3 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Fri, 25 Sep 2020 21:31:42 +0000 Subject: [PATCH 0351/1366] Translated using Weblate (Polish) Currently translated at 99.5% (3472 of 3487 strings) --- OsmAnd/res/values-pl/strings.xml | 60 +++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index 5250a19bc4..c7ba4f0c15 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -92,7 +92,7 @@ Wybrany język nie jest obsługiwany przez zainstalowany moduł syntezy mowy (TTS), więc zostanie użyty aktualny język. Poszukać innego mechanizmu syntezy mowy w sklepie\? Brakujące dane Czy chcesz odwiedzić sklep, by zainstalować wybrany język? - Odwróć kierunek GPX + Odwróć kierunek śladu Użyj bieżącego celu Pobierz mapę wektorową offline tego położenia w „Ustawieniach” (\"Zarządzaj mapami\") lub przełącz na wtyczkę \"Mapy online\". Dla bieżącego położenia dostępna jest wektorowa mapa offline. @@ -2014,7 +2014,7 @@ Wymagane, aby pobrać mapy. Szukanie położenia… Wolna pamięć - Katalog przechowywania danych OsmAnd (mapy, pliki GPX, itp.): %1$s. + Przechowywanie danych OsmAnd (dla map, plików śladów, itp.): %1$s. Zezwól Zezwól na dostęp do położenia Wyszukaj aktualne położenie @@ -2066,8 +2066,8 @@ Wyświetla powiadomienie systemowe umożliwiające rejestrowanie podróży. Powiadomienia Kontynuuj - Nie ma na razie żadnych plików GPX - Można także dodać pliki GPX do katalogu + Nie masz jeszcze żadnych plików śladów + Można również dodać pliki śladów do folderu Dodaj więcej… Wygląd Bardzo cienki @@ -2896,10 +2896,10 @@ Wymień Wyświetl więcej Wyświetlane ślady - Przełącz widoczność śladów GPX - Przycisk do pokazywania lub ukrywania wybranych ścieżek GPX na mapie. - Ukryj ślady GPX - Wyświetl ślady GPX + Pokaż/Ukryj ślady + Przycisk do pokazywania lub ukrywania wybranych śladów na mapie. + Ukryj ślady + Pokaż ślady Proszę najpierw ustalić cel Poprzednia trasa Dowiedz się więcej na naszym blogu, jak OsmAnd wyznacza trasy. @@ -3783,13 +3783,13 @@ Zastosowanie tych zmian wyczyści dane z pamięci podręcznej dla tego źródła kafelków Kierunek Usunięto %1$s - Ponowne uruchomienie jest wymagane, żeby całkowicie usunąć dane fotoradarów. + Uruchom ponownie aplikację, aby usunąć wszystkie dane o fotoradarach. Odinstaluj i zrestartuj Tracker OsmAnd Podaj długość pojazdu, niektóre ograniczenia tras mogą być stosowane dla długich pojazdów. To urządzenie nie ma fotoradarów. - Usuń następny punkt docelowy - Włącz sterowanie poziomem powiększenia mapy za pomocą przycisków głośności urządzenia. + Usuń najbliższy punkt docelowy + Steruj poziomem powiększenia mapy za pomocą przycisków głośności na urządzeniu. Podaj nazwę punktu Bieżący punkt docelowy na trasie zostanie usunięty. Jeśli będzie to miejsce docelowe, nawigacja zostanie zatrzymana. Pobierz mapy Wikipedii @@ -3814,8 +3814,8 @@ Wybierz żądaną opcję podziału: według czasu lub odległości. Stałe OsmAnd GPX nie jest dobrze uformowany, prosimy o kontakt z zespołem wsparcia technicznego w celu dalszego zbadania sprawy. - Ustaw limit czasu ekranu po przebudzeniu. (\"%1$s\" nie stosuje się żadnego limitu czasu.) - Pokaż ikony rozpoczęcia i zakończenia + Wybierz limit czasu ekranu po przebudzeniu. (\"%1$s\" nie powoduje przekroczenia limitu czasu). + Pokaż ikony początku i końca Wybierz przedział czasowy, w którym będą wyświetlane znaki z odległością lub czasem na torze. Dostosowany Strzałki kierunku @@ -3827,7 +3827,7 @@ Wykonane Wyłączone. Wymagane „Pozostaw ekran włączony” w sekcji „Limit czasu po wybudzeniu”. Zastępowanie ścieżki - Zapisz jako nowa Ścieżka + Zapisz jako nowa ślad Odwróć trasę Cała trasa Nowy segment @@ -3835,19 +3835,19 @@ Profil nawigacji Wybierz plik śladu do którego zostanie dodany nowy segment. Cała trasa zostanie ponownie wyznaczona przy użyciu wybranego profilu. - Tylko następny segment zostanie ponownie obliczony przy użyciu wybranego profilu. - Wybierz sposób łączenia punktów linią prostą lub obliczania trasy między nimi z wybranym profilem. + Tylko następny segment zostanie przeliczony przy użyciu wybranego profilu. + Wybierz sposób łączenia punktów, za pomocą linii prostej, lub oblicz trasę między nimi w sposób określony poniżej. Aby skorzystać z tej opcji, OsmAnd musi przyciągnąć ślad do dróg mapy. \n \nW następnym kroku należy wybrać profil nawigacji w celu wykrycia dozwolonych dróg i odległości progowej w celu przybliżenia śledzenia drogi. Zdjęcia z poziomu ulicy - Zakończyć planowanie trasy bez zapisywania\? Wszystkie zmiany zostaną utracone. + Czy na pewno chcesz odrzucić wszystkie zmiany w zaplanowanej trasie, zamykając ją\? W przypadku odwrotnego kierunku Przejdź z mojej lokalizacji na trasę Wózek naprzód Ślady Podążanie za śladem - Wybierz plik śladu do obserwacji lub zaimportować go. + Wybierz plik śladu do śledzenia lub zaimportuj go z urządzenia. Zapisz jako nowy plik śladu Dodaj do pliku śladu Ślady @@ -3857,7 +3857,7 @@ Trasa szlaku Dodaj pliki śladów Importowanie lub rejestrowanie plików śladu - Dodaj punkt orientacyjny + Dodaj punkt trasy Dodaj punkt trasy Rejestrowanie śladu Zapisz jako plik śladu @@ -3880,7 +3880,7 @@ %s wybrane pliki ścieżki Określ interwał rejestrowania dla ogólnego rejestrowania śladu (włączany za pomocą widżetu Rejestrowanie podróży na mapie). Wstrzymaj nagrywanie podróży - Wznów nagrywanie podróży + Wznowienie rejestracji podróży Domyślny systemu Wszystkie kolejne segmenty Poprzedni segment @@ -3891,4 +3891,24 @@ Otwórz zapisaną ścieżkę jest zapisywany Należy dodać co najmniej dwa punkty. + Wstrzyma rejestrowanie ścieżki, gdy aplikacja zostanie zabita (za pośrednictwem ostatnich aplikacji). (Wskazanie tła OsmAnd znika z paska powiadomień Androida). + Ponów + • Zaktualizowana funkcja planu trasy: umożliwia korzystanie z różnych typów nawigacji na segment i dołączanie ścieżek +\n +\n• Nowe menu wygląd utworów: wybierz kolor, grubość, strzałki kierunku wyświetlania, ikony startu / wykończenia +\n +\n• Lepsza widoczność węzłów rowerowych. +\n +\n• Utwory są teraz tappable, mają menu kontekstowe z podstawowymi informacjami. +\n +\n• Ulepszone algorytmy wyszukiwania +\n +\n• Ulepszone opcje śledzenia w nawigacji +\n +\n• Naprawiono problemy z importem/eksportowaniem ustawień profilu +\n +\n + Ostatnia modyfikacja + Nazwa: Z – A + Nazwa: A – Z \ No newline at end of file From e736ada0bbc751814e2734a0e29a3514a77a0738 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Sat, 26 Sep 2020 19:45:41 +0000 Subject: [PATCH 0352/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 2d2a7b8cf6..f3bbf28ac6 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -977,7 +977,7 @@ مصدر الخريطة عرض أسماء المفضلة لغة الخريطة - التفاصيل + تفاصيل إضافية الوقت الحالي اتجاه الخريطة اتجاه الحركة في الأعلى @@ -2081,8 +2081,8 @@ ماء عرض الخطوط الكنتورية عرض الخطوط الكنتورية - كثافة الخط المحيطي - كثافة الخط المحيطي + كثافة الخط الكنتوري + كثافة الخط الكنتوري عالي وسط منخفض @@ -2126,7 +2126,7 @@ عرض/إخفاء المفضلة عرض المفضلة إخفاء المفضلة - عرض/إخفاء POI + عرض/إخفاء نقاط الاهتمام عرض %1$s إخفاء %1$s إضافة فئة @@ -2279,7 +2279,7 @@ زر يظهر أو يخفي ملاحظات OSM على الخريطة. إخفاء من مستوى التكبير/التصغير يجب تحميل خريطة الخطوط الكنتورية لهذه المنطقة لعرضها. - العرض بدءا من مستوى التكبير + العرض بداية من مستوى التكبير عرض مستوى التكبير: %1$s استقراء موقعي لمشاهدة خطوط التضاريس على الخريطة، يجب تحميل الملحق أولاً. @@ -2844,7 +2844,7 @@ ابحث عن المسارات مع نقاط الطريق حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق). نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر التوجيه المباشر. - يمكنك استيراد المجموعات المفضلة أو نقاط المسار كعلامات. + يمكنك استيراد المجموعات المفضلة أو نقاط المسار كتوجيه. ستظهر العلامات التي تم تجاوزها على هذه الشاشة. خط مباشر من موقعك إلى الهدف. عرض سهم واحد أو اثنين ليشير إلى الوجهة النشطة. From 021c218df4bdbac7ac38b6ba8d2b57ce14ac3ddf Mon Sep 17 00:00:00 2001 From: iman Date: Sat, 26 Sep 2020 17:59:45 +0000 Subject: [PATCH 0353/1366] Translated using Weblate (Persian) Currently translated at 99.7% (3478 of 3487 strings) --- OsmAnd/res/values-fa/strings.xml | 122 ++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 28 deletions(-) diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index e8c4cbb15c..fe618c6f25 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -511,7 +511,7 @@ نقشه و ناوبری با OsmAnd+‎ برنامهٔ همراه برای مشاهدهٔ نقشهٔ جهانی و ناوبری با نقشه‌های آفلاین و آنلاین OSM ساخت پالایهٔ POI - مسافت‌سنج و ابزار طرح‌ریزی سفر + مسافت‌سنج و ابزار طراحی سفر شروع یک زیررَد جدید اغتشاشات قطب‌نما را کاهش می‌دهد اما اینرسی را بیشتر می‌کند. ضبط سفر @@ -559,7 +559,7 @@ در حال استخراج فایل… شبکه ثانیه - دقیقه + min. جزئیات مسیر اصلاح POI حذف POI @@ -711,7 +711,7 @@ گشودن دادهٔ جدید… ناوبری آنلاین به‌طور آفلاین کار نمی‌کند. داده وجود ندارد - برعکس‌کردن جهت GPX + برعکس‌کردن جهت رد از مقصد جاری استفاده کن گذر از سرتاسر رد برای این محل نقشهٔ بُرداری آفلاین وجود دارد. @@ -751,8 +751,8 @@ نمایه‌کردن POI‏… در حال نمایه‌کردن حمل‌ونقل… خطای ورودی/خروجی - ک‌م - متر + km + m منبع کاشی‌های نقشه هدف سرعت مجاز @@ -1141,8 +1141,8 @@ اطلاعات مسیر از رد نمایش‌داده‌شده برای ناوبری استفاده می‌کنید؟ افزودن به‌عنوان مقصد آخر - محاسبهٔ مسیر بدون استفاده از اینترنت - برای قطعهٔ ابتدایی و انتهایی مسیر، مسیریابی کن + محاسبهٔ آفلاین پارهٔ مسیر + برای پارهٔ ابتدایی و انتهایی مسیر، مسیریابی کن نشانی‌های سراسری اصلاح ارتفاع جهانی علائم دریایی جهانی @@ -1242,7 +1242,7 @@ صعود/نزول: %1$s بازهٔ زمانی: %1$s مدت حرکت: %1$s - بخش + پاره %1$s نقطه نقطهٔ %1$s %1$s \nنقاط مسیر %2$s @@ -1299,7 +1299,7 @@ شروع ردیابی آنلاین توقف ردیابی آنلاین ساختمان‌ها - شروع بخش جدید + شروع پارهٔ جدید راه‌های غیرموتوری نوشته جنگل و بوته‌زار @@ -1487,7 +1487,7 @@ برای حذف‌کردن علامت بزنید از آپلود این %1$d تغییر در OSM مطمئن هستید؟ سوابق را پاک می‌کنید؟ - مدت‌زمان ماندن در صفحهٔ طراحی مسیر تا شروع ناوبری را مشخص کنید. + زمان انتظار برای ماندن در صفحهٔ طراحی مسیر را مشخص کنید. آغاز راهنمایی پیچ به پیچ پس از… برو تأخیر دارید @@ -1514,7 +1514,7 @@ ویدئو عکس نقاط مسیر - تکه‌های رد + پاره‌های رد نقاط رد خالی %1$s پیش‌فرض @@ -1592,7 +1592,7 @@ کلید نقشه ‏POI را بدون مشخص‌کردن نوعش ذخیره می‌کنید؟ تنظیمات ناوبری را انجام دهید. - طرح‌ریزی سفر + طراحی سفر سؤالات رایج سؤالاتی که زیاد پرسیده شده است مرور نقشه @@ -1690,7 +1690,7 @@ مقصد تنظیم نشده سویهٔ مغناطیسی سویهٔ نسبی - با خارج‌شدن از مسیر، مسیر تازه‌ای پیدا نکن + اگر از مسیر خارج شدم، مسیر تازه‌ای پیدا نکن اگر از مسیر خارج شوید مسیریابی تازه‌ای انجام نمی‌شود. با حرکت خلاف جهت، مسیر تازه پیدا نکن با حرکت در خلاف جهت مسیر، مسیریابی مجدد نمی‌کند. @@ -1727,7 +1727,7 @@ حافظهٔ اشتراکی نوار بالا گزارش کامل - پیداکردن مجدد مسیر + محاسبهٔ مجدد مسیر نام کاربری و گذرواژهٔ OSM کمک‌های مالی تعداد گیرندگان @@ -1869,7 +1869,7 @@ اندازه‌گیری مسافت مکث/ادامهٔ ناوبری پیغام پایان‌یافتن ناوبری را نشان بده - شروع/پایان ناوبری + آغاز/پایان ناوبری تنظیم مجدد بارکردن مجدد از «نشانه‌های نقشه» حذف شود @@ -2024,7 +2024,7 @@ ویکی‌پدیا از حدف این %1$d یادداشت مطمئن هستید؟ س - دقیقه + min مخفی شود ظاهر جاده کدِ مکانی باز (OLC) @@ -2117,7 +2117,7 @@ محل ذخیره‌سازی نقشه‌ها و فایل‌های دیگر را مشخص کنید. نام کشور را بنویسید نسخهٔ جدید - شروع کار با OsmAnd + اولین گام‌ها با OsmAnd قابلیت‌ها در بهبود OsmAnd یاری‌رسان باشید سایر @@ -2257,8 +2257,8 @@ بدون پویانمایی پویانمایی‌های نقشه را خاموش می‌کند. اصلاح خط - افزودن نقطه به قبل - افزودن نقطه به بعد + افزودن نقطه قبل از آن + افزودن نقطه بعد از آن بر اساس پروفایل انتخابی، OsmAnd نقطه‌ها را به مسیر متصل می‌کند. پروفایل ناوبری را انتخاب کنید لطفاً حداقل یک نقطه اضافه کنید. @@ -2327,7 +2327,7 @@ هموار پیچ‌هایی که در این مسیر می‌گذرانید مدت حرکت - بعد از ۶ دقیقه وقفه، بخش جدید شروع می‌شود. بعد از ۲ ساعت وقفه، رد جدید شروع می‌شود. بعد از وقفهٔ طولانی‌تر در صورتی که تاریخ تغییر کند فایل جدید ایجاد می‌شود. + بعد از ۶ دقیقه وقفه، پارهٔ جدید شروع می‌شود. بعد از ۲ ساعت وقفه، رد جدید شروع می‌شود. بعد از وقفهٔ طولانی‌تر در صورتی که تاریخ تغییر کند فایل جدید ایجاد می‌شود. یادداشت‌های OSM خود را به‌صورت ناشناس یا با نام کاربری‌تان در سایت OpenStreetMap.org، آپلود کنید. خروجی %1$d را بگیرید و بروید در نوار اعلان دستگاه یک اعلان برای شروع ضبط سفر نشان می‌دهد. @@ -2945,7 +2945,7 @@ %1$d انتقال افزودن مبدأ و مقصد افزودن مبدأ - انتخاب نقطهٔ مبدأ + مبدأ را انتخاب کنید روسازی‌نشده خاک گِل @@ -3139,7 +3139,7 @@ حالت: %s حالت کاربر، بر پایهٔ: %s نوع: %s - دوچرخه کوهستان، موتور گازی، اسب + دوچرخهٔ کوهستان، موتورگازی، اسب انواع وسایل نقلیهٔ عمومی کشتی، روئینگ، بادبانی‌رانی پروفایل‌ها را انتخاب کنید تا در برنامه فعال شوند. @@ -3246,7 +3246,7 @@ کپی از پروفایل دیگر سایر وزن، ارتفاع، طول، سرعت - پارامترهای وسیله نقلیه + پارامترهای وسیلهٔ نقلیه پیکربندی پارامترهای مسیر پارامترهای مسیر سورتمه @@ -3829,10 +3829,10 @@ نقطهٔ اضافه‌شده روی نقشه دیده نمی‌شود، زیرا گروه انتخاب‌شده پنهان است. آن را در «%s» پیدا می‌کنید. برای ادامه روزهای کاری را تنظیم کنید مسیر بین نقطه‌ها - طرح‌ریزی مسیر - نمایش آیکون‌های شروع و پایان + طراحی مسیر + نمایش نمادهای ابتدا و انتها انتخاب عرض - انتخاب کنید نشانه‌های روی رد بر اساس زمان یا مسافت با چه تناوبی نمایش یابند. + مشخص کنید نشانه‌گذاری روی رد بر اساس زمان یا مسافت و با چه تناوبی باشد. گزینهٔ تقسیم‌بندی دلخواه را انتخاب کنید: بر اساس زمان یا مسافت. سفارشی فلش‌های جهت‌نما @@ -3847,9 +3847,9 @@ ذخیره شد لطفاً حداقل دو نقطه اضافه کنید. ازنو - • قابلیت «طرح‌ریزی مسیر» روزآمد شد: امکان استفاده از شیوهٔ ناوبری متفاوت برای هر پاره از مسیر و در کار آوردن ردها اضافه شده است. + • قابلیت «طراحی مسیر» روزآمد شد: امکان استفاده از شیوهٔ ناوبری متفاوت برای هر پاره از مسیر و در کار آوردن ردها اضافه شده است. \n -\n• منوی جدید «ظاهر» برای ردها: رنگ و ضخامت را مشخص کنید، فلش‌های جهت‌نما و نمادهای آغاز/پایان را نمایش دهید. +\n• منوی جدید «ظاهر» برای ردها: رنگ و ضخامت را مشخص کنید، فلش‌های جهت‌نما و نمادهای ابتدا و انتها را ببینید. \n \n• پدیداری گره‌های شبکهٔ دوچرخه بهبود یافته است. \n @@ -3862,4 +3862,70 @@ \n• مشکلاتی مربوط به درون‌برد/برون‌برد تنظیمات پروفایل برطرف شده است. \n \n + حذفِ قبل + حذفِ بعد + تغییر نوع مسیرِ بعد از آن + تغییر نوع مسیرِ قبل از آن + تک‌رنگ + طول وسیلهٔ نقلیهٔ خود را مشخص کنید. ممکن است محدودیت‌های مسیر برای وسایل نقلیهٔ طویل اِعمال شود. + مقصد کنونی مسیر حذف خواهد شد. اگر این قرار است مقصد باشد، ناوبری متوقف می‌شود. + افزودن به یک رد + ذخیره به‌عنوان رد جدید + برعکس‌کردن مسیر + تمام رد با استفاده از پروفایل انتخابی بازمحاسبه خواهد شد. + با استفاده از پروفایل انتخابی فقط پارهٔ بعدی بازمحاسبه خواهد شد. + همهٔ پاره‌های بعدی + پارهٔ قبلی + همهٔ پاره‌های قبلی + همهٔ پاره‌های بعدی با استفاده از پروفایل انتخابی بازمحاسبه می‌شوند. + همهٔ پاره‌های قبلی با استفاده از پروفایل انتخابی بازمحاسبه می‌شوند. + مشخص کنید نقطه‌ها با خط مستقیم به هم وصل شوند یا مسیر بینشان مطابق تنظیمات زیر محاسبه شود. + تمام رد + پارهٔ بعدی + در ادامه برای استفاده از این گزینه، با یکی از پروفایل‌های ناوبری‌تان رد خود را به نزدیک‌ترین جادهٔ مجاز بچسبانید. + پروفایل ناوبری + یک فایل رد انتخاب کنید تا پارهٔ جدید را به آن بیفزایید. + تصاویر نمای خیابان + آیا می‌خواهید خارج شوید و همهٔ تغییرات مسیر طراحی‌شده را از بین ببرید؟ + اگر برعکس حرکت کردم + ابتدای رد + انتخاب فایل رد برای دنبال‌کردن + یک فایل رد انتخاب کنید یا از دستگاه خود درون‌برد نمایید تا مسیر آن را دنبال کنید. + انتخاب رد دیگر + از موقعیت من به‌سوی رد ناوبری کن + نقطه‌ای از رد برای ناوبری تا آن + مسیر رد + دنبال‌کردن رد + نزدیک‌ترین نقطه + چسبیدن به راه‌ها + نوشتن نشانی + افزودن نشانی + حذف نشانی + ردِ ساده‌شده + فقط خط مسیر ذخیره می‌شود. نقاط بین‌راهی حذف خواهند شد. + نام فایل + پیشفرض سیستم + فقط پارهٔ انتخاب‌شده با استفاده از پروفایل انتخابی بازمحاسبه می‌شود. + آخرین تغییر + نام: ی - الف + نام: الف - ی + ردنگاری خودکار در هنگام ناوبری + ذخیره به‌عنوان فایل رد جدید + افزودن به یک فایل رد + ردها + ردها + ردها + ضبط رد در فایل GPX + فایل رد اضافه کنید + فایل رد درون‌برد یا ضبط کنید + افزودن نقطهٔ بین‌راهی رد + افزودن نقطهٔ بین‌راهی رد + ضبط سفر + ذخیره در قالب فایل رد + %s فایل رد انتخاب شده است + ضبط + هنگامی که برنامه را از طریق برنامه‌های اخیر ببندید ضبط رد به‌طور موقت می‌ایستد. (نشانگر اجرای پس‌زمینه از نوار اعلان حذف می‌شود.) + بازهٔ زمانی برای ضبط رد را انتخاب کنید (که از طریق ابزار ضبط سفر روی نقشه فعال می‌شود). + نگه‌داشتن ضبط سفر + ازسرگیری ضبط سفر \ No newline at end of file From 189efed54947c74f8936655454c1172e5c5eea08 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Sat, 26 Sep 2020 16:43:46 +0000 Subject: [PATCH 0354/1366] Translated using Weblate (Sardinian) Currently translated at 99.7% (3479 of 3487 strings) --- OsmAnd/res/values-sc/strings.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index 8dba26d6c3..accd1282b4 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -817,7 +817,7 @@ Màchina Bitzicleta A pede - Furria diretzione GPX + Fùrria sa diretzione de sa rasta Diretzione de sa mòvida Ammustra diretzione de osservatzione de abbistadura Tzentra automaticamente sa mapa @@ -3829,9 +3829,7 @@ Ischerta comente connètere sos puntos: cun una lìnia reta o calculende un\'àndala intre issos comente dislindadu inoghe in suta. Rasta intrea Segmentu imbeniente - Pro impreare custa optzione OsmAnd tenet bisòngiu de alliniare sa rasta tua a sos caminos de sa mapa. -\n -\n In su passu chi benit as a dèpere ischertare su profilu de navigatzione pro rilevare sos caminos permìtidos e su lìmite de distàntzia pro aprossimare sa rasta tua cun sos caminos. + In su passu chi benit liga sa rasta tua a su caminu permìtidu prus a curtzu cun unu de sos profilos de navigatzione tuos pro impreare custa optzione. Lìmite de distàntzia Profilu de navigatzione Ischerta unu documentu de rasta in ue annànghere su segmentu nou. @@ -3902,4 +3900,7 @@ \n • Problemas cun s\'importatzione e s\'esportatzione de sas impostatziones de sos profilos risoltos \n \n + Ùrtima modìfica + Nùmene: Z – A + Nùmene: A – Z \ No newline at end of file From 202b832ceaf3ef433411445311ffbd6dbc3fd038 Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Sun, 27 Sep 2020 01:33:20 +0000 Subject: [PATCH 0355/1366] Translated using Weblate (Japanese) Currently translated at 99.4% (3803 of 3824 strings) --- OsmAnd/res/values-ja/phrases.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OsmAnd/res/values-ja/phrases.xml b/OsmAnd/res/values-ja/phrases.xml index 2165c6fca4..680da76205 100644 --- a/OsmAnd/res/values-ja/phrases.xml +++ b/OsmAnd/res/values-ja/phrases.xml @@ -3814,4 +3814,12 @@ 触覚矢印 振動装置 公称圧力 + 触覚矢印:無し + 有り + 有り + 振動:無し + 状態:釣瓶・管がない + 吸引 + 加圧 + 地下水 \ No newline at end of file From a2bbab51b319be78e1f1a2b692280b70ae81bb1d Mon Sep 17 00:00:00 2001 From: Roberto GEB Date: Sat, 26 Sep 2020 09:49:35 +0000 Subject: [PATCH 0356/1366] Translated using Weblate (Spanish) Currently translated at 99.9% (3821 of 3824 strings) --- OsmAnd/res/values-es/phrases.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OsmAnd/res/values-es/phrases.xml b/OsmAnd/res/values-es/phrases.xml index e1625c9b0a..d892b94f7e 100644 --- a/OsmAnd/res/values-es/phrases.xml +++ b/OsmAnd/res/values-es/phrases.xml @@ -3833,4 +3833,16 @@ Vibración Manzana Flecha: no + Almacén de frutos secos + Colmena + Horario + Tiempo real + Retraso + + Tablero de salidas: no + Ascensor + Municipio + Pequeños electrodomésticos + Tablero de salidas + Relleno de agua potable \ No newline at end of file From deda08bf11b10671bd5b4e16205daf59cbb87481 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sat, 26 Sep 2020 23:26:49 +0000 Subject: [PATCH 0357/1366] Translated using Weblate (Esperanto) Currently translated at 98.8% (3448 of 3487 strings) --- OsmAnd/res/values-eo/strings.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index fc643544e6..d27d45ba70 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -3868,4 +3868,25 @@ Antaŭe modifita Nomo: Z – A Nomo: A – Z + Ĉiuj sekvaj segmentoj estos rekalkulitaj uzante la elektitan profilon. + Ĉiuj antaŭaj segmentoj estos rekalkulitaj uzante la elektitan profilon. + Malfermi konservitan spuron + estas konservata + Aldonu almenaŭ du punktojn. + Refari + • plibonigoj al “plani kurson”: eblo uzi diversajn specojn de navigo por ĉiu segmento aparte kaj ampleksi spurojn +\n +\n• nova menuo de aspekto por spuroj: eblo elekti koloron kaj dikecon, montri sagetojn de direkto kaj vidigi komencon/finon de spuro +\n +\n• plibonigita videblo de biciklaj nodoj +\n +\n• nun eblas frapeti spuron sur la mapo, vidigi ĝian kuntekstan menuon kun bazajn informojn +\n +\n• plibonigoj al serĉ‑algoritmojn +\n +\n• plibonigoj al la funkcio “sekvi spuron” dum navigi +\n +\n• riparitaj problemoj pri en-/el-porti agordojn de profilo +\n +\n \ No newline at end of file From 8ac567535385c1ccaa8ba2924fd3789894234e63 Mon Sep 17 00:00:00 2001 From: iman Date: Sat, 26 Sep 2020 14:47:43 +0000 Subject: [PATCH 0358/1366] Translated using Weblate (Persian) Currently translated at 29.2% (78 of 267 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/fa/ --- OsmAnd-telegram/res/values-fa/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd-telegram/res/values-fa/strings.xml b/OsmAnd-telegram/res/values-fa/strings.xml index 113a944e7c..13e67eef49 100644 --- a/OsmAnd-telegram/res/values-fa/strings.xml +++ b/OsmAnd-telegram/res/values-fa/strings.xml @@ -38,8 +38,8 @@ yd ft mi - ک‌م - متر + km + m nmi min/m min/km From 67a846a8258a83002d1c90c13bc1cffaf0a2a573 Mon Sep 17 00:00:00 2001 From: Denis Kolomiets Date: Sun, 27 Sep 2020 13:42:55 +0300 Subject: [PATCH 0359/1366] fix string formatting --- OsmAnd/res/values-es/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 8c6fad630e..caf2e2ec40 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -3818,7 +3818,7 @@ Seleccionar anchura Grabar automáticamente la traza durante la navegación Consigue información sobre puntos de interés en Wikipedia. Es tu guía de bolsillo sin conexión. Sólo tienes que activar el complemento de Wikipedia y disfrutar de los artículos sobre los objetos que te rodean. - El punto agregado no será visible en el mapa, ya que el grupo seleccionado está oculto, puedes encontrarlo en \"% s\". + El punto agregado no será visible en el mapa, ya que el grupo seleccionado está oculto, puedes encontrarlo en \"%s\". Motocicleta de enduro Moto scooter Silla de ruedas @@ -3897,4 +3897,4 @@ Último modificado Nombre: Z – A Nombre: A - Z - \ No newline at end of file + From df56eaa22601332a5682a1da9654feee1ee8de47 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 28 Sep 2020 14:15:29 +0300 Subject: [PATCH 0360/1366] WIP huawei subscriptions --- OsmAnd/.gitignore | 1 + OsmAnd/AndroidManifest-freehuawei.xml | 32 +- OsmAnd/AndroidManifest-huawei.xml | 25 - OsmAnd/build.gradle | 89 +-- .../plus/inapp/InAppPurchaseHelperImpl.java | 546 ++++++++++++++ .../plus/inapp/InAppPurchaseHelperImpl.java | 475 ++++++++++++ .../src/net/osmand/plus/AppInitializer.java | 4 +- .../src/net/osmand/plus/HuaweiDrmHelper.java | 66 -- OsmAnd/src/net/osmand/plus/Version.java | 4 +- .../osmand/plus/activities/MapActivity.java | 4 - .../osmand/plus/helpers/DiscountHelper.java | 2 +- .../plus/inapp/InAppPurchaseHelper.java | 678 +++--------------- .../net/osmand/plus/inapp/InAppPurchases.java | 74 +- OsmAndHms.jks | Bin 0 -> 2243 bytes agconnect-services.json | 1 + 15 files changed, 1264 insertions(+), 737 deletions(-) delete mode 100644 OsmAnd/AndroidManifest-huawei.xml create mode 100644 OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java create mode 100644 OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java delete mode 100644 OsmAnd/src/net/osmand/plus/HuaweiDrmHelper.java create mode 100644 OsmAndHms.jks create mode 100644 agconnect-services.json diff --git a/OsmAnd/.gitignore b/OsmAnd/.gitignore index e3071e5fbf..e1887fffff 100644 --- a/OsmAnd/.gitignore +++ b/OsmAnd/.gitignore @@ -17,6 +17,7 @@ libs/huawei-*.jar huaweidrmlib/ HwDRM_SDK_* drm_strings.xml +agconnect-services.json # copy_widget_icons.sh res/drawable-large/map_* diff --git a/OsmAnd/AndroidManifest-freehuawei.xml b/OsmAnd/AndroidManifest-freehuawei.xml index e96bb7fe47..c234628537 100644 --- a/OsmAnd/AndroidManifest-freehuawei.xml +++ b/OsmAnd/AndroidManifest-freehuawei.xml @@ -2,24 +2,24 @@ - - - - + + + + + - + tools:replace="android:authorities" + android:authorities="net.osmand.huawei.fileprovider"/> - \ No newline at end of file diff --git a/OsmAnd/AndroidManifest-huawei.xml b/OsmAnd/AndroidManifest-huawei.xml deleted file mode 100644 index bc847980cd..0000000000 --- a/OsmAnd/AndroidManifest-huawei.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 91b0b8022f..0aef4aa139 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -40,10 +40,17 @@ android { keyAlias "osmand" keyPassword System.getenv("OSMAND_APK_PASSWORD") } + + publishingHuawei { + storeFile file("/var/lib/jenkins/osmand_hw_key") + storePassword System.getenv("OSMAND_HW_APK_PASSWORD") + keyAlias "OsmAndHms" + keyPassword System.getenv("OSMAND_HW_APK_PASSWORD") + } } defaultConfig { - minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15 + minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 17 targetSdkVersion 28 versionCode 390 versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode @@ -107,19 +114,23 @@ android { debug { manifest.srcFile "AndroidManifest-debug.xml" } + full { + java.srcDirs = ["src-google"] + } free { + java.srcDirs = ["src-google"] manifest.srcFile "AndroidManifest-free.xml" } freedev { + java.srcDirs = ["src-google"] manifest.srcFile "AndroidManifest-freedev.xml" } freecustom { + java.srcDirs = ["src-google"] manifest.srcFile "AndroidManifest-freecustom.xml" } - huawei { - manifest.srcFile "AndroidManifest-huawei.xml" - } freehuawei { + java.srcDirs = ["src-huawei"] manifest.srcFile "AndroidManifest-freehuawei.xml" } @@ -191,10 +202,6 @@ android { resConfig "en" //resConfigs "xxhdpi", "nodpi" } - huawei { - dimension "version" - applicationId "net.osmand.plus.huawei" - } freehuawei { dimension "version" applicationId "net.osmand.huawei" @@ -219,7 +226,10 @@ android { signingConfig signingConfigs.development } release { - signingConfig signingConfigs.publishing + productFlavors.all { flavor -> + flavor.signingConfig signingConfigs.publishing + } + productFlavors.freehuawei.signingConfig signingConfigs.publishingHuawei } } @@ -276,46 +286,14 @@ task downloadWorldMiniBasemap { } } -task downloadHuaweiDrmZip { +task setupHuaweiConfig { doLast { - ant.get(src: 'https://obs.cn-north-2.myhwclouds.com/hms-ds-wf/sdk/HwDRM_SDK_2.5.2.300_ADT.zip', dest: 'HwDRM_SDK_2.5.2.300_ADT.zip', skipexisting: 'true') - ant.unzip(src: 'HwDRM_SDK_2.5.2.300_ADT.zip', dest: 'huaweidrmlib/') + if (System.getenv("HUAWEI_SDK_JSON")) { + new File("agconnect-services.json").text = System.getenv("HUAWEI_SDK_JSON") + } } } -task copyHuaweiDrmLibs(type: Copy) { - dependsOn downloadHuaweiDrmZip - from "huaweidrmlib/HwDRM_SDK_2.5.2.300_ADT/libs" - into "libs" -} - -task copyHuaweiDrmValues(type: Copy) { - dependsOn downloadHuaweiDrmZip - from "huaweidrmlib/HwDRM_SDK_2.5.2.300_ADT/res" - into "res" -} - -task downloadPrebuiltHuaweiDrm { - dependsOn copyHuaweiDrmLibs, copyHuaweiDrmValues -} - -task cleanHuaweiDrmLibs(type: Delete) { - delete "huaweidrmlib" - delete fileTree("libs").matching { - include "**/huawei-*.jar" - } -} - -task cleanHuaweiDrmValues(type: Delete) { - delete fileTree("res").matching { - include "**/drm_strings.xml" - } -} - -task cleanPrebuiltHuaweiDrm { - dependsOn cleanHuaweiDrmLibs, cleanHuaweiDrmValues -} - task collectVoiceAssets(type: Sync) { from "../../resources/voice" into "assets/voice" @@ -397,8 +375,6 @@ task copyLargePOIIcons(type: Sync) { } } - - task copyWidgetIconsXhdpi(type: Sync) { from "res/drawable-xxhdpi/" into "res/drawable-large-xhdpi/" @@ -445,13 +421,9 @@ task collectExternalResources { copyPoiCategories, downloadWorldMiniBasemap - Gradle gradle = getGradle() - String tskReqStr = gradle.getStartParameter().getTaskRequests().toString().toLowerCase() - // Use Drm SDK only for huawei build + String tskReqStr = gradle.startParameter.taskNames.toString() if (tskReqStr.contains("huawei")) { - dependsOn downloadPrebuiltHuaweiDrm - } else { - dependsOn cleanPrebuiltHuaweiDrm + dependsOn setupHuaweiConfig } } @@ -503,10 +475,16 @@ task cleanupDuplicatesInCore() { file("libs/x86_64/libc++_shared.so").renameTo(file("libc++/x86_64/libc++_shared.so")) } } + afterEvaluate { android.applicationVariants.all { variant -> variant.javaCompiler.dependsOn(collectExternalResources, buildOsmAndCore, cleanupDuplicatesInCore) } + Gradle gradle = getGradle() + String tskReqStr = gradle.getStartParameter().getTaskRequests().toString().toLowerCase() + if (tskReqStr.contains("huawei")) { + apply plugin: 'com.huawei.agconnect' + } } task appStart(type: Exec) { @@ -516,7 +494,6 @@ task appStart(type: Exec) { // commandLine 'cmd', '/c', 'adb', 'shell', 'am', 'start', '-n', 'net.osmand.plus/net.osmand.plus.activities.MapActivity' } - dependencies { implementation project(path: ':OsmAnd-java', configuration: 'android') implementation project(':OsmAnd-api') @@ -565,6 +542,6 @@ dependencies { } implementation 'com.jaredrummler:colorpicker:1.1.0' - huaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar') - freehuaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar') + //freehuaweiImplementation 'com.huawei.agconnect:agconnect-core:1.4.1.300' + freehuaweiImplementation 'com.huawei.hms:iap:5.0.2.300' } diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java new file mode 100644 index 0000000000..c48294aeb2 --- /dev/null +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -0,0 +1,546 @@ +package net.osmand.plus.inapp; + +import android.app.Activity; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.billingclient.api.BillingClient; +import com.android.billingclient.api.BillingResult; +import com.android.billingclient.api.Purchase; +import com.android.billingclient.api.SkuDetails; +import com.android.billingclient.api.SkuDetailsResponseListener; + +import net.osmand.AndroidUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.inapp.util.BillingManager; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.util.Algorithms; + +import java.lang.ref.WeakReference; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { + + // The helper object + private BillingManager billingManager; + private List skuDetailsList; + + /* base64EncodedPublicKey should be YOUR APPLICATION'S PUBLIC KEY + * (that you got from the Google Play developer console). This is not your + * developer public key, it's the *app-specific* public key. + * + * Instead of just storing the entire literal string here embedded in the + * program, construct the key at runtime from pieces or + * use bit manipulation (for example, XOR with some other string) to hide + * the actual key. The key itself is not secret information, but we don't + * want to make it easy for an attacker to replace the public key with one + * of their own and then fake messages from the server. + */ + private static final String BASE64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgk8cEx" + + "UO4mfEwWFLkQnX1Tkzehr4SnXLXcm2Osxs5FTJPEgyTckTh0POKVMrxeGLn0KoTY2NTgp1U/inp" + + "wccWisPhVPEmw9bAVvWsOkzlyg1kv03fJdnAXRBSqDDPV6X8Z3MtkPVqZkupBsxyIllEILKHK06" + + "OCw49JLTsMR3oTRifGzma79I71X0spw0fM+cIRlkS2tsXN8GPbdkJwHofZKPOXS51pgC1zU8uWX" + + "I+ftJO46a1XkNh1dO2anUiQ8P/H4yOTqnMsXF7biyYuiwjXPOcy0OMhEHi54Dq6Mr3u5ZALOAkc" + + "YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB"; + + public InAppPurchaseHelperImpl(OsmandApplication ctx) { + super(ctx); + } + + private BillingManager getBillingManager() { + return billingManager; + } + + protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppRunnable runnable) { + billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() { + + @Override + public void onBillingClientSetupFinished() { + logDebug("Setup finished."); + + BillingManager billingManager = getBillingManager(); + // Have we been disposed of in the meantime? If so, quit. + if (billingManager == null) { + stop(true); + return; + } + + if (!billingManager.isServiceConnected()) { + // Oh noes, there was a problem. + //complain("Problem setting up in-app billing: " + result); + notifyError(taskType, billingManager.getBillingClientResponseMessage()); + stop(true); + return; + } + + processingTask = !runnable.run(InAppPurchaseHelperImpl.this); + } + + @Override + public void onConsumeFinished(String token, BillingResult billingResult) { + } + + @Override + public void onPurchasesUpdated(final List purchases) { + + BillingManager billingManager = getBillingManager(); + // Have we been disposed of in the meantime? If so, quit. + if (billingManager == null) { + stop(true); + return; + } + + if (activeTask == InAppPurchaseTaskType.REQUEST_INVENTORY) { + List skuInApps = new ArrayList<>(); + for (InAppPurchases.InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { + skuInApps.add(purchase.getSku()); + } + for (Purchase p : purchases) { + skuInApps.add(p.getSku()); + } + billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() { + @Override + public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListInApps) { + // Is it a failure? + if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { + logError("Failed to query inapps sku details: " + billingResult.getResponseCode()); + notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); + stop(true); + return; + } + + List skuSubscriptions = new ArrayList<>(); + for (InAppPurchases.InAppSubscription subscription : getInAppPurchases().getAllInAppSubscriptions()) { + skuSubscriptions.add(subscription.getSku()); + } + for (Purchase p : purchases) { + skuSubscriptions.add(p.getSku()); + } + + BillingManager billingManager = getBillingManager(); + // Have we been disposed of in the meantime? If so, quit. + if (billingManager == null) { + stop(true); + return; + } + + billingManager.querySkuDetailsAsync(BillingClient.SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() { + @Override + public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListSubscriptions) { + // Is it a failure? + if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { + logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode()); + notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); + stop(true); + return; + } + + List skuDetailsList = new ArrayList<>(skuDetailsListInApps); + skuDetailsList.addAll(skuDetailsListSubscriptions); + InAppPurchaseHelperImpl.this.skuDetailsList = skuDetailsList; + + mSkuDetailsResponseListener.onSkuDetailsResponse(billingResult, skuDetailsList); + } + }); + } + }); + } + for (Purchase purchase : purchases) { + if (!purchase.isAcknowledged()) { + onPurchaseFinished(purchase); + } + } + } + + @Override + public void onPurchaseCanceled() { + stop(true); + } + }); + } + + public void purchaseFullVersion(final Activity activity) { + notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); + exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppRunnable() { + @Override + public boolean run(InAppPurchaseHelper helper) { + try { + SkuDetails skuDetails = getSkuDetails(getFullVersion().getSku()); + if (skuDetails == null) { + throw new IllegalArgumentException("Cannot find sku details"); + } + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.initiatePurchaseFlow(activity, skuDetails); + } else { + throw new IllegalStateException("BillingManager disposed"); + } + return false; + } catch (Exception e) { + complain("Cannot launch full version purchase!"); + logError("purchaseFullVersion Error", e); + stop(true); + } + return true; + } + }); + } + + public void purchaseDepthContours(final Activity activity) { + notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); + exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppRunnable() { + @Override + public boolean run(InAppPurchaseHelper helper) { + try { + SkuDetails skuDetails = getSkuDetails(getDepthContours().getSku()); + if (skuDetails == null) { + throw new IllegalArgumentException("Cannot find sku details"); + } + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.initiatePurchaseFlow(activity, skuDetails); + } else { + throw new IllegalStateException("BillingManager disposed"); + } + return false; + } catch (Exception e) { + complain("Cannot launch depth contours purchase!"); + logError("purchaseDepthContours Error", e); + stop(true); + } + return true; + } + }); + } + + @Nullable + private SkuDetails getSkuDetails(@NonNull String sku) { + List skuDetailsList = this.skuDetailsList; + if (skuDetailsList != null) { + for (SkuDetails details : skuDetailsList) { + if (details.getSku().equals(sku)) { + return details; + } + } + } + return null; + } + + private boolean hasDetails(@NonNull String sku) { + return getSkuDetails(sku) != null; + } + + @Nullable + private Purchase getPurchase(@NonNull String sku) { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + List purchases = billingManager.getPurchases(); + if (purchases != null) { + for (Purchase p : purchases) { + if (p.getSku().equals(sku)) { + return p; + } + } + } + } + return null; + } + + // Listener that's called when we finish querying the items and subscriptions we own + private SkuDetailsResponseListener mSkuDetailsResponseListener = new SkuDetailsResponseListener() { + + @NonNull + private List getAllOwnedSubscriptionSkus() { + List result = new ArrayList<>(); + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + for (Purchase p : billingManager.getPurchases()) { + if (getInAppPurchases().getInAppSubscriptionBySku(p.getSku()) != null) { + result.add(p.getSku()); + } + } + } + return result; + } + + @Override + public void onSkuDetailsResponse(BillingResult billingResult, List skuDetailsList) { + + logDebug("Query sku details finished."); + + // Have we been disposed of in the meantime? If so, quit. + if (getBillingManager() == null) { + stop(true); + return; + } + + // Is it a failure? + if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { + logError("Failed to query inventory: " + billingResult.getResponseCode()); + notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); + stop(true); + return; + } + + logDebug("Query sku details was successful."); + + /* + * Check for items we own. Notice that for each purchase, we check + * the developer payload to see if it's correct! See + * verifyDeveloperPayload(). + */ + + List allOwnedSubscriptionSkus = getAllOwnedSubscriptionSkus(); + for (InAppPurchases.InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { + if (hasDetails(s.getSku())) { + Purchase purchase = getPurchase(s.getSku()); + SkuDetails liveUpdatesDetails = getSkuDetails(s.getSku()); + if (liveUpdatesDetails != null) { + fetchInAppPurchase(s, liveUpdatesDetails, purchase); + } + allOwnedSubscriptionSkus.remove(s.getSku()); + } + } + for (String sku : allOwnedSubscriptionSkus) { + Purchase purchase = getPurchase(sku); + SkuDetails liveUpdatesDetails = getSkuDetails(sku); + if (liveUpdatesDetails != null) { + InAppPurchases.InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); + if (s == null) { + s = new InAppPurchases.InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails); + } + fetchInAppPurchase(s, liveUpdatesDetails, purchase); + } + } + + InAppPurchases.InAppPurchase fullVersion = getFullVersion(); + if (hasDetails(fullVersion.getSku())) { + Purchase purchase = getPurchase(fullVersion.getSku()); + SkuDetails fullPriceDetails = getSkuDetails(fullVersion.getSku()); + if (fullPriceDetails != null) { + fetchInAppPurchase(fullVersion, fullPriceDetails, purchase); + } + } + + InAppPurchases.InAppPurchase depthContours = getDepthContours(); + if (hasDetails(depthContours.getSku())) { + Purchase purchase = getPurchase(depthContours.getSku()); + SkuDetails depthContoursDetails = getSkuDetails(depthContours.getSku()); + if (depthContoursDetails != null) { + fetchInAppPurchase(depthContours, depthContoursDetails, purchase); + } + } + + InAppPurchases.InAppPurchase contourLines = getContourLines(); + if (hasDetails(contourLines.getSku())) { + Purchase purchase = getPurchase(contourLines.getSku()); + SkuDetails contourLinesDetails = getSkuDetails(contourLines.getSku()); + if (contourLinesDetails != null) { + fetchInAppPurchase(contourLines, contourLinesDetails, purchase); + } + } + + Purchase fullVersionPurchase = getPurchase(fullVersion.getSku()); + boolean fullVersionPurchased = fullVersionPurchase != null; + if (fullVersionPurchased) { + ctx.getSettings().FULL_VERSION_PURCHASED.set(true); + } + + Purchase depthContoursPurchase = getPurchase(depthContours.getSku()); + boolean depthContoursPurchased = depthContoursPurchase != null; + if (depthContoursPurchased) { + ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); + } + + // Do we have the live updates? + boolean subscribedToLiveUpdates = false; + List liveUpdatesPurchases = new ArrayList<>(); + for (InAppPurchases.InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { + Purchase purchase = getPurchase(p.getSku()); + if (purchase != null) { + liveUpdatesPurchases.add(purchase); + if (!subscribedToLiveUpdates) { + subscribedToLiveUpdates = true; + } + } + } + OsmandSettings.OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; + if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) { + if (subscriptionCancelledTime.get() == 0) { + subscriptionCancelledTime.set(System.currentTimeMillis()); + ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN.set(false); + ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN.set(false); + } else if (System.currentTimeMillis() - subscriptionCancelledTime.get() > SUBSCRIPTION_HOLDING_TIME_MSEC) { + ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false); + if (!isDepthContoursPurchased(ctx)) { + ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false); + } + } + } else if (subscribedToLiveUpdates) { + subscriptionCancelledTime.set(0L); + ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); + } + + lastValidationCheckTime = System.currentTimeMillis(); + logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") + + " live updates purchased."); + + OsmandSettings settings = ctx.getSettings(); + settings.INAPPS_READ.set(true); + + List tokensToSend = new ArrayList<>(); + if (liveUpdatesPurchases.size() > 0) { + List tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";")); + for (Purchase purchase : liveUpdatesPurchases) { + if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) + && !Algorithms.isEmpty(purchase.getDeveloperPayload())) { + String payload = purchase.getDeveloperPayload(); + if (!Algorithms.isEmpty(payload)) { + String[] arr = payload.split(" "); + if (arr.length > 0) { + settings.BILLING_USER_ID.set(arr[0]); + } + if (arr.length > 1) { + token = arr[1]; + settings.BILLING_USER_TOKEN.set(token); + } + } + } + if (!tokensSent.contains(purchase.getSku())) { + tokensToSend.add(purchase); + } + } + } + List purchaseInfoList = new ArrayList<>(); + for (Purchase purchase : tokensToSend) { + purchaseInfoList.add(getPurchaseInfo(purchase)); + } + onSkuDetailsResponseDone(purchaseInfoList); + } + }; + + private PurchaseInfo getPurchaseInfo(Purchase purchase) { + return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken()); + } + + private void fetchInAppPurchase(@NonNull InAppPurchases.InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) { + if (purchase != null) { + inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.PURCHASED); + inAppPurchase.setPurchaseTime(purchase.getPurchaseTime()); + } else { + inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.NOT_PURCHASED); + } + inAppPurchase.setPrice(skuDetails.getPrice()); + inAppPurchase.setPriceCurrencyCode(skuDetails.getPriceCurrencyCode()); + if (skuDetails.getPriceAmountMicros() > 0) { + inAppPurchase.setPriceValue(skuDetails.getPriceAmountMicros() / 1000000d); + } + String subscriptionPeriod = skuDetails.getSubscriptionPeriod(); + if (!Algorithms.isEmpty(subscriptionPeriod)) { + if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + try { + ((InAppPurchases.InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); + } catch (ParseException e) { + LOG.error(e); + } + } + } + if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + String introductoryPrice = skuDetails.getIntroductoryPrice(); + String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod(); + String introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles(); + long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros(); + if (!Algorithms.isEmpty(introductoryPrice)) { + InAppPurchases.InAppSubscription s = (InAppPurchases.InAppSubscription) inAppPurchase; + try { + s.setIntroductoryInfo(new InAppPurchases.InAppSubscriptionIntroductoryInfo(s, introductoryPrice, + introductoryPriceAmountMicros, introductoryPricePeriod, introductoryPriceCycles)); + } catch (ParseException e) { + LOG.error(e); + } + } + } + } + + protected InAppRunnable getPurchaseLiveUpdatesCommand(final WeakReference activity, final String sku, final String payload) { + return new InAppRunnable() { + @Override + public boolean run(InAppPurchaseHelper helper) { + try { + Activity a = activity.get(); + SkuDetails skuDetails = getSkuDetails(sku); + if (AndroidUtils.isActivityNotDestroyed(a) && skuDetails != null) { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.setPayload(payload); + billingManager.initiatePurchaseFlow(a, skuDetails); + } else { + throw new IllegalStateException("BillingManager disposed"); + } + return false; + } else { + stop(true); + } + } catch (Exception e) { + logError("launchPurchaseFlow Error", e); + stop(true); + } + return true; + } + }; + } + + protected InAppRunnable getRequestInventoryCommand() { + return new InAppRunnable() { + @Override + public boolean run(InAppPurchaseHelper helper) { + logDebug("Setup successful. Querying inventory."); + try { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.queryPurchases(); + } else { + throw new IllegalStateException("BillingManager disposed"); + } + return false; + } catch (Exception e) { + logError("queryInventoryAsync Error", e); + notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); + stop(true); + } + return true; + } + }; + } + + // Call when a purchase is finished + private void onPurchaseFinished(Purchase purchase) { + logDebug("Purchase finished: " + purchase); + + // if we were disposed of in the meantime, quit. + if (getBillingManager() == null) { + stop(true); + return; + } + + onPurchaseDone(getPurchaseInfo(purchase)); + } + + @Override + protected boolean isBillingManagerExists() { + return getBillingManager() != null; + } + + @Override + protected void destroyBillingManager() { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.destroy(); + this.billingManager = null; + } + } +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java new file mode 100644 index 0000000000..a7e8589f33 --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -0,0 +1,475 @@ +package net.osmand.plus.inapp; + +import android.app.Activity; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.AndroidUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.inapp.util.BillingManager; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.util.Algorithms; + +import java.lang.ref.WeakReference; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { + + // The helper object + private BillingManager billingManager; + private List skuDetailsList; + + + public InAppPurchaseHelperImpl(OsmandApplication ctx) { + super(ctx); + } + + protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppRunnable runnable) { + billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() { + + @Override + public void onBillingClientSetupFinished() { + logDebug("Setup finished."); + + BillingManager billingManager = getBillingManager(); + // Have we been disposed of in the meantime? If so, quit. + if (billingManager == null) { + stop(true); + return; + } + + if (!billingManager.isServiceConnected()) { + // Oh noes, there was a problem. + //complain("Problem setting up in-app billing: " + result); + notifyError(taskType, billingManager.getBillingClientResponseMessage()); + stop(true); + return; + } + + processingTask = !runnable.run(InAppPurchaseHelperImpl.this); + } + + @Override + public void onConsumeFinished(String token, BillingResult billingResult) { + } + + @Override + public void onPurchasesUpdated(final List purchases) { + + BillingManager billingManager = getBillingManager(); + // Have we been disposed of in the meantime? If so, quit. + if (billingManager == null) { + stop(true); + return; + } + + if (activeTask == InAppPurchaseTaskType.REQUEST_INVENTORY) { + List skuInApps = new ArrayList<>(); + for (InAppPurchases.InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { + skuInApps.add(purchase.getSku()); + } + for (Purchase p : purchases) { + skuInApps.add(p.getSku()); + } + billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() { + @Override + public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListInApps) { + // Is it a failure? + if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { + logError("Failed to query inapps sku details: " + billingResult.getResponseCode()); + notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); + stop(true); + return; + } + + List skuSubscriptions = new ArrayList<>(); + for (InAppPurchases.InAppSubscription subscription : getInAppPurchases().getAllInAppSubscriptions()) { + skuSubscriptions.add(subscription.getSku()); + } + for (Purchase p : purchases) { + skuSubscriptions.add(p.getSku()); + } + + BillingManager billingManager = getBillingManager(); + // Have we been disposed of in the meantime? If so, quit. + if (billingManager == null) { + stop(true); + return; + } + + billingManager.querySkuDetailsAsync(BillingClient.SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() { + @Override + public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListSubscriptions) { + // Is it a failure? + if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { + logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode()); + notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); + stop(true); + return; + } + + List skuDetailsList = new ArrayList<>(skuDetailsListInApps); + skuDetailsList.addAll(skuDetailsListSubscriptions); + InAppPurchaseHelperImpl.this.skuDetailsList = skuDetailsList; + + mSkuDetailsResponseListener.onSkuDetailsResponse(billingResult, skuDetailsList); + } + }); + } + }); + } + for (Purchase purchase : purchases) { + if (!purchase.isAcknowledged()) { + onPurchaseFinished(purchase); + } + } + } + + @Override + public void onPurchaseCanceled() { + stop(true); + } + }); + } + + @Override + public void purchaseFullVersion(Activity activity) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void purchaseDepthContours(Activity activity) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Nullable + private SkuDetails getSkuDetails(@NonNull String sku) { + List skuDetailsList = this.skuDetailsList; + if (skuDetailsList != null) { + for (SkuDetails details : skuDetailsList) { + if (details.getSku().equals(sku)) { + return details; + } + } + } + return null; + } + + private boolean hasDetails(@NonNull String sku) { + return getSkuDetails(sku) != null; + } + + @Nullable + private Purchase getPurchase(@NonNull String sku) { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + List purchases = billingManager.getPurchases(); + if (purchases != null) { + for (Purchase p : purchases) { + if (p.getSku().equals(sku)) { + return p; + } + } + } + } + return null; + } + + // Listener that's called when we finish querying the items and subscriptions we own + private SkuDetailsResponseListener mSkuDetailsResponseListener = new SkuDetailsResponseListener() { + + @NonNull + private List getAllOwnedSubscriptionSkus() { + List result = new ArrayList<>(); + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + for (Purchase p : billingManager.getPurchases()) { + if (getInAppPurchases().getInAppSubscriptionBySku(p.getSku()) != null) { + result.add(p.getSku()); + } + } + } + return result; + } + + @Override + public void onSkuDetailsResponse(BillingResult billingResult, List skuDetailsList) { + + logDebug("Query sku details finished."); + + // Have we been disposed of in the meantime? If so, quit. + if (getBillingManager() == null) { + stop(true); + return; + } + + // Is it a failure? + if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { + logError("Failed to query inventory: " + billingResult.getResponseCode()); + notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); + stop(true); + return; + } + + logDebug("Query sku details was successful."); + + /* + * Check for items we own. Notice that for each purchase, we check + * the developer payload to see if it's correct! See + * verifyDeveloperPayload(). + */ + + List allOwnedSubscriptionSkus = getAllOwnedSubscriptionSkus(); + for (InAppPurchases.InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { + if (hasDetails(s.getSku())) { + Purchase purchase = getPurchase(s.getSku()); + SkuDetails liveUpdatesDetails = getSkuDetails(s.getSku()); + if (liveUpdatesDetails != null) { + fetchInAppPurchase(s, liveUpdatesDetails, purchase); + } + allOwnedSubscriptionSkus.remove(s.getSku()); + } + } + for (String sku : allOwnedSubscriptionSkus) { + Purchase purchase = getPurchase(sku); + SkuDetails liveUpdatesDetails = getSkuDetails(sku); + if (liveUpdatesDetails != null) { + InAppPurchases.InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); + if (s == null) { + s = new InAppPurchases.InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails); + } + fetchInAppPurchase(s, liveUpdatesDetails, purchase); + } + } + + InAppPurchases.InAppPurchase fullVersion = getFullVersion(); + if (hasDetails(fullVersion.getSku())) { + Purchase purchase = getPurchase(fullVersion.getSku()); + SkuDetails fullPriceDetails = getSkuDetails(fullVersion.getSku()); + if (fullPriceDetails != null) { + fetchInAppPurchase(fullVersion, fullPriceDetails, purchase); + } + } + + InAppPurchases.InAppPurchase depthContours = getDepthContours(); + if (hasDetails(depthContours.getSku())) { + Purchase purchase = getPurchase(depthContours.getSku()); + SkuDetails depthContoursDetails = getSkuDetails(depthContours.getSku()); + if (depthContoursDetails != null) { + fetchInAppPurchase(depthContours, depthContoursDetails, purchase); + } + } + + InAppPurchases.InAppPurchase contourLines = getContourLines(); + if (hasDetails(contourLines.getSku())) { + Purchase purchase = getPurchase(contourLines.getSku()); + SkuDetails contourLinesDetails = getSkuDetails(contourLines.getSku()); + if (contourLinesDetails != null) { + fetchInAppPurchase(contourLines, contourLinesDetails, purchase); + } + } + + Purchase fullVersionPurchase = getPurchase(fullVersion.getSku()); + boolean fullVersionPurchased = fullVersionPurchase != null; + if (fullVersionPurchased) { + ctx.getSettings().FULL_VERSION_PURCHASED.set(true); + } + + Purchase depthContoursPurchase = getPurchase(depthContours.getSku()); + boolean depthContoursPurchased = depthContoursPurchase != null; + if (depthContoursPurchased) { + ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); + } + + // Do we have the live updates? + boolean subscribedToLiveUpdates = false; + List liveUpdatesPurchases = new ArrayList<>(); + for (InAppPurchases.InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { + Purchase purchase = getPurchase(p.getSku()); + if (purchase != null) { + liveUpdatesPurchases.add(purchase); + if (!subscribedToLiveUpdates) { + subscribedToLiveUpdates = true; + } + } + } + OsmandSettings.OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; + if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) { + if (subscriptionCancelledTime.get() == 0) { + subscriptionCancelledTime.set(System.currentTimeMillis()); + ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN.set(false); + ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN.set(false); + } else if (System.currentTimeMillis() - subscriptionCancelledTime.get() > SUBSCRIPTION_HOLDING_TIME_MSEC) { + ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false); + if (!isDepthContoursPurchased(ctx)) { + ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false); + } + } + } else if (subscribedToLiveUpdates) { + subscriptionCancelledTime.set(0L); + ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); + } + + lastValidationCheckTime = System.currentTimeMillis(); + logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") + + " live updates purchased."); + + OsmandSettings settings = ctx.getSettings(); + settings.INAPPS_READ.set(true); + + List tokensToSend = new ArrayList<>(); + if (liveUpdatesPurchases.size() > 0) { + List tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";")); + for (Purchase purchase : liveUpdatesPurchases) { + if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) + && !Algorithms.isEmpty(purchase.getDeveloperPayload())) { + String payload = purchase.getDeveloperPayload(); + if (!Algorithms.isEmpty(payload)) { + String[] arr = payload.split(" "); + if (arr.length > 0) { + settings.BILLING_USER_ID.set(arr[0]); + } + if (arr.length > 1) { + token = arr[1]; + settings.BILLING_USER_TOKEN.set(token); + } + } + } + if (!tokensSent.contains(purchase.getSku())) { + tokensToSend.add(purchase); + } + } + } + List purchaseInfoList = new ArrayList<>(); + for (Purchase purchase : tokensToSend) { + purchaseInfoList.add(getPurchaseInfo(purchase)); + } + onSkuDetailsResponseDone(purchaseInfoList); + } + }; + + private PurchaseInfo getPurchaseInfo(Purchase purchase) { + return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken()); + } + + private void fetchInAppPurchase(@NonNull InAppPurchases.InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) { + if (purchase != null) { + inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.PURCHASED); + inAppPurchase.setPurchaseTime(purchase.getPurchaseTime()); + } else { + inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.NOT_PURCHASED); + } + inAppPurchase.setPrice(skuDetails.getPrice()); + inAppPurchase.setPriceCurrencyCode(skuDetails.getPriceCurrencyCode()); + if (skuDetails.getPriceAmountMicros() > 0) { + inAppPurchase.setPriceValue(skuDetails.getPriceAmountMicros() / 1000000d); + } + String subscriptionPeriod = skuDetails.getSubscriptionPeriod(); + if (!Algorithms.isEmpty(subscriptionPeriod)) { + if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + try { + ((InAppPurchases.InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); + } catch (ParseException e) { + LOG.error(e); + } + } + } + if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + String introductoryPrice = skuDetails.getIntroductoryPrice(); + String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod(); + String introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles(); + long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros(); + if (!Algorithms.isEmpty(introductoryPrice)) { + InAppPurchases.InAppSubscription s = (InAppPurchases.InAppSubscription) inAppPurchase; + try { + s.setIntroductoryInfo(new InAppPurchases.InAppSubscriptionIntroductoryInfo(s, introductoryPrice, + introductoryPriceAmountMicros, introductoryPricePeriod, introductoryPriceCycles)); + } catch (ParseException e) { + LOG.error(e); + } + } + } + } + + protected InAppRunnable getPurchaseLiveUpdatesCommand(final WeakReference activity, final String sku, final String payload) { + return new InAppRunnable() { + @Override + public boolean run(InAppPurchaseHelper helper) { + try { + Activity a = activity.get(); + SkuDetails skuDetails = getSkuDetails(sku); + if (AndroidUtils.isActivityNotDestroyed(a) && skuDetails != null) { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.setPayload(payload); + billingManager.initiatePurchaseFlow(a, skuDetails); + } else { + throw new IllegalStateException("BillingManager disposed"); + } + return false; + } else { + stop(true); + } + } catch (Exception e) { + logError("launchPurchaseFlow Error", e); + stop(true); + } + return true; + } + }; + } + + protected InAppRunnable getRequestInventoryCommand() { + return new InAppRunnable() { + @Override + public boolean run(InAppPurchaseHelper helper) { + logDebug("Setup successful. Querying inventory."); + try { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.queryPurchases(); + } else { + throw new IllegalStateException("BillingManager disposed"); + } + return false; + } catch (Exception e) { + logError("queryInventoryAsync Error", e); + notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); + stop(true); + } + return true; + } + }; + } + + // Call when a purchase is finished + private void onPurchaseFinished(Purchase purchase) { + logDebug("Purchase finished: " + purchase); + + // if we were disposed of in the meantime, quit. + if (getBillingManager() == null) { + stop(true); + return; + } + + onPurchaseDone(getPurchaseInfo(purchase)); + } + + @Override + protected boolean isBillingManagerExists() { + return getBillingManager() != null; + } + + @Override + protected void destroyBillingManager() { + BillingManager billingManager = getBillingManager(); + if (billingManager != null) { + billingManager.destroy(); + this.billingManager = null; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 2837bff6f8..0ae24b7c5f 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -38,7 +38,7 @@ import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.WaypointHelper; -import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchaseHelperImpl; import net.osmand.plus.liveupdates.LiveUpdatesHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper; @@ -428,7 +428,7 @@ public class AppInitializer implements IProgress { } getLazyRoutingConfig(); app.applyTheme(app); - app.inAppPurchaseHelper = startupInit(new InAppPurchaseHelper(app), InAppPurchaseHelper.class); + app.inAppPurchaseHelper = startupInit(new InAppPurchaseHelperImpl(app), InAppPurchaseHelperImpl.class); app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class); app.transportRoutingHelper = startupInit(new TransportRoutingHelper(app), TransportRoutingHelper.class); app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.class); diff --git a/OsmAnd/src/net/osmand/plus/HuaweiDrmHelper.java b/OsmAnd/src/net/osmand/plus/HuaweiDrmHelper.java deleted file mode 100644 index 7cc2f2798e..0000000000 --- a/OsmAnd/src/net/osmand/plus/HuaweiDrmHelper.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.osmand.plus; - -import android.app.Activity; -import android.util.Log; - -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class HuaweiDrmHelper { - private static final String TAG = HuaweiDrmHelper.class.getSimpleName(); - - //Copyright protection id - private static final String DRM_ID = "101117397"; - //Copyright protection public key - private static final String DRM_PUBLIC_KEY = "9d6f861e7d46be167809a6a62302749a6753b3c1bd02c9729efb3973e268091d"; - - public static void check(Activity activity) { - boolean succeed = false; - try { - final WeakReference activityRef = new WeakReference<>(activity); - Class drmCheckCallbackClass = Class.forName("com.huawei.android.sdk.drm.DrmCheckCallback"); - Object callback = java.lang.reflect.Proxy.newProxyInstance( - drmCheckCallbackClass.getClassLoader(), - new java.lang.Class[]{drmCheckCallbackClass}, - new java.lang.reflect.InvocationHandler() { - - @Override - public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) { - Activity a = activityRef.get(); - if (a != null && !a.isFinishing()) { - String method_name = method.getName(); - if (method_name.equals("onCheckSuccess")) { - // skip now - } else if (method_name.equals("onCheckFailed")) { - closeApplication(a); - } - } - return null; - } - }); - - Class drmClass = Class.forName("com.huawei.android.sdk.drm.Drm"); - Class[] partypes = new Class[]{Activity.class, String.class, String.class, String.class, drmCheckCallbackClass}; - Method check = drmClass.getMethod("check", partypes); - check.invoke(null, activity, activity.getPackageName(), DRM_ID, DRM_PUBLIC_KEY, callback); - succeed = true; - - } catch (ClassNotFoundException e) { - Log.e(TAG, "check: ", e); - } catch (NoSuchMethodException e) { - Log.e(TAG, "check: ", e); - } catch (IllegalAccessException e) { - Log.e(TAG, "check: ", e); - } catch (InvocationTargetException e) { - Log.e(TAG, "check: ", e); - } - if (!succeed) { - closeApplication(activity); - } - } - - private static void closeApplication(Activity activity) { - ((OsmandApplication) activity.getApplication()).closeApplicationAnywayImpl(activity, true); - } -} diff --git a/OsmAnd/src/net/osmand/plus/Version.java b/OsmAnd/src/net/osmand/plus/Version.java index 14ed68b100..86d26ec954 100644 --- a/OsmAnd/src/net/osmand/plus/Version.java +++ b/OsmAnd/src/net/osmand/plus/Version.java @@ -121,8 +121,8 @@ public class Version { public static boolean isFreeVersion(OsmandApplication ctx){ return ctx.getPackageName().equals(FREE_VERSION_NAME) || ctx.getPackageName().equals(FREE_DEV_VERSION_NAME) || - ctx.getPackageName().equals(FREE_CUSTOM_VERSION_NAME) - ; + ctx.getPackageName().equals(FREE_CUSTOM_VERSION_NAME) || + isHuawei(ctx); } public static boolean isPaidVersion(OsmandApplication ctx) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index e23e596dcf..db9f055406 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -67,7 +67,6 @@ import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer.AppInitializeListener; import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; -import net.osmand.plus.HuaweiDrmHelper; import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener; import net.osmand.plus.OnDismissDialogFragmentListener; @@ -276,9 +275,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven super.onCreate(savedInstanceState); - if (Version.isHuawei(getMyApplication())) { - HuaweiDrmHelper.check(this); - } // Full screen is not used here // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); diff --git a/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java b/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java index 61ae82399f..855f648332 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java @@ -81,7 +81,7 @@ public class DiscountHelper { public static void checkAndDisplay(final MapActivity mapActivity) { OsmandApplication app = mapActivity.getMyApplication(); OsmandSettings settings = app.getSettings(); - if (settings.DO_NOT_SHOW_STARTUP_MESSAGES.get() || !settings.INAPPS_READ.get() || Version.isHuawei(app)) { + if (settings.DO_NOT_SHOW_STARTUP_MESSAGES.get() || !settings.INAPPS_READ.get()) { return; } if (mBannerVisible) { diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java index ac7e2c77fb..c037c13d0a 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java @@ -9,33 +9,21 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.billingclient.api.BillingClient.BillingResponseCode; -import com.android.billingclient.api.BillingClient.SkuType; -import com.android.billingclient.api.BillingResult; -import com.android.billingclient.api.Purchase; -import com.android.billingclient.api.SkuDetails; -import com.android.billingclient.api.SkuDetailsResponseListener; - import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils.OnRequestResultListener; import net.osmand.AndroidNetworkUtils.OnRequestsResultListener; import net.osmand.AndroidNetworkUtils.RequestResponse; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; import net.osmand.plus.inapp.InAppPurchases.InAppPurchase.PurchaseState; -import net.osmand.plus.inapp.InAppPurchases.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; -import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo; import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionList; -import net.osmand.plus.inapp.util.BillingManager; -import net.osmand.plus.inapp.util.BillingManager.BillingUpdatesListener; import net.osmand.plus.liveupdates.CountrySelectionFragment; import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; import org.json.JSONArray; @@ -43,7 +31,6 @@ import org.json.JSONException; import org.json.JSONObject; import java.lang.ref.WeakReference; -import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -53,52 +40,28 @@ import java.util.List; import java.util.Map; import java.util.Set; -public class InAppPurchaseHelper { +public abstract class InAppPurchaseHelper { // Debug tag, for logging - private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class); + protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class); private static final String TAG = InAppPurchaseHelper.class.getSimpleName(); private boolean mDebugLog = false; public static final long SUBSCRIPTION_HOLDING_TIME_MSEC = 1000 * 60 * 60 * 24 * 3; // 3 days - private InAppPurchases purchases; - private long lastValidationCheckTime; - private boolean inventoryRequested; + protected InAppPurchases purchases; + protected long lastValidationCheckTime; + protected boolean inventoryRequested; private static final long PURCHASE_VALIDATION_PERIOD_MSEC = 1000 * 60 * 60 * 24; // daily - // (arbitrary) request code for the purchase flow - private static final int RC_REQUEST = 10001; - // The helper object - private BillingManager billingManager; - private List skuDetailsList; + protected boolean isDeveloperVersion; + protected String token = ""; + protected InAppPurchaseTaskType activeTask; + protected boolean processingTask = false; + protected boolean inventoryRequestPending = false; - private boolean isDeveloperVersion; - private String token = ""; - private InAppPurchaseTaskType activeTask; - private boolean processingTask = false; - private boolean inventoryRequestPending = false; - - private OsmandApplication ctx; - private InAppPurchaseListener uiActivity = null; - - /* base64EncodedPublicKey should be YOUR APPLICATION'S PUBLIC KEY - * (that you got from the Google Play developer console). This is not your - * developer public key, it's the *app-specific* public key. - * - * Instead of just storing the entire literal string here embedded in the - * program, construct the key at runtime from pieces or - * use bit manipulation (for example, XOR with some other string) to hide - * the actual key. The key itself is not secret information, but we don't - * want to make it easy for an attacker to replace the public key with one - * of their own and then fake messages from the server. - */ - private static final String BASE64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgk8cEx" + - "UO4mfEwWFLkQnX1Tkzehr4SnXLXcm2Osxs5FTJPEgyTckTh0POKVMrxeGLn0KoTY2NTgp1U/inp" + - "wccWisPhVPEmw9bAVvWsOkzlyg1kv03fJdnAXRBSqDDPV6X8Z3MtkPVqZkupBsxyIllEILKHK06" + - "OCw49JLTsMR3oTRifGzma79I71X0spw0fM+cIRlkS2tsXN8GPbdkJwHofZKPOXS51pgC1zU8uWX" + - "I+ftJO46a1XkNh1dO2anUiQ8P/H4yOTqnMsXF7biyYuiwjXPOcy0OMhEHi54Dq6Mr3u5ZALOAkc" + - "YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB"; + protected OsmandApplication ctx; + protected InAppPurchaseListener uiActivity = null; public interface InAppPurchaseListener { void onError(InAppPurchaseTaskType taskType, String error); @@ -124,6 +87,30 @@ public class InAppPurchaseHelper { boolean run(InAppPurchaseHelper helper); } + public static class PurchaseInfo { + private String sku; + private String orderId; + private String purchaseToken; + + public PurchaseInfo(String sku, String orderId, String purchaseToken) { + this.sku = sku; + this.orderId = orderId; + this.purchaseToken = purchaseToken; + } + + public String getSku() { + return sku; + } + + public String getOrderId() { + return orderId; + } + + public String getPurchaseToken() { + return purchaseToken; + } + } + public String getToken() { return token; } @@ -194,11 +181,7 @@ public class InAppPurchaseHelper { return false; } - private BillingManager getBillingManager() { - return billingManager; - } - - private void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppRunnable runnable) { + protected void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppRunnable runnable) { if (isDeveloperVersion || !Version.isGooglePlayEnabled(ctx)) { notifyDismissProgress(taskType); stop(true); @@ -222,117 +205,15 @@ public class InAppPurchaseHelper { try { processingTask = true; activeTask = taskType; - billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingUpdatesListener() { - - @Override - public void onBillingClientSetupFinished() { - logDebug("Setup finished."); - - BillingManager billingManager = getBillingManager(); - // Have we been disposed of in the meantime? If so, quit. - if (billingManager == null) { - stop(true); - return; - } - - if (!billingManager.isServiceConnected()) { - // Oh noes, there was a problem. - //complain("Problem setting up in-app billing: " + result); - notifyError(taskType, billingManager.getBillingClientResponseMessage()); - stop(true); - return; - } - - processingTask = !runnable.run(InAppPurchaseHelper.this); - } - - @Override - public void onConsumeFinished(String token, BillingResult billingResult) { - } - - @Override - public void onPurchasesUpdated(final List purchases) { - - BillingManager billingManager = getBillingManager(); - // Have we been disposed of in the meantime? If so, quit. - if (billingManager == null) { - stop(true); - return; - } - - if (activeTask == InAppPurchaseTaskType.REQUEST_INVENTORY) { - List skuInApps = new ArrayList<>(); - for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { - skuInApps.add(purchase.getSku()); - } - for (Purchase p : purchases) { - skuInApps.add(p.getSku()); - } - billingManager.querySkuDetailsAsync(SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() { - @Override - public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListInApps) { - // Is it a failure? - if (billingResult.getResponseCode() != BillingResponseCode.OK) { - logError("Failed to query inapps sku details: " + billingResult.getResponseCode()); - notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); - stop(true); - return; - } - - List skuSubscriptions = new ArrayList<>(); - for (InAppSubscription subscription : getInAppPurchases().getAllInAppSubscriptions()) { - skuSubscriptions.add(subscription.getSku()); - } - for (Purchase p : purchases) { - skuSubscriptions.add(p.getSku()); - } - - BillingManager billingManager = getBillingManager(); - // Have we been disposed of in the meantime? If so, quit. - if (billingManager == null) { - stop(true); - return; - } - - billingManager.querySkuDetailsAsync(SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() { - @Override - public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListSubscriptions) { - // Is it a failure? - if (billingResult.getResponseCode() != BillingResponseCode.OK) { - logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode()); - notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); - stop(true); - return; - } - - List skuDetailsList = new ArrayList<>(skuDetailsListInApps); - skuDetailsList.addAll(skuDetailsListSubscriptions); - InAppPurchaseHelper.this.skuDetailsList = skuDetailsList; - - mSkuDetailsResponseListener.onSkuDetailsResponse(billingResult, skuDetailsList); - } - }); - } - }); - } - for (Purchase purchase : purchases) { - if (!purchase.isAcknowledged()) { - onPurchaseFinished(purchase); - } - } - } - - @Override - public void onPurchaseCanceled() { - stop(true); - } - }); + execImpl(taskType, runnable); } catch (Exception e) { logError("exec Error", e); stop(true); } } + protected abstract void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppRunnable runnable); + public boolean needRequestInventory() { return !inventoryRequested && ((isSubscribedToLiveUpdates(ctx) && Algorithms.isEmpty(ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.get())) || System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC); @@ -343,32 +224,7 @@ public class InAppPurchaseHelper { new RequestInventoryTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); } - public void purchaseFullVersion(final Activity activity) { - notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); - exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppRunnable() { - @Override - public boolean run(InAppPurchaseHelper helper) { - try { - SkuDetails skuDetails = getSkuDetails(getFullVersion().getSku()); - if (skuDetails == null) { - throw new IllegalArgumentException("Cannot find sku details"); - } - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.initiatePurchaseFlow(activity, skuDetails); - } else { - throw new IllegalStateException("BillingManager disposed"); - } - return false; - } catch (Exception e) { - complain("Cannot launch full version purchase!"); - logError("purchaseFullVersion Error", e); - stop(true); - } - return true; - } - }); - } + public abstract void purchaseFullVersion(final Activity activity) throws UnsupportedOperationException; public void purchaseLiveUpdates(Activity activity, String sku, String email, String userName, String countryDownloadName, boolean hideUserName) { @@ -377,288 +233,7 @@ public class InAppPurchaseHelper { .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); } - public void purchaseDepthContours(final Activity activity) { - notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); - exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppRunnable() { - @Override - public boolean run(InAppPurchaseHelper helper) { - try { - SkuDetails skuDetails = getSkuDetails(getDepthContours().getSku()); - if (skuDetails == null) { - throw new IllegalArgumentException("Cannot find sku details"); - } - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.initiatePurchaseFlow(activity, skuDetails); - } else { - throw new IllegalStateException("BillingManager disposed"); - } - return false; - } catch (Exception e) { - complain("Cannot launch depth contours purchase!"); - logError("purchaseDepthContours Error", e); - stop(true); - } - return true; - } - }); - } - - @Nullable - private SkuDetails getSkuDetails(@NonNull String sku) { - List skuDetailsList = this.skuDetailsList; - if (skuDetailsList != null) { - for (SkuDetails details : skuDetailsList) { - if (details.getSku().equals(sku)) { - return details; - } - } - } - return null; - } - - private boolean hasDetails(@NonNull String sku) { - return getSkuDetails(sku) != null; - } - - @Nullable - private Purchase getPurchase(@NonNull String sku) { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - List purchases = billingManager.getPurchases(); - if (purchases != null) { - for (Purchase p : purchases) { - if (p.getSku().equals(sku)) { - return p; - } - } - } - } - return null; - } - - // Listener that's called when we finish querying the items and subscriptions we own - private SkuDetailsResponseListener mSkuDetailsResponseListener = new SkuDetailsResponseListener() { - - @NonNull - private List getAllOwnedSubscriptionSkus() { - List result = new ArrayList<>(); - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - for (Purchase p : billingManager.getPurchases()) { - if (getInAppPurchases().getInAppSubscriptionBySku(p.getSku()) != null) { - result.add(p.getSku()); - } - } - } - return result; - } - - @Override - public void onSkuDetailsResponse(BillingResult billingResult, List skuDetailsList) { - - logDebug("Query sku details finished."); - - // Have we been disposed of in the meantime? If so, quit. - if (getBillingManager() == null) { - stop(true); - return; - } - - // Is it a failure? - if (billingResult.getResponseCode() != BillingResponseCode.OK) { - logError("Failed to query inventory: " + billingResult.getResponseCode()); - notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); - stop(true); - return; - } - - logDebug("Query sku details was successful."); - - /* - * Check for items we own. Notice that for each purchase, we check - * the developer payload to see if it's correct! See - * verifyDeveloperPayload(). - */ - - List allOwnedSubscriptionSkus = getAllOwnedSubscriptionSkus(); - for (InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { - if (hasDetails(s.getSku())) { - Purchase purchase = getPurchase(s.getSku()); - SkuDetails liveUpdatesDetails = getSkuDetails(s.getSku()); - if (liveUpdatesDetails != null) { - fetchInAppPurchase(s, liveUpdatesDetails, purchase); - } - allOwnedSubscriptionSkus.remove(s.getSku()); - } - } - for (String sku : allOwnedSubscriptionSkus) { - Purchase purchase = getPurchase(sku); - SkuDetails liveUpdatesDetails = getSkuDetails(sku); - if (liveUpdatesDetails != null) { - InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); - if (s == null) { - s = new InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails); - } - fetchInAppPurchase(s, liveUpdatesDetails, purchase); - } - } - - InAppPurchase fullVersion = getFullVersion(); - if (hasDetails(fullVersion.getSku())) { - Purchase purchase = getPurchase(fullVersion.getSku()); - SkuDetails fullPriceDetails = getSkuDetails(fullVersion.getSku()); - if (fullPriceDetails != null) { - fetchInAppPurchase(fullVersion, fullPriceDetails, purchase); - } - } - - InAppPurchase depthContours = getDepthContours(); - if (hasDetails(depthContours.getSku())) { - Purchase purchase = getPurchase(depthContours.getSku()); - SkuDetails depthContoursDetails = getSkuDetails(depthContours.getSku()); - if (depthContoursDetails != null) { - fetchInAppPurchase(depthContours, depthContoursDetails, purchase); - } - } - - InAppPurchase contourLines = getContourLines(); - if (hasDetails(contourLines.getSku())) { - Purchase purchase = getPurchase(contourLines.getSku()); - SkuDetails contourLinesDetails = getSkuDetails(contourLines.getSku()); - if (contourLinesDetails != null) { - fetchInAppPurchase(contourLines, contourLinesDetails, purchase); - } - } - - Purchase fullVersionPurchase = getPurchase(fullVersion.getSku()); - boolean fullVersionPurchased = fullVersionPurchase != null; - if (fullVersionPurchased) { - ctx.getSettings().FULL_VERSION_PURCHASED.set(true); - } - - Purchase depthContoursPurchase = getPurchase(depthContours.getSku()); - boolean depthContoursPurchased = depthContoursPurchase != null; - if (depthContoursPurchased) { - ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); - } - - // Do we have the live updates? - boolean subscribedToLiveUpdates = false; - List liveUpdatesPurchases = new ArrayList<>(); - for (InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { - Purchase purchase = getPurchase(p.getSku()); - if (purchase != null) { - liveUpdatesPurchases.add(purchase); - if (!subscribedToLiveUpdates) { - subscribedToLiveUpdates = true; - } - } - } - OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; - if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) { - if (subscriptionCancelledTime.get() == 0) { - subscriptionCancelledTime.set(System.currentTimeMillis()); - ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN.set(false); - ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN.set(false); - } else if (System.currentTimeMillis() - subscriptionCancelledTime.get() > SUBSCRIPTION_HOLDING_TIME_MSEC) { - ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false); - if (!isDepthContoursPurchased(ctx)) { - ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false); - } - } - } else if (subscribedToLiveUpdates) { - subscriptionCancelledTime.set(0L); - ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); - } - - lastValidationCheckTime = System.currentTimeMillis(); - logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") - + " live updates purchased."); - - OsmandSettings settings = ctx.getSettings(); - settings.INAPPS_READ.set(true); - - List tokensToSend = new ArrayList<>(); - if (liveUpdatesPurchases.size() > 0) { - List tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";")); - for (Purchase purchase : liveUpdatesPurchases) { - if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) - && !Algorithms.isEmpty(purchase.getDeveloperPayload())) { - String payload = purchase.getDeveloperPayload(); - if (!Algorithms.isEmpty(payload)) { - String[] arr = payload.split(" "); - if (arr.length > 0) { - settings.BILLING_USER_ID.set(arr[0]); - } - if (arr.length > 1) { - token = arr[1]; - settings.BILLING_USER_TOKEN.set(token); - } - } - } - if (!tokensSent.contains(purchase.getSku())) { - tokensToSend.add(purchase); - } - } - } - - final OnRequestResultListener listener = new OnRequestResultListener() { - @Override - public void onResult(String result) { - notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); - notifyGetItems(); - stop(true); - logDebug("Initial inapp query finished"); - } - }; - - if (tokensToSend.size() > 0) { - sendTokens(tokensToSend, listener); - } else { - listener.onResult("OK"); - } - } - }; - - private void fetchInAppPurchase(@NonNull InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) { - if (purchase != null) { - inAppPurchase.setPurchaseState(PurchaseState.PURCHASED); - inAppPurchase.setPurchaseTime(purchase.getPurchaseTime()); - } else { - inAppPurchase.setPurchaseState(PurchaseState.NOT_PURCHASED); - } - inAppPurchase.setPrice(skuDetails.getPrice()); - inAppPurchase.setPriceCurrencyCode(skuDetails.getPriceCurrencyCode()); - if (skuDetails.getPriceAmountMicros() > 0) { - inAppPurchase.setPriceValue(skuDetails.getPriceAmountMicros() / 1000000d); - } - String subscriptionPeriod = skuDetails.getSubscriptionPeriod(); - if (!Algorithms.isEmpty(subscriptionPeriod)) { - if (inAppPurchase instanceof InAppSubscription) { - try { - ((InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); - } catch (ParseException e) { - LOG.error(e); - } - } - } - if (inAppPurchase instanceof InAppSubscription) { - String introductoryPrice = skuDetails.getIntroductoryPrice(); - String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod(); - String introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles(); - long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros(); - if (!Algorithms.isEmpty(introductoryPrice)) { - InAppSubscription s = (InAppSubscription) inAppPurchase; - try { - s.setIntroductoryInfo(new InAppSubscriptionIntroductoryInfo(s, introductoryPrice, - introductoryPriceAmountMicros, introductoryPricePeriod, introductoryPriceCycles)); - } catch (ParseException e) { - LOG.error(e); - } - } - } - } + public abstract void purchaseDepthContours(final Activity activity) throws UnsupportedOperationException; @SuppressLint("StaticFieldLeak") private class LiveUpdatesPurchaseTask extends AsyncTask { @@ -746,31 +321,7 @@ public class InAppPurchaseHelper { if (!Algorithms.isEmpty(userId) && !Algorithms.isEmpty(token)) { logDebug("Launching purchase flow for live updates subscription for userId=" + userId); final String payload = userId + " " + token; - exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, new InAppRunnable() { - @Override - public boolean run(InAppPurchaseHelper helper) { - try { - Activity a = activity.get(); - SkuDetails skuDetails = getSkuDetails(sku); - if (a != null && skuDetails != null) { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.setPayload(payload); - billingManager.initiatePurchaseFlow(a, skuDetails); - } else { - throw new IllegalStateException("BillingManager disposed"); - } - return false; - } else { - stop(true); - } - } catch (Exception e) { - logError("launchPurchaseFlow Error", e); - stop(true); - } - return true; - } - }); + exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, getPurchaseLiveUpdatesCommand(activity, sku, payload)); } else { notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Empty userId"); stop(true); @@ -778,6 +329,9 @@ public class InAppPurchaseHelper { } } + protected abstract InAppRunnable getPurchaseLiveUpdatesCommand(final WeakReference activity, + final String sku, final String payload) throws UnsupportedOperationException; + @SuppressLint("StaticFieldLeak") private class RequestInventoryTask extends AsyncTask { @@ -808,38 +362,41 @@ public class InAppPurchaseHelper { try { JSONObject obj = new JSONObject(response); JSONArray names = obj.names(); - for (int i = 0; i < names.length(); i++) { - String skuType = names.getString(i); - JSONObject subObj = obj.getJSONObject(skuType); - String sku = subObj.getString("sku"); - if (!Algorithms.isEmpty(sku)) { - getLiveUpdates().upgradeSubscription(sku); + if (names != null) { + for (int i = 0; i < names.length(); i++) { + String skuType = names.getString(i); + JSONObject subObj = obj.getJSONObject(skuType); + String sku = subObj.getString("sku"); + if (!Algorithms.isEmpty(sku)) { + getLiveUpdates().upgradeSubscription(sku); + } } } } catch (JSONException e) { logError("Json parsing error", e); } } - exec(InAppPurchaseTaskType.REQUEST_INVENTORY, new InAppRunnable() { - @Override - public boolean run(InAppPurchaseHelper helper) { - logDebug("Setup successful. Querying inventory."); - try { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.queryPurchases(); - } else { - throw new IllegalStateException("BillingManager disposed"); - } - return false; - } catch (Exception e) { - logError("queryInventoryAsync Error", e); - notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); - stop(true); - } - return true; - } - }); + exec(InAppPurchaseTaskType.REQUEST_INVENTORY, getRequestInventoryCommand()); + } + } + + protected abstract InAppRunnable getRequestInventoryCommand() throws UnsupportedOperationException; + + protected void onSkuDetailsResponseDone(List purchaseInfoList) { + final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() { + @Override + public void onResult(String result) { + notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); + notifyGetItems(); + stop(true); + logDebug("Initial inapp query finished"); + } + }; + + if (purchaseInfoList.size() > 0) { + sendTokens(purchaseInfoList, listener); + } else { + listener.onResult("OK"); } } @@ -852,25 +409,16 @@ public class InAppPurchaseHelper { parameters.put("aid", ctx.getUserAndroidId()); } - // Call when a purchase is finished - private void onPurchaseFinished(Purchase purchase) { - logDebug("Purchase finished: " + purchase); - - // if we were disposed of in the meantime, quit. - if (getBillingManager() == null) { - stop(true); - return; - } - + protected void onPurchaseDone(PurchaseInfo info) { logDebug("Purchase successful."); - InAppPurchase liveUpdatesPurchase = getLiveUpdates().getSubscriptionBySku(purchase.getSku()); + InAppPurchase liveUpdatesPurchase = getLiveUpdates().getSubscriptionBySku(info.getSku()); if (liveUpdatesPurchase != null) { // bought live updates logDebug("Live updates subscription purchased."); final String sku = liveUpdatesPurchase.getSku(); liveUpdatesPurchase.setPurchaseState(PurchaseState.PURCHASED); - sendTokens(Collections.singletonList(purchase), new OnRequestResultListener() { + sendTokens(Collections.singletonList(info), new OnRequestResultListener() { @Override public void onResult(String result) { boolean active = ctx.getSettings().LIVE_UPDATES_PURCHASED.get(); @@ -887,7 +435,7 @@ public class InAppPurchaseHelper { } }); - } else if (purchase.getSku().equals(getFullVersion().getSku())) { + } else if (info.getSku().equals(getFullVersion().getSku())) { // bought full version getFullVersion().setPurchaseState(PurchaseState.PURCHASED); logDebug("Full version purchased."); @@ -898,7 +446,7 @@ public class InAppPurchaseHelper { notifyItemPurchased(getFullVersion().getSku(), false); stop(true); - } else if (purchase.getSku().equals(getDepthContours().getSku())) { + } else if (info.getSku().equals(getDepthContours().getSku())) { // bought sea depth contours getDepthContours().setPurchaseState(PurchaseState.PURCHASED); logDebug("Sea depth contours purchased."); @@ -921,17 +469,19 @@ public class InAppPurchaseHelper { stop(false); } - private void stop(boolean taskDone) { + protected abstract boolean isBillingManagerExists(); + + protected abstract void destroyBillingManager(); + + protected void stop(boolean taskDone) { logDebug("Destroying helper."); - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { + if (isBillingManagerExists()) { if (taskDone) { processingTask = false; } if (!processingTask) { activeTask = null; - billingManager.destroy(); - this.billingManager = null; + destroyBillingManager(); } } else { processingTask = false; @@ -943,7 +493,7 @@ public class InAppPurchaseHelper { } } - private void sendTokens(@NonNull final List purchases, final OnRequestResultListener listener) { + protected void sendTokens(@NonNull final List purchaseInfoList, final OnRequestResultListener listener) { final String userId = ctx.getSettings().BILLING_USER_ID.get(); final String token = ctx.getSettings().BILLING_USER_TOKEN.get(); final String email = ctx.getSettings().BILLING_USER_EMAIL.get(); @@ -951,12 +501,12 @@ public class InAppPurchaseHelper { String url = "https://osmand.net/subscription/purchased"; String userOperation = "Sending purchase info..."; final List requests = new ArrayList<>(); - for (Purchase purchase : purchases) { + for (PurchaseInfo info : purchaseInfoList) { Map parameters = new HashMap<>(); parameters.put("userid", userId); - parameters.put("sku", purchase.getSku()); - parameters.put("orderId", purchase.getOrderId()); - parameters.put("purchaseToken", purchase.getPurchaseToken()); + parameters.put("sku", info.getSku()); + parameters.put("orderId", info.getOrderId()); + parameters.put("purchaseToken", info.getPurchaseToken()); parameters.put("email", email); parameters.put("token", token); addUserInfo(parameters); @@ -967,9 +517,9 @@ public class InAppPurchaseHelper { public void onResult(@NonNull List results) { for (RequestResponse rr : results) { String sku = rr.getRequest().getParameters().get("sku"); - Purchase purchase = getPurchase(sku); - if (purchase != null) { - updateSentTokens(purchase); + PurchaseInfo info = getPurchaseInfo(sku); + if (info != null) { + updateSentTokens(info); String result = rr.getResponse(); if (result != null) { try { @@ -979,13 +529,13 @@ public class InAppPurchaseHelper { } else { complain("SendToken Error: " + obj.getString("error") - + " (userId=" + userId + " token=" + token + " response=" + result + " google=" + purchase.toString() + ")"); + + " (userId=" + userId + " token=" + token + " response=" + result + " google=" + info.toString() + ")"); } } catch (JSONException e) { logError("SendToken", e); complain("SendToken Error: " + (e.getMessage() != null ? e.getMessage() : "JSONException") - + " (userId=" + userId + " token=" + token + " response=" + result + " google=" + purchase.toString() + ")"); + + " (userId=" + userId + " token=" + token + " response=" + result + " google=" + info.toString() + ")"); } } } @@ -995,10 +545,10 @@ public class InAppPurchaseHelper { } } - private void updateSentTokens(@NonNull Purchase purchase) { + private void updateSentTokens(@NonNull PurchaseInfo info) { String tokensSentStr = ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.get(); Set tokensSent = new HashSet<>(Arrays.asList(tokensSentStr.split(";"))); - tokensSent.add(purchase.getSku()); + tokensSent.add(info.getSku()); ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.set(TextUtils.join(";", tokensSent)); } @@ -1032,10 +582,10 @@ public class InAppPurchaseHelper { } @Nullable - private Purchase getPurchase(String sku) { - for (Purchase purchase : purchases) { - if (purchase.getSku().equals(sku)) { - return purchase; + private PurchaseInfo getPurchaseInfo(String sku) { + for (PurchaseInfo info : purchaseInfoList) { + if (info.getSku().equals(sku)) { + return info; } } return null; @@ -1049,31 +599,31 @@ public class InAppPurchaseHelper { } } - private void notifyError(InAppPurchaseTaskType taskType, String message) { + protected void notifyError(InAppPurchaseTaskType taskType, String message) { if (uiActivity != null) { uiActivity.onError(taskType, message); } } - private void notifyGetItems() { + protected void notifyGetItems() { if (uiActivity != null) { uiActivity.onGetItems(); } } - private void notifyItemPurchased(String sku, boolean active) { + protected void notifyItemPurchased(String sku, boolean active) { if (uiActivity != null) { uiActivity.onItemPurchased(sku, active); } } - private void notifyShowProgress(InAppPurchaseTaskType taskType) { + protected void notifyShowProgress(InAppPurchaseTaskType taskType) { if (uiActivity != null) { uiActivity.showProgress(taskType); } } - private void notifyDismissProgress(InAppPurchaseTaskType taskType) { + protected void notifyDismissProgress(InAppPurchaseTaskType taskType) { if (uiActivity != null) { uiActivity.dismissProgress(taskType); } @@ -1090,26 +640,26 @@ public class InAppPurchaseHelper { } } - private void complain(String message) { + protected void complain(String message) { logError("**** InAppPurchaseHelper Error: " + message); showToast(message); } - private void showToast(final String message) { + protected void showToast(final String message) { ctx.showToastMessage(message); } - private void logDebug(String msg) { + protected void logDebug(String msg) { if (mDebugLog) { Log.d(TAG, msg); } } - private void logError(String msg) { + protected void logError(String msg) { Log.e(TAG, msg); } - private void logError(String msg, Throwable e) { + protected void logError(String msg, Throwable e) { Log.e(TAG, "Error: " + msg, e); } diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java index b42b57f045..8c42448ec7 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java @@ -55,6 +55,12 @@ public class InAppPurchases { new InAppPurchaseLiveUpdatesAnnualFree() }; + private static final InAppSubscription[] LIVE_UPDATES_HW_FREE = new InAppSubscription[]{ + new InAppPurchaseLiveUpdatesMonthlyHWFree(), + new InAppPurchaseLiveUpdates3MonthsHWFree(), + new InAppPurchaseLiveUpdatesAnnualHWFree() + }; + private InAppPurchase fullVersion; private InAppPurchase depthContours; private InAppPurchase contourLines; @@ -65,7 +71,9 @@ public class InAppPurchases { InAppPurchases(OsmandApplication ctx) { fullVersion = FULL_VERSION; - if (Version.isFreeVersion(ctx)) { + if (Version.isHuawei(ctx)) { + liveUpdates = new LiveUpdatesInAppPurchasesHWFree(); + } else if (Version.isFreeVersion(ctx)) { liveUpdates = new LiveUpdatesInAppPurchasesFree(); } else { liveUpdates = new LiveUpdatesInAppPurchasesFull(); @@ -267,6 +275,13 @@ public class InAppPurchases { } } + public static class LiveUpdatesInAppPurchasesHWFree extends InAppSubscriptionList { + + public LiveUpdatesInAppPurchasesHWFree() { + super(LIVE_UPDATES_HW_FREE); + } + } + public static class LiveUpdatesInAppPurchasesFull extends InAppSubscriptionList { public LiveUpdatesInAppPurchasesFull() { @@ -943,6 +958,25 @@ public class InAppPurchases { } } + public static class InAppPurchaseLiveUpdatesMonthlyHWFree extends InAppPurchaseLiveUpdatesMonthly { + + private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.test.monthly"; + + InAppPurchaseLiveUpdatesMonthlyHWFree() { + super(SKU_LIVE_UPDATES_MONTHLY_HW_FREE, 1); + } + + private InAppPurchaseLiveUpdatesMonthlyHWFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyHWFree(sku) : null; + } + } + public static abstract class InAppPurchaseLiveUpdates3Months extends InAppSubscription { InAppPurchaseLiveUpdates3Months(String skuNoVersion, int version) { @@ -1024,6 +1058,25 @@ public class InAppPurchases { } } + public static class InAppPurchaseLiveUpdates3MonthsHWFree extends InAppPurchaseLiveUpdates3Months { + + private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.test.3months"; + + InAppPurchaseLiveUpdates3MonthsHWFree() { + super(SKU_LIVE_UPDATES_3_MONTHS_HW_FREE, 1); + } + + private InAppPurchaseLiveUpdates3MonthsHWFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsHWFree(sku) : null; + } + } + public static abstract class InAppPurchaseLiveUpdatesAnnual extends InAppSubscription { InAppPurchaseLiveUpdatesAnnual(String skuNoVersion, int version) { @@ -1105,6 +1158,25 @@ public class InAppPurchases { } } + public static class InAppPurchaseLiveUpdatesAnnualHWFree extends InAppPurchaseLiveUpdatesAnnual { + + private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.test.annual"; + + InAppPurchaseLiveUpdatesAnnualHWFree() { + super(SKU_LIVE_UPDATES_ANNUAL_HW_FREE, 1); + } + + private InAppPurchaseLiveUpdatesAnnualHWFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualHWFree(sku) : null; + } + } + public static class InAppPurchaseLiveUpdatesOldMonthly extends InAppPurchaseLiveUpdatesMonthly { InAppPurchaseLiveUpdatesOldMonthly(String sku) { diff --git a/OsmAndHms.jks b/OsmAndHms.jks new file mode 100644 index 0000000000000000000000000000000000000000..b1d7e59362b69659660ae0e1bc29bfdca0f751f2 GIT binary patch literal 2243 zcmchY={Fk)7sj*LnvmF2YF|oi6I+y^YN?2=T1)L)f)cxFETt7KHI!EE65FImETyWn zYS%@Jh*lJ>poUVk7&U6}X6C$e&YbrTct6~8&;5P4=bq=@^W4Mr!*u`v0OADj?>H72 z8}1*03ki?qkT^!@>;39E-PVlh5HSeC*=2vw+ zlp0xNT|F3ew=wYMIoPmb(Ky*v0>;OVC*v;%`j`wZ-X^>IJMav3Khu3;&PrYtHi~

os?$`26el>Y`xz_6E$6w15z$tjc4G|*L{$kGVP zIGE$L`gl-t)tC^4u94MeHRh}F9z2ys=w~>Tsb0lEUXOLr^~GXT&$_c)O;(D}T}01D zQrpAC{O5|`1oKXZQIdh~wMLH;K}J%&+V1gRO#LfrtQkUMwwlhCGgxDzA>YOOqX`n@ ze*06aG1-~C4vS-tn`!&X&(F?o4kc>B1L`v%9%-KM%l3A1kHcDn%+6bT2FLCHRQuK6!@+Ig_9_Tr;$O2>^ZBc2hg|M)%?r_!U7^i}@vS}wD=WNuZ<6?W;!NYA0poXIC z7ctf!qeZ{mSFoQl-ZY(ja9iX`!q&bL9uXu>F2wv zg5tqFx;yT|MvlUxC{97f9Tx412U6duSP1IxEU2`K)nL*!@6L$CjsqLA~{3&~`Qq9`tB-)%6*< zkJ%_OZQ(!3UV}T3tWmJJ57ArZ2*CvdXehZHCai|cW(sUO-|-1R!wwKNp4$jp$(72> zH~>}pc;+Rvp48)7WR-J16Rj&q9RVM5zqC4_8x9zFe-mN;no{QxWYx^|+W(Ai+ZU5J z&`+_f(eIwD}j-&9jb6^X_hIU*+q0oGei%zWNkAng4 zu{8FG%WlZB^ZdMpR?3!A)xa3-<1}z_O;e8Dr3lEJhD}{HjvPp*&Z)DbuT%L=HN28T z`9J%iB=UO9Nd4+D(=3Z}v5U43qqgA;eiE-$x*aOJM_AmaS(m?#*tGlNvee*?vyjlb zvz$8e6>&yt$%|lsT1-yJOz!m0p)~1)nHwOGiYkE%Po5kAqW9Gk-qw5lZH?TQwDggN z001}vNdo_jB!Rpu!5|Ol(d98*ijr0)sui^2I6U=k3{c_Bauhy(-z zZgnEUZu`o>rG1PrWY=k*h;Yerr%>sRGqq4_sMnzx(ec3{?RZ}4ehG7IV@mtQjVyTJ0s{fS zU*(aqNNLWVrD0s+T%w_gD1jqrUqLB~l~rJGBQNDtp!shRITytd5eSfMCl;QSLm2}D z>t7a7x_S+V3JF+lNT=3tvjR~`ukJ=qPl$W!14hl2VksH<<~U6r22A`3?HyN3nN)r& z{W}J>rY6mQZpjU&cGvdK!h}W^i&;3lBJ2|#IrtlBKO3vexEEx%;e^^Y>YKQkF_X1s zgE=v>Ddk!o+38kYE4see`b%A%c3D~d1&Tufse_9 z)wPmC4|dewMTbjnSIxagh{P%O*MAki(u6nrV1?*!n0mvOzEwf!s|+`UU+aW_z*m Date: Mon, 28 Sep 2020 09:46:08 +0000 Subject: [PATCH 0361/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 42c016b76d..bf6cecf439 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3346,7 +3346,7 @@ Значок местоположения в состоянии покоя После нажатия кнопки «Применить» удалённые профили будут полностью потеряны. Базовый профиль - Цвет + Выберите цвет Вы не можете удалить стандартные профили OsmAnd, но вы можете отключить их на предыдущем экране или переместить вниз. Редактировать профили Режим навигации определяет правила расчета маршрутов. From 241a7f97d4b00b8198c6aac84c57512fec0f19de Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Mon, 28 Sep 2020 09:11:53 +0000 Subject: [PATCH 0362/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 46 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index bf6cecf439..4c2e2314e7 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3108,7 +3108,7 @@ Повторяющееся имя BRouter (локально) Альпийские/горные лыжи - Склоны для катания на альпийских или горных лыжах и доступ к подъёмникам. + Склоны для катания и спуска на горных лыжах и доступ к подъёмникам. Лыжные туры Сани Склоны для катания на санях. @@ -3555,7 +3555,7 @@ Невозможно разобрать геоссылку «%s». Для отображения затенения рельефа на карте необходимы дополнительные карты. Мин. - Отображение затенения рельефа или склонов. Подробнее об этих типах карт вы можете прочитать на нашем сайте. + Отображение затенения рельефа или карты уклонов. Подробнее об этих типах карт вы можете прочитать на нашем сайте. Прозрачность Уровни масштаба Пересчитывать маршрут в случае отклонения @@ -3582,12 +3582,12 @@ Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. В этом случае будут записываться только точки, измеренные с минимальной точностью (в метрах/футах согласно настройкам устройства). Точность — это близость измерений к истинному местоположению и не имеет прямого отношения к точности, подразумевающейся под разбросом повторных замеров. Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться. - Склон использует цвета для визуализации крутизны. - Подробнее о склонах можно прочитать в %1$s. + Уклон использует цвета для визуализации крутизны рельефа. + Подробнее об уклонах можно прочитать в %1$s. Затенение рельефа Затенение рельефа использует тёмные оттенки для отображения склонов, вершин и низменностей. Для отображения склонов на карте необходимы дополнительные карты. - Склоны + Уклоны Заменить этой точкой другую. Изменения применены к профилю «%1$s». Невозможно прочитать из «%1$s». @@ -3668,24 +3668,24 @@ Справка по символике карты. Избранное Профили навигации - • Новые локальные карты склонов -\n -\n • Полная настройка избранных и путевых точек GPX: пользовательские цвета, значки, формы -\n -\n • Изменение порядка элементов в контекстном меню, настройках карты и панели -\n -\n • Википедия как отдельный слой в настройках карты, можно выбрать только нужные языки -\n -\n • Можно создать собственный очень гибкий фильтр POI/карты -\n -\n • Добавлены параметры для восстановления настроек пользовательских профилей -\n -\n • Полные GPX-маршруты в «Навигации» с поддержкой полос движения и подробными инструкциями поворотов -\n -\n • Исправлены размеры интерфейса на планшетах -\n -\n • Исправлены ошибки для языков, пишущихся справа налево -\n + • Новые локальные карты уклонов +\n +\n • Полная настройка избранных и путевых точек GPX: пользовательские цвета, значки, формы +\n +\n • Изменение порядка элементов в контекстном меню, настройках карты и панели +\n +\n • Википедия как отдельный слой в настройках карты, можно выбрать только нужные языки +\n +\n • Можно создать собственный очень гибкий фильтр POI/карты +\n +\n • Добавлены параметры для восстановления настроек пользовательских профилей +\n +\n • Полные GPX-маршруты в «Навигации» с поддержкой полос движения и подробными инструкциями поворотов +\n +\n • Исправлены размеры интерфейса на планшетах +\n +\n • Исправлены ошибки RTL +\n \n Функции, доступные при нажатии кнопки «%1$s». Скрыть общественный транспорт From a29c3db22f6f322c4aa032dd89d521ee811fe0d0 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 27 Sep 2020 18:43:15 +0000 Subject: [PATCH 0363/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 4c2e2314e7..701641a64d 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -481,7 +481,7 @@ Друзья Места Другое - Не нужно + Нет, спасибо Загрузите базовую карту мира, чтобы получить обзор всего мира с низким уровнем масштабирования. На устройстве отсутствуют локальные данные. Загрузите их, чтобы использовать приложение без интернета. " From 10ebbafc8871937efdf01da771b6b3d45bdbcb55 Mon Sep 17 00:00:00 2001 From: Zmicer Turok Date: Mon, 28 Sep 2020 06:07:58 +0000 Subject: [PATCH 0364/1366] Translated using Weblate (Belarusian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-be/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index 2ac856d032..6839ec5d24 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -3939,17 +3939,17 @@ \nАдзін месяц - 43 829 хвілін. Абярыце спосаб захоўвання спампаваных фрагментаў. Вярнуць - • Абноўлены рэжым планавання маршруту дазваляе выкарыстоўваць розныя тыпы навігацыі для кожнага сегмента і прымацоўвае любы шлях да дарог + • Абноўлена функцыя планавання маршруту. З’явілася магчымасць выкарыстоўваць розныя тыпы навігацыі для кожнага сегмента і прымацоўваць сляды \n -\n • Новыя варыянты выгляду для дарожак: абраць колер, таўшчыню, уключыць стрэлкі кірунку і адзнакі старту/фінішу +\n • Новае меню \"Выгляд\" для слядоў. Можна абраць колер, таўшчыню, уключыць стрэлкі кірунку, адзнакі старту / фінішу \n -\n • Палепшаная бачнасць роварных вузлоў +\n • Палепшана бачнасць роварных вузлоў. \n -\n • Кантэкстнае меню для слядоў з асноўнай інфармацыяй +\n • Для слядоў з’явілася кантэкстнае меню з асноўнай інфармацыяй. \n \n • Палепшаны алгарытмы пошуку \n -\n • Палепшаны параметры адсочвання ў навігацыі +\n • Палепшаны параметры адсочвання слядоў у навігацыі \n \n • Выпраўлены праблемы з імпартам / экспартам налад профілю \n From 02bce3bf39f474bd62f46cfa2ba10f241d2b50c5 Mon Sep 17 00:00:00 2001 From: iman Date: Mon, 28 Sep 2020 08:39:50 +0000 Subject: [PATCH 0365/1366] Translated using Weblate (Persian) Currently translated at 99.7% (3478 of 3487 strings) --- OsmAnd/res/values-fa/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index fe618c6f25..4d8d47c875 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -1499,8 +1499,8 @@ حداکثر زمان پارک تا باقی مانده ویرایش‌های شما - بازدیدکردن بعد از - بازدیدکردن قبل از + بازدید بعد از + بازدید قبل از شبیه‌سازی موقعیت شما عرض %1$s \nطول %2$s @@ -3864,8 +3864,8 @@ \n حذفِ قبل حذفِ بعد - تغییر نوع مسیرِ بعد از آن - تغییر نوع مسیرِ قبل از آن + تغییر نوع مسیرِ بعد آن + تغییر نوع مسیرِ قبل آن تک‌رنگ طول وسیلهٔ نقلیهٔ خود را مشخص کنید. ممکن است محدودیت‌های مسیر برای وسایل نقلیهٔ طویل اِعمال شود. مقصد کنونی مسیر حذف خواهد شد. اگر این قرار است مقصد باشد، ناوبری متوقف می‌شود. From 7e19830f0a284cdad3299fc3e6e1b00b2d309d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sun, 27 Sep 2020 08:16:05 +0000 Subject: [PATCH 0366/1366] Translated using Weblate (Estonian) Currently translated at 99.3% (3466 of 3487 strings) --- OsmAnd/res/values-et/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index 47d430d832..e219936c08 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -896,7 +896,7 @@ Halda rakenduse profiile… Jõus kogu rakenduses OsmAnd seaded - Kopeeri teiselt profiililt + Kopeeri teisest profiilist Lülita ekraan sisse Kaart navigeerimise ajal Kaart navigeerimise ajal From 8a5dd81d663a18303f11bbec45fab7397fed0495 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sun, 27 Sep 2020 11:44:08 +0000 Subject: [PATCH 0367/1366] Translated using Weblate (Esperanto) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-eo/strings.xml | 48 +++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index d27d45ba70..50bc2c4390 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -955,7 +955,7 @@ Dropbox kromprogramo Ŝanĝi ordon Bonvolu konsideri aĉeti la kromprogramon “nivelkurboj” en la vendejo por subteni ĝian pluan evoluigon. - Je peto\? + Demandi Registri videon Registri sonon Implicita ago de fenestraĵo: @@ -1417,7 +1417,7 @@ La elektita lingvo ne estas subtenata per la instalita Androida parolsintezilo, la aktuala lingvo de sintezilo estos uzata. Ĉu serĉi alian parolsintezilon en la Vendejo Play\? Mankas datumoj Ĉu malfermi vendejon por elŝuti elektitan lingvon? - Inversigi direkton de GPX + Inversigi direkton de spuro Uzi aktualan celon Iri laŭ tuta kurso Eksterreta vektora mapo disponebla por tiu ĉi loko. @@ -2007,7 +2007,7 @@ Bezonata por elŝuti mapojn. Determinado de pozicio… Libera loko - Dosierujo por datumoj de OsmAnd (por mapoj, GPX-dosieroj, ktp.): %1$s. + Dosierujo por datumoj de OsmAnd (por mapoj, spuroj, ktp.): %1$s. Permesi Permesi aliron al pozicio Navigi kaj esplori novajn lokojn sen interreta konekto @@ -2062,8 +2062,8 @@ Aktivigi rapidan registradon Montri sisteman sciigon kun eblo ekigi registradon de kurso. Sciigoj - Vi ankoraŭ havas neniujn GPX-dosierojn - Vi ankaŭ povas aldoni GPX-dosierojn al la dosierujo + Vi ankoraŭ havas neniun dosieron de spuro + Vi ankaŭ povas aldoni dosierojn de spurojn al la dosierujo Aldoni pli… Aspekto Eteta @@ -2404,7 +2404,7 @@ Trovis nenion Ŝanĝu serĉpeton aŭ pliigu radiuson de serĉo. Via celo troviĝas en privata tereno. Ĉu permesi aliron al privataj vojoj por tiu ĉi kurso\? - Strat-nivela fotaro + Mapillary Mapillary-fenestraĵo Ebligas rapide kontribui al Mapillary. Enretaj strat-nivelaj fotoj por ĉiuj. Esplori lokojn, kunlabori kaj foti la mondon. @@ -2892,10 +2892,10 @@ Specoj de vojoj Eliru ĉe Atendu ĉe haltejo - Montri/kaŝi GPX-spurojn - Butono por montri/kaŝi elektitajn GPX-spurojn sur la mapo. - Kaŝi GPX-spurojn - Montri GPX-spurojn + Montri/kaŝi spurojn + Butono por montri/kaŝi elektitajn spurojn sur la mapo. + Kaŝi spurojn + Montri spurojn • nova ekrano “navigi”: butonoj por navigi al hejmo aŭ laborejo, butono “antaŭa kurso”, listo de aktivaj GPX-spuroj kaj map-markoj, serĉ-historio \n \n • pliaj informoj ĉe “detaloj pri kurso”: specoj de vojoj, pavimo, klineco, glateco @@ -3443,7 +3443,7 @@ Minimuma rapido Minimuma precizo Minimuma delokiĝo - Restarigi implicitajn agordojn de kromprogramo + Restarigi implicitajn agordojn de la kromprogramo Dividilo de registraĵoj Uzi sisteman aplikaĵon Sono de fotilo @@ -3780,14 +3780,14 @@ Avertoj pri rapidkontroliloj estas kontraŭleĝaj en iuj landoj. Direkto %1$s forigita - Restarto estas necesa por tute forigi datumojn pri rapidkontroliloj. + Restartigu la aplikaĵon por forigi ĉiujn datumojn pri rapidkontroliloj. Malinstali kaj restartigi Difini permesatan longon de veturilo. Limigo de longo Tiu ĉi aplikaĵo ne liveras informojn pri rapidkontrolliloj. Rulglitiloj Skali per sonfortecaj butonoj - Uzi la butonojn de sonforteco por pli-/mal-grandigi la mapon. + Pligrandigi/malgrandigi la mapon per butonoj de sonforteco. Enigu longon de via veturilo, iuj vojaj limigoj aplikas al longaj veturiloj. Forigi sekvan celon Enigu nomon por la punkto @@ -3801,7 +3801,7 @@ Gokarto Fermita OSM‑rimarko La aldonita punkto ne estos videbla sur la mapo, ĉar la elektita grupo estas kaŝita, vi povas trovi ĝin en “%s”. - Necesas enigi tagojn de malfermo por pluigi + Enigu tagojn de malfermo por pluigi Kurso inter punktoj Plani kurson Aldoni al spuro @@ -3833,7 +3833,7 @@ Profilo de navigo Elektu dosieron de spuro al kiu nova segmento estos aldonita. Strat-nivela fotaro - Ĉu vi certe volas fermi planadon de kurso sen konservi\? Ĉiuj viaj ŝanĝoj perdiĝos. + Ĉu vi certe volas forĵeti ĉiujn ŝanĝojn en la planita kurso per fermi ĝin\? Kiam en inversa direkto Aŭtomate registri spuron dum navigi Konservi kiel novan dosieron de spuro @@ -3849,7 +3849,7 @@ Aldoni navigadpunkton al spuro Registri spuron Konservi kiel dosieron de kurso - Elekti dosieron de spuro por sekvi aŭ enporti el la aparato. + Elekti dosieron de spuro por ĝin sekvi aŭ enporti el via aparato. Elekti alian spuron Navigi el mia pozicio al la spuro Punkto de spuro por navigi @@ -3876,7 +3876,7 @@ Refari • plibonigoj al “plani kurson”: eblo uzi diversajn specojn de navigo por ĉiu segmento aparte kaj ampleksi spurojn \n -\n• nova menuo de aspekto por spuroj: eblo elekti koloron kaj dikecon, montri sagetojn de direkto kaj vidigi komencon/finon de spuro +\n• nova menuo de aspekto por spuroj: eblo elekti koloron kaj dikecon, montri sagetojn de direkto kaj vidigi markojn de komenco/fino de la spuro \n \n• plibonigita videblo de biciklaj nodoj \n @@ -3889,4 +3889,18 @@ \n• riparitaj problemoj pri en-/el-porti agordojn de profilo \n \n + Registri + Elektu la intervalon de registrado por la ĝenerala registrado de spuro (aktivigata per la fenestraĵo “registri spuron” sur la mapo). + Simpligita spuro + Nur la linio de kurso estos konservita, la navigadpunktoj estos forigitaj. + Dosiernomo + %d dosieroj de spuroj elektitaj + Paŭzigos registri spuron je halto de la aplikaĵo (per la menuo de lastaj aplikaĵoj). (Fona emblemo de OsmAnd malaperos de la androida sciiga zono.) + Paŭzigi registri spuron + Daŭrigi registri spuron + Sistema + Ĉiuj sekvaj segmentoj + Antaŭa segmento + Ĉiuj antaŭaj segmentoj + Nur la elektita segmento estos rekalkulita uzante la elektitan profilon. \ No newline at end of file From 751e6ffeb758c0dd35dd2e77735a266f50767002 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sun, 27 Sep 2020 11:58:57 +0000 Subject: [PATCH 0368/1366] Translated using Weblate (Esperanto) Currently translated at 100.0% (3824 of 3824 strings) --- OsmAnd/res/values-eo/phrases.xml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml index ac3f84fe04..8dc446b363 100644 --- a/OsmAnd/res/values-eo/phrases.xml +++ b/OsmAnd/res/values-eo/phrases.xml @@ -413,7 +413,7 @@ kartonoj gazetoj (revuoj) paperaj ujoj - elektronikaj aparatoj etaj + malgrandaj elektraj aparatoj ligno libroj ŝuoj @@ -3808,7 +3808,7 @@ Akv-nivelo: sub la mezuma nivelo de akvo Akv-nivelo: super la mezuma nivelo de akvo Baraĵo - Plenigi per trinkebla akvo: jes + jes Plenigi per trinkebla akvo: ne Plenigi per trinkebla akvo: reto senprema @@ -3826,4 +3826,15 @@ Dombloko Suburbo Sageto: ne + jes + Tabulo de forveturoj: ne + Lifto + malgrandaj elektraj aparatoj + Nuksa vendejo + Abelujo + neelektronika + realtempa + prokrasto + Tabulo de forveturoj + Plenigi per trinkebla akvo \ No newline at end of file From 3a60ccc91d0eb31c7dda64dd73fa5e5db8876903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Sun, 27 Sep 2020 11:38:08 +0000 Subject: [PATCH 0369/1366] Translated using Weblate (Icelandic) Currently translated at 99.9% (3822 of 3824 strings) --- OsmAnd/res/values-is/phrases.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-is/phrases.xml b/OsmAnd/res/values-is/phrases.xml index 123761efa7..2c6a85bdb4 100644 --- a/OsmAnd/res/values-is/phrases.xml +++ b/OsmAnd/res/values-is/phrases.xml @@ -3783,7 +3783,7 @@ Rangt Aðeins þegar má ganga Hindrun - Áfylling drykkjarvatns: já + Áfylling drykkjarvatns: nei Kerfi fyrir áfyllingu drykkjarvatns Mislitt @@ -3818,4 +3818,13 @@ Götureitur Kaupstaður Ör: nei + Verslun með þurrkaða ávexti + Býflugnabú + Tímatafla + Rauntíma + Töf + + Lyfta + Smærri raftæki + Áfylling drykkjarvatns \ No newline at end of file From e1086074c5d370adfe19241a6440ff7f3103ab08 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 28 Sep 2020 18:10:15 +0300 Subject: [PATCH 0370/1366] Fix #9902 --- OsmAnd/res/values/strings.xml | 1 + .../plus/dialogs/GpxAppearanceAdapter.java | 46 ++++++++++----- .../net/osmand/plus/helpers/GpxUiHelper.java | 16 +++-- .../plus/settings/backend/OsmandSettings.java | 2 + .../plus/track/ShowStartFinishCard.java | 59 +++++++++++++++++++ .../plus/track/TrackAppearanceFragment.java | 21 ++++++- .../osmand/plus/track/TrackColoringCard.java | 5 +- .../net/osmand/plus/track/TrackDrawInfo.java | 3 +- .../osmand/plus/views/layers/GPXLayer.java | 29 +++++---- 9 files changed, 145 insertions(+), 37 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 14e08c0176..086a7470d5 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Start/finish icons Name: A – Z Name: Z – A Last modified diff --git a/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java b/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java index 1a1e873b95..87af46891a 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java @@ -25,10 +25,13 @@ public class GpxAppearanceAdapter extends ArrayAdapter getAppearanceItems(OsmandApplication app, GpxAppearanceAdapterType adapterType) { + return getAppearanceItems(app, adapterType, false); + } + + public static List getAppearanceItems(OsmandApplication app, GpxAppearanceAdapterType adapterType, + boolean showStartFinishIcons) { List items = new ArrayList<>(); RenderingRuleProperty trackWidthProp = null; RenderingRuleProperty trackColorProp = null; @@ -118,11 +126,19 @@ public class GpxAppearanceAdapter extends ArrayAdapter 0) { for (Map.Entry entry : gpxAppearanceParams.entrySet()) { - final OsmandSettings.CommonPreference pref - = app.getSettings().getCustomRenderProperty(entry.getKey()); - pref.set(entry.getValue()); + if (SHOW_START_FINISH_ATTR.equals(entry.getKey())) { + app.getSettings().SHOW_START_FINISH_ICONS.set("true".equals(entry.getValue())); + } else { + final OsmandSettings.CommonPreference pref + = app.getSettings().getCustomRenderProperty(entry.getKey()); + pref.set(entry.getValue()); + } } if (activity instanceof MapActivity) { ConfigureMapMenu.refreshMapComplete((MapActivity) activity); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index e41c7d58df..efa7147e6c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -2214,6 +2214,8 @@ public class OsmandSettings { } }.makeProfile().cache(); + public final OsmandPreference SHOW_START_FINISH_ICONS = new BooleanPreference("show_start_finish_icons", true).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); // public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache(); public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); diff --git a/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java b/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java new file mode 100644 index 0000000000..3941bdbb15 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java @@ -0,0 +1,59 @@ +package net.osmand.plus.track; + +import android.view.View; +import android.widget.CompoundButton; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; + +class ShowStartFinishCard extends BaseCard { + + private TrackDrawInfo trackDrawInfo; + private OsmandPreference showStartFinishPreference; + + public ShowStartFinishCard(@NonNull MapActivity mapActivity, @NonNull TrackDrawInfo trackDrawInfo) { + super(mapActivity); + this.showStartFinishPreference = app.getSettings().SHOW_START_FINISH_ICONS; + this.trackDrawInfo = trackDrawInfo; + } + + @Override + public int getCardLayoutId() { + return R.layout.bottom_sheet_item_with_switch; + } + + @Override + protected void updateContent() { + AndroidUiHelper.updateVisibility(view.findViewById(R.id.icon), false); + + TextView titleView = view.findViewById(R.id.title); + titleView.setText(R.string.track_show_start_finish_icons); + + final CompoundButton compoundButton = view.findViewById(R.id.compound_button); + //compoundButton.setChecked(trackDrawInfo.isShowStartFinish()); + compoundButton.setChecked(showStartFinishPreference.get()); + + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean checked = !compoundButton.isChecked(); + compoundButton.setChecked(checked); + //trackDrawInfo.setShowStartFinish(checked); + showStartFinishPreference.set(checked); + mapActivity.refreshMap(); + + CardListener listener = getListener(); + if (listener != null) { + listener.onCardPressed(ShowStartFinishCard.this); + } + } + }); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 4381dd61f6..81a43da20f 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -62,9 +62,10 @@ import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM; public class TrackAppearanceFragment extends ContextMenuScrollFragment implements CardListener, ColorPickerListener { public static final String TAG = TrackAppearanceFragment.class.getName(); - private static final Log log = PlatformUtil.getLog(TrackAppearanceFragment.class); + private static final String SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY = "showStartFinishIconsInitialValueKey"; + private OsmandApplication app; @Nullable @@ -79,6 +80,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement private TrackWidthCard trackWidthCard; private SplitIntervalCard splitIntervalCard; private TrackColoringCard trackColoringCard; + private boolean showStartFinishIconsInitialValue; private ImageView trackIcon; private View buttonsShadow; @@ -134,9 +136,12 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement if (!selectedGpxFile.isShowCurrentTrack()) { gpxDataItem = app.getGpxDbHelper().getItem(new File(trackDrawInfo.getFilePath())); } + showStartFinishIconsInitialValue = savedInstanceState.getBoolean(SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY, + app.getSettings().SHOW_START_FINISH_ICONS.get()); } else if (arguments != null) { String gpxFilePath = arguments.getString(TRACK_FILE_NAME); boolean currentRecording = arguments.getBoolean(CURRENT_RECORDING, false); + showStartFinishIconsInitialValue = app.getSettings().SHOW_START_FINISH_ICONS.get(); if (gpxFilePath == null && !currentRecording) { log.error("Required extra '" + TRACK_FILE_NAME + "' is missing"); @@ -152,7 +157,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); } else { gpxDataItem = app.getGpxDbHelper().getItem(new File(gpxFilePath)); - trackDrawInfo = new TrackDrawInfo(gpxDataItem, false); + trackDrawInfo = new TrackDrawInfo(app, gpxDataItem, false); selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath); } updateTrackColor(); @@ -294,6 +299,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); trackDrawInfo.saveToBundle(outState); + outState.putBoolean(SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY, showStartFinishIconsInitialValue); } @Override @@ -455,6 +461,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement @Override public void onClick(View v) { discardSplitChanges(); + discardShowStartFinishChanges(); FragmentActivity activity = getActivity(); if (activity != null) { activity.onBackPressed(); @@ -520,7 +527,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement gpxFile.setSplitInterval(trackDrawInfo.getSplitInterval()); gpxFile.setShowArrows(trackDrawInfo.isShowArrows()); - gpxFile.setShowStartFinish(trackDrawInfo.isShowStartFinish()); + //gpxFile.setShowStartFinish(trackDrawInfo.isShowStartFinish()); if (gpxFile.showCurrentTrack) { app.getSettings().CURRENT_TRACK_COLOR.set(trackDrawInfo.getColor()); @@ -551,6 +558,10 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } } + private void discardShowStartFinishChanges() { + app.getSettings().SHOW_START_FINISH_ICONS.set(showStartFinishIconsInitialValue); + } + void applySplit(GpxSplitType splitType, int timeSplit, double distanceSplit) { if (splitIntervalCard != null) { splitIntervalCard.updateContent(); @@ -599,6 +610,10 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement directionArrowsCard.setListener(this); cardsContainer.addView(directionArrowsCard.build(mapActivity)); + ShowStartFinishCard showStartFinishCard = new ShowStartFinishCard(mapActivity, trackDrawInfo); + showStartFinishCard.setListener(this); + cardsContainer.addView(showStartFinishCard.build(mapActivity)); + trackColoringCard = new TrackColoringCard(mapActivity, trackDrawInfo, this); trackColoringCard.setListener(this); cardsContainer.addView(trackColoringCard.build(mapActivity)); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index e8ab755507..99571dad6c 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -29,6 +29,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType; import net.osmand.plus.helpers.AndroidUiHelper; @@ -41,8 +42,6 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; -import static net.osmand.plus.dialogs.GpxAppearanceAdapter.getAppearanceItems; - public class TrackColoringCard extends BaseCard implements ColorPickerListener { private static final int MINIMUM_CONTRAST_RATIO = 3; @@ -131,7 +130,7 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { selectColor.addView(createDividerView(selectColor)); List colors = new ArrayList<>(); - for (AppearanceListItem appearanceListItem : getAppearanceItems(app, GpxAppearanceAdapterType.TRACK_COLOR)) { + for (AppearanceListItem appearanceListItem : GpxAppearanceAdapter.getAppearanceItems(app, GpxAppearanceAdapterType.TRACK_COLOR)) { if (!colors.contains(appearanceListItem.getColor())) { colors.add(appearanceListItem.getColor()); } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java index 3dbacb7b56..18d1c30775 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java @@ -5,6 +5,7 @@ import android.os.Bundle; import androidx.annotation.NonNull; import net.osmand.plus.GPXDatabase.GpxDataItem; +import net.osmand.plus.OsmandApplication; import net.osmand.util.Algorithms; import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING; @@ -40,7 +41,7 @@ public class TrackDrawInfo { readBundle(bundle); } - public TrackDrawInfo(GpxDataItem gpxDataItem, boolean currentRecording) { + public TrackDrawInfo(@NonNull OsmandApplication app, @NonNull GpxDataItem gpxDataItem, boolean currentRecording) { filePath = gpxDataItem.getFile().getPath(); width = gpxDataItem.getWidth(); gradientScaleType = gpxDataItem.getGradientScaleType(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 3bb49859be..641944ce21 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -453,7 +453,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM if (segment.points.size() >= 2) { WptPt start = segment.points.get(0); WptPt end = segment.points.get(segment.points.size() - 1); - drawStartEndPoints(canvas, tileBox, start, end); + drawStartEndPoints(canvas, tileBox, start, selectedGpxFile.isShowCurrentTrack() ? null : end); } } } @@ -461,24 +461,28 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } } - private void drawStartEndPoints(Canvas canvas, RotatedTileBox tileBox, WptPt start, WptPt end) { - int startX = (int) tileBox.getPixXFromLatLon(start.lat, start.lon); - int startY = (int) tileBox.getPixYFromLatLon(start.lat, start.lon); - int endX = (int) tileBox.getPixXFromLatLon(end.lat, end.lon); - int endY = (int) tileBox.getPixYFromLatLon(end.lat, end.lon); + private void drawStartEndPoints(@NonNull Canvas canvas, @NonNull RotatedTileBox tileBox, @Nullable WptPt start, @Nullable WptPt end) { + int startX = start != null ? (int) tileBox.getPixXFromLatLon(start.lat, start.lon) : 0; + int startY = start != null ? (int) tileBox.getPixYFromLatLon(start.lat, start.lon) : 0; + int endX = end != null ? (int) tileBox.getPixXFromLatLon(end.lat, end.lon) : 0; + int endY = end != null ? (int) tileBox.getPixYFromLatLon(end.lat, end.lon) : 0; int iconSize = AndroidUtils.dpToPx(view.getContext(), 14); QuadRect startRectWithoutShadow = calculateRect(startX, startY, iconSize, iconSize); QuadRect endRectWithoutShadow = calculateRect(endX, endY, iconSize, iconSize); - if (QuadRect.intersects(startRectWithoutShadow, endRectWithoutShadow)) { + if (start != null && end != null && QuadRect.intersects(startRectWithoutShadow, endRectWithoutShadow)) { QuadRect startAndFinishRect = calculateRect(startX, startY, startAndFinishIcon.getIntrinsicWidth(), startAndFinishIcon.getIntrinsicHeight()); drawPoint(canvas, startAndFinishRect, startAndFinishIcon); } else { - QuadRect startRect = calculateRect(startX, startY, startPointIcon.getIntrinsicWidth(), startPointIcon.getIntrinsicHeight()); - QuadRect endRect = calculateRect(endX, endY, finishPointIcon.getIntrinsicWidth(), finishPointIcon.getIntrinsicHeight()); - drawPoint(canvas, startRect, startPointIcon); - drawPoint(canvas, endRect, finishPointIcon); + if (start != null) { + QuadRect startRect = calculateRect(startX, startY, startPointIcon.getIntrinsicWidth(), startPointIcon.getIntrinsicHeight()); + drawPoint(canvas, startRect, startPointIcon); + } + if (end != null) { + QuadRect endRect = calculateRect(endX, endY, finishPointIcon.getIntrinsicWidth(), finishPointIcon.getIntrinsicHeight()); + drawPoint(canvas, endRect, finishPointIcon); + } } } @@ -711,6 +715,8 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } private boolean isShowStartFinishForTrack(GPXFile gpxFile) { + return view.getApplication().getSettings().SHOW_START_FINISH_ICONS.get(); + /* if (hasTrackDrawInfoForTrack(gpxFile)) { return trackDrawInfo.isShowStartFinish(); } else if (gpxFile.showCurrentTrack) { @@ -718,6 +724,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } else { return gpxFile.isShowStartFinish(); } + */ } private boolean hasTrackDrawInfoForTrack(GPXFile gpxFile) { From d2e9632862fbfe13ef6d7604147465ced0a480d0 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 28 Sep 2020 18:10:15 +0300 Subject: [PATCH 0371/1366] Fix #9902 --- OsmAnd/res/values/strings.xml | 1 + .../plus/dialogs/GpxAppearanceAdapter.java | 46 ++++++++++----- .../net/osmand/plus/helpers/GpxUiHelper.java | 16 +++-- .../plus/settings/backend/OsmandSettings.java | 2 + .../plus/track/ShowStartFinishCard.java | 59 +++++++++++++++++++ .../plus/track/TrackAppearanceFragment.java | 21 ++++++- .../osmand/plus/track/TrackColoringCard.java | 5 +- .../net/osmand/plus/track/TrackDrawInfo.java | 3 +- .../osmand/plus/views/layers/GPXLayer.java | 29 +++++---- 9 files changed, 145 insertions(+), 37 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 14e08c0176..086a7470d5 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Start/finish icons Name: A – Z Name: Z – A Last modified diff --git a/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java b/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java index 1a1e873b95..87af46891a 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/GpxAppearanceAdapter.java @@ -25,10 +25,13 @@ public class GpxAppearanceAdapter extends ArrayAdapter getAppearanceItems(OsmandApplication app, GpxAppearanceAdapterType adapterType) { + return getAppearanceItems(app, adapterType, false); + } + + public static List getAppearanceItems(OsmandApplication app, GpxAppearanceAdapterType adapterType, + boolean showStartFinishIcons) { List items = new ArrayList<>(); RenderingRuleProperty trackWidthProp = null; RenderingRuleProperty trackColorProp = null; @@ -118,11 +126,19 @@ public class GpxAppearanceAdapter extends ArrayAdapter 0) { for (Map.Entry entry : gpxAppearanceParams.entrySet()) { - final OsmandSettings.CommonPreference pref - = app.getSettings().getCustomRenderProperty(entry.getKey()); - pref.set(entry.getValue()); + if (SHOW_START_FINISH_ATTR.equals(entry.getKey())) { + app.getSettings().SHOW_START_FINISH_ICONS.set("true".equals(entry.getValue())); + } else { + final OsmandSettings.CommonPreference pref + = app.getSettings().getCustomRenderProperty(entry.getKey()); + pref.set(entry.getValue()); + } } if (activity instanceof MapActivity) { ConfigureMapMenu.refreshMapComplete((MapActivity) activity); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index e41c7d58df..efa7147e6c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -2214,6 +2214,8 @@ public class OsmandSettings { } }.makeProfile().cache(); + public final OsmandPreference SHOW_START_FINISH_ICONS = new BooleanPreference("show_start_finish_icons", true).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); // public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache(); public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); diff --git a/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java b/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java new file mode 100644 index 0000000000..3941bdbb15 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java @@ -0,0 +1,59 @@ +package net.osmand.plus.track; + +import android.view.View; +import android.widget.CompoundButton; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; + +class ShowStartFinishCard extends BaseCard { + + private TrackDrawInfo trackDrawInfo; + private OsmandPreference showStartFinishPreference; + + public ShowStartFinishCard(@NonNull MapActivity mapActivity, @NonNull TrackDrawInfo trackDrawInfo) { + super(mapActivity); + this.showStartFinishPreference = app.getSettings().SHOW_START_FINISH_ICONS; + this.trackDrawInfo = trackDrawInfo; + } + + @Override + public int getCardLayoutId() { + return R.layout.bottom_sheet_item_with_switch; + } + + @Override + protected void updateContent() { + AndroidUiHelper.updateVisibility(view.findViewById(R.id.icon), false); + + TextView titleView = view.findViewById(R.id.title); + titleView.setText(R.string.track_show_start_finish_icons); + + final CompoundButton compoundButton = view.findViewById(R.id.compound_button); + //compoundButton.setChecked(trackDrawInfo.isShowStartFinish()); + compoundButton.setChecked(showStartFinishPreference.get()); + + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean checked = !compoundButton.isChecked(); + compoundButton.setChecked(checked); + //trackDrawInfo.setShowStartFinish(checked); + showStartFinishPreference.set(checked); + mapActivity.refreshMap(); + + CardListener listener = getListener(); + if (listener != null) { + listener.onCardPressed(ShowStartFinishCard.this); + } + } + }); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 4381dd61f6..81a43da20f 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -62,9 +62,10 @@ import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM; public class TrackAppearanceFragment extends ContextMenuScrollFragment implements CardListener, ColorPickerListener { public static final String TAG = TrackAppearanceFragment.class.getName(); - private static final Log log = PlatformUtil.getLog(TrackAppearanceFragment.class); + private static final String SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY = "showStartFinishIconsInitialValueKey"; + private OsmandApplication app; @Nullable @@ -79,6 +80,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement private TrackWidthCard trackWidthCard; private SplitIntervalCard splitIntervalCard; private TrackColoringCard trackColoringCard; + private boolean showStartFinishIconsInitialValue; private ImageView trackIcon; private View buttonsShadow; @@ -134,9 +136,12 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement if (!selectedGpxFile.isShowCurrentTrack()) { gpxDataItem = app.getGpxDbHelper().getItem(new File(trackDrawInfo.getFilePath())); } + showStartFinishIconsInitialValue = savedInstanceState.getBoolean(SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY, + app.getSettings().SHOW_START_FINISH_ICONS.get()); } else if (arguments != null) { String gpxFilePath = arguments.getString(TRACK_FILE_NAME); boolean currentRecording = arguments.getBoolean(CURRENT_RECORDING, false); + showStartFinishIconsInitialValue = app.getSettings().SHOW_START_FINISH_ICONS.get(); if (gpxFilePath == null && !currentRecording) { log.error("Required extra '" + TRACK_FILE_NAME + "' is missing"); @@ -152,7 +157,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); } else { gpxDataItem = app.getGpxDbHelper().getItem(new File(gpxFilePath)); - trackDrawInfo = new TrackDrawInfo(gpxDataItem, false); + trackDrawInfo = new TrackDrawInfo(app, gpxDataItem, false); selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath); } updateTrackColor(); @@ -294,6 +299,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); trackDrawInfo.saveToBundle(outState); + outState.putBoolean(SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY, showStartFinishIconsInitialValue); } @Override @@ -455,6 +461,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement @Override public void onClick(View v) { discardSplitChanges(); + discardShowStartFinishChanges(); FragmentActivity activity = getActivity(); if (activity != null) { activity.onBackPressed(); @@ -520,7 +527,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement gpxFile.setSplitInterval(trackDrawInfo.getSplitInterval()); gpxFile.setShowArrows(trackDrawInfo.isShowArrows()); - gpxFile.setShowStartFinish(trackDrawInfo.isShowStartFinish()); + //gpxFile.setShowStartFinish(trackDrawInfo.isShowStartFinish()); if (gpxFile.showCurrentTrack) { app.getSettings().CURRENT_TRACK_COLOR.set(trackDrawInfo.getColor()); @@ -551,6 +558,10 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } } + private void discardShowStartFinishChanges() { + app.getSettings().SHOW_START_FINISH_ICONS.set(showStartFinishIconsInitialValue); + } + void applySplit(GpxSplitType splitType, int timeSplit, double distanceSplit) { if (splitIntervalCard != null) { splitIntervalCard.updateContent(); @@ -599,6 +610,10 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement directionArrowsCard.setListener(this); cardsContainer.addView(directionArrowsCard.build(mapActivity)); + ShowStartFinishCard showStartFinishCard = new ShowStartFinishCard(mapActivity, trackDrawInfo); + showStartFinishCard.setListener(this); + cardsContainer.addView(showStartFinishCard.build(mapActivity)); + trackColoringCard = new TrackColoringCard(mapActivity, trackDrawInfo, this); trackColoringCard.setListener(this); cardsContainer.addView(trackColoringCard.build(mapActivity)); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index e8ab755507..99571dad6c 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -29,6 +29,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType; import net.osmand.plus.helpers.AndroidUiHelper; @@ -41,8 +42,6 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; -import static net.osmand.plus.dialogs.GpxAppearanceAdapter.getAppearanceItems; - public class TrackColoringCard extends BaseCard implements ColorPickerListener { private static final int MINIMUM_CONTRAST_RATIO = 3; @@ -131,7 +130,7 @@ public class TrackColoringCard extends BaseCard implements ColorPickerListener { selectColor.addView(createDividerView(selectColor)); List colors = new ArrayList<>(); - for (AppearanceListItem appearanceListItem : getAppearanceItems(app, GpxAppearanceAdapterType.TRACK_COLOR)) { + for (AppearanceListItem appearanceListItem : GpxAppearanceAdapter.getAppearanceItems(app, GpxAppearanceAdapterType.TRACK_COLOR)) { if (!colors.contains(appearanceListItem.getColor())) { colors.add(appearanceListItem.getColor()); } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java index 3dbacb7b56..18d1c30775 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java @@ -5,6 +5,7 @@ import android.os.Bundle; import androidx.annotation.NonNull; import net.osmand.plus.GPXDatabase.GpxDataItem; +import net.osmand.plus.OsmandApplication; import net.osmand.util.Algorithms; import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING; @@ -40,7 +41,7 @@ public class TrackDrawInfo { readBundle(bundle); } - public TrackDrawInfo(GpxDataItem gpxDataItem, boolean currentRecording) { + public TrackDrawInfo(@NonNull OsmandApplication app, @NonNull GpxDataItem gpxDataItem, boolean currentRecording) { filePath = gpxDataItem.getFile().getPath(); width = gpxDataItem.getWidth(); gradientScaleType = gpxDataItem.getGradientScaleType(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 3bb49859be..641944ce21 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -453,7 +453,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM if (segment.points.size() >= 2) { WptPt start = segment.points.get(0); WptPt end = segment.points.get(segment.points.size() - 1); - drawStartEndPoints(canvas, tileBox, start, end); + drawStartEndPoints(canvas, tileBox, start, selectedGpxFile.isShowCurrentTrack() ? null : end); } } } @@ -461,24 +461,28 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } } - private void drawStartEndPoints(Canvas canvas, RotatedTileBox tileBox, WptPt start, WptPt end) { - int startX = (int) tileBox.getPixXFromLatLon(start.lat, start.lon); - int startY = (int) tileBox.getPixYFromLatLon(start.lat, start.lon); - int endX = (int) tileBox.getPixXFromLatLon(end.lat, end.lon); - int endY = (int) tileBox.getPixYFromLatLon(end.lat, end.lon); + private void drawStartEndPoints(@NonNull Canvas canvas, @NonNull RotatedTileBox tileBox, @Nullable WptPt start, @Nullable WptPt end) { + int startX = start != null ? (int) tileBox.getPixXFromLatLon(start.lat, start.lon) : 0; + int startY = start != null ? (int) tileBox.getPixYFromLatLon(start.lat, start.lon) : 0; + int endX = end != null ? (int) tileBox.getPixXFromLatLon(end.lat, end.lon) : 0; + int endY = end != null ? (int) tileBox.getPixYFromLatLon(end.lat, end.lon) : 0; int iconSize = AndroidUtils.dpToPx(view.getContext(), 14); QuadRect startRectWithoutShadow = calculateRect(startX, startY, iconSize, iconSize); QuadRect endRectWithoutShadow = calculateRect(endX, endY, iconSize, iconSize); - if (QuadRect.intersects(startRectWithoutShadow, endRectWithoutShadow)) { + if (start != null && end != null && QuadRect.intersects(startRectWithoutShadow, endRectWithoutShadow)) { QuadRect startAndFinishRect = calculateRect(startX, startY, startAndFinishIcon.getIntrinsicWidth(), startAndFinishIcon.getIntrinsicHeight()); drawPoint(canvas, startAndFinishRect, startAndFinishIcon); } else { - QuadRect startRect = calculateRect(startX, startY, startPointIcon.getIntrinsicWidth(), startPointIcon.getIntrinsicHeight()); - QuadRect endRect = calculateRect(endX, endY, finishPointIcon.getIntrinsicWidth(), finishPointIcon.getIntrinsicHeight()); - drawPoint(canvas, startRect, startPointIcon); - drawPoint(canvas, endRect, finishPointIcon); + if (start != null) { + QuadRect startRect = calculateRect(startX, startY, startPointIcon.getIntrinsicWidth(), startPointIcon.getIntrinsicHeight()); + drawPoint(canvas, startRect, startPointIcon); + } + if (end != null) { + QuadRect endRect = calculateRect(endX, endY, finishPointIcon.getIntrinsicWidth(), finishPointIcon.getIntrinsicHeight()); + drawPoint(canvas, endRect, finishPointIcon); + } } } @@ -711,6 +715,8 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } private boolean isShowStartFinishForTrack(GPXFile gpxFile) { + return view.getApplication().getSettings().SHOW_START_FINISH_ICONS.get(); + /* if (hasTrackDrawInfoForTrack(gpxFile)) { return trackDrawInfo.isShowStartFinish(); } else if (gpxFile.showCurrentTrack) { @@ -718,6 +724,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } else { return gpxFile.isShowStartFinish(); } + */ } private boolean hasTrackDrawInfoForTrack(GPXFile gpxFile) { From 7d7112a5710afc26e3d6a9d0cb6a214651cd7bf4 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 28 Sep 2020 18:58:26 +0300 Subject: [PATCH 0372/1366] Fix sorting track --- .../plus/myplaces/AvailableGPXFragment.java | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 9596bafb89..57bdb13a18 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -45,6 +45,7 @@ import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; +import net.osmand.Collator; import net.osmand.FileUtils; import net.osmand.FileUtils.RenameCallback; import net.osmand.GPXUtilities; @@ -53,6 +54,7 @@ import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.WptPt; import net.osmand.IndexConstants; +import net.osmand.OsmAndCollator; import net.osmand.data.PointDescription; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter.ItemClickListener; @@ -85,7 +87,6 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.TracksSortByMode; import java.io.File; -import java.text.Collator; import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -165,8 +166,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement super.onAttach(activity); this.app = (OsmandApplication) getActivity().getApplication(); sortByMode = app.getSettings().TRACKS_SORT_BY_MODE.get(); - final Collator collator = Collator.getInstance(); - collator.setStrength(Collator.SECONDARY); currentRecording = new GpxInfo(app.getSavingTrackHelper().getCurrentGpx(), getString(R.string.shared_string_currently_recording_track)); currentRecording.currentlyRecordingTrack = true; asyncLoader = new LoadGpxTask(); @@ -607,6 +606,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement this.sortByMode = sortByMode; app.getSettings().TRACKS_SORT_BY_MODE.set(sortByMode); reloadTracks(); +// allGpxAdapter.sort(); } private void openCoordinatesInput() { @@ -950,26 +950,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement for (GpxInfo v : values) { allGpxAdapter.addLocalIndexInfo(v); } - // disable sort - // allGpxAdapter.sort(); allGpxAdapter.notifyDataSetChanged(); } - public void setResult(List result) { - this.result = result; - allGpxAdapter.clear(); - if (result != null) { - for (GpxInfo v : result) { - allGpxAdapter.addLocalIndexInfo(v); - } - // disable sort - // allGpxAdapter.sort(); - allGpxAdapter.refreshSelected(); - allGpxAdapter.notifyDataSetChanged(); - onPostExecute(result); - } - } - @Override protected void onPostExecute(List result) { this.result = result; @@ -989,17 +972,18 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } // This file could be sorted in different way for folders // now folders are also sorted by last modified date + final Collator collator = OsmAndCollator.primaryCollator(); Arrays.sort(listFiles, new Comparator() { @Override public int compare(File f1, File f2) { if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { - return f1.getName().compareTo(f2.getName()); + return collator.compare(f1.getName(), (f2.getName())); } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { - return -f1.getName().compareTo(f2.getName()); + return -collator.compare(f1.getName(), (f2.getName())); } else { // here we could guess date from file name '2017-08-30 ...' - first part date if (f1.lastModified() == f2.lastModified()) { - return -f1.getName().compareTo(f2.getName()); + return -collator.compare(f1.getName(), (f2.getName())); } return -((f1.lastModified() < f2.lastModified()) ? -1 : ((f1.lastModified() == f2.lastModified()) ? 0 : 1)); } @@ -1096,21 +1080,22 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement public void refreshSelected() { selected.clear(); selected.addAll(getSelectedGpx()); + final Collator collator = OsmAndCollator.primaryCollator(); Collections.sort(selected, new Comparator() { @Override public int compare(GpxInfo i1, GpxInfo i2) { if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { - return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return collator.compare(i1.getName(), i2.getName()); } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { - return -i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return -collator.compare(i1.getName(), i2.getName()); } else { if (i1.file == null || i2.file == null) { - return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return collator.compare(i1.getName(), i2.getName()); } long time1 = i1.file.lastModified(); long time2 = i2.file.lastModified(); if (time1 == time2) { - return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return collator.compare(i1.getName(), i2.getName()); } return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1)); } @@ -1175,15 +1160,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement data.get(category.get(found)).add(info); } - public void sort() { - Collections.sort(category, new Comparator() { - @Override - public int compare(String lhs, String rhs) { - return lhs.toLowerCase().compareTo(rhs.toLowerCase()); - } - }); - } - @Override public GpxInfo getChild(int groupPosition, int childPosition) { if (isSelectedGroup(groupPosition)) { From 0870e89011adf9dde9c772100effe09b2d7b78de Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 28 Sep 2020 19:01:18 +0300 Subject: [PATCH 0373/1366] Fix sorting track --- OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 57bdb13a18..fae190ea01 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -606,7 +606,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement this.sortByMode = sortByMode; app.getSettings().TRACKS_SORT_BY_MODE.set(sortByMode); reloadTracks(); -// allGpxAdapter.sort(); } private void openCoordinatesInput() { From 9dcadead063c6751e061a5d11f10506675106bfc Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 28 Sep 2020 18:58:26 +0300 Subject: [PATCH 0374/1366] Fix sorting track (cherry picked from commit 7d7112a5710afc26e3d6a9d0cb6a214651cd7bf4) --- .../plus/myplaces/AvailableGPXFragment.java | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 9596bafb89..57bdb13a18 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -45,6 +45,7 @@ import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; +import net.osmand.Collator; import net.osmand.FileUtils; import net.osmand.FileUtils.RenameCallback; import net.osmand.GPXUtilities; @@ -53,6 +54,7 @@ import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.WptPt; import net.osmand.IndexConstants; +import net.osmand.OsmAndCollator; import net.osmand.data.PointDescription; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter.ItemClickListener; @@ -85,7 +87,6 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.TracksSortByMode; import java.io.File; -import java.text.Collator; import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -165,8 +166,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement super.onAttach(activity); this.app = (OsmandApplication) getActivity().getApplication(); sortByMode = app.getSettings().TRACKS_SORT_BY_MODE.get(); - final Collator collator = Collator.getInstance(); - collator.setStrength(Collator.SECONDARY); currentRecording = new GpxInfo(app.getSavingTrackHelper().getCurrentGpx(), getString(R.string.shared_string_currently_recording_track)); currentRecording.currentlyRecordingTrack = true; asyncLoader = new LoadGpxTask(); @@ -607,6 +606,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement this.sortByMode = sortByMode; app.getSettings().TRACKS_SORT_BY_MODE.set(sortByMode); reloadTracks(); +// allGpxAdapter.sort(); } private void openCoordinatesInput() { @@ -950,26 +950,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement for (GpxInfo v : values) { allGpxAdapter.addLocalIndexInfo(v); } - // disable sort - // allGpxAdapter.sort(); allGpxAdapter.notifyDataSetChanged(); } - public void setResult(List result) { - this.result = result; - allGpxAdapter.clear(); - if (result != null) { - for (GpxInfo v : result) { - allGpxAdapter.addLocalIndexInfo(v); - } - // disable sort - // allGpxAdapter.sort(); - allGpxAdapter.refreshSelected(); - allGpxAdapter.notifyDataSetChanged(); - onPostExecute(result); - } - } - @Override protected void onPostExecute(List result) { this.result = result; @@ -989,17 +972,18 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } // This file could be sorted in different way for folders // now folders are also sorted by last modified date + final Collator collator = OsmAndCollator.primaryCollator(); Arrays.sort(listFiles, new Comparator() { @Override public int compare(File f1, File f2) { if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { - return f1.getName().compareTo(f2.getName()); + return collator.compare(f1.getName(), (f2.getName())); } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { - return -f1.getName().compareTo(f2.getName()); + return -collator.compare(f1.getName(), (f2.getName())); } else { // here we could guess date from file name '2017-08-30 ...' - first part date if (f1.lastModified() == f2.lastModified()) { - return -f1.getName().compareTo(f2.getName()); + return -collator.compare(f1.getName(), (f2.getName())); } return -((f1.lastModified() < f2.lastModified()) ? -1 : ((f1.lastModified() == f2.lastModified()) ? 0 : 1)); } @@ -1096,21 +1080,22 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement public void refreshSelected() { selected.clear(); selected.addAll(getSelectedGpx()); + final Collator collator = OsmAndCollator.primaryCollator(); Collections.sort(selected, new Comparator() { @Override public int compare(GpxInfo i1, GpxInfo i2) { if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { - return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return collator.compare(i1.getName(), i2.getName()); } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { - return -i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return -collator.compare(i1.getName(), i2.getName()); } else { if (i1.file == null || i2.file == null) { - return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return collator.compare(i1.getName(), i2.getName()); } long time1 = i1.file.lastModified(); long time2 = i2.file.lastModified(); if (time1 == time2) { - return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase()); + return collator.compare(i1.getName(), i2.getName()); } return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1)); } @@ -1175,15 +1160,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement data.get(category.get(found)).add(info); } - public void sort() { - Collections.sort(category, new Comparator() { - @Override - public int compare(String lhs, String rhs) { - return lhs.toLowerCase().compareTo(rhs.toLowerCase()); - } - }); - } - @Override public GpxInfo getChild(int groupPosition, int childPosition) { if (isSelectedGroup(groupPosition)) { From d65cde6db176aa4fa12aa2790cea5386f6a852db Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 28 Sep 2020 19:01:18 +0300 Subject: [PATCH 0375/1366] Fix sorting track (cherry picked from commit 0870e89011adf9dde9c772100effe09b2d7b78de) --- OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 57bdb13a18..fae190ea01 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -606,7 +606,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement this.sortByMode = sortByMode; app.getSettings().TRACKS_SORT_BY_MODE.set(sortByMode); reloadTracks(); -// allGpxAdapter.sort(); } private void openCoordinatesInput() { From 20a770fe82f32a1e846d9dd7d7cf5f1bae3b08db Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 29 Sep 2020 12:14:18 +0300 Subject: [PATCH 0376/1366] Fix plan route sorting track --- .../SelectFileBottomSheet.java | 141 ++++++++++++------ 1 file changed, 92 insertions(+), 49 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index 31502bea57..24d3ec8282 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -14,7 +14,9 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; +import net.osmand.Collator; import net.osmand.IndexConstants; +import net.osmand.OsmAndCollator; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -41,6 +43,10 @@ import static net.osmand.util.Algorithms.collectDirs; public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { + private List folders; + private HorizontalSelectionAdapter folderAdapter; + private GPXInfo currentlyRecording; + enum Mode { OPEN_TRACK(R.string.shared_string_gpx_tracks, R.string.sort_by), ADD_TO_TRACK(R.string.add_to_a_track, R.string.route_between_points_add_track_desc); @@ -98,55 +104,52 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { if (fragmentMode == Mode.OPEN_TRACK) { titleView.setText(AndroidUtils.addColon(app, fragmentMode.title)); updateDescription(descriptionView); - final ImageButton sortButton = mainView.findViewById(R.id.sort_button); - Drawable background = app.getUIUtilities().getIcon(R.drawable.bg_dash_line_dark, - nightMode - ? R.color.inactive_buttons_and_links_bg_dark - : R.color.inactive_buttons_and_links_bg_light); - AndroidUtils.setBackground(sortButton, background); - sortButton.setImageResource(sortByMode.getIconId()); - sortButton.setVisibility(View.VISIBLE); - sortButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final List items = new ArrayList<>(); - for (final TracksSortByMode mode : TracksSortByMode.values()) { - items.add(new SimplePopUpMenuItem( - getString(mode.getNameId()), - app.getUIUtilities().getThemedIcon(mode.getIconId()), - new View.OnClickListener() { - @Override - public void onClick(View v) { - sortByMode = mode; - sortButton.setImageResource(mode.getIconId()); - updateDescription(descriptionView); - sortFileList(); - adapter.notifyDataSetChanged(); - } - }, sortByMode == mode - )); - } - UiUtilities.showPopUpMenu(v, items); - } - }); } + final ImageButton sortButton = mainView.findViewById(R.id.sort_button); + Drawable background = app.getUIUtilities().getIcon(R.drawable.bg_dash_line_dark, + nightMode + ? R.color.inactive_buttons_and_links_bg_dark + : R.color.inactive_buttons_and_links_bg_light); + AndroidUtils.setBackground(sortButton, background); + sortButton.setImageResource(sortByMode.getIconId()); + sortButton.setVisibility(View.VISIBLE); + sortButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final List items = new ArrayList<>(); + for (final TracksSortByMode mode : TracksSortByMode.values()) { + items.add(new SimplePopUpMenuItem( + getString(mode.getNameId()), + app.getUIUtilities().getThemedIcon(mode.getIconId()), + new View.OnClickListener() { + @Override + public void onClick(View v) { + sortByMode = mode; + sortButton.setImageResource(mode.getIconId()); + updateDescription(descriptionView); + sortFolderList(); + folderAdapter.setItems(getFolderNames()); + folderAdapter.notifyDataSetChanged(); + sortFileList(); + adapter.notifyDataSetChanged(); + } + }, sortByMode == mode + )); + } + UiUtilities.showPopUpMenu(v, items); + } + }); - List dirs = new ArrayList<>(); final File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); - collectDirs(gpxDir, dirs); - List dirItems = new ArrayList<>(); + allFilesFolder = context.getString(R.string.shared_string_all); if (savedInstanceState == null) { selectedFolder = allFilesFolder; } - dirItems.add(allFilesFolder); - for (File dir : dirs) { - dirItems.add(dir.getName()); - } - final List allGpxList = getSortedGPXFilesInfo(gpxDir, null, false); + currentlyRecording = new GPXInfo(getString(R.string.shared_string_currently_recording_track), 0, 0); if (isShowCurrentGpx()) { - allGpxList.add(0, new GPXInfo(getString(R.string.shared_string_currently_recording_track), 0, 0)); + allGpxList.add(0, currentlyRecording); } gpxInfoMap = new HashMap<>(); gpxInfoMap.put(allFilesFolder, allGpxList); @@ -184,8 +187,11 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { final RecyclerView foldersRecyclerView = mainView.findViewById(R.id.folder_list); foldersRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)); - final HorizontalSelectionAdapter folderAdapter = new HorizontalSelectionAdapter(app, nightMode); - folderAdapter.setItems(dirItems); + folderAdapter = new HorizontalSelectionAdapter(app, nightMode); + folders = new ArrayList<>(); + collectDirs(gpxDir, folders); + sortFolderList(); + folderAdapter.setItems(getFolderNames()); folderAdapter.setSelectedItem(selectedFolder); foldersRecyclerView.setAdapter(folderAdapter); folderAdapter.setListener(new HorizontalSelectionAdapterListener() { @@ -199,11 +205,22 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { updateFileList(folderAdapter); } + private List getFolderNames() { + List folderNames = new ArrayList<>(); + folderNames.add(allFilesFolder); + for (File folder : folders) { + folderNames.add(folder.getName()); + } + return folderNames; + } + private void updateDescription(TextView descriptionView) { - String string = getString(sortByMode.getNameId()); - descriptionView.setText(String.format(getString(R.string.ltr_or_rtl_combine_via_space), - getString(fragmentMode.description), - Character.toLowerCase(string.charAt(0)) + string.substring(1))); + if (fragmentMode == Mode.OPEN_TRACK) { + String string = getString(sortByMode.getNameId()); + descriptionView.setText(String.format(getString(R.string.ltr_or_rtl_combine_via_space), + getString(fragmentMode.description), + Character.toLowerCase(string.charAt(0)) + string.substring(1))); + } } private void updateFileList(HorizontalSelectionAdapter folderAdapter) { @@ -213,6 +230,27 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { folderAdapter.notifyDataSetChanged(); } + private void sortFolderList() { + final Collator collator = OsmAndCollator.primaryCollator(); + Collections.sort(folders, new Comparator() { + @Override + public int compare(File i1, File i2) { + if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { + return collator.compare(i1.getName(), i2.getName()); + } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { + return -collator.compare(i1.getName(), i2.getName()); + } else { + long time1 = i1.lastModified(); + long time2 = i2.lastModified(); + if (time1 == time2) { + return collator.compare(i1.getName(), i2.getName()); + } + return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1)); + } + } + }); + } + private void sortFileList() { List gpxInfoList = gpxInfoMap.get(selectedFolder); if (gpxInfoList != null) { @@ -222,23 +260,28 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { } public void sortSelected(List gpxInfoList) { + boolean hasRecording = gpxInfoList.remove(currentlyRecording); + final Collator collator = OsmAndCollator.primaryCollator(); Collections.sort(gpxInfoList, new Comparator() { @Override public int compare(GPXInfo i1, GPXInfo i2) { if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) { - return i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase()); + return collator.compare(i1.getFileName(), i2.getFileName()); } else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) { - return -i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase()); + return -collator.compare(i1.getFileName(), i2.getFileName()); } else { long time1 = i1.getLastModified(); long time2 = i2.getLastModified(); if (time1 == time2) { - return i1.getFileName().toLowerCase().compareTo(i2.getFileName().toLowerCase()); + return collator.compare(i1.getFileName(), i2.getFileName()); } return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1)); } } }); + if (hasRecording) { + gpxInfoList.add(0, currentlyRecording); + } } private boolean showFoldersName() { From 47f2b9a380172f5e287a36aae200a3e6ed3ff477 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Wed, 30 Sep 2020 11:42:05 +0300 Subject: [PATCH 0377/1366] Drop config files --- .gitignore | 4 ++++ OsmAnd/.gitignore | 1 - OsmAndHms.jks | Bin 2243 -> 0 bytes agconnect-services.json | 1 - 4 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 OsmAndHms.jks delete mode 100644 agconnect-services.json diff --git a/.gitignore b/.gitignore index 5798e73f27..33e746a3d6 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,10 @@ OsmAndCore_*.aar .project out/ +# Huawei +agconnect-services.json +OsmAndHms.jks + # Android Studio /.idea *.iml diff --git a/OsmAnd/.gitignore b/OsmAnd/.gitignore index e1887fffff..e3071e5fbf 100644 --- a/OsmAnd/.gitignore +++ b/OsmAnd/.gitignore @@ -17,7 +17,6 @@ libs/huawei-*.jar huaweidrmlib/ HwDRM_SDK_* drm_strings.xml -agconnect-services.json # copy_widget_icons.sh res/drawable-large/map_* diff --git a/OsmAndHms.jks b/OsmAndHms.jks deleted file mode 100644 index b1d7e59362b69659660ae0e1bc29bfdca0f751f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2243 zcmchY={Fk)7sj*LnvmF2YF|oi6I+y^YN?2=T1)L)f)cxFETt7KHI!EE65FImETyWn zYS%@Jh*lJ>poUVk7&U6}X6C$e&YbrTct6~8&;5P4=bq=@^W4Mr!*u`v0OADj?>H72 z8}1*03ki?qkT^!@>;39E-PVlh5HSeC*=2vw+ zlp0xNT|F3ew=wYMIoPmb(Ky*v0>;OVC*v;%`j`wZ-X^>IJMav3Khu3;&PrYtHi~

os?$`26el>Y`xz_6E$6w15z$tjc4G|*L{$kGVP zIGE$L`gl-t)tC^4u94MeHRh}F9z2ys=w~>Tsb0lEUXOLr^~GXT&$_c)O;(D}T}01D zQrpAC{O5|`1oKXZQIdh~wMLH;K}J%&+V1gRO#LfrtQkUMwwlhCGgxDzA>YOOqX`n@ ze*06aG1-~C4vS-tn`!&X&(F?o4kc>B1L`v%9%-KM%l3A1kHcDn%+6bT2FLCHRQuK6!@+Ig_9_Tr;$O2>^ZBc2hg|M)%?r_!U7^i}@vS}wD=WNuZ<6?W;!NYA0poXIC z7ctf!qeZ{mSFoQl-ZY(ja9iX`!q&bL9uXu>F2wv zg5tqFx;yT|MvlUxC{97f9Tx412U6duSP1IxEU2`K)nL*!@6L$CjsqLA~{3&~`Qq9`tB-)%6*< zkJ%_OZQ(!3UV}T3tWmJJ57ArZ2*CvdXehZHCai|cW(sUO-|-1R!wwKNp4$jp$(72> zH~>}pc;+Rvp48)7WR-J16Rj&q9RVM5zqC4_8x9zFe-mN;no{QxWYx^|+W(Ai+ZU5J z&`+_f(eIwD}j-&9jb6^X_hIU*+q0oGei%zWNkAng4 zu{8FG%WlZB^ZdMpR?3!A)xa3-<1}z_O;e8Dr3lEJhD}{HjvPp*&Z)DbuT%L=HN28T z`9J%iB=UO9Nd4+D(=3Z}v5U43qqgA;eiE-$x*aOJM_AmaS(m?#*tGlNvee*?vyjlb zvz$8e6>&yt$%|lsT1-yJOz!m0p)~1)nHwOGiYkE%Po5kAqW9Gk-qw5lZH?TQwDggN z001}vNdo_jB!Rpu!5|Ol(d98*ijr0)sui^2I6U=k3{c_Bauhy(-z zZgnEUZu`o>rG1PrWY=k*h;Yerr%>sRGqq4_sMnzx(ec3{?RZ}4ehG7IV@mtQjVyTJ0s{fS zU*(aqNNLWVrD0s+T%w_gD1jqrUqLB~l~rJGBQNDtp!shRITytd5eSfMCl;QSLm2}D z>t7a7x_S+V3JF+lNT=3tvjR~`ukJ=qPl$W!14hl2VksH<<~U6r22A`3?HyN3nN)r& z{W}J>rY6mQZpjU&cGvdK!h}W^i&;3lBJ2|#IrtlBKO3vexEEx%;e^^Y>YKQkF_X1s zgE=v>Ddk!o+38kYE4see`b%A%c3D~d1&Tufse_9 z)wPmC4|dewMTbjnSIxagh{P%O*MAki(u6nrV1?*!n0mvOzEwf!s|+`UU+aW_z*m Date: Wed, 30 Sep 2020 12:56:11 +0300 Subject: [PATCH 0378/1366] Fixed gradle scripts --- OsmAnd/build.gradle | 1 - build.gradle | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 0aef4aa139..1232b9661f 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -542,6 +542,5 @@ dependencies { } implementation 'com.jaredrummler:colorpicker:1.1.0' - //freehuaweiImplementation 'com.huawei.agconnect:agconnect-core:1.4.1.300' freehuaweiImplementation 'com.huawei.hms:iap:5.0.2.300' } diff --git a/build.gradle b/build.gradle index 1cd0b221b4..e75ca7d5b8 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,14 @@ buildscript { google() mavenCentral() jcenter() + maven { + url 'https://developer.huawei.com/repo/' + content { + includeGroup 'com.huawei.agconnect' + includeGroup 'com.huawei.hms' + includeGroup 'com.huawei.hmf' + } + } } dependencies { //classpath 'com.android.tools.build:gradle:2.+' @@ -11,6 +19,9 @@ buildscript { classpath 'com.google.gms:google-services:3.0.0' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + if (gradle.startParameter.taskNames.toString().contains("huawei")) { + classpath 'com.huawei.agconnect:agcp:1.4.1.300' + } } } @@ -32,5 +43,13 @@ allprojects { maven { url "https://jitpack.io" } + maven { + url 'https://developer.huawei.com/repo/' + content { + includeGroup 'com.huawei.agconnect' + includeGroup 'com.huawei.hms' + includeGroup 'com.huawei.hmf' + } + } } } From cc107157fcc72062930dc41db77f10587093a708 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 30 Sep 2020 14:34:14 +0300 Subject: [PATCH 0379/1366] oauth authtoken saved --- OsmAnd/AndroidManifest.xml | 19 ++- OsmAnd/build.gradle | 7 ++ .../osmedit/SettingsOsmEditingActivity.java | 47 +++++++- .../oauth/OsmOAuthAuthorizationClient.java | 114 ++++++++++++++++++ .../plus/settings/backend/OsmandSettings.java | 6 + 5 files changed, 184 insertions(+), 9 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index 2c6d6b6463..4e5395a04a 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -7,7 +7,7 @@ - + @@ -52,7 +52,7 @@ @@ -65,7 +65,7 @@ - + - + + + + + + + + @@ -1025,7 +1034,7 @@ callback) { + if (accessToken == null) { + throw new IllegalStateException("Access token is null"); + } + OAuthRequest req = new OAuthRequest(Verb.GET, url); + service.signRequest(accessToken, req); + service.execute(req, callback); + } + + public void startOAuth(ViewGroup rootLayout) { + try { + requestToken = service.getRequestToken(); + loadWebView(rootLayout, service.getAuthorizationUrl(requestToken)); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + public void authorize(String oauthVerifier) { + try { + accessToken = service.getAccessToken(requestToken, oauthVerifier); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + saveToken(); + } + + public boolean isValidToken(){ + return !(accessToken == null); + } + + public void restoreToken() { + String token = application.getSettings().USER_ACCESS_TOKEN.get(); + String tokenSecret = application.getSettings().USER_ACCESS_TOKEN_SECRET.get(); + accessToken = new OAuth1AccessToken(token, tokenSecret); + } + + private void saveToken() { + application.getSettings().USER_ACCESS_TOKEN.set(accessToken.getToken()); + application.getSettings().USER_ACCESS_TOKEN_SECRET.set(accessToken.getTokenSecret()); + } + + private void loadWebView(ViewGroup root, String url) { + WebView webView = new WebView(root.getContext()); + webView.requestFocus(View.FOCUS_DOWN); + webView.loadUrl(url); + root.addView(webView); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index e41c7d58df..a3e5876a0b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -2023,6 +2023,12 @@ public class OsmandSettings { public final OsmandPreference USER_PASSWORD = new StringPreference("user_password", "").makeGlobal(); + public final OsmandPreference USER_ACCESS_TOKEN = + new StringPreference("user_access_token", "").makeGlobal(); + + public final OsmandPreference USER_ACCESS_TOKEN_SECRET = + new StringPreference("user_access_token_secret", "").makeGlobal(); + // this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition public final OsmandPreference OFFLINE_EDITION = new BooleanPreference("offline_osm_editing", true).makeGlobal(); From c2264c3838f5ed0a4a17ea0bc12508f972cfd849 Mon Sep 17 00:00:00 2001 From: sergosm Date: Wed, 30 Sep 2020 14:48:07 +0300 Subject: [PATCH 0380/1366] Bottom sheets: buttons types and behaviors --- OsmAnd/res/layout/bottom_buttons_vertical.xml | 51 ++++++ OsmAnd/res/layout/bottom_sheet_menu_base.xml | 8 +- .../base/MenuBottomSheetDialogFragment.java | 172 ++++++++++++++---- .../ExitBottomSheetDialogFragment.java | 69 +++---- 4 files changed, 223 insertions(+), 77 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_buttons_vertical.xml diff --git a/OsmAnd/res/layout/bottom_buttons_vertical.xml b/OsmAnd/res/layout/bottom_buttons_vertical.xml new file mode 100644 index 0000000000..5ea2d4954c --- /dev/null +++ b/OsmAnd/res/layout/bottom_buttons_vertical.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_menu_base.xml b/OsmAnd/res/layout/bottom_sheet_menu_base.xml index 5110455a7c..d265ba938c 100644 --- a/OsmAnd/res/layout/bottom_sheet_menu_base.xml +++ b/OsmAnd/res/layout/bottom_sheet_menu_base.xml @@ -35,10 +35,8 @@ android:layout_width="match_parent" android:layout_height="10dp" android:layout_gravity="bottom" - android:visibility="gone" - android:background="@drawable/bg_contextmenu_shadow_top_light" /> + android:background="@drawable/bg_contextmenu_shadow_top_light" + android:visibility="gone" /> - - - + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index 7625e5de20..57378848f5 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -8,11 +8,11 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; import android.os.Bundle; -import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.Window; import android.view.WindowManager; import android.widget.LinearLayout; @@ -50,8 +50,11 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra protected int themeRes; protected View dismissButton; protected View rightButton; + protected View thirdButton; private LinearLayout itemsContainer; + private LinearLayout buttonsContainer; + protected View buttonsShadow; @StringRes protected int dismissButtonStringRes = R.string.shared_string_cancel; @@ -74,45 +77,21 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { createMenuItems(savedInstanceState); - Context ctx = requireContext(); - View mainView = View.inflate(new ContextThemeWrapper(ctx, themeRes), R.layout.bottom_sheet_menu_base, null); + Activity activity = requireActivity(); + LayoutInflater themedInflater = UiUtilities.getInflater(activity, nightMode); + View mainView = themedInflater.inflate(R.layout.bottom_sheet_menu_base, null); if (useScrollableItemsContainer()) { - itemsContainer = (LinearLayout) mainView.findViewById(R.id.scrollable_items_container); + itemsContainer = mainView.findViewById(R.id.scrollable_items_container); } else { mainView.findViewById(R.id.scroll_view).setVisibility(View.GONE); - itemsContainer = (LinearLayout) mainView.findViewById(R.id.non_scrollable_items_container); + itemsContainer = mainView.findViewById(R.id.non_scrollable_items_container); itemsContainer.setVisibility(View.VISIBLE); } + buttonsShadow = mainView.findViewById(R.id.buttons_shadow); inflateMenuItems(); - - dismissButton = mainView.findViewById(R.id.dismiss_button); - UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), getDismissButtonTextId()); - dismissButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onDismissButtonClickAction(); - dismiss(); - } - }); - if (hideButtonsContainer()) { - mainView.findViewById(R.id.buttons_container).setVisibility(View.GONE); - } else { - int rightBottomButtonTextId = getRightBottomButtonTextId(); - if (rightBottomButtonTextId != DEFAULT_VALUE) { - mainView.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); - rightButton = mainView.findViewById(R.id.right_bottom_button); - UiUtilities.setupDialogButton(nightMode, rightButton, getRightBottomButtonType(), rightBottomButtonTextId); - rightButton.setVisibility(View.VISIBLE); - rightButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onRightBottomButtonClick(); - } - }); - } - } - updateBottomButtons(); + setupScrollShadow(mainView); + setupBottomButtons((ViewGroup) mainView); setupHeightAndBackground(mainView); return mainView; } @@ -183,7 +162,6 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } final int screenHeight = AndroidUtils.getScreenHeight(activity); final int statusBarHeight = AndroidUtils.getStatusBarHeight(activity); - final int contentHeight = getContentHeight(screenHeight - statusBarHeight); mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override @@ -194,12 +172,13 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } else { obs.removeGlobalOnLayoutListener(this); } + final int contentHeight = getContentHeight(screenHeight - statusBarHeight); final View contentView = useScrollableItemsContainer() ? mainView.findViewById(R.id.scroll_view) : itemsContainer; if (contentView.getHeight() > contentHeight) { if (useScrollableItemsContainer() || useExpandableList()) { contentView.getLayoutParams().height = contentHeight; - mainView.findViewById(R.id.buttons_shadow).setVisibility(View.VISIBLE); + buttonsShadow.setVisibility(View.VISIBLE); } else { contentView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; } @@ -222,7 +201,13 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private int getContentHeight(int availableScreenHeight) { int customHeight = getCustomHeight(); - int maxHeight = availableScreenHeight - getResources().getDimensionPixelSize(R.dimen.dialog_button_ex_height); + int buttonsHeight = 0; + if (useVerticalButtons()) { + buttonsHeight = AndroidUtils.dpToPx(getContext(), 112); + } else { + buttonsHeight = getResources().getDimensionPixelSize(R.dimen.dialog_button_ex_height); + } + int maxHeight = availableScreenHeight - buttonsHeight; if (customHeight != DEFAULT_VALUE && customHeight <= maxHeight) { return customHeight; } @@ -280,6 +265,18 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } + protected int getThirdBottomButtonTextId() { + return DEFAULT_VALUE; + } + + protected DialogButtonType getThirdBottomButtonType() { + return DialogButtonType.PRIMARY; + } + + protected void onThirdBottomButtonClick() { + + } + protected boolean isDismissButtonEnabled() { return true; } @@ -288,6 +285,40 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra return true; } + protected void setupBottomButtons(ViewGroup view) { + Activity activity = requireActivity(); + LayoutInflater themedInflater = UiUtilities.getInflater(activity, nightMode); + if (!hideButtonsContainer()) { + if (useVerticalButtons()) { + buttonsContainer = (LinearLayout) themedInflater.inflate(R.layout.bottom_buttons_vertical, view); + setupThirdButton(); + } else { + buttonsContainer = (LinearLayout) themedInflater.inflate(R.layout.bottom_buttons, view); + } + setupRightButton(); + setupDismissButton(); + updateBottomButtons(); + } + } + + boolean useVerticalButtons() { + Activity activity = requireActivity(); + int rightBottomButtonTextId = getRightBottomButtonTextId(); + if (getDismissButtonTextId() != DEFAULT_VALUE && rightBottomButtonTextId != DEFAULT_VALUE) { + if (getThirdBottomButtonTextId() != DEFAULT_VALUE) { + return true; + } + String rightButtonText = getString(rightBottomButtonTextId); + boolean portrait = AndroidUiHelper.isOrientationPortrait(activity); + int dialogWidth = portrait ? AndroidUtils.getScreenWidth(activity) : getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width); + int measuredTextWidth = AndroidUtils.getTextWidth(getResources().getDimensionPixelSize(R.dimen.default_desc_text_size), rightButtonText); + int availableTextWidth = (dialogWidth - AndroidUtils.dpToPx(activity, 96)) / 2; + + return measuredTextWidth > availableTextWidth; + } + return false; + } + protected void updateBottomButtons() { if (dismissButton != null) { boolean enabled = isDismissButtonEnabled(); @@ -301,6 +332,54 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } } + private void setupDismissButton() { + dismissButton = buttonsContainer.findViewById(R.id.dismiss_button); + int buttonTextId = getDismissButtonTextId(); + if (buttonTextId != DEFAULT_VALUE) { + UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), buttonTextId); + dismissButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onDismissButtonClickAction(); + dismiss(); + } + }); + } + AndroidUiHelper.updateVisibility(dismissButton, buttonTextId != DEFAULT_VALUE); + } + + private void setupRightButton() { + rightButton = buttonsContainer.findViewById(R.id.right_bottom_button); + int buttonTextId = getRightBottomButtonTextId(); + if (buttonTextId != DEFAULT_VALUE) { + UiUtilities.setupDialogButton(nightMode, rightButton, getRightBottomButtonType(), buttonTextId); + rightButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onRightBottomButtonClick(); + } + }); + } + AndroidUiHelper.updateVisibility(rightButton, buttonTextId != DEFAULT_VALUE); + AndroidUiHelper.updateVisibility(buttonsContainer.findViewById(R.id.buttons_divider), buttonTextId != DEFAULT_VALUE); + } + + private void setupThirdButton() { + thirdButton = buttonsContainer.findViewById(R.id.third_button); + int buttonTextId = getThirdBottomButtonTextId(); + if (buttonTextId != DEFAULT_VALUE) { + UiUtilities.setupDialogButton(nightMode, thirdButton, getThirdBottomButtonType(), buttonTextId); + thirdButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onThirdBottomButtonClick(); + } + }); + } + AndroidUiHelper.updateVisibility(thirdButton, buttonTextId != DEFAULT_VALUE); + AndroidUiHelper.updateVisibility(buttonsContainer.findViewById(R.id.buttons_divider_top), buttonTextId != DEFAULT_VALUE); + } + @ColorRes protected int getBgColorId() { return nightMode ? R.color.list_background_color_dark : R.color.list_background_color_light; @@ -325,7 +404,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private LayerDrawable createBackgroundDrawable(@NonNull Context ctx, @DrawableRes int shadowDrawableResId) { Drawable shadowDrawable = ContextCompat.getDrawable(ctx, shadowDrawableResId); - Drawable[] layers = new Drawable[]{shadowDrawable, getColoredBg(ctx)}; + Drawable[] layers = new Drawable[] {shadowDrawable, getColoredBg(ctx)}; return new LayerDrawable(layers); } @@ -335,4 +414,21 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } return !app.getSettings().isLightContent(); } -} + + private void setupScrollShadow(View view) { + final View scrollView; + if (useScrollableItemsContainer()) { + scrollView = view.findViewById(R.id.scroll_view); + } else { + scrollView = itemsContainer; + } + scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() { + + @Override + public void onScrollChanged() { + boolean scrollToBottomAvailable = scrollView.canScrollVertically(1); + AndroidUiHelper.updateVisibility(buttonsShadow, scrollToBottomAvailable); + } + }); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java index df7b4ae9b7..94b5b16e46 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java @@ -28,46 +28,14 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment items.add(new ShortDescriptionItem.Builder() .setDescription(getString(R.string.plan_route_exit_dialog_descr)) - .setTitle(getString(R.string.exit_without_saving)) + .setTitle(getString(R.string. + exit_without_saving)) .setLayoutId(R.layout.bottom_sheet_item_list_title_with_descr) .create()); items.add(new DividerSpaceItem(getContext(), getResources().getDimensionPixelSize(R.dimen.bottom_sheet_exit_button_margin))); - items.add(new BottomSheetItemButton.Builder() - .setButtonType(UiUtilities.DialogButtonType.SECONDARY) - .setTitle(getString(R.string.shared_string_exit)) - .setLayoutId(R.layout.bottom_sheet_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Fragment targetFragment = getTargetFragment(); - if (targetFragment != null) { - targetFragment.onActivityResult(REQUEST_CODE, EXIT_RESULT_CODE, null); - } - dismiss(); - } - }) - .create()); - - items.add(new DividerSpaceItem(getContext(), - getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin))); - - items.add(new BottomSheetItemButton.Builder() - .setTitle(getString(R.string.shared_string_save)) - .setLayoutId(R.layout.bottom_sheet_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Fragment targetFragment = getTargetFragment(); - if (targetFragment != null) { - targetFragment.onActivityResult(REQUEST_CODE, SAVE_RESULT_CODE, null); - } - dismiss(); - } - }) - .create()); } @Override @@ -75,6 +43,39 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment return R.string.shared_string_cancel; } + @Override + protected int getRightBottomButtonTextId() { + return R.string.shared_string_save; + } + + @Override + protected int getThirdBottomButtonTextId() { + return R.string.shared_string_exit; + } + + @Override + protected void onRightBottomButtonClick() { + Fragment targetFragment = getTargetFragment(); + if (targetFragment != null) { + targetFragment.onActivityResult(REQUEST_CODE, SAVE_RESULT_CODE, null); + } + dismiss(); + } + + @Override + protected void onThirdBottomButtonClick() { + Fragment targetFragment = getTargetFragment(); + if (targetFragment != null) { + targetFragment.onActivityResult(REQUEST_CODE, EXIT_RESULT_CODE, null); + } + dismiss(); + } + + @Override + protected UiUtilities.DialogButtonType getThirdBottomButtonType() { + return (UiUtilities.DialogButtonType.SECONDARY); + } + public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment targetFragment) { if (!fragmentManager.isStateSaved()) { ExitBottomSheetDialogFragment fragment = new ExitBottomSheetDialogFragment(); From 6d0e76095fa72cc2efd0e97797448eeae43f85c8 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 30 Sep 2020 17:00:02 +0300 Subject: [PATCH 0381/1366] saving state --- .../plus/osmedit/EditPOIMenuController.java | 14 ++++- .../plus/osmedit/OpenstreetmapRemoteUtil.java | 11 +++- .../plus/osmedit/OsmBugsRemoteUtil.java | 11 +++- .../osmedit/SettingsOsmEditingActivity.java | 63 +++++++++++++++---- .../UploadOpenstreetmapPointAsyncTask.java | 4 ++ .../oauth/OsmOAuthAuthorizationClient.java | 5 ++ 6 files changed, 90 insertions(+), 18 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java b/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java index 47c2eb5200..b94ac7cc1c 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java @@ -14,6 +14,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.osmedit.OsmPoint.Action; import net.osmand.plus.osmedit.dialogs.SendPoiDialogFragment; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; import net.osmand.plus.render.RenderingIcons; import net.osmand.util.Algorithms; @@ -39,9 +40,16 @@ public class EditPOIMenuController extends MenuController { public void buttonPressed() { MapActivity activity = getMapActivity(); if (plugin != null && activity != null) { - SendPoiDialogFragment sendPoiDialogFragment = - SendPoiDialogFragment.createInstance(new OsmPoint[]{getOsmPoint()}, SendPoiDialogFragment.PoiUploaderType.SIMPLE); - sendPoiDialogFragment.show(activity.getSupportFragmentManager(), SendPoiDialogFragment.TAG); + OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(activity.getMyApplication()); + if (client.isValidToken()){ + new SendPoiDialogFragment.SimpleProgressDialogPoiUploader(activity). + showProgressDialog(new OsmPoint[] { getOsmPoint() }, false, false); + } + else { + SendPoiDialogFragment sendPoiDialogFragment = + SendPoiDialogFragment.createInstance(new OsmPoint[]{getOsmPoint()}, SendPoiDialogFragment.PoiUploaderType.SIMPLE); + sendPoiDialogFragment.show(activity.getSupportFragmentManager(), SendPoiDialogFragment.TAG); + } } } }; diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java index 3577987a8b..c8bf73e423 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java @@ -21,6 +21,7 @@ import net.osmand.osm.io.Base64; import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.OsmBaseStorage; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -119,8 +120,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$ StringBuilder responseBody = new StringBuilder(); if (doAuthenticate) { - String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ - connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(ctx); + if (client.isValidToken()){ + connection.addRequestProperty("Authorization", "OAuth " + client.getAccessToken()); + } + else { + String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ + connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } } connection.setDoInput(true); if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java index 8d1238e324..581206fb98 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java @@ -5,6 +5,7 @@ import net.osmand.PlatformUtil; import net.osmand.osm.io.Base64; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -109,6 +110,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil { private OsmBugResult editingPOI(String url, String requestMethod, String userOperation, boolean anonymous) { + OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(this.app); OsmBugResult r = new OsmBugResult(); try { HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url); @@ -118,8 +120,13 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil { connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); //$NON-NLS-1$ if (!anonymous) { - String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ - connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (client.isValidToken()){ + connection.addRequestProperty("Authorization", "OAuth " + client.getAccessToken()); + } + else { + String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ + connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } } connection.setDoInput(true); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java index d2cd35e82b..c0262e436f 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java @@ -18,6 +18,8 @@ import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.Response; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; import net.osmand.plus.OsmandApplication; @@ -25,6 +27,8 @@ import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.settings.backend.OsmAndAppCustomization; +import java.io.IOException; + public class SettingsOsmEditingActivity extends SettingsBaseActivity { OsmOAuthAuthorizationClient client; @@ -72,17 +76,54 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { grp.addPreference(pref); final Preference prefOAuth = new Preference(this); - prefOAuth.setTitle(R.string.osb_author_dialog_password); - prefOAuth.setSummary(R.string.osb_author_dialog_password); - prefOAuth.setKey("local_openstreetmap_points"); - prefOAuth.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - ViewGroup preferenceView = (ViewGroup)getListView().getChildAt(preference.getOrder()); - client.startOAuth(preferenceView); - return true; - } - }); + if (client.isValidToken()){ + prefOAuth.setTitle(R.string.osm_authorization_success); + prefOAuth.setSummary(R.string.osm_authorization_success); + prefOAuth.setKey("local_openstreetmap_token"); + + final Preference prefTestUser = new Preference(this); + prefTestUser.setTitle("Test user request"); + prefTestUser.setSummary("Test user request"); + prefTestUser.setKey("local_openstreetmap_token"); + prefTestUser.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + String url = "https://api.openstreetmap.org/api/0.6/user/details"; + client.performGetRequest(url, new OAuthAsyncRequestCallback() { + @Override + public void onCompleted(Response response) { + try { + Toast.makeText(SettingsOsmEditingActivity.this, + "DATA RETRIEVED: " + response.getBody().toString(),Toast.LENGTH_SHORT).show(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onThrowable(Throwable t) { + Toast.makeText(SettingsOsmEditingActivity.this, + "ERROR happened",Toast.LENGTH_SHORT).show(); + } + }); + return true; + } + }); + grp.addPreference(prefTestUser); + } + else { + prefOAuth.setTitle(R.string.osb_author_dialog_password); + prefOAuth.setSummary(R.string.osb_author_dialog_password); + prefOAuth.setKey("local_openstreetmap_token"); + prefOAuth.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + ViewGroup preferenceView = (ViewGroup)getListView().getChildAt(preference.getOrder()); + client.startOAuth(preferenceView); + return true; + } + }); + } grp.addPreference(prefOAuth); } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java b/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java index 1d99aee0c0..3824d060c7 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java @@ -1,6 +1,7 @@ package net.osmand.plus.osmedit; import android.content.DialogInterface; +import android.net.TrafficStats; import android.os.AsyncTask; import net.osmand.osm.edit.Entity; @@ -43,6 +44,9 @@ public class UploadOpenstreetmapPointAsyncTask @Override protected Map doInBackground(OsmPoint... points) { + final int THREAD_ID = 10102; + TrafficStats.setThreadStatsTag(THREAD_ID); + Map loadErrorsMap = new HashMap<>(); boolean uploaded = false; diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java index 95819b8e5d..1e53c48628 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java @@ -53,6 +53,11 @@ public class OsmOAuthAuthorizationClient { final int THREAD_ID = 10101; TrafficStats.setThreadStatsTag(THREAD_ID); this.application = application; + restoreToken(); + } + + public String getAccessToken() { + return this.accessToken.getToken(); } public void performGetRequest(String url,OAuthAsyncRequestCallback callback) { From b01e72b00d6c3190c3cb273007be86a62192a81e Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 1 Oct 2020 11:06:52 +0300 Subject: [PATCH 0382/1366] Add the ability to update ContextMenuItem itself --- .../net/osmand/plus/ContextMenuAdapter.java | 10 +------ .../src/net/osmand/plus/ContextMenuItem.java | 27 +++++++++++++++-- .../osmand/plus/dashboard/DashboardOnMap.java | 28 +++++++++--------- .../osmand/plus/dialogs/ConfigureMapMenu.java | 29 +++++++------------ 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 795bc7224c..0842a1923e 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -65,7 +65,6 @@ public class ContextMenuAdapter { @LayoutRes private int DEFAULT_LAYOUT_ID = R.layout.list_menu_item_native; List items = new ArrayList<>(); - private ArrayAdapter arrayAdapter; private boolean profileDependent = false; private boolean nightMode; private ConfigureMapMenu.OnClickListener changeAppModeListener = null; @@ -202,9 +201,8 @@ public class ContextMenuAdapter { } } items.removeAll(itemsToRemove); - arrayAdapter = new ContextMenuArrayAdapter(activity, layoutId, R.id.title, + return new ContextMenuArrayAdapter(activity, layoutId, R.id.title, items.toArray(new ContextMenuItem[items.size()]), app, lightTheme, changeAppModeListener); - return arrayAdapter; } public class ContextMenuArrayAdapter extends ArrayAdapter { @@ -627,12 +625,6 @@ public class ContextMenuAdapter { return visible; } - public void notifyDataSetChanged() { - if (arrayAdapter != null) { - arrayAdapter.notifyDataSetChanged(); - } - } - public static OnItemDeleteAction makeDeleteAction(final OsmandPreference... prefs) { return new OnItemDeleteAction() { @Override diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuItem.java b/OsmAnd/src/net/osmand/plus/ContextMenuItem.java index 3a5b391a67..3718169532 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuItem.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuItem.java @@ -34,6 +34,7 @@ public class ContextMenuItem { private boolean hidden; private int order; private String description; + private final OnUpdateCallback onUpdateCallback; private final ContextMenuAdapter.ItemClickListener itemClickListener; private final ContextMenuAdapter.OnIntegerValueChangedListener integerListener; private final ContextMenuAdapter.ProgressListener progressListener; @@ -58,6 +59,7 @@ public class ContextMenuItem { boolean skipPaintingWithoutColor, int order, String description, + OnUpdateCallback onUpdateCallback, ContextMenuAdapter.ItemClickListener itemClickListener, ContextMenuAdapter.OnIntegerValueChangedListener integerListener, ContextMenuAdapter.ProgressListener progressListener, @@ -81,6 +83,7 @@ public class ContextMenuItem { this.skipPaintingWithoutColor = skipPaintingWithoutColor; this.order = order; this.description = description; + this.onUpdateCallback = onUpdateCallback; this.itemClickListener = itemClickListener; this.integerListener = integerListener; this.progressListener = progressListener; @@ -245,6 +248,16 @@ public class ContextMenuItem { return id; } + public void update() { + if (onUpdateCallback != null) { + onUpdateCallback.onUpdateMenuItem(this); + } + } + + public interface OnUpdateCallback { + void onUpdateMenuItem(ContextMenuItem item); + } + public static ItemBuilder createBuilder(String title) { return new ItemBuilder().setTitle(title); } @@ -268,6 +281,7 @@ public class ContextMenuItem { private boolean mIsClickable = true; private int mOrder = 0; private String mDescription = null; + private OnUpdateCallback mOnUpdateCallback = null; private ContextMenuAdapter.ItemClickListener mItemClickListener = null; private ContextMenuAdapter.OnIntegerValueChangedListener mIntegerListener = null; private ContextMenuAdapter.ProgressListener mProgressListener = null; @@ -348,6 +362,11 @@ public class ContextMenuItem { return this; } + public ItemBuilder setOnUpdateCallback(OnUpdateCallback onUpdateCallback) { + mOnUpdateCallback = onUpdateCallback; + return this; + } + public ItemBuilder setListener(ContextMenuAdapter.ItemClickListener checkBoxListener) { mItemClickListener = checkBoxListener; return this; @@ -403,10 +422,12 @@ public class ContextMenuItem { } public ContextMenuItem createItem() { - return new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mSecondaryIcon, + ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mSecondaryIcon, mSelected, mProgress, mLayout, mLoading, mIsCategory, mIsClickable, mSkipPaintingWithoutColor, - mOrder, mDescription, mItemClickListener, mIntegerListener, mProgressListener, mItemDeleteAction, - mHideDivider, mHideCompoundButton, mMinHeight, mTag, mId); + mOrder, mDescription, mOnUpdateCallback, mItemClickListener, mIntegerListener, mProgressListener, + mItemDeleteAction, mHideDivider, mHideCompoundButton, mMinHeight, mTag, mId); + item.update(); + return item; } } } diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index 4c2c4a6a8d..a7bb87db2a 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -96,8 +96,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_STYLE_ID; - public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInformationListener { private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(DashboardOnMap.class); @@ -132,7 +130,6 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo private ArrayAdapter listAdapter; private OnItemClickListener listAdapterOnClickListener; - private ConfigureMapMenu configureMapMenu; private boolean visible = false; private DashboardType visibleType; @@ -659,16 +656,10 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo fragment.show(mapActivity.getSupportFragmentManager(), MapillaryFirstDialogFragment.TAG); settings.MAPILLARY_FIRST_DIALOG_SHOWN.set(true); } - - deleteTmpReferences(); } mapActivity.updateStatusBarColor(); } - private void deleteTmpReferences() { - configureMapMenu = null; - } - public void updateDashboard() { if (visibleType == DashboardType.ROUTE_PREFERENCES) { refreshContent(false); @@ -714,8 +705,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo if (visibleType == DashboardType.CONFIGURE_SCREEN) { cm = mapActivity.getMapLayers().getMapWidgetRegistry().getViewConfigureMenuAdapter(mapActivity); } else if (visibleType == DashboardType.CONFIGURE_MAP) { - configureMapMenu = new ConfigureMapMenu(mapActivity); - cm = configureMapMenu.createListAdapter(); + cm = new ConfigureMapMenu(mapActivity).createListAdapter(); } else if (visibleType == DashboardType.LIST_MENU) { cm = mapActivity.getMapActions().createMainOptionsMenu(); } else if (visibleType == DashboardType.ROUTE_PREFERENCES) { @@ -1043,8 +1033,20 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo } public void onMapSettingsUpdated() { - if (configureMapMenu != null) { - configureMapMenu.updateMenuItem(MAP_STYLE_ID); + if (DashboardType.CONFIGURE_MAP.equals(visibleType)) { + updateMenuItems(); + } + } + + public void updateMenuItems() { + if (listAdapter != null) { + for (int i = 0; i < listAdapter.getCount(); i++) { + Object o = listAdapter.getItem(i); + if (o instanceof ContextMenuItem) { + ((ContextMenuItem) o).update(); + } + } + listAdapter.notifyDataSetChanged(); } } diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index d9a60adff3..ea1934c5e6 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -111,7 +111,6 @@ public class ConfigureMapMenu { private boolean transliterateNames; private MapActivity ma; - private ContextMenuAdapter contextMenuAdapter; public interface OnClickListener { void onClick(); @@ -143,7 +142,6 @@ public class ConfigureMapMenu { adapter.setNightMode(nightMode); createLayersItems(customRules, adapter, ma, themeRes, nightMode); createRenderingAttributeItems(customRules, adapter, ma, themeRes, nightMode); - this.contextMenuAdapter = adapter; return adapter; } @@ -281,16 +279,16 @@ public class ConfigureMapMenu { final OsmandSettings settings = app.getSettings(); final int selectedProfileColorRes = settings.APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode); final int selectedProfileColor = ContextCompat.getColor(app, selectedProfileColorRes); - String renderDescr = getRenderDescr(app); adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_map_rendering, activity) .setId(MAP_RENDERING_CATEGORY_ID) .setCategory(true).setLayout(R.layout.list_group_title_with_switch).createItem()); - adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_renderer, activity) + adapter.addItem(new ContextMenuItem.ItemBuilder() .setId(MAP_STYLE_ID) - .setDescription(renderDescr) + .setTitleId(R.string.map_widget_renderer, activity) .setLayout(R.layout.list_item_single_line_descrition_narrow) - .setIcon(R.drawable.ic_map).setListener(new ContextMenuAdapter.ItemClickListener() { + .setIcon(R.drawable.ic_map) + .setListener(new ContextMenuAdapter.ItemClickListener() { @Override public boolean onContextMenuClick(final ArrayAdapter ad, int itemId, final int pos, boolean isChecked, int[] viewCoordinates) { @@ -300,6 +298,13 @@ public class ConfigureMapMenu { } }) .setItemDeleteAction(makeDeleteAction(settings.RENDERER)) + .setOnUpdateCallback(new ContextMenuItem.OnUpdateCallback() { + @Override + public void onUpdateMenuItem(ContextMenuItem item) { + String renderDescr = getRenderDescr(app); + item.setDescription(renderDescr); + } + }) .createItem()); String description = ""; @@ -1119,18 +1124,6 @@ public class ConfigureMapMenu { } } - public void updateMenuItem(String itemId) { - OsmandApplication app = getMyApplication(); - if (app == null) return; - - if (MAP_STYLE_ID.equals(itemId) && contextMenuAdapter != null) { - ContextMenuItem item = contextMenuAdapter.getItemById(MAP_STYLE_ID); - String renderDescr = getRenderDescr(app); - item.setDescription(renderDescr); - contextMenuAdapter.notifyDataSetChanged(); - } - } - private OsmandApplication getMyApplication() { return ma.getMyApplication(); } From f24e491ebb252d7bf653386cac0167bb1f9b3027 Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 1 Oct 2020 11:13:02 +0300 Subject: [PATCH 0383/1366] delete unnecessary code --- OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java | 9 --------- OsmAnd/src/net/osmand/plus/render/RendererRegistry.java | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 0842a1923e..7263f119bd 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -100,15 +100,6 @@ public class ContextMenuAdapter { return items.get(position); } - public ContextMenuItem getItemById(@NonNull String id) { - for (ContextMenuItem item : items) { - if (id.equals(item.getId())) { - return item; - } - } - return null; - } - public List getItems() { return items; } diff --git a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java index d382fa9882..3f8ed81ba7 100644 --- a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java +++ b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java @@ -334,7 +334,7 @@ public class RendererRegistry { return currentSelectedRender; } - public void setCurrentSelectedRender(final RenderingRulesStorage currentSelectedRender) { + public void setCurrentSelectedRender(RenderingRulesStorage currentSelectedRender) { this.currentSelectedRender = currentSelectedRender; } From b594076f142978438b297d18b8cffbcc8c43c3cd Mon Sep 17 00:00:00 2001 From: MadWasp79 Date: Thu, 1 Oct 2020 14:03:06 +0300 Subject: [PATCH 0384/1366] #9853 fix calc time in android --- .../src/main/java/net/osmand/router/RoutePlannerFrontEnd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java index 54464afc32..bff7db3a6d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java @@ -739,7 +739,7 @@ public class RoutePlannerFrontEnd { res = searchRouteImpl(ctx, points, routeDirection); } if (ctx.calculationProgress != null) { - ctx.calculationProgress.timeToCalculate += (System.nanoTime() - timeToCalculate); + ctx.calculationProgress.timeToCalculate = (System.nanoTime() - timeToCalculate); } BinaryRoutePlanner.printDebugMemoryInformation(ctx); if (res != null) { From 8b0285031a6e06b89e3617e3e89042201819c568 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 1 Oct 2020 14:51:43 +0300 Subject: [PATCH 0385/1366] Fix track arrows --- .../views/layers/geometry/GeometryWayContext.java | 15 ++++++++++++++- .../views/layers/geometry/GeometryWayDrawer.java | 14 ++++++-------- .../views/layers/geometry/GpxGeometryWay.java | 1 + .../layers/geometry/GpxGeometryWayContext.java | 13 ++++++++++++- .../PublicTransportGeometryWayContext.java | 5 +++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java index d53160bd04..16efb3a69b 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java @@ -121,4 +121,17 @@ public abstract class GeometryWayContext { return arrowBitmap; } -} + public double getPxStep(double zoomCoef) { + return getDefaultPxStep(zoomCoef); + } + + public double getPxStepRegular(double zoomCoef) { + return getDefaultPxStep(zoomCoef); + } + + public double getDefaultPxStep(double zoomCoef) { + Bitmap arrow = getArrowBitmap(); + int arrowHeight = arrow.getHeight(); + return arrowHeight * 4f * zoomCoef; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java index db45a9b55c..18039c35d6 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java @@ -31,22 +31,20 @@ public class GeometryWayDrawer { int h = tb.getPixHeight(); int w = tb.getPixWidth(); - int left = -w / 4; + int left = -w / 4; int right = w + w / 4; - int top = - h/4; - int bottom = h + h/4; + int top = -h / 4; + int bottom = h + h / 4; boolean hasStyles = styles != null && styles.size() == tx.size(); double zoomCoef = tb.getZoomAnimation() > 0 ? (Math.pow(2, tb.getZoomAnimation() + tb.getZoomFloatPart())) : 1f; - Bitmap arrow = context.getArrowBitmap(); - int arrowHeight = arrow.getHeight(); - double pxStep = arrowHeight * 4f * zoomCoef; - double pxStepRegular = arrowHeight * 4f * zoomCoef; + double pxStep = context.getPxStep(zoomCoef); + double pxStepRegular = context.getPxStepRegular(zoomCoef); double dist = 0; if (distPixToFinish != 0) { dist = distPixToFinish - pxStep * ((int) (distPixToFinish / pxStep)); // dist < 1 } - for (int i = tx.size() - 2; i >= 0; i --) { + for (int i = tx.size() - 2; i >= 0; i--) { GeometryWayStyle style = hasStyles ? styles.get(i) : null; float px = tx.get(i); float py = ty.get(i); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java index 24d49df0b1..d51d9e0231 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java @@ -48,6 +48,7 @@ public class GpxGeometryWay extends GeometryWay Date: Thu, 1 Oct 2020 15:33:22 +0300 Subject: [PATCH 0386/1366] Add phrase --- OsmAnd/res/values/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 3f4394578a..b58d25a781 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4257,5 +4257,7 @@ Nut store + LNG + From e0d266ff0d2959923cd87c3689ae3f8cc3b64ef2 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 1 Oct 2020 15:38:36 +0300 Subject: [PATCH 0387/1366] remove unnecessary changes --- .../views/layers/geometry/GeometryWayContext.java | 15 +-------------- .../views/layers/geometry/GeometryWayDrawer.java | 13 ++++++++++--- .../views/layers/geometry/GpxGeometryWay.java | 1 - .../layers/geometry/GpxGeometryWayContext.java | 13 +------------ .../PublicTransportGeometryWayContext.java | 5 ----- 5 files changed, 12 insertions(+), 35 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java index 16efb3a69b..d53160bd04 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayContext.java @@ -121,17 +121,4 @@ public abstract class GeometryWayContext { return arrowBitmap; } - public double getPxStep(double zoomCoef) { - return getDefaultPxStep(zoomCoef); - } - - public double getPxStepRegular(double zoomCoef) { - return getDefaultPxStep(zoomCoef); - } - - public double getDefaultPxStep(double zoomCoef) { - Bitmap arrow = getArrowBitmap(); - int arrowHeight = arrow.getHeight(); - return arrowHeight * 4f * zoomCoef; - } -} \ No newline at end of file +} diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java index 18039c35d6..ac6f514ed1 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java @@ -38,8 +38,15 @@ public class GeometryWayDrawer { boolean hasStyles = styles != null && styles.size() == tx.size(); double zoomCoef = tb.getZoomAnimation() > 0 ? (Math.pow(2, tb.getZoomAnimation() + tb.getZoomFloatPart())) : 1f; - double pxStep = context.getPxStep(zoomCoef); - double pxStepRegular = context.getPxStepRegular(zoomCoef); + Bitmap arrow = context.getArrowBitmap(); + int arrowHeight = arrow.getHeight(); + double defaultPxStep; + if (hasStyles && styles.get(0) != null) { + defaultPxStep = styles.get(0).getPointStepPx(zoomCoef); + } else { + defaultPxStep = arrowHeight * 4f * zoomCoef; + } + double pxStep = defaultPxStep; double dist = 0; if (distPixToFinish != 0) { dist = distPixToFinish - pxStep * ((int) (distPixToFinish / pxStep)); // dist < 1 @@ -55,7 +62,7 @@ public class GeometryWayDrawer { if (distSegment == 0) { continue; } - pxStep = style != null ? style.getPointStepPx(zoomCoef) : pxStepRegular; + pxStep = style != null ? style.getPointStepPx(zoomCoef) : defaultPxStep; if (dist >= pxStep) { dist = 0; } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java index d51d9e0231..24d49df0b1 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GpxGeometryWay.java @@ -48,7 +48,6 @@ public class GpxGeometryWay extends GeometryWay Date: Thu, 1 Oct 2020 15:51:08 +0300 Subject: [PATCH 0388/1366] Fix start style index --- .../views/layers/geometry/GeometryWayDrawer.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java index ac6f514ed1..0bfa86f43b 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java @@ -38,20 +38,21 @@ public class GeometryWayDrawer { boolean hasStyles = styles != null && styles.size() == tx.size(); double zoomCoef = tb.getZoomAnimation() > 0 ? (Math.pow(2, tb.getZoomAnimation() + tb.getZoomFloatPart())) : 1f; - Bitmap arrow = context.getArrowBitmap(); - int arrowHeight = arrow.getHeight(); + + int startIndex = tx.size() - 2; double defaultPxStep; - if (hasStyles && styles.get(0) != null) { - defaultPxStep = styles.get(0).getPointStepPx(zoomCoef); + if (hasStyles && styles.get(startIndex) != null) { + defaultPxStep = styles.get(startIndex).getPointStepPx(zoomCoef); } else { - defaultPxStep = arrowHeight * 4f * zoomCoef; + Bitmap arrow = context.getArrowBitmap(); + defaultPxStep = arrow.getHeight() * 4f * zoomCoef; } double pxStep = defaultPxStep; double dist = 0; if (distPixToFinish != 0) { dist = distPixToFinish - pxStep * ((int) (distPixToFinish / pxStep)); // dist < 1 } - for (int i = tx.size() - 2; i >= 0; i--) { + for (int i = startIndex; i >= 0; i--) { GeometryWayStyle style = hasStyles ? styles.get(i) : null; float px = tx.get(i); float py = ty.get(i); From 47b0bc2ff07dc7c5a07cc0624bd652fc527797fa Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 1 Oct 2020 15:57:45 +0300 Subject: [PATCH 0389/1366] Add AIDL import/export profiles --- .../osmand/aidlapi/IOsmAndAidlInterface.aidl | 8 + .../customization/ProfileSettingsParams.java | 42 ++++- .../aidlapi/profile/ExportProfileParams.aidl | 3 + .../aidlapi/profile/ExportProfileParams.java | 61 +++++++ .../aidlapi/profile/ExportSettingsType.aidl | 3 + .../aidlapi/profile/ExportSettingsType.java | 11 ++ OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 32 +++- .../net/osmand/aidl/OsmandAidlService.java | 3 +- .../net/osmand/aidl/OsmandAidlServiceV2.java | 15 +- .../customization/ProfileSettingsParams.java | 21 ++- .../net/osmand/plus/helpers/ImportHelper.java | 166 +++++++++++++++++- .../settings/backend/ExportSettingsType.java | 11 ++ .../plus/settings/backend/SettingsHelper.java | 107 +++++++++++ .../ExportImportSettingsAdapter.java | 37 ++-- .../fragments/ExportProfileBottomSheet.java | 119 +------------ .../fragments/ImportCompleteFragment.java | 9 +- .../fragments/ImportSettingsFragment.java | 92 +--------- .../ImportedSettingsItemsAdapter.java | 14 +- 18 files changed, 496 insertions(+), 258 deletions(-) create mode 100644 OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl create mode 100644 OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java create mode 100644 OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl create mode 100644 OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl index 3edd8c94da..3a8edb6d80 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl @@ -20,6 +20,8 @@ import net.osmand.aidlapi.mapmarker.UpdateMapMarkerParams; import net.osmand.aidlapi.calculateroute.CalculateRouteParams; +import net.osmand.aidlapi.profile.ExportProfileParams; + import net.osmand.aidlapi.gpx.ImportGpxParams; import net.osmand.aidlapi.gpx.ShowGpxParams; import net.osmand.aidlapi.gpx.StartGpxRecordingParams; @@ -103,6 +105,10 @@ import net.osmand.aidlapi.events.AKeyEventsParams; import net.osmand.aidlapi.info.AppInfoParams; +import net.osmand.aidlapi.profile.ExportProfileParams; +import net.osmand.aidlapi.profile.ExportSettingsType; + + // NOTE: Add new methods at the end of file!!! interface IOsmAndAidlInterface { @@ -867,4 +873,6 @@ interface IOsmAndAidlInterface { AppInfoParams getAppInfo(); boolean setMapMargins(in MapMarginsParams params); + + boolean exportProfile(in ExportProfileParams params); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java index 36959ef776..427ccc71fd 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java @@ -5,15 +5,31 @@ import android.os.Bundle; import android.os.Parcel; import net.osmand.aidlapi.AidlParams; +import net.osmand.aidlapi.profile.ExportSettingsType; + +import java.util.ArrayList; + +import static net.osmand.aidlapi.profile.ExportProfileParams.SETTINGS_TYPE_KEY; public class ProfileSettingsParams extends AidlParams { + public static final String VERSION_KEY = "version"; + public static final String REPLACE_KEY = "replace"; + public static final String LATEST_CHANGES_KEY = "latestChanges"; + public static final String PROFILE_SETTINGS_URI_KEY = "profileSettingsUri"; private Uri profileSettingsUri; private String latestChanges; private int version; + ArrayList settingsTypeKeyList = new ArrayList<>(); + boolean replace; - public ProfileSettingsParams(Uri profileSettingsUri, String latestChanges, int version) { + public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, boolean replace, + String latestChanges, int version) { this.profileSettingsUri = profileSettingsUri; + for (ExportSettingsType settingsType : settingsTypeList) { + settingsTypeKeyList.add(settingsType.name()); + } + this.replace = replace; this.latestChanges = latestChanges; this.version = version; } @@ -46,17 +62,29 @@ public class ProfileSettingsParams extends AidlParams { return profileSettingsUri; } + public ArrayList getSettingsTypeKeys() { + return settingsTypeKeyList; + } + + public boolean isReplace() { + return replace; + } + @Override public void writeToBundle(Bundle bundle) { - bundle.putInt("version", version); - bundle.putString("latestChanges", latestChanges); - bundle.putParcelable("profileSettingsUri", profileSettingsUri); + bundle.putInt(VERSION_KEY, version); + bundle.putString(LATEST_CHANGES_KEY, latestChanges); + bundle.putParcelable(PROFILE_SETTINGS_URI_KEY, profileSettingsUri); + bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList); + bundle.putBoolean(REPLACE_KEY, replace); } @Override protected void readFromBundle(Bundle bundle) { - version = bundle.getInt("version"); - latestChanges = bundle.getString("latestChanges"); - profileSettingsUri = bundle.getParcelable("profileSettingsUri"); + version = bundle.getInt(VERSION_KEY); + latestChanges = bundle.getString(LATEST_CHANGES_KEY); + profileSettingsUri = bundle.getParcelable(PROFILE_SETTINGS_URI_KEY); + settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY); + replace = bundle.getBoolean(REPLACE_KEY); } } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl new file mode 100644 index 0000000000..0dfefce6be --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidlapi.profile; + +parcelable ExportProfileParams; \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java new file mode 100644 index 0000000000..6298ccba04 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java @@ -0,0 +1,61 @@ +package net.osmand.aidlapi.profile; + +import android.os.Bundle; +import android.os.Parcel; + +import net.osmand.aidlapi.AidlParams; + +import java.util.ArrayList; +import java.util.List; + +public class ExportProfileParams extends AidlParams { + + public static final String PROFILE_KEY = "profile"; + public static final String SETTINGS_TYPE_KEY = "settings_type"; + private String profile; + ArrayList settingsTypeKeyList = new ArrayList<>(); + + public ExportProfileParams(String profile, ArrayList settingsTypeList) { + + this.profile = profile; + for (ExportSettingsType settingsType : settingsTypeList) { + settingsTypeKeyList.add(settingsType.name()); + } + } + + public ExportProfileParams(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public ExportProfileParams createFromParcel(Parcel in) { + return new ExportProfileParams(in); + } + + @Override + public ExportProfileParams[] newArray(int size) { + return new ExportProfileParams[size]; + } + }; + + public String getProfile() { + return profile; + } + + public List getSettingsTypeKeys() { + return settingsTypeKeyList; + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putString(PROFILE_KEY, profile); + bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList); + } + + @Override + protected void readFromBundle(Bundle bundle) { + profile = bundle.getString(PROFILE_KEY); + settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY); + } +} \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl new file mode 100644 index 0000000000..13ac783db1 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidlapi.profile; + +parcelable ExportSettingsType; \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java new file mode 100644 index 0000000000..19bdad37dc --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java @@ -0,0 +1,11 @@ +package net.osmand.aidlapi.profile; + +public enum ExportSettingsType { + PROFILE, + QUICK_ACTIONS, + POI_TYPES, + MAP_SOURCES, + CUSTOM_RENDER_STYLE, + CUSTOM_ROUTING, + AVOID_ROADS; +} diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 58dbdd1559..a86f48f714 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -81,6 +81,7 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.SettingsHelper; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.layers.AidlMapLayer; @@ -135,6 +136,7 @@ import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_NAME; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_TURN; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DISTANCE; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_IMMINENT; +import static net.osmand.plus.settings.backend.SettingsHelper.REPLACE_KEY; public class OsmandAidlApi { @@ -205,7 +207,7 @@ public class OsmandAidlApi { private static final ApplicationMode DEFAULT_PROFILE = ApplicationMode.CAR; - private static final ApplicationMode[] VALID_PROFILES = new ApplicationMode[] { + private static final ApplicationMode[] VALID_PROFILES = new ApplicationMode[]{ ApplicationMode.CAR, ApplicationMode.BICYCLE, ApplicationMode.PEDESTRIAN @@ -285,7 +287,7 @@ public class OsmandAidlApi { } private void initOsmandTelegram() { - String[] packages = new String[] {"net.osmand.telegram", "net.osmand.telegram.debug"}; + String[] packages = new String[]{"net.osmand.telegram", "net.osmand.telegram.debug"}; Intent intent = new Intent("net.osmand.telegram.InitApp"); for (String pack : packages) { intent.setComponent(new ComponentName(pack, "net.osmand.telegram.InitAppBroadcastReceiver")); @@ -1016,7 +1018,7 @@ public class OsmandAidlApi { } if (!newName.equals(f.getName()) || !newDescription.equals(f.getDescription()) || !newCategory.equals(f.getCategory()) || !newAddress.equals(f.getAddress())) { - favoritesHelper.editFavouriteName(f, newName, newCategory, newDescription,newAddress); + favoritesHelper.editFavouriteName(f, newName, newCategory, newDescription, newAddress); } refreshMap(); return true; @@ -2249,9 +2251,12 @@ public class OsmandAidlApi { private Map copyFilesCache = new ConcurrentHashMap<>(); - public boolean importProfile(final Uri profileUri, String latestChanges, int version) { + public boolean importProfile(final Uri profileUri, ArrayList settingsTypeKeys, boolean replace, + String latestChanges, int version) { if (profileUri != null) { Bundle bundle = new Bundle(); + bundle.putStringArrayList(SettingsHelper.SETTINGS_TYPE_LIST_KEY, settingsTypeKeys); + bundle.putBoolean(REPLACE_KEY, replace); bundle.putString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY, latestChanges); bundle.putInt(SettingsHelper.SETTINGS_VERSION_KEY, version); @@ -2324,6 +2329,25 @@ public class OsmandAidlApi { return true; } + public boolean exportProfile(String appModeKey, List settingsTypesKeys) { + ApplicationMode appMode = ApplicationMode.valueOfStringKey(appModeKey, null); + if (app != null && appMode != null) { + List settingsTypes = new ArrayList<>(); + for (String key : settingsTypesKeys) { + settingsTypes.add(ExportSettingsType.valueOf(key)); + } + List settingsItems = new ArrayList<>(); + settingsItems.add(new SettingsHelper.ProfileSettingsItem(app, appMode)); + File tempDir = FileUtils.getTempDir(app); + String fileName = appMode.toHumanString(); + SettingsHelper settingsHelper = app.getSettingsHelper(); + settingsItems.addAll(settingsHelper.getFilteredSettingsItems(settingsHelper.getAdditionalData(), settingsTypes)); + settingsHelper.exportSettings(tempDir, fileName, null, settingsItems, true); + return true; + } + return false; + } + private static class FileCopyInfo { long startTime; long lastAccessTime; diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java index f1c9493fc8..17c87431e8 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java @@ -1299,7 +1299,8 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { public boolean importProfile(ProfileSettingsParams params) { try { OsmandAidlApi api = getApi("importProfile"); - return api != null && api.importProfile(params.getProfileSettingsUri(), params.getLatestChanges(), params.getVersion()); + return api != null && api.importProfile(params.getProfileSettingsUri(), params.getSettingsTypeKeys(), + params.isReplace(), params.getLatestChanges(), params.getVersion()); } catch (Exception e) { handleException(e); return false; diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 333fd01895..4cd13d12da 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -85,6 +85,7 @@ import net.osmand.aidlapi.note.StartVideoRecordingParams; import net.osmand.aidlapi.note.StopRecordingParams; import net.osmand.aidlapi.note.TakePhotoNoteParams; import net.osmand.aidlapi.plugins.PluginParams; +import net.osmand.aidlapi.profile.ExportProfileParams; import net.osmand.aidlapi.quickaction.QuickActionInfoParams; import net.osmand.aidlapi.quickaction.QuickActionParams; import net.osmand.aidlapi.search.SearchParams; @@ -1258,7 +1259,19 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener public boolean importProfile(ProfileSettingsParams params) { try { OsmandAidlApi api = getApi("importProfile"); - return api != null && api.importProfile(params.getProfileSettingsUri(), params.getLatestChanges(), params.getVersion()); + return api != null && api.importProfile(params.getProfileSettingsUri(), params.getSettingsTypeKeys(), + params.isReplace(), params.getLatestChanges(), params.getVersion()); + } catch (Exception e) { + handleException(e); + return false; + } + } + + @Override + public boolean exportProfile(ExportProfileParams params) { + try { + OsmandAidlApi api = getApi("exportProfile"); + return api != null && api.exportProfile(params.getProfile(), params.getSettingsTypeKeys()); } catch (Exception e) { handleException(e); return false; diff --git a/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java b/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java index 6c2f82cd8f..cd5cfecddf 100644 --- a/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java +++ b/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java @@ -4,13 +4,20 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; +import net.osmand.aidlapi.profile.ExportSettingsType; + +import java.util.ArrayList; + public class ProfileSettingsParams implements Parcelable { private Uri profileSettingsUri; private String latestChanges; private int version; + ArrayList settingsTypeKeyList = new ArrayList<>(); + boolean replace; - public ProfileSettingsParams(Uri profileSettingsUri, String latestChanges, int version) { + public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, + boolean replace, String latestChanges, int version) { this.profileSettingsUri = profileSettingsUri; this.latestChanges = latestChanges; this.version = version; @@ -44,17 +51,29 @@ public class ProfileSettingsParams implements Parcelable { return profileSettingsUri; } + public ArrayList getSettingsTypeKeys() { + return settingsTypeKeyList; + } + + public boolean isReplace() { + return replace; + } + @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(version); out.writeString(latestChanges); out.writeParcelable(profileSettingsUri, flags); + out.writeStringList(settingsTypeKeyList); + out.writeInt(replace ? 1 : 0); } private void readFromParcel(Parcel in) { version = in.readInt(); latestChanges = in.readString(); profileSettingsUri = in.readParcelable(Uri.class.getClassLoader()); + in.readStringList(settingsTypeKeyList); + replace = in.readInt() == 1; } @Override diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index e3dcb9cd2d..ec2cf92031 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -30,6 +30,7 @@ import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint.BackgroundType; +import net.osmand.map.ITileSource; import net.osmand.plus.AppInitializer; import net.osmand.plus.CustomOsmandPlugin; import net.osmand.plus.FavouritesDbHelper; @@ -42,7 +43,11 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment; import net.osmand.plus.measurementtool.MeasurementToolFragment; +import net.osmand.plus.poi.PoiUIFilter; +import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.SettingsHelper; import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener; import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem; @@ -50,6 +55,7 @@ import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener; import net.osmand.plus.settings.backend.SettingsHelper.SettingsImportListener; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; +import net.osmand.plus.settings.fragments.ImportCompleteFragment; import net.osmand.plus.settings.fragments.ImportSettingsFragment; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.router.RoutingConfiguration; @@ -70,8 +76,10 @@ import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; @@ -87,6 +95,7 @@ import static net.osmand.plus.AppInitializer.loadRoutingFiles; import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; +import static net.osmand.plus.settings.backend.SettingsHelper.*; /** * @author Koen Rabaey @@ -691,17 +700,31 @@ public class ImportHelper { } private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject> callback) { - if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { - int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); - String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); - handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback); + if (extras != null && extras.containsKey(SETTINGS_VERSION_KEY) + && extras.containsKey(REPLACE_KEY) + && extras.containsKey(SETTINGS_LATEST_CHANGES_KEY) + && extras.containsKey(SETTINGS_TYPE_LIST_KEY)) { + int version = extras.getInt(SETTINGS_VERSION_KEY, -1); + String latestChanges = extras.getString(SETTINGS_LATEST_CHANGES_KEY); + boolean replace = extras.getBoolean(REPLACE_KEY); + ArrayList settingsTypeKeys = extras.getStringArrayList(SETTINGS_TYPE_LIST_KEY); + List settingsTypes = new ArrayList<>(); + if (settingsTypeKeys != null) { + for (String key : settingsTypeKeys) { + settingsTypes.add(ExportSettingsType.valueOf(key)); + } + } + handleOsmAndSettingsImport(intentUri, fileName, settingsTypes, replace, latestChanges, version, callback); } else { - handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback); + handleOsmAndSettingsImport(intentUri, fileName, null, false, null, -1, callback); } } @SuppressLint("StaticFieldLeak") - private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, + private void handleOsmAndSettingsImport(final Uri uri, final String name, + final List settingsTypes, + final boolean replace, + final String latestChanges, final int version, final CallbackWithObject> callback) { final AsyncTask settingsImportTask = new AsyncTask() { @@ -726,7 +749,8 @@ public class ImportHelper { File tempDir = FileUtils.getTempDir(app); final File file = new File(tempDir, name); if (error == null && file.exists()) { - app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { + final SettingsHelper settingsHelper = app.getSettingsHelper(); + settingsHelper.collectSettings(file, latestChanges, version, new SettingsCollectListener() { @Override public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { @@ -746,8 +770,14 @@ public class ImportHelper { handlePluginImport(pluginItem, file); } if (!pluginIndependentItems.isEmpty()) { - FragmentManager fragmentManager = activity.getSupportFragmentManager(); - ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file); + if (settingsTypes == null) { + FragmentManager fragmentManager = activity.getSupportFragmentManager(); + ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file); + } else { + Map> allSettingsList = getSettingsToOperate(pluginIndependentItems, false); + List settingsList = settingsHelper.getFilteredSettingsItems(allSettingsList, settingsTypes); + settingsHelper.checkDuplicates(file, settingsList, settingsList, getDuplicatesListener(file, replace)); + } } } else if (empty) { app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error))); @@ -765,6 +795,124 @@ public class ImportHelper { executeImportTask(settingsImportTask); } + private CheckDuplicatesListener getDuplicatesListener(final File file, final boolean replace) { + return new CheckDuplicatesListener() { + @Override + public void onDuplicatesChecked(@NonNull List duplicates, List items) { + if (replace) { + for (SettingsItem item : items) { + item.setShouldReplace(true); + } + } + app.getSettingsHelper().importSettings(file, items, "", 1, getImportListener(file)); + } + }; + } + + private SettingsImportListener getImportListener(final File file) { + return new SettingsImportListener() { + @Override + public void onSettingsImportFinished(boolean succeed, @NonNull List items) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null && succeed) { + FragmentManager fm = mapActivity.getSupportFragmentManager(); + app.getRendererRegistry().updateExternalRenderers(); + AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { + @Override + public void onRoutingFilesLoaded() { + } + }); + if (file != null) { + ImportCompleteFragment.showInstance(fm, items, file.getName()); + } + } + } + }; + } + + public static Map> getSettingsToOperate(List settingsItems, boolean importComplete) { + Map> settingsToOperate = new HashMap<>(); + List profiles = new ArrayList<>(); + List quickActions = new ArrayList<>(); + List poiUIFilters = new ArrayList<>(); + List tileSourceTemplates = new ArrayList<>(); + List routingFilesList = new ArrayList<>(); + List renderFilesList = new ArrayList<>(); + List avoidRoads = new ArrayList<>(); + for (SettingsItem item : settingsItems) { + switch (item.getType()) { + case PROFILE: + profiles.add(((ProfileSettingsItem) item).getModeBean()); + break; + case FILE: + FileSettingsItem fileItem = (FileSettingsItem) item; + if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.RENDERING_STYLE) { + renderFilesList.add(fileItem.getFile()); + } else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.ROUTING_CONFIG) { + routingFilesList.add(fileItem.getFile()); + } + break; + case QUICK_ACTIONS: + QuickActionsSettingsItem quickActionsItem = (QuickActionsSettingsItem) item; + if (importComplete) { + quickActions.addAll(quickActionsItem.getAppliedItems()); + } else { + quickActions.addAll(quickActionsItem.getItems()); + } + break; + case POI_UI_FILTERS: + PoiUiFiltersSettingsItem poiUiFilterItem = (PoiUiFiltersSettingsItem) item; + if (importComplete) { + poiUIFilters.addAll(poiUiFilterItem.getAppliedItems()); + } else { + poiUIFilters.addAll(poiUiFilterItem.getItems()); + } + break; + case MAP_SOURCES: + MapSourcesSettingsItem mapSourcesItem = (MapSourcesSettingsItem) item; + if (importComplete) { + tileSourceTemplates.addAll(mapSourcesItem.getAppliedItems()); + } else { + tileSourceTemplates.addAll(mapSourcesItem.getItems()); + } + break; + case AVOID_ROADS: + AvoidRoadsSettingsItem avoidRoadsItem = (AvoidRoadsSettingsItem) item; + if (importComplete) { + avoidRoads.addAll(avoidRoadsItem.getAppliedItems()); + } else { + avoidRoads.addAll(avoidRoadsItem.getItems()); + } + break; + default: + break; + } + } + + if (!profiles.isEmpty()) { + settingsToOperate.put(ExportSettingsType.PROFILE, profiles); + } + if (!quickActions.isEmpty()) { + settingsToOperate.put(ExportSettingsType.QUICK_ACTIONS, quickActions); + } + if (!poiUIFilters.isEmpty()) { + settingsToOperate.put(ExportSettingsType.POI_TYPES, poiUIFilters); + } + if (!tileSourceTemplates.isEmpty()) { + settingsToOperate.put(ExportSettingsType.MAP_SOURCES, tileSourceTemplates); + } + if (!renderFilesList.isEmpty()) { + settingsToOperate.put(ExportSettingsType.CUSTOM_RENDER_STYLE, renderFilesList); + } + if (!routingFilesList.isEmpty()) { + settingsToOperate.put(ExportSettingsType.CUSTOM_ROUTING, routingFilesList); + } + if (!avoidRoads.isEmpty()) { + settingsToOperate.put(ExportSettingsType.AVOID_ROADS, avoidRoads); + } + return settingsToOperate; + } + private void handlePluginImport(final PluginSettingsItem pluginItem, final File file) { final ProgressDialog progress = new ProgressDialog(activity); progress.setTitle(app.getString(R.string.loading_smth, "")); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java b/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java new file mode 100644 index 0000000000..bda48d389f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java @@ -0,0 +1,11 @@ +package net.osmand.plus.settings.backend; + +public enum ExportSettingsType { + PROFILE, + QUICK_ACTIONS, + POI_TYPES, + MAP_SOURCES, + CUSTOM_RENDER_STYLE, + CUSTOM_ROUTING, + AVOID_ROADS +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java index 2b5b4282d4..01ca1cb38c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java @@ -100,6 +100,8 @@ public class SettingsHelper { public static final int VERSION = 1; + public static final String SETTINGS_TYPE_LIST_KEY = "settings_type_list_key"; + public static final String REPLACE_KEY = "replace"; public static final String SETTINGS_LATEST_CHANGES_KEY = "settings_latest_changes"; public static final String SETTINGS_VERSION_KEY = "settings_version"; @@ -2928,4 +2930,109 @@ public class SettingsHelper { CHECK_DUPLICATES, IMPORT } + + public List getFilteredSettingsItems(Map> additionalData, + List settingsTypes) { + List settingsItems = new ArrayList<>(); + for (ExportSettingsType settingsType : settingsTypes) { + List settingsDataObjects = additionalData.get(settingsType); + if (settingsDataObjects != null) { + settingsItems.addAll(app.getSettingsHelper().prepareAdditionalSettingsItems( + new ArrayList<>(settingsDataObjects))); + } + } + return settingsItems; + } + + public Map> getAdditionalData() { + Map> dataList = new HashMap<>(); + + QuickActionRegistry registry = app.getQuickActionRegistry(); + List actionsList = registry.getQuickActions(); + if (!actionsList.isEmpty()) { + dataList.put(ExportSettingsType.QUICK_ACTIONS, actionsList); + } + + List poiList = app.getPoiFilters().getUserDefinedPoiFilters(false); + if (!poiList.isEmpty()) { + dataList.put(ExportSettingsType.POI_TYPES, poiList); + } + + List iTileSources = new ArrayList<>(); + Set tileSourceNames = app.getSettings().getTileSourceEntries(true).keySet(); + for (String name : tileSourceNames) { + File f = app.getAppPath(IndexConstants.TILES_INDEX_DIR + name); + if (f != null) { + ITileSource template; + if (f.getName().endsWith(SQLiteTileSource.EXT)) { + template = new SQLiteTileSource(app, f, TileSourceManager.getKnownSourceTemplates()); + } else { + template = TileSourceManager.createTileSourceTemplate(f); + } + if (template.getUrlTemplate() != null) { + iTileSources.add(template); + } + } + } + if (!iTileSources.isEmpty()) { + dataList.put(ExportSettingsType.MAP_SOURCES, iTileSources); + } + + Map externalRenderers = app.getRendererRegistry().getExternalRenderers(); + if (!externalRenderers.isEmpty()) { + dataList.put(ExportSettingsType.CUSTOM_RENDER_STYLE, new ArrayList<>(externalRenderers.values())); + } + + File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); + if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) { + File[] fl = routingProfilesFolder.listFiles(); + if (fl != null && fl.length > 0) { + dataList.put(ExportSettingsType.CUSTOM_ROUTING, Arrays.asList(fl)); + } + } + + Map impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads(); + if (!impassableRoads.isEmpty()) { + dataList.put(ExportSettingsType.AVOID_ROADS, new ArrayList<>(impassableRoads.values())); + } + return dataList; + } + + public List prepareAdditionalSettingsItems(List data) { + List settingsItems = new ArrayList<>(); + List quickActions = new ArrayList<>(); + List poiUIFilters = new ArrayList<>(); + List tileSourceTemplates = new ArrayList<>(); + List avoidRoads = new ArrayList<>(); + for (Object object : data) { + if (object instanceof QuickAction) { + quickActions.add((QuickAction) object); + } else if (object instanceof PoiUIFilter) { + poiUIFilters.add((PoiUIFilter) object); + } else if (object instanceof TileSourceTemplate || object instanceof SQLiteTileSource) { + tileSourceTemplates.add((ITileSource) object); + } else if (object instanceof File) { + try { + settingsItems.add(new FileSettingsItem(app, (File) object)); + } catch (IllegalArgumentException e) { + LOG.warn("Trying to export unsuported file type", e); + } + } else if (object instanceof AvoidRoadInfo) { + avoidRoads.add((AvoidRoadInfo) object); + } + } + if (!quickActions.isEmpty()) { + settingsItems.add(new QuickActionsSettingsItem(app, quickActions)); + } + if (!poiUIFilters.isEmpty()) { + settingsItems.add(new PoiUiFiltersSettingsItem(app, poiUIFilters)); + } + if (!tileSourceTemplates.isEmpty()) { + settingsItems.add(new MapSourcesSettingsItem(app, tileSourceTemplates)); + } + if (!avoidRoads.isEmpty()) { + settingsItems.add(new AvoidRoadsSettingsItem(app, avoidRoads)); + } + return settingsItems; + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java index 18e8900203..01199ccff2 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java @@ -16,6 +16,7 @@ import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.map.ITileSource; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmandApplication; @@ -50,8 +51,8 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter { private OsmandApplication app; private UiUtilities uiUtilities; private List data; - private Map> itemsMap; - private List itemsTypes; + private Map> itemsMap; + private List itemsTypes; private boolean nightMode; private boolean importState; private int activeColorRes; @@ -82,7 +83,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter { } boolean isLastGroup = groupPosition == getGroupCount() - 1; - final Type type = itemsTypes.get(groupPosition); + final ExportSettingsType type = itemsTypes.get(groupPosition); TextView titleTv = group.findViewById(R.id.title_tv); TextView subTextTv = group.findViewById(R.id.sub_text_tv); @@ -146,7 +147,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter { boolean isLastGroup = groupPosition == getGroupCount() - 1; boolean itemSelected = data.contains(currentItem); - final Type type = itemsTypes.get(groupPosition); + final ExportSettingsType type = itemsTypes.get(groupPosition); TextView title = child.findViewById(R.id.title_tv); TextView subText = child.findViewById(R.id.sub_title_tv); @@ -299,7 +300,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter { return app.getString(R.string.n_items_of_z, String.valueOf(amount), String.valueOf(listItems.size())); } - private int getGroupTitle(Type type) { + private int getGroupTitle(ExportSettingsType type) { switch (type) { case PROFILE: return R.string.shared_string_profiles; @@ -320,15 +321,15 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter { } } - private void setupIcon(ImageView icon, int iconRes, boolean itemSelected) { - if (itemSelected) { - icon.setImageDrawable(uiUtilities.getIcon(iconRes, activeColorRes)); - } else { - icon.setImageDrawable(uiUtilities.getIcon(iconRes, nightMode)); - } - } + private void setupIcon(ImageView icon, int iconRes, boolean itemSelected) { + if (itemSelected) { + icon.setImageDrawable(uiUtilities.getIcon(iconRes, activeColorRes)); + } else { + icon.setImageDrawable(uiUtilities.getIcon(iconRes, nightMode)); + } + } - public void updateSettingsList(Map> itemsMap) { + public void updateSettingsList(Map> itemsMap) { this.itemsMap = itemsMap; this.itemsTypes = new ArrayList<>(itemsMap.keySet()); Collections.sort(itemsTypes); @@ -354,14 +355,4 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter { List getData() { return this.data; } - - public enum Type { - PROFILE, - QUICK_ACTIONS, - POI_TYPES, - MAP_SOURCES, - CUSTOM_RENDER_STYLE, - CUSTOM_ROUTING, - AVOID_ROADS - } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java index 40fa4e290c..c95f7d578c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportProfileBottomSheet.java @@ -24,43 +24,27 @@ import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; -import net.osmand.data.LatLon; -import net.osmand.map.ITileSource; -import net.osmand.map.TileSourceManager; -import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.UiUtilities; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; -import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; -import net.osmand.plus.poi.PoiUIFilter; -import net.osmand.plus.quickaction.QuickAction; -import net.osmand.plus.quickaction.QuickActionRegistry; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.SettingsHelper; -import net.osmand.plus.settings.backend.SettingsHelper.AvoidRoadsSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.FileSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.MapSourcesSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.PoiUiFiltersSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.QuickActionsSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; -import net.osmand.plus.settings.fragments.ExportImportSettingsAdapter.Type; import org.apache.commons.logging.Log; import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { @@ -73,7 +57,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { private OsmandApplication app; private ApplicationMode profile; - private Map> dataList = new HashMap<>(); + private Map> dataList = new HashMap<>(); private ExportImportSettingsAdapter adapter; private SettingsHelper.SettingsExportListener exportListener; @@ -87,7 +71,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { super.onCreate(savedInstanceState); app = requiredMyApplication(); profile = getAppMode(); - dataList = getAdditionalData(); + dataList = app.getSettingsHelper().getAdditionalData(); if (savedInstanceState != null) { includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY); exportingProfile = savedInstanceState.getBoolean(EXPORTING_PROFILE_KEY); @@ -146,7 +130,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { topSwitchDivider.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE); bottomSwitchDivider.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE); if (includeAdditionalData) { - adapter.updateSettingsList(getAdditionalData()); + adapter.updateSettingsList(app.getSettingsHelper().getAdditionalData()); adapter.selectAll(true); } else { adapter.selectAll(false); @@ -224,104 +208,11 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { } } - private Map> getAdditionalData() { - Map> dataList = new HashMap<>(); - - - QuickActionRegistry registry = app.getQuickActionRegistry(); - List actionsList = registry.getQuickActions(); - if (!actionsList.isEmpty()) { - dataList.put(Type.QUICK_ACTIONS, actionsList); - } - - List poiList = app.getPoiFilters().getUserDefinedPoiFilters(false); - if (!poiList.isEmpty()) { - dataList.put(Type.POI_TYPES, poiList); - } - - List iTileSources = new ArrayList<>(); - Set tileSourceNames = app.getSettings().getTileSourceEntries(true).keySet(); - for (String name : tileSourceNames) { - File f = app.getAppPath(IndexConstants.TILES_INDEX_DIR + name); - if (f != null) { - ITileSource template; - if (f.getName().endsWith(SQLiteTileSource.EXT)) { - template = new SQLiteTileSource(app, f, TileSourceManager.getKnownSourceTemplates()); - } else { - template = TileSourceManager.createTileSourceTemplate(f); - } - if (template.getUrlTemplate() != null) { - iTileSources.add(template); - } - } - } - if (!iTileSources.isEmpty()) { - dataList.put(Type.MAP_SOURCES, iTileSources); - } - - Map externalRenderers = app.getRendererRegistry().getExternalRenderers(); - if (!externalRenderers.isEmpty()) { - dataList.put(Type.CUSTOM_RENDER_STYLE, new ArrayList<>(externalRenderers.values())); - } - - File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); - if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) { - File[] fl = routingProfilesFolder.listFiles(); - if (fl != null && fl.length > 0) { - dataList.put(Type.CUSTOM_ROUTING, Arrays.asList(fl)); - } - } - - Map impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads(); - if (!impassableRoads.isEmpty()) { - dataList.put(Type.AVOID_ROADS, new ArrayList<>(impassableRoads.values())); - } - return dataList; - } - private List prepareSettingsItemsForExport() { List settingsItems = new ArrayList<>(); settingsItems.add(new ProfileSettingsItem(app, profile)); if (includeAdditionalData) { - settingsItems.addAll(prepareAdditionalSettingsItems()); - } - return settingsItems; - } - - private List prepareAdditionalSettingsItems() { - List settingsItems = new ArrayList<>(); - List quickActions = new ArrayList<>(); - List poiUIFilters = new ArrayList<>(); - List tileSourceTemplates = new ArrayList<>(); - List avoidRoads = new ArrayList<>(); - for (Object object : adapter.getData()) { - if (object instanceof QuickAction) { - quickActions.add((QuickAction) object); - } else if (object instanceof PoiUIFilter) { - poiUIFilters.add((PoiUIFilter) object); - } else if (object instanceof TileSourceTemplate || object instanceof SQLiteTileSource) { - tileSourceTemplates.add((ITileSource) object); - } else if (object instanceof File) { - try { - settingsItems.add(new FileSettingsItem(app, (File) object)); - } catch (IllegalArgumentException e) { - LOG.warn("Trying to export unsuported file type", e); - } - } else if (object instanceof AvoidRoadInfo) { - avoidRoads.add((AvoidRoadInfo) object); - } - } - if (!quickActions.isEmpty()) { - settingsItems.add(new QuickActionsSettingsItem(app, quickActions)); - } - if (!poiUIFilters.isEmpty()) { - settingsItems.add(new PoiUiFiltersSettingsItem(app, poiUIFilters)); - } - if (!tileSourceTemplates.isEmpty()) { - settingsItems.add(new MapSourcesSettingsItem(app, tileSourceTemplates)); - } - if (!avoidRoads.isEmpty()) { - settingsItems.add(new AvoidRoadsSettingsItem(app, avoidRoads)); + settingsItems.addAll(app.getSettingsHelper().prepareAdditionalSettingsItems(adapter.getData())); } return settingsItems; } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java index a18e2f6aa9..e152d5ea68 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java @@ -22,6 +22,8 @@ import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -31,7 +33,6 @@ import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment; import net.osmand.plus.quickaction.QuickActionListFragment; import net.osmand.plus.routepreparationmenu.AvoidRoadsBottomSheetDialogFragment; import net.osmand.plus.search.QuickSearchDialogFragment; -import net.osmand.plus.settings.fragments.ExportImportSettingsAdapter.Type; import java.util.List; @@ -117,11 +118,11 @@ public class ImportCompleteFragment extends BaseOsmAndFragment { if (settingsItems != null) { ImportedSettingsItemsAdapter adapter = new ImportedSettingsItemsAdapter( app, - ImportSettingsFragment.getSettingsToOperate(settingsItems, true), + ImportHelper.getSettingsToOperate(settingsItems, true), nightMode, new ImportedSettingsItemsAdapter.OnItemClickListener() { @Override - public void onItemClick(Type type) { + public void onItemClick(ExportSettingsType type) { navigateTo(type); } }); @@ -137,7 +138,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment { } } - private void navigateTo(Type type) { + private void navigateTo(ExportSettingsType type) { FragmentManager fm = getFragmentManager(); Activity activity = requireActivity(); if (fm == null || fm.isStateSaved()) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java index 284964b88d..051bf422f8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java @@ -34,11 +34,11 @@ import net.osmand.plus.AppInitializer; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.plus.settings.backend.SettingsHelper; import net.osmand.plus.settings.backend.SettingsHelper.AvoidRoadsSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.FileSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.FileSettingsItem.FileSubtype; import net.osmand.plus.settings.backend.SettingsHelper.ImportAsyncTask; import net.osmand.plus.settings.backend.SettingsHelper.ImportType; import net.osmand.plus.settings.backend.SettingsHelper.MapSourcesSettingsItem; @@ -53,7 +53,6 @@ import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.quickaction.QuickAction; -import net.osmand.plus.settings.fragments.ExportImportSettingsAdapter.Type; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; @@ -65,6 +64,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static net.osmand.plus.helpers.ImportHelper.getSettingsToOperate; + public class ImportSettingsFragment extends BaseOsmAndFragment implements View.OnClickListener { @@ -180,7 +181,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment } adapter = new ExportImportSettingsAdapter(app, nightMode, true); - Map> itemsMap = new HashMap<>(); + Map> itemsMap = new HashMap<>(); if (settingsItems != null) { itemsMap = getSettingsToOperate(settingsItems, false); adapter.updateSettingsList(itemsMap); @@ -196,7 +197,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment } else { toolbarLayout.setTitle(getString(R.string.shared_string_import)); } - if (itemsMap.size() == 1 && itemsMap.containsKey(Type.PROFILE)) { + if (itemsMap.size() == 1 && itemsMap.containsKey(ExportSettingsType.PROFILE)) { expandableList.expandGroup(0); } } @@ -420,89 +421,6 @@ public class ImportSettingsFragment extends BaseOsmAndFragment return settingsItems; } - public static Map> getSettingsToOperate(List settingsItems, boolean importComplete) { - Map> settingsToOperate = new HashMap<>(); - List profiles = new ArrayList<>(); - List quickActions = new ArrayList<>(); - List poiUIFilters = new ArrayList<>(); - List tileSourceTemplates = new ArrayList<>(); - List routingFilesList = new ArrayList<>(); - List renderFilesList = new ArrayList<>(); - List avoidRoads = new ArrayList<>(); - for (SettingsItem item : settingsItems) { - switch (item.getType()) { - case PROFILE: - profiles.add(((ProfileSettingsItem) item).getModeBean()); - break; - case FILE: - FileSettingsItem fileItem = (FileSettingsItem) item; - if (fileItem.getSubtype() == FileSubtype.RENDERING_STYLE) { - renderFilesList.add(fileItem.getFile()); - } else if (fileItem.getSubtype() == FileSubtype.ROUTING_CONFIG) { - routingFilesList.add(fileItem.getFile()); - } - break; - case QUICK_ACTIONS: - QuickActionsSettingsItem quickActionsItem = (QuickActionsSettingsItem) item; - if (importComplete) { - quickActions.addAll(quickActionsItem.getAppliedItems()); - } else { - quickActions.addAll(quickActionsItem.getItems()); - } - break; - case POI_UI_FILTERS: - PoiUiFiltersSettingsItem poiUiFilterItem = (PoiUiFiltersSettingsItem) item; - if (importComplete) { - poiUIFilters.addAll(poiUiFilterItem.getAppliedItems()); - } else { - poiUIFilters.addAll(poiUiFilterItem.getItems()); - } - break; - case MAP_SOURCES: - MapSourcesSettingsItem mapSourcesItem = (MapSourcesSettingsItem) item; - if (importComplete) { - tileSourceTemplates.addAll(mapSourcesItem.getAppliedItems()); - } else { - tileSourceTemplates.addAll(mapSourcesItem.getItems()); - } - break; - case AVOID_ROADS: - AvoidRoadsSettingsItem avoidRoadsItem = (AvoidRoadsSettingsItem) item; - if (importComplete) { - avoidRoads.addAll(avoidRoadsItem.getAppliedItems()); - } else { - avoidRoads.addAll(avoidRoadsItem.getItems()); - } - break; - default: - break; - } - } - - if (!profiles.isEmpty()) { - settingsToOperate.put(Type.PROFILE, profiles); - } - if (!quickActions.isEmpty()) { - settingsToOperate.put(Type.QUICK_ACTIONS, quickActions); - } - if (!poiUIFilters.isEmpty()) { - settingsToOperate.put(Type.POI_TYPES, poiUIFilters); - } - if (!tileSourceTemplates.isEmpty()) { - settingsToOperate.put(Type.MAP_SOURCES, tileSourceTemplates); - } - if (!renderFilesList.isEmpty()) { - settingsToOperate.put(Type.CUSTOM_RENDER_STYLE, renderFilesList); - } - if (!routingFilesList.isEmpty()) { - settingsToOperate.put(Type.CUSTOM_ROUTING, routingFilesList); - } - if (!avoidRoads.isEmpty()) { - settingsToOperate.put(Type.AVOID_ROADS, avoidRoads); - } - return settingsToOperate; - } - @Override public int getStatusBarColorId() { return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportedSettingsItemsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportedSettingsItemsAdapter.java index 270391c619..e663e6f189 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportedSettingsItemsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportedSettingsItemsAdapter.java @@ -14,7 +14,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.settings.fragments.ExportImportSettingsAdapter.Type; +import net.osmand.plus.settings.backend.ExportSettingsType; import java.util.ArrayList; @@ -25,15 +25,15 @@ import java.util.Map; public class ImportedSettingsItemsAdapter extends RecyclerView.Adapter { - private Map> itemsMap; - private List itemsTypes; + private Map> itemsMap; + private List itemsTypes; private UiUtilities uiUtils; private OsmandApplication app; private boolean nightMode; private OnItemClickListener listener; - ImportedSettingsItemsAdapter(@NonNull OsmandApplication app, Map> itemsMap, - boolean nightMode, OnItemClickListener listener) { + ImportedSettingsItemsAdapter(@NonNull OsmandApplication app, Map> itemsMap, + boolean nightMode, OnItemClickListener listener) { this.app = app; this.itemsMap = itemsMap; this.nightMode = nightMode; @@ -53,7 +53,7 @@ public class ImportedSettingsItemsAdapter extends @Override public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { - final Type currentItemType = itemsTypes.get(position); + final ExportSettingsType currentItemType = itemsTypes.get(position); boolean isLastItem = itemsTypes.size() - 1 == position; int activeColorRes = nightMode ? R.color.active_color_primary_dark @@ -130,6 +130,6 @@ public class ImportedSettingsItemsAdapter extends } interface OnItemClickListener { - void onItemClick(Type type); + void onItemClick(ExportSettingsType type); } } From ac78952962b33c274445007c28198c9c56392ac7 Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 1 Oct 2020 17:51:03 +0300 Subject: [PATCH 0390/1366] delete unnecessary code --- .../net/osmand/plus/dashboard/DashboardOnMap.java | 6 +++--- .../net/osmand/plus/dialogs/ConfigureMapMenu.java | 14 ++------------ .../fragments/ConfigureMenuItemsFragment.java | 4 ++-- .../fragments/ConfigureMenuRootFragment.java | 4 ++-- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index a7bb87db2a..bb2143c7eb 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -567,8 +567,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo boolean appModeChanged = currentAppMode != previousAppMode; boolean refresh = this.visibleType == type && !appModeChanged; - this.previousAppMode = currentAppMode; - this.visibleType = type; + previousAppMode = currentAppMode; + visibleType = type; DashboardOnMap.staticVisible = visible; DashboardOnMap.staticVisibleType = type; mapActivity.enableDrawer(); @@ -705,7 +705,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo if (visibleType == DashboardType.CONFIGURE_SCREEN) { cm = mapActivity.getMapLayers().getMapWidgetRegistry().getViewConfigureMenuAdapter(mapActivity); } else if (visibleType == DashboardType.CONFIGURE_MAP) { - cm = new ConfigureMapMenu(mapActivity).createListAdapter(); + cm = new ConfigureMapMenu().createListAdapter(mapActivity); } else if (visibleType == DashboardType.LIST_MENU) { cm = mapActivity.getMapActions().createMainOptionsMenu(); } else if (visibleType == DashboardType.ROUTE_PREFERENCES) { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index ea1934c5e6..83c4e1942d 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -110,17 +110,11 @@ public class ConfigureMapMenu { private int selectedLanguageIndex; private boolean transliterateNames; - private MapActivity ma; - public interface OnClickListener { void onClick(); } - public ConfigureMapMenu(MapActivity mapActivity) { - this.ma = mapActivity; - } - - public ContextMenuAdapter createListAdapter() { + public ContextMenuAdapter createListAdapter(final MapActivity ma) { OsmandApplication app = ma.getMyApplication(); boolean nightMode = app.getDaynightHelper().isNightModeForMapControls(); int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; @@ -133,7 +127,7 @@ public class ConfigureMapMenu { adapter.setChangeAppModeListener(new OnClickListener() { @Override public void onClick() { - ma.getDashboard().updateListAdapter(createListAdapter()); + ma.getDashboard().updateListAdapter(createListAdapter(ma)); } }); List customRules = getCustomRules(app, @@ -1124,10 +1118,6 @@ public class ConfigureMapMenu { } } - private OsmandApplication getMyApplication() { - return ma.getMyApplication(); - } - private static class StringSpinnerArrayAdapter extends ArrayAdapter { private boolean nightMode; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java index 926264aceb..44fb4bf7f6 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java @@ -197,8 +197,8 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment contextMenuAdapter = ((MapActivity) activity).getMapActions().createMainOptionsMenu(); break; case CONFIGURE_MAP: - ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity) activity); - contextMenuAdapter = configureMapMenu.createListAdapter(); + ConfigureMapMenu configureMapMenu = new ConfigureMapMenu(); + contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity); break; case CONTEXT_MENU_ACTIONS: MapContextMenu menu = ((MapActivity) activity).getContextMenu(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java index f7b2dda412..330f1c0a18 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuRootFragment.java @@ -285,8 +285,8 @@ public class ConfigureMenuRootFragment extends BaseOsmAndFragment { contextMenuAdapter = mapActivityActions.createMainOptionsMenu(); break; case CONFIGURE_MAP: - ConfigureMapMenu configureMapMenu = new ConfigureMapMenu((MapActivity) activity); - contextMenuAdapter = configureMapMenu.createListAdapter(); + ConfigureMapMenu configureMapMenu = new ConfigureMapMenu(); + contextMenuAdapter = configureMapMenu.createListAdapter((MapActivity) activity); break; case CONTEXT_MENU_ACTIONS: MapContextMenu menu = ((MapActivity) activity).getContextMenu(); From 48dbb64d09610243ef6956678e1920db7d9cab2b Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Jun 2020 15:47:01 +0300 Subject: [PATCH 0391/1366] Fix kmz file import --- .../net/osmand/plus/helpers/ImportHelper.java | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index c57f53a0fa..a8d621f9ed 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -71,6 +71,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; @@ -314,13 +315,17 @@ public class ImportHelper { } else if (fileName != null && fileName.endsWith(KMZ_SUFFIX)) { try { zis = new ZipInputStream(is); - zis.getNextEntry(); - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(KML_SUFFIX)) { + final String result = Kml2Gpx.toGpx(zis); + if (result != null) { + try { + return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + return null; + } + } } } } catch (Exception e) { @@ -418,13 +423,18 @@ public class ImportHelper { is = app.getContentResolver().openInputStream(kmzFile); if (is != null) { zis = new ZipInputStream(is); - zis.getNextEntry(); - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(KML_SUFFIX)) { + final String result = Kml2Gpx.toGpx(zis); + if (result != null) { + try { + return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + return null; + } + } } } } From b7bbe55dad6678ed93f38fcf7b533038fc0e699a Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 1 Oct 2020 19:14:46 +0300 Subject: [PATCH 0392/1366] Huawei inapps/subs introduced --- .../plus/inapp/InAppPurchaseHelperImpl.java | 62 +- .../osmand/plus/inapp/InAppPurchasesImpl.java | 323 +++++++ .../net/osmand/plus/inapp/CipherUtil.java | 96 ++ .../net/osmand/plus/inapp/Constants.java | 33 + .../osmand/plus/inapp/ExceptionHandle.java | 103 +++ .../net/osmand/plus/inapp/IapApiCallback.java | 37 + .../osmand/plus/inapp/IapRequestHelper.java | 351 +++++++ .../plus/inapp/InAppPurchaseHelperImpl.java | 861 +++++++++++------- .../osmand/plus/inapp/InAppPurchasesImpl.java | 184 ++++ .../net/osmand/plus/inapp/InAppUtils.java | 49 + .../osmand/plus/inapp/SubscriptionUtils.java | 139 +++ .../OsmandInAppPurchaseActivity.java | 70 +- .../osmand/plus/helpers/DiscountHelper.java | 10 +- .../plus/inapp/InAppPurchaseHelper.java | 58 +- .../net/osmand/plus/inapp/InAppPurchases.java | 407 +-------- 15 files changed, 1987 insertions(+), 796 deletions(-) create mode 100644 OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java create mode 100755 OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java create mode 100755 OsmAnd/src-huawei/net/osmand/plus/inapp/Constants.java create mode 100755 OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java create mode 100755 OsmAnd/src-huawei/net/osmand/plus/inapp/IapApiCallback.java create mode 100755 OsmAnd/src-huawei/net/osmand/plus/inapp/IapRequestHelper.java create mode 100644 OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java create mode 100644 OsmAnd/src-huawei/net/osmand/plus/inapp/InAppUtils.java create mode 100755 OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index c48294aeb2..fc9b1056f6 100644 --- a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -13,6 +13,8 @@ import com.android.billingclient.api.SkuDetailsResponseListener; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; +import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.inapp.util.BillingManager; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -49,13 +51,21 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { public InAppPurchaseHelperImpl(OsmandApplication ctx) { super(ctx); + purchases = new InAppPurchasesImpl(ctx); + } + + @Override + public void isInAppPurchaseSupported(@NonNull final Activity activity, @Nullable final InAppPurchaseInitCallback callback) { + if (callback != null) { + callback.onSuccess(); + } } private BillingManager getBillingManager() { return billingManager; } - protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppRunnable runnable) { + protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppCommand runnable) { billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() { @Override @@ -77,7 +87,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { return; } - processingTask = !runnable.run(InAppPurchaseHelperImpl.this); + runnable.run(InAppPurchaseHelperImpl.this); } @Override @@ -114,7 +124,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } List skuSubscriptions = new ArrayList<>(); - for (InAppPurchases.InAppSubscription subscription : getInAppPurchases().getAllInAppSubscriptions()) { + for (InAppSubscription subscription : getInAppPurchases().getAllInAppSubscriptions()) { skuSubscriptions.add(subscription.getSku()); } for (Purchase p : purchases) { @@ -165,9 +175,9 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { public void purchaseFullVersion(final Activity activity) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); - exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppRunnable() { + exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppCommand() { @Override - public boolean run(InAppPurchaseHelper helper) { + public void run(InAppPurchaseHelper helper) { try { SkuDetails skuDetails = getSkuDetails(getFullVersion().getSku()); if (skuDetails == null) { @@ -179,22 +189,21 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } else { throw new IllegalStateException("BillingManager disposed"); } - return false; + commandDone(); } catch (Exception e) { complain("Cannot launch full version purchase!"); logError("purchaseFullVersion Error", e); stop(true); } - return true; } }); } public void purchaseDepthContours(final Activity activity) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); - exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppRunnable() { + exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppCommand() { @Override - public boolean run(InAppPurchaseHelper helper) { + public void run(InAppPurchaseHelper helper) { try { SkuDetails skuDetails = getSkuDetails(getDepthContours().getSku()); if (skuDetails == null) { @@ -206,13 +215,12 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } else { throw new IllegalStateException("BillingManager disposed"); } - return false; + commandDone(); } catch (Exception e) { complain("Cannot launch depth contours purchase!"); logError("purchaseDepthContours Error", e); stop(true); } - return true; } }); } @@ -295,7 +303,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { */ List allOwnedSubscriptionSkus = getAllOwnedSubscriptionSkus(); - for (InAppPurchases.InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { + for (InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { if (hasDetails(s.getSku())) { Purchase purchase = getPurchase(s.getSku()); SkuDetails liveUpdatesDetails = getSkuDetails(s.getSku()); @@ -309,9 +317,9 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { Purchase purchase = getPurchase(sku); SkuDetails liveUpdatesDetails = getSkuDetails(sku); if (liveUpdatesDetails != null) { - InAppPurchases.InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); + InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); if (s == null) { - s = new InAppPurchases.InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails); + s = new InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails); } fetchInAppPurchase(s, liveUpdatesDetails, purchase); } @@ -441,21 +449,21 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } String subscriptionPeriod = skuDetails.getSubscriptionPeriod(); if (!Algorithms.isEmpty(subscriptionPeriod)) { - if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + if (inAppPurchase instanceof InAppSubscription) { try { - ((InAppPurchases.InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); + ((InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); } catch (ParseException e) { LOG.error(e); } } } - if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + if (inAppPurchase instanceof InAppSubscription) { String introductoryPrice = skuDetails.getIntroductoryPrice(); String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod(); String introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles(); long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros(); if (!Algorithms.isEmpty(introductoryPrice)) { - InAppPurchases.InAppSubscription s = (InAppPurchases.InAppSubscription) inAppPurchase; + InAppSubscription s = (InAppSubscription) inAppPurchase; try { s.setIntroductoryInfo(new InAppPurchases.InAppSubscriptionIntroductoryInfo(s, introductoryPrice, introductoryPriceAmountMicros, introductoryPricePeriod, introductoryPriceCycles)); @@ -466,10 +474,10 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } - protected InAppRunnable getPurchaseLiveUpdatesCommand(final WeakReference activity, final String sku, final String payload) { - return new InAppRunnable() { + protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference activity, final String sku, final String payload) { + return new InAppCommand() { @Override - public boolean run(InAppPurchaseHelper helper) { + public void run(InAppPurchaseHelper helper) { try { Activity a = activity.get(); SkuDetails skuDetails = getSkuDetails(sku); @@ -481,7 +489,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } else { throw new IllegalStateException("BillingManager disposed"); } - return false; + commandDone(); } else { stop(true); } @@ -489,15 +497,14 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { logError("launchPurchaseFlow Error", e); stop(true); } - return true; } }; } - protected InAppRunnable getRequestInventoryCommand() { - return new InAppRunnable() { + protected InAppCommand getRequestInventoryCommand() { + return new InAppCommand() { @Override - public boolean run(InAppPurchaseHelper helper) { + public void run(InAppPurchaseHelper helper) { logDebug("Setup successful. Querying inventory."); try { BillingManager billingManager = getBillingManager(); @@ -506,13 +513,12 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } else { throw new IllegalStateException("BillingManager disposed"); } - return false; + commandDone(); } catch (Exception e) { logError("queryInventoryAsync Error", e); notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); stop(true); } - return true; } }; } diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java new file mode 100644 index 0000000000..a2a0f8d680 --- /dev/null +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java @@ -0,0 +1,323 @@ +package net.osmand.plus.inapp; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.billingclient.api.SkuDetails; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.Version; + +public class InAppPurchasesImpl extends InAppPurchases { + + private static final InAppPurchase FULL_VERSION = new InAppPurchaseFullVersion(); + private static final InAppPurchaseDepthContoursFull DEPTH_CONTOURS_FULL = new InAppPurchaseDepthContoursFull(); + private static final InAppPurchaseDepthContoursFree DEPTH_CONTOURS_FREE = new InAppPurchaseDepthContoursFree(); + private static final InAppPurchaseContourLinesFull CONTOUR_LINES_FULL = new InAppPurchaseContourLinesFull(); + private static final InAppPurchaseContourLinesFree CONTOUR_LINES_FREE = new InAppPurchaseContourLinesFree(); + + private static final InAppSubscription[] LIVE_UPDATES_FULL = new InAppSubscription[]{ + new InAppPurchaseLiveUpdatesOldMonthlyFull(), + new InAppPurchaseLiveUpdatesMonthlyFull(), + new InAppPurchaseLiveUpdates3MonthsFull(), + new InAppPurchaseLiveUpdatesAnnualFull() + }; + + private static final InAppSubscription[] LIVE_UPDATES_FREE = new InAppSubscription[]{ + new InAppPurchaseLiveUpdatesOldMonthlyFree(), + new InAppPurchaseLiveUpdatesMonthlyFree(), + new InAppPurchaseLiveUpdates3MonthsFree(), + new InAppPurchaseLiveUpdatesAnnualFree() + }; + + public InAppPurchasesImpl(OsmandApplication ctx) { + super(ctx); + fullVersion = FULL_VERSION; + if (Version.isFreeVersion(ctx)) { + liveUpdates = new LiveUpdatesInAppPurchasesFree(); + } else { + liveUpdates = new LiveUpdatesInAppPurchasesFull(); + } + for (InAppSubscription s : liveUpdates.getAllSubscriptions()) { + if (s instanceof InAppPurchaseLiveUpdatesMonthly) { + if (s.isDiscounted()) { + discountedMonthlyLiveUpdates = s; + } else { + monthlyLiveUpdates = s; + } + } + } + if (Version.isFreeVersion(ctx)) { + depthContours = DEPTH_CONTOURS_FREE; + } else { + depthContours = DEPTH_CONTOURS_FULL; + } + if (Version.isFreeVersion(ctx)) { + contourLines = CONTOUR_LINES_FREE; + } else { + contourLines = CONTOUR_LINES_FULL; + } + + inAppPurchases = new InAppPurchase[] { fullVersion, depthContours, contourLines }; + } + + @Override + public boolean isFullVersion(String sku) { + return FULL_VERSION.getSku().equals(sku); + } + + @Override + public boolean isDepthContours(String sku) { + return DEPTH_CONTOURS_FULL.getSku().equals(sku) || DEPTH_CONTOURS_FREE.getSku().equals(sku); + } + + @Override + public boolean isContourLines(String sku) { + return CONTOUR_LINES_FULL.getSku().equals(sku) || CONTOUR_LINES_FREE.getSku().equals(sku); + } + + @Override + public boolean isLiveUpdates(String sku) { + for (InAppPurchase p : LIVE_UPDATES_FULL) { + if (p.getSku().equals(sku)) { + return true; + } + } + for (InAppPurchase p : LIVE_UPDATES_FREE) { + if (p.getSku().equals(sku)) { + return true; + } + } + return false; + } + + private static class InAppPurchaseFullVersion extends InAppPurchase { + + private static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price"; + + InAppPurchaseFullVersion() { + super(SKU_FULL_VERSION_PRICE); + } + + @Override + public String getDefaultPrice(Context ctx) { + return ctx.getString(R.string.full_version_price); + } + } + + private static class InAppPurchaseDepthContoursFull extends InAppPurchaseDepthContours { + + private static final String SKU_DEPTH_CONTOURS_FULL = "net.osmand.seadepth_plus"; + + InAppPurchaseDepthContoursFull() { + super(SKU_DEPTH_CONTOURS_FULL); + } + } + + private static class InAppPurchaseDepthContoursFree extends InAppPurchaseDepthContours { + + private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth"; + + InAppPurchaseDepthContoursFree() { + super(SKU_DEPTH_CONTOURS_FREE); + } + } + + private static class InAppPurchaseContourLinesFull extends InAppPurchaseContourLines { + + private static final String SKU_CONTOUR_LINES_FULL = "net.osmand.contourlines_plus"; + + InAppPurchaseContourLinesFull() { + super(SKU_CONTOUR_LINES_FULL); + } + } + + private static class InAppPurchaseContourLinesFree extends InAppPurchaseContourLines { + + private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.contourlines"; + + InAppPurchaseContourLinesFree() { + super(SKU_CONTOUR_LINES_FREE); + } + } + + private static class InAppPurchaseLiveUpdatesMonthlyFull extends InAppPurchaseLiveUpdatesMonthly { + + private static final String SKU_LIVE_UPDATES_MONTHLY_FULL = "osm_live_subscription_monthly_full"; + + InAppPurchaseLiveUpdatesMonthlyFull() { + super(SKU_LIVE_UPDATES_MONTHLY_FULL, 1); + } + + private InAppPurchaseLiveUpdatesMonthlyFull(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyFull(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdatesMonthlyFree extends InAppPurchaseLiveUpdatesMonthly { + + private static final String SKU_LIVE_UPDATES_MONTHLY_FREE = "osm_live_subscription_monthly_free"; + + InAppPurchaseLiveUpdatesMonthlyFree() { + super(SKU_LIVE_UPDATES_MONTHLY_FREE, 1); + } + + private InAppPurchaseLiveUpdatesMonthlyFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyFree(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdates3MonthsFull extends InAppPurchaseLiveUpdates3Months { + + private static final String SKU_LIVE_UPDATES_3_MONTHS_FULL = "osm_live_subscription_3_months_full"; + + InAppPurchaseLiveUpdates3MonthsFull() { + super(SKU_LIVE_UPDATES_3_MONTHS_FULL, 1); + } + + private InAppPurchaseLiveUpdates3MonthsFull(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsFull(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdates3MonthsFree extends InAppPurchaseLiveUpdates3Months { + + private static final String SKU_LIVE_UPDATES_3_MONTHS_FREE = "osm_live_subscription_3_months_free"; + + InAppPurchaseLiveUpdates3MonthsFree() { + super(SKU_LIVE_UPDATES_3_MONTHS_FREE, 1); + } + + private InAppPurchaseLiveUpdates3MonthsFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsFree(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdatesAnnualFull extends InAppPurchaseLiveUpdatesAnnual { + + private static final String SKU_LIVE_UPDATES_ANNUAL_FULL = "osm_live_subscription_annual_full"; + + InAppPurchaseLiveUpdatesAnnualFull() { + super(SKU_LIVE_UPDATES_ANNUAL_FULL, 1); + } + + private InAppPurchaseLiveUpdatesAnnualFull(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualFull(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdatesAnnualFree extends InAppPurchaseLiveUpdatesAnnual { + + private static final String SKU_LIVE_UPDATES_ANNUAL_FREE = "osm_live_subscription_annual_free"; + + InAppPurchaseLiveUpdatesAnnualFree() { + super(SKU_LIVE_UPDATES_ANNUAL_FREE, 1); + } + + private InAppPurchaseLiveUpdatesAnnualFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualFree(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdatesOldMonthlyFull extends InAppPurchaseLiveUpdatesOldMonthly { + + private static final String SKU_LIVE_UPDATES_OLD_MONTHLY_FULL = "osm_live_subscription_2"; + + InAppPurchaseLiveUpdatesOldMonthlyFull() { + super(SKU_LIVE_UPDATES_OLD_MONTHLY_FULL); + } + } + + private static class InAppPurchaseLiveUpdatesOldMonthlyFree extends InAppPurchaseLiveUpdatesOldMonthly { + + private static final String SKU_LIVE_UPDATES_OLD_MONTHLY_FREE = "osm_free_live_subscription_2"; + + InAppPurchaseLiveUpdatesOldMonthlyFree() { + super(SKU_LIVE_UPDATES_OLD_MONTHLY_FREE); + } + } + + public static class InAppPurchaseLiveUpdatesOldSubscription extends InAppSubscription { + + private SkuDetails details; + + InAppPurchaseLiveUpdatesOldSubscription(@NonNull SkuDetails details) { + super(details.getSku(), true); + this.details = details; + } + + @Override + public String getDefaultPrice(Context ctx) { + return ""; + } + + @Override + public CharSequence getTitle(Context ctx) { + return details.getTitle(); + } + + @Override + public CharSequence getDescription(@NonNull Context ctx) { + return details.getDescription(); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return null; + } + } + + private static class LiveUpdatesInAppPurchasesFree extends InAppSubscriptionList { + + public LiveUpdatesInAppPurchasesFree() { + super(LIVE_UPDATES_FREE); + } + } + + private static class LiveUpdatesInAppPurchasesFull extends InAppSubscriptionList { + + public LiveUpdatesInAppPurchasesFull() { + super(LIVE_UPDATES_FULL); + } + } +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java new file mode 100755 index 0000000000..2bfef4b76b --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java @@ -0,0 +1,96 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.osmand.plus.inapp; + +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +/** + * Signature related tools. + * + * @since 2019/12/9 + */ +public class CipherUtil { + private static final String TAG = "CipherUtil"; + private static final String SIGN_ALGORITHMS = "SHA256WithRSA"; + private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAooen3X9jSWarxugznzzMSvp4zir1Pg6uPOm7fqlLOL0Ix52e5FpeotMx871pQ9hrCkiyFg2e6UxD8IXXjvK6QJQbjNJ2jIfKkCusm90yloSEfvyLeiq5y7zg4+DoPglHi8RxZ9y308YIqnRDoslfGm5DnWa8RKUvFRVRiu1p3FN4SYIa/FWLtS5yygemtqMJi8I14V7xqQ5wExCGeSA6j1/AAWXEwZncJwKn0BTXQSvwVBPBRM5ksgt4q+Sc484ZIbntATyxsUipnEBFxq1OXn5Zw5/vVxUC8RSyDMQ/kC2RaEcFtA1tlIIjIdurbpNg3tyViPfQUQndvOs4nDrFzwIDAQAB"; + + /** + * the method to check the signature for the data returned from the interface + * @param content Unsigned data + * @param sign the signature for content + * @param publicKey the public of the application + * @return boolean + */ + public static boolean doCheck(String content, String sign, String publicKey) { + if (TextUtils.isEmpty(publicKey)) { + Log.e(TAG, "publicKey is null"); + return false; + } + + if (TextUtils.isEmpty(content) || TextUtils.isEmpty(sign)) { + Log.e(TAG, "data is error"); + return false; + } + + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + byte[] encodedKey = Base64.decode(publicKey, Base64.DEFAULT); + PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); + + java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); + + signature.initVerify(pubKey); + signature.update(content.getBytes("utf-8")); + + boolean bverify = signature.verify(Base64.decode(sign, Base64.DEFAULT)); + return bverify; + + } catch (NoSuchAlgorithmException e) { + Log.e(TAG, "doCheck NoSuchAlgorithmException" + e); + } catch (InvalidKeySpecException e) { + Log.e(TAG, "doCheck InvalidKeySpecException" + e); + } catch (InvalidKeyException e) { + Log.e(TAG, "doCheck InvalidKeyException" + e); + } catch (SignatureException e) { + Log.e(TAG, "doCheck SignatureException" + e); + } catch (UnsupportedEncodingException e) { + Log.e(TAG, "doCheck UnsupportedEncodingException" + e); + } + return false; + } + + /** + * get the publicKey of the application + * During the encoding process, avoid storing the public key in clear text. + * @return publickey + */ + public static String getPublicKey(){ + return PUBLIC_KEY; + } + +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/Constants.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/Constants.java new file mode 100755 index 0000000000..fba4db210a --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/Constants.java @@ -0,0 +1,33 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.osmand.plus.inapp; + +/** + * Constants Class. + * + * @since 2019/12/9 + */ +public class Constants { + + /** requestCode for pull up the pmsPay page */ + public static final int REQ_CODE_BUY_SUB = 4002; + public static final int REQ_CODE_BUY_INAPP = 4003; + + /** requestCode for pull up the login page for isEnvReady interface */ + public static final int REQ_CODE_LOGIN = 2001; + +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java new file mode 100755 index 0000000000..06fa78b260 --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java @@ -0,0 +1,103 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.osmand.plus.inapp; + +import android.app.Activity; +import android.widget.Toast; + +import androidx.annotation.Nullable; + +import com.huawei.hms.iap.IapApiException; +import com.huawei.hms.iap.entity.OrderStatusCode; + +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; + +/** + * Handles the exception returned from the iap api. + * + * @since 2019/12/9 + */ +public class ExceptionHandle { + + protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ExceptionHandle.class); + + /** + * The exception is solved. + */ + public static final int SOLVED = 0; + + /** + * Handles the exception returned from the iap api. + * @param activity The Activity to call the iap api. + * @param e The exception returned from the iap api. + * @return int + */ + public static int handle(@Nullable Activity activity, Exception e) { + + if (e instanceof IapApiException) { + IapApiException iapApiException = (IapApiException) e; + LOG.info("returnCode: " + iapApiException.getStatusCode()); + switch (iapApiException.getStatusCode()) { + case OrderStatusCode.ORDER_STATE_CANCEL: + showToast(activity, "Order has been canceled!"); + return SOLVED; + case OrderStatusCode.ORDER_STATE_PARAM_ERROR: + showToast(activity, "Order state param error!"); + return SOLVED; + case OrderStatusCode.ORDER_STATE_NET_ERROR: + showToast(activity, "Order state net error!"); + return SOLVED; + case OrderStatusCode.ORDER_VR_UNINSTALL_ERROR: + showToast(activity, "Order vr uninstall error!"); + return SOLVED; + case OrderStatusCode.ORDER_HWID_NOT_LOGIN: + IapRequestHelper.startResolutionForResult(activity, iapApiException.getStatus(), Constants.REQ_CODE_LOGIN); + return SOLVED; + case OrderStatusCode.ORDER_PRODUCT_OWNED: + showToast(activity, "Product already owned error!"); + return OrderStatusCode.ORDER_PRODUCT_OWNED; + case OrderStatusCode.ORDER_PRODUCT_NOT_OWNED: + showToast(activity, "Product not owned error!"); + return SOLVED; + case OrderStatusCode.ORDER_PRODUCT_CONSUMED: + showToast(activity, "Product consumed error!"); + return SOLVED; + case OrderStatusCode.ORDER_ACCOUNT_AREA_NOT_SUPPORTED: + showToast(activity, "Order account area not supported error!"); + return SOLVED; + case OrderStatusCode.ORDER_NOT_ACCEPT_AGREEMENT: + showToast(activity, "User does not agree the agreement"); + return SOLVED; + default: + // handle other error scenarios + showToast(activity, "Order unknown error!"); + return SOLVED; + } + } else { + showToast(activity, "External error"); + LOG.error(e.getMessage(), e); + return SOLVED; + } + } + + private static void showToast(@Nullable Activity activity, String s) { + if (AndroidUtils.isActivityNotDestroyed(activity)) { + Toast.makeText(activity, s, Toast.LENGTH_SHORT).show(); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/IapApiCallback.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/IapApiCallback.java new file mode 100755 index 0000000000..d8fb908093 --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/IapApiCallback.java @@ -0,0 +1,37 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.osmand.plus.inapp; + +/** + * Used to callback the result from iap api. + * + * @since 2019/12/9 + */ +public interface IapApiCallback { + + /** + * The request is successful. + * @param result The result of a successful response. + */ + void onSuccess(T result); + + /** + * Callback fail. + * @param e An Exception from IAPSDK. + */ + void onFail(Exception e); +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/IapRequestHelper.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/IapRequestHelper.java new file mode 100755 index 0000000000..5c1b7838a5 --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/IapRequestHelper.java @@ -0,0 +1,351 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.osmand.plus.inapp; + +import android.app.Activity; +import android.content.IntentSender; +import android.text.TextUtils; +import android.util.Log; + +import com.huawei.hmf.tasks.OnFailureListener; +import com.huawei.hmf.tasks.OnSuccessListener; +import com.huawei.hmf.tasks.Task; +import com.huawei.hms.iap.Iap; +import com.huawei.hms.iap.IapApiException; +import com.huawei.hms.iap.IapClient; +import com.huawei.hms.iap.entity.ConsumeOwnedPurchaseReq; +import com.huawei.hms.iap.entity.ConsumeOwnedPurchaseResult; +import com.huawei.hms.iap.entity.IsEnvReadyResult; +import com.huawei.hms.iap.entity.OwnedPurchasesReq; +import com.huawei.hms.iap.entity.OwnedPurchasesResult; +import com.huawei.hms.iap.entity.ProductInfoReq; +import com.huawei.hms.iap.entity.ProductInfoResult; +import com.huawei.hms.iap.entity.PurchaseIntentReq; +import com.huawei.hms.iap.entity.PurchaseIntentResult; +import com.huawei.hms.iap.entity.StartIapActivityReq; +import com.huawei.hms.iap.entity.StartIapActivityResult; +import com.huawei.hms.support.api.client.Status; + +import java.util.List; + +/** + * The tool class of Iap interface. + * + * @since 2019/12/9 + */ +public class IapRequestHelper { + private final static String TAG = "IapRequestHelper"; + + /** + * Create a PurchaseIntentReq object. + * @param type In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription + * @param productId ID of the in-app product to be paid. + * The in-app product ID is the product ID you set during in-app product configuration in AppGallery Connect. + * @return PurchaseIntentReq + */ + private static PurchaseIntentReq createPurchaseIntentReq(int type, String productId) { + PurchaseIntentReq req = new PurchaseIntentReq(); + req.setPriceType(type); + req.setProductId(productId); + req.setDeveloperPayload("testPurchase"); + return req; + } + + /** + * Create a ConsumeOwnedPurchaseReq object. + * @param purchaseToken which is generated by the Huawei payment server during product payment and returned to the app through InAppPurchaseData. + * The app transfers this parameter for the Huawei payment server to update the order status and then deliver the in-app product. + * @return ConsumeOwnedPurchaseReq + */ + private static ConsumeOwnedPurchaseReq createConsumeOwnedPurchaseReq(String purchaseToken) { + ConsumeOwnedPurchaseReq req = new ConsumeOwnedPurchaseReq(); + req.setPurchaseToken(purchaseToken); + req.setDeveloperChallenge("testConsume"); + return req; + } + + /** + * Create a OwnedPurchasesReq object. + * @param type type In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription + * @param continuationToken A data location flag which returns from obtainOwnedPurchases api or obtainOwnedPurchaseRecord api. + * @return OwnedPurchasesReq + */ + private static OwnedPurchasesReq createOwnedPurchasesReq(int type, String continuationToken) { + OwnedPurchasesReq req = new OwnedPurchasesReq(); + req.setPriceType(type); + req.setContinuationToken(continuationToken); + return req; + } + + /** + * Create a ProductInfoReq object. + * @param type In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription + * @param productIds ID list of products to be queried. Each product ID must exist and be unique in the current app. + * @return ProductInfoReq + */ + private static ProductInfoReq createProductInfoReq(int type, List productIds) { + ProductInfoReq req = new ProductInfoReq(); + req.setPriceType(type); + req.setProductIds(productIds); + return req; + } + + /** + * To check whether the country or region of the logged in HUAWEI ID is included in the countries or regions supported by HUAWEI IAP. + * @param mClient IapClient instance to call the isEnvReady API. + * @param callback IapApiCallback. + */ + public static void isEnvReady(IapClient mClient, final IapApiCallback callback) { + Log.i(TAG, "call isEnvReady"); + Task task = mClient.isEnvReady(); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(IsEnvReadyResult result) { + Log.i(TAG, "isEnvReady, success"); + callback.onSuccess(result); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Log.e(TAG, "isEnvReady, fail"); + callback.onFail(e); + } + }); + } + + /** + * Obtain in-app product details configured in AppGallery Connect. + * @param iapClient IapClient instance to call the obtainProductInfo API. + * @param productIds ID list of products to be queried. Each product ID must exist and be unique in the current app. + * @param type In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription + * @param callback IapApiCallback + */ + public static void obtainProductInfo(IapClient iapClient, final List productIds, int type, final IapApiCallback callback) { + Log.i(TAG, "call obtainProductInfo"); + + Task task = iapClient.obtainProductInfo(createProductInfoReq(type, productIds)); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(ProductInfoResult result) { + Log.i(TAG, "obtainProductInfo, success"); + callback.onSuccess(result); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Log.e(TAG, "obtainProductInfo, fail"); + callback.onFail(e); + } + }); + } + + /** + * create orders for in-app products in the PMS + * @param iapClient IapClient instance to call the createPurchaseIntent API. + * @param productId ID of the in-app product to be paid. + * The in-app product ID is the product ID you set during in-app product configuration in AppGallery Connect. + * @param type In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription + * @param callback IapApiCallback + */ + public static void createPurchaseIntent(final IapClient iapClient, String productId, int type, final IapApiCallback callback) { + Log.i(TAG, "call createPurchaseIntent"); + Task task = iapClient.createPurchaseIntent(createPurchaseIntentReq(type, productId)); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(PurchaseIntentResult result) { + Log.i(TAG, "createPurchaseIntent, success"); + callback.onSuccess(result); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Log.e(TAG, "createPurchaseIntent, fail"); + callback.onFail(e); + + } + }); + } + + public static void createPurchaseIntent(final IapClient iapClient, String productId, int type, String payload, final IapApiCallback callback) { + Log.i(TAG, "call createPurchaseIntent"); + PurchaseIntentReq req = createPurchaseIntentReq(type, productId); + req.setDeveloperPayload(payload); + Task task = iapClient.createPurchaseIntent(req); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(PurchaseIntentResult result) { + Log.i(TAG, "createPurchaseIntent, success"); + callback.onSuccess(result); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Log.e(TAG, "createPurchaseIntent, fail"); + callback.onFail(e); + + } + }); + } + + /** + * to start an activity. + * @param activity the activity to launch a new page. + * @param status This parameter contains the pendingIntent object of the payment page. + * @param reqCode Result code. + */ + public static void startResolutionForResult(Activity activity, Status status, int reqCode) { + if (status == null) { + Log.e(TAG, "status is null"); + return; + } + if (status.hasResolution()) { + try { + status.startResolutionForResult(activity, reqCode); + } catch (IntentSender.SendIntentException exp) { + Log.e(TAG, exp.getMessage()); + } + } else { + Log.e(TAG, "intent is null"); + } + } + + /** + * query information about all subscribed in-app products, including consumables, non-consumables, and auto-renewable subscriptions.
+ * If consumables are returned, the system needs to deliver them and calls the consumeOwnedPurchase API to consume the products. + * If non-consumables are returned, the in-app products do not need to be consumed. + * If subscriptions are returned, all existing subscription relationships of the user under the app are returned. + * @param mClient IapClient instance to call the obtainOwnedPurchases API. + * @param type In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription + * @param callback IapApiCallback + */ + public static void obtainOwnedPurchases(IapClient mClient, final int type, String continuationToken, final IapApiCallback callback) { + Log.i(TAG, "call obtainOwnedPurchases"); + Task task = mClient.obtainOwnedPurchases(IapRequestHelper.createOwnedPurchasesReq(type, continuationToken)); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(OwnedPurchasesResult result) { + Log.i(TAG, "obtainOwnedPurchases, success"); + callback.onSuccess(result); + + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Log.e(TAG, "obtainOwnedPurchases, fail"); + callback.onFail(e); + } + }); + + } + + /** + * obtain the historical consumption information about a consumable in-app product or all subscription receipts of a subscription. + * @param iapClient IapClient instance to call the obtainOwnedPurchaseRecord API. + * @param priceType In-app product type. + * The value contains: 0: consumable 1: non-consumable 2 auto-renewable subscription. + * @param continuationToken Data locating flag for supporting query in pagination mode. + * @param callback IapApiCallback + */ + public static void obtainOwnedPurchaseRecord(IapClient iapClient, int priceType, String continuationToken, final IapApiCallback callback) { + Log.i(TAG, "call obtainOwnedPurchaseRecord"); + Task task = iapClient.obtainOwnedPurchaseRecord(createOwnedPurchasesReq(priceType, continuationToken)); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(OwnedPurchasesResult result) { + Log.i(TAG, "obtainOwnedPurchaseRecord, success"); + callback.onSuccess(result); + + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Log.e(TAG, "obtainOwnedPurchaseRecord, fail"); + callback.onFail(e); + } + }); + } + + /** + * Consume all the unconsumed purchases with priceType 0. + * @param iapClient IapClient instance to call the consumeOwnedPurchase API. + * @param purchaseToken which is generated by the Huawei payment server during product payment and returned to the app through InAppPurchaseData. + */ + public static void consumeOwnedPurchase(IapClient iapClient, String purchaseToken) { + Log.i(TAG, "call consumeOwnedPurchase"); + Task task = iapClient.consumeOwnedPurchase(createConsumeOwnedPurchaseReq(purchaseToken)); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(ConsumeOwnedPurchaseResult result) { + // Consume success. + Log.i(TAG, "consumeOwnedPurchase success"); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + if (e instanceof IapApiException) { + IapApiException apiException = (IapApiException)e; + int returnCode = apiException.getStatusCode(); + Log.e(TAG, "consumeOwnedPurchase fail, IapApiException returnCode: " + returnCode); + } else { + // Other external errors + Log.e(TAG, e.getMessage()); + } + + } + }); + + } + + /** + * link to subscription manager page + * @param activity activity + * @param productId the productId of the subscription product + */ + public static void showSubscription(final Activity activity, String productId) { + StartIapActivityReq req = new StartIapActivityReq(); + if (TextUtils.isEmpty(productId)) { + req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_MANAGER_ACTIVITY); + } else { + req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_EDIT_ACTIVITY); + req.setSubscribeProductId(productId); + } + + IapClient iapClient = Iap.getIapClient(activity); + Task task = iapClient.startIapActivity(req); + + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(StartIapActivityResult result) { + if(result != null) { + result.startActivity(activity); + } + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + ExceptionHandle.handle(activity, e); + } + }); + } + +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index a7e8589f33..61de5125c0 100644 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -1,393 +1,229 @@ package net.osmand.plus.inapp; import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.huawei.hms.iap.Iap; +import com.huawei.hms.iap.IapClient; +import com.huawei.hms.iap.entity.InAppPurchaseData; +import com.huawei.hms.iap.entity.IsEnvReadyResult; +import com.huawei.hms.iap.entity.OrderStatusCode; +import com.huawei.hms.iap.entity.OwnedPurchasesResult; +import com.huawei.hms.iap.entity.ProductInfo; +import com.huawei.hms.iap.entity.ProductInfoResult; +import com.huawei.hms.iap.entity.PurchaseIntentResult; +import com.huawei.hms.iap.entity.PurchaseResultInfo; + import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.inapp.util.BillingManager; +import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { - // The helper object - private BillingManager billingManager; - private List skuDetailsList; + private boolean envReady = false; + private boolean purchaseSupported = false; + private List productInfos; + private OwnedPurchasesResult ownedSubscriptions; + private List ownedInApps = new ArrayList<>(); public InAppPurchaseHelperImpl(OsmandApplication ctx) { super(ctx); + purchases = new InAppPurchasesImpl(ctx); } - protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppRunnable runnable) { - billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() { - - @Override - public void onBillingClientSetupFinished() { - logDebug("Setup finished."); - - BillingManager billingManager = getBillingManager(); - // Have we been disposed of in the meantime? If so, quit. - if (billingManager == null) { - stop(true); - return; + @Override + public void isInAppPurchaseSupported(@NonNull final Activity activity, @Nullable final InAppPurchaseInitCallback callback) { + if (envReady) { + if (callback != null) { + if (purchaseSupported) { + callback.onSuccess(); + } else { + callback.onFail(); } - - if (!billingManager.isServiceConnected()) { - // Oh noes, there was a problem. - //complain("Problem setting up in-app billing: " + result); - notifyError(taskType, billingManager.getBillingClientResponseMessage()); - stop(true); - return; - } - - processingTask = !runnable.run(InAppPurchaseHelperImpl.this); } + } else { + // Initiating an isEnvReady request when entering the app. + // Check if the account service country supports IAP. + IapClient mClient = Iap.getIapClient(activity); + final WeakReference activityRef = new WeakReference<>(activity); + IapRequestHelper.isEnvReady(mClient, new IapApiCallback() { - @Override - public void onConsumeFinished(String token, BillingResult billingResult) { - } - - @Override - public void onPurchasesUpdated(final List purchases) { - - BillingManager billingManager = getBillingManager(); - // Have we been disposed of in the meantime? If so, quit. - if (billingManager == null) { - stop(true); - return; + private void onReady(boolean succeed) { + logDebug("Setup finished."); + envReady = true; + purchaseSupported = succeed; + if (callback != null) { + if (succeed) { + callback.onSuccess(); + } else { + callback.onFail(); + } + } } - if (activeTask == InAppPurchaseTaskType.REQUEST_INVENTORY) { - List skuInApps = new ArrayList<>(); - for (InAppPurchases.InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { - skuInApps.add(purchase.getSku()); - } - for (Purchase p : purchases) { - skuInApps.add(p.getSku()); - } - billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() { - @Override - public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListInApps) { - // Is it a failure? - if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { - logError("Failed to query inapps sku details: " + billingResult.getResponseCode()); - notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); - stop(true); - return; - } + @Override + public void onSuccess(IsEnvReadyResult result) { + onReady(true); + } - List skuSubscriptions = new ArrayList<>(); - for (InAppPurchases.InAppSubscription subscription : getInAppPurchases().getAllInAppSubscriptions()) { - skuSubscriptions.add(subscription.getSku()); - } - for (Purchase p : purchases) { - skuSubscriptions.add(p.getSku()); - } + @Override + public void onFail(Exception e) { + onReady(false); + LOG.error("isEnvReady fail, " + e.getMessage(), e); + ExceptionHandle.handle(activityRef.get(), e); + } + }); + } + } - BillingManager billingManager = getBillingManager(); - // Have we been disposed of in the meantime? If so, quit. - if (billingManager == null) { - stop(true); - return; - } + protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppCommand command) { + if (envReady) { + command.run(this); + } else { + command.commandDone(); + } + } - billingManager.querySkuDetailsAsync(BillingClient.SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() { + private InAppCommand getPurchaseInAppCommand(@NonNull final Activity activity, @NonNull final String productId) throws UnsupportedOperationException { + return new InAppCommand() { + @Override + public void run(InAppPurchaseHelper helper) { + try { + ProductInfo productInfo = getProductInfo(productId); + IapRequestHelper.createPurchaseIntent(getIapClient(), productInfo.getProductId(), + IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback() { @Override - public void onSkuDetailsResponse(BillingResult billingResult, final List skuDetailsListSubscriptions) { - // Is it a failure? - if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { - logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode()); - notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); - stop(true); - return; + public void onSuccess(PurchaseIntentResult result) { + if (result == null) { + logError("result is null"); + } else { + // you should pull up the page to complete the payment process + IapRequestHelper.startResolutionForResult(activity, result.getStatus(), Constants.REQ_CODE_BUY_INAPP); } + commandDone(); + } - List skuDetailsList = new ArrayList<>(skuDetailsListInApps); - skuDetailsList.addAll(skuDetailsListSubscriptions); - InAppPurchaseHelperImpl.this.skuDetailsList = skuDetailsList; - - mSkuDetailsResponseListener.onSkuDetailsResponse(billingResult, skuDetailsList); + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle(activity, e); + if (errorCode != ExceptionHandle.SOLVED) { + logDebug("createPurchaseIntent, returnCode: " + errorCode); + if (OrderStatusCode.ORDER_PRODUCT_OWNED == errorCode) { + logError("already own this product"); + } else { + logError("unknown error"); + } + } + commandDone(); } }); - } - }); - } - for (Purchase purchase : purchases) { - if (!purchase.isAcknowledged()) { - onPurchaseFinished(purchase); - } + } catch (Exception e) { + complain("Cannot launch full version purchase!"); + logError("purchaseFullVersion Error", e); + stop(true); } } - - @Override - public void onPurchaseCanceled() { - stop(true); - } - }); + }; } @Override - public void purchaseFullVersion(Activity activity) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); + public void purchaseFullVersion(@NonNull final Activity activity) throws UnsupportedOperationException { + notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); + exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, getPurchaseInAppCommand(activity, "")); } @Override - public void purchaseDepthContours(Activity activity) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); + public void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException { + notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); + exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, getPurchaseInAppCommand(activity, "")); } @Nullable - private SkuDetails getSkuDetails(@NonNull String sku) { - List skuDetailsList = this.skuDetailsList; - if (skuDetailsList != null) { - for (SkuDetails details : skuDetailsList) { - if (details.getSku().equals(sku)) { - return details; + private ProductInfo getProductInfo(@NonNull String productId) { + List productInfos = this.productInfos; + if (productInfos != null) { + for (ProductInfo info : productInfos) { + if (info.getProductId().equals(productId)) { + return info; } } } return null; } - private boolean hasDetails(@NonNull String sku) { - return getSkuDetails(sku) != null; + private boolean hasDetails(@NonNull String productId) { + return getProductInfo(productId) != null; } @Nullable - private Purchase getPurchase(@NonNull String sku) { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - List purchases = billingManager.getPurchases(); - if (purchases != null) { - for (Purchase p : purchases) { - if (p.getSku().equals(sku)) { - return p; - } + private InAppPurchaseData getPurchaseData(@NonNull String productId) { + InAppPurchaseData data = SubscriptionUtils.getPurchaseData(ownedSubscriptions, productId); + if (data == null) { + for (OwnedPurchasesResult result : ownedInApps) { + data = InAppUtils.getPurchaseData(result, productId); + if (data != null) { + break; } } } - return null; + return data; } - // Listener that's called when we finish querying the items and subscriptions we own - private SkuDetailsResponseListener mSkuDetailsResponseListener = new SkuDetailsResponseListener() { - - @NonNull - private List getAllOwnedSubscriptionSkus() { - List result = new ArrayList<>(); - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - for (Purchase p : billingManager.getPurchases()) { - if (getInAppPurchases().getInAppSubscriptionBySku(p.getSku()) != null) { - result.add(p.getSku()); - } - } - } - return result; - } - - @Override - public void onSkuDetailsResponse(BillingResult billingResult, List skuDetailsList) { - - logDebug("Query sku details finished."); - - // Have we been disposed of in the meantime? If so, quit. - if (getBillingManager() == null) { - stop(true); - return; - } - - // Is it a failure? - if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { - logError("Failed to query inventory: " + billingResult.getResponseCode()); - notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage()); - stop(true); - return; - } - - logDebug("Query sku details was successful."); - - /* - * Check for items we own. Notice that for each purchase, we check - * the developer payload to see if it's correct! See - * verifyDeveloperPayload(). - */ - - List allOwnedSubscriptionSkus = getAllOwnedSubscriptionSkus(); - for (InAppPurchases.InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { - if (hasDetails(s.getSku())) { - Purchase purchase = getPurchase(s.getSku()); - SkuDetails liveUpdatesDetails = getSkuDetails(s.getSku()); - if (liveUpdatesDetails != null) { - fetchInAppPurchase(s, liveUpdatesDetails, purchase); - } - allOwnedSubscriptionSkus.remove(s.getSku()); - } - } - for (String sku : allOwnedSubscriptionSkus) { - Purchase purchase = getPurchase(sku); - SkuDetails liveUpdatesDetails = getSkuDetails(sku); - if (liveUpdatesDetails != null) { - InAppPurchases.InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); - if (s == null) { - s = new InAppPurchases.InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails); - } - fetchInAppPurchase(s, liveUpdatesDetails, purchase); - } - } - - InAppPurchases.InAppPurchase fullVersion = getFullVersion(); - if (hasDetails(fullVersion.getSku())) { - Purchase purchase = getPurchase(fullVersion.getSku()); - SkuDetails fullPriceDetails = getSkuDetails(fullVersion.getSku()); - if (fullPriceDetails != null) { - fetchInAppPurchase(fullVersion, fullPriceDetails, purchase); - } - } - - InAppPurchases.InAppPurchase depthContours = getDepthContours(); - if (hasDetails(depthContours.getSku())) { - Purchase purchase = getPurchase(depthContours.getSku()); - SkuDetails depthContoursDetails = getSkuDetails(depthContours.getSku()); - if (depthContoursDetails != null) { - fetchInAppPurchase(depthContours, depthContoursDetails, purchase); - } - } - - InAppPurchases.InAppPurchase contourLines = getContourLines(); - if (hasDetails(contourLines.getSku())) { - Purchase purchase = getPurchase(contourLines.getSku()); - SkuDetails contourLinesDetails = getSkuDetails(contourLines.getSku()); - if (contourLinesDetails != null) { - fetchInAppPurchase(contourLines, contourLinesDetails, purchase); - } - } - - Purchase fullVersionPurchase = getPurchase(fullVersion.getSku()); - boolean fullVersionPurchased = fullVersionPurchase != null; - if (fullVersionPurchased) { - ctx.getSettings().FULL_VERSION_PURCHASED.set(true); - } - - Purchase depthContoursPurchase = getPurchase(depthContours.getSku()); - boolean depthContoursPurchased = depthContoursPurchase != null; - if (depthContoursPurchased) { - ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); - } - - // Do we have the live updates? - boolean subscribedToLiveUpdates = false; - List liveUpdatesPurchases = new ArrayList<>(); - for (InAppPurchases.InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { - Purchase purchase = getPurchase(p.getSku()); - if (purchase != null) { - liveUpdatesPurchases.add(purchase); - if (!subscribedToLiveUpdates) { - subscribedToLiveUpdates = true; - } - } - } - OsmandSettings.OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; - if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) { - if (subscriptionCancelledTime.get() == 0) { - subscriptionCancelledTime.set(System.currentTimeMillis()); - ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN.set(false); - ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN.set(false); - } else if (System.currentTimeMillis() - subscriptionCancelledTime.get() > SUBSCRIPTION_HOLDING_TIME_MSEC) { - ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false); - if (!isDepthContoursPurchased(ctx)) { - ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false); - } - } - } else if (subscribedToLiveUpdates) { - subscriptionCancelledTime.set(0L); - ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); - } - - lastValidationCheckTime = System.currentTimeMillis(); - logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") - + " live updates purchased."); - - OsmandSettings settings = ctx.getSettings(); - settings.INAPPS_READ.set(true); - - List tokensToSend = new ArrayList<>(); - if (liveUpdatesPurchases.size() > 0) { - List tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";")); - for (Purchase purchase : liveUpdatesPurchases) { - if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) - && !Algorithms.isEmpty(purchase.getDeveloperPayload())) { - String payload = purchase.getDeveloperPayload(); - if (!Algorithms.isEmpty(payload)) { - String[] arr = payload.split(" "); - if (arr.length > 0) { - settings.BILLING_USER_ID.set(arr[0]); - } - if (arr.length > 1) { - token = arr[1]; - settings.BILLING_USER_TOKEN.set(token); - } - } - } - if (!tokensSent.contains(purchase.getSku())) { - tokensToSend.add(purchase); - } - } - } - List purchaseInfoList = new ArrayList<>(); - for (Purchase purchase : tokensToSend) { - purchaseInfoList.add(getPurchaseInfo(purchase)); - } - onSkuDetailsResponseDone(purchaseInfoList); - } - }; - - private PurchaseInfo getPurchaseInfo(Purchase purchase) { - return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken()); + private PurchaseInfo getPurchaseInfo(InAppPurchaseData purchase) { + return new PurchaseInfo(purchase.getProductId(), purchase.getOrderID(), purchase.getPurchaseToken()); } - private void fetchInAppPurchase(@NonNull InAppPurchases.InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) { - if (purchase != null) { - inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.PURCHASED); - inAppPurchase.setPurchaseTime(purchase.getPurchaseTime()); + private void fetchInAppPurchase(@NonNull InAppPurchase inAppPurchase, @NonNull ProductInfo productInfo, @Nullable InAppPurchaseData purchaseData) { + if (purchaseData != null) { + inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.PURCHASED); + inAppPurchase.setPurchaseTime(purchaseData.getPurchaseTime()); } else { - inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.NOT_PURCHASED); + inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.NOT_PURCHASED); } - inAppPurchase.setPrice(skuDetails.getPrice()); - inAppPurchase.setPriceCurrencyCode(skuDetails.getPriceCurrencyCode()); - if (skuDetails.getPriceAmountMicros() > 0) { - inAppPurchase.setPriceValue(skuDetails.getPriceAmountMicros() / 1000000d); + inAppPurchase.setPrice(productInfo.getPrice()); + inAppPurchase.setPriceCurrencyCode(productInfo.getCurrency()); + if (productInfo.getMicrosPrice() > 0) { + inAppPurchase.setPriceValue(productInfo.getMicrosPrice() / 1000000d); } - String subscriptionPeriod = skuDetails.getSubscriptionPeriod(); + String subscriptionPeriod = productInfo.getSubPeriod(); if (!Algorithms.isEmpty(subscriptionPeriod)) { - if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { + if (inAppPurchase instanceof InAppSubscription) { try { - ((InAppPurchases.InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); + ((InAppSubscription) inAppPurchase).setSubscriptionPeriodString(subscriptionPeriod); } catch (ParseException e) { LOG.error(e); } } } - if (inAppPurchase instanceof InAppPurchases.InAppSubscription) { - String introductoryPrice = skuDetails.getIntroductoryPrice(); - String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod(); - String introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles(); - long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros(); + if (inAppPurchase instanceof InAppSubscription) { + String introductoryPrice = productInfo.getSubSpecialPrice(); + String introductoryPricePeriod = productInfo.getSubSpecialPeriod(); + int introductoryPriceCycles = productInfo.getSubSpecialPeriodCycles(); + long introductoryPriceAmountMicros = productInfo.getSubSpecialPriceMicros(); if (!Algorithms.isEmpty(introductoryPrice)) { - InAppPurchases.InAppSubscription s = (InAppPurchases.InAppSubscription) inAppPurchase; + InAppSubscription s = (InAppSubscription) inAppPurchase; try { - s.setIntroductoryInfo(new InAppPurchases.InAppSubscriptionIntroductoryInfo(s, introductoryPrice, - introductoryPriceAmountMicros, introductoryPricePeriod, introductoryPriceCycles)); + s.setIntroductoryInfo(new InAppSubscriptionIntroductoryInfo(s, introductoryPrice, + introductoryPriceAmountMicros, introductoryPricePeriod, String.valueOf(introductoryPriceCycles))); } catch (ParseException e) { LOG.error(e); } @@ -395,22 +231,45 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } - protected InAppRunnable getPurchaseLiveUpdatesCommand(final WeakReference activity, final String sku, final String payload) { - return new InAppRunnable() { + protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference activity, final String sku, final String payload) { + return new InAppCommand() { @Override - public boolean run(InAppPurchaseHelper helper) { + public void run(InAppPurchaseHelper helper) { try { Activity a = activity.get(); - SkuDetails skuDetails = getSkuDetails(sku); - if (AndroidUtils.isActivityNotDestroyed(a) && skuDetails != null) { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.setPayload(payload); - billingManager.initiatePurchaseFlow(a, skuDetails); - } else { - throw new IllegalStateException("BillingManager disposed"); - } - return false; + ProductInfo productInfo = getProductInfo(sku); + if (AndroidUtils.isActivityNotDestroyed(a) && productInfo != null) { + IapRequestHelper.createPurchaseIntent(getIapClient(), sku, + IapClient.PriceType.IN_APP_SUBSCRIPTION, payload, new IapApiCallback() { + @Override + public void onSuccess(PurchaseIntentResult result) { + if (result == null) { + logError("GetBuyIntentResult is null"); + } else { + Activity a = activity.get(); + if (AndroidUtils.isActivityNotDestroyed(a)) { + IapRequestHelper.startResolutionForResult(a, result.getStatus(), Constants.REQ_CODE_BUY_SUB); + } else { + logError("startResolutionForResult on destroyed activity"); + } + } + commandDone(); + } + + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle(activity.get(), e); + if (ExceptionHandle.SOLVED != errorCode) { + logError("createPurchaseIntent, returnCode: " + errorCode); + if (OrderStatusCode.ORDER_PRODUCT_OWNED == errorCode) { + logError("already own this product"); + } else { + logError("unknown error"); + } + } + commandDone(); + } + }); } else { stop(true); } @@ -418,58 +277,362 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { logError("launchPurchaseFlow Error", e); stop(true); } - return true; } }; } - protected InAppRunnable getRequestInventoryCommand() { - return new InAppRunnable() { + @Override + protected InAppCommand getRequestInventoryCommand() { + return new InAppCommand() { + @Override - public boolean run(InAppPurchaseHelper helper) { + public void run(InAppPurchaseHelper helper) { logDebug("Setup successful. Querying inventory."); try { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.queryPurchases(); + productInfos = new ArrayList<>(); + if (uiActivity != null) { + obtainOwnedSubscriptions(); } else { - throw new IllegalStateException("BillingManager disposed"); + commandDone(); } - return false; } catch (Exception e) { logError("queryInventoryAsync Error", e); notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); stop(true); + commandDone(); } - return true; + } + + private void obtainOwnedSubscriptions() { + if (uiActivity != null) { + IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_SUBSCRIPTION, + null, new IapApiCallback() { + @Override + public void onSuccess(OwnedPurchasesResult result) { + ownedSubscriptions = result; + obtainOwnedInApps(null); + } + + @Override + public void onFail(Exception e) { + logError("obtainOwnedSubscriptions exception", e); + ExceptionHandle.handle((Activity) uiActivity, e); + commandDone(); + } + }); + } else { + commandDone(); + } + } + + private void obtainOwnedInApps(final String continuationToken) { + // Query users' purchased non-consumable products. + IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_NONCONSUMABLE, + continuationToken, new IapApiCallback() { + @Override + public void onSuccess(OwnedPurchasesResult result) { + ownedInApps.add(result); + if (result != null && !TextUtils.isEmpty(result.getContinuationToken())) { + obtainOwnedInApps(result.getContinuationToken()); + } else { + obtainSubscriptionsInfo(); + } + } + + @Override + public void onFail(Exception e) { + logError("obtainOwnedInApps exception", e); + ExceptionHandle.handle((Activity) uiActivity, e); + commandDone(); + } + }); + + } + + private void obtainSubscriptionsInfo() { + Set productIds = new HashSet<>(); + List subscriptions = purchases.getLiveUpdates().getAllSubscriptions(); + for (InAppSubscription s : subscriptions) { + productIds.add(s.getSku()); + } + productIds.addAll(ownedSubscriptions.getItemList()); + IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), + IapClient.PriceType.IN_APP_SUBSCRIPTION, new IapApiCallback() { + @Override + public void onSuccess(final ProductInfoResult result) { + if (result == null) { + logError("obtainSubscriptionsInfo: ProductInfoResult is null"); + commandDone(); + return; + } + productInfos.addAll(result.getProductInfoList()); + obtainInAppsInfo(); + } + + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle((Activity) uiActivity, e); + if (ExceptionHandle.SOLVED != errorCode) { + LOG.error("Unknown error"); + } + commandDone(); + } + }); + } + + private void obtainInAppsInfo() { + Set productIds = new HashSet<>(); + for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { + productIds.add(purchase.getSku()); + } + for (OwnedPurchasesResult result : ownedInApps) { + productIds.addAll(result.getItemList()); + } + IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), + IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback() { + @Override + public void onSuccess(ProductInfoResult result) { + if (result == null || result.getProductInfoList() == null) { + logError("obtainInAppsInfo: ProductInfoResult is null"); + commandDone(); + return; + } + productInfos.addAll(result.getProductInfoList()); + + processInventory(); + commandDone(); + } + + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle((Activity) uiActivity, e); + if (ExceptionHandle.SOLVED != errorCode) { + LOG.error("Unknown error"); + } + commandDone(); + } + }); + } + + private void processInventory() { + logDebug("Query sku details was successful."); + + /* + * Check for items we own. Notice that for each purchase, we check + * the developer payload to see if it's correct! + */ + + List allOwnedSubscriptionSkus = ownedSubscriptions.getItemList(); + for (InAppSubscription s : getLiveUpdates().getAllSubscriptions()) { + if (hasDetails(s.getSku())) { + InAppPurchaseData purchaseData = getPurchaseData(s.getSku()); + ProductInfo liveUpdatesInfo = getProductInfo(s.getSku()); + if (liveUpdatesInfo != null) { + fetchInAppPurchase(s, liveUpdatesInfo, purchaseData); + } + allOwnedSubscriptionSkus.remove(s.getSku()); + } + } + for (String sku : allOwnedSubscriptionSkus) { + InAppPurchaseData purchaseData = getPurchaseData(sku); + ProductInfo liveUpdatesInfo = getProductInfo(sku); + if (liveUpdatesInfo != null) { + InAppSubscription s = getLiveUpdates().upgradeSubscription(sku); + if (s == null) { + s = new InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesInfo); + } + fetchInAppPurchase(s, liveUpdatesInfo, purchaseData); + } + } + + InAppPurchase fullVersion = getFullVersion(); + if (hasDetails(fullVersion.getSku())) { + InAppPurchaseData purchaseData = getPurchaseData(fullVersion.getSku()); + ProductInfo fullPriceDetails = getProductInfo(fullVersion.getSku()); + if (fullPriceDetails != null) { + fetchInAppPurchase(fullVersion, fullPriceDetails, purchaseData); + } + } + + InAppPurchase depthContours = getDepthContours(); + if (hasDetails(depthContours.getSku())) { + InAppPurchaseData purchaseData = getPurchaseData(depthContours.getSku()); + ProductInfo depthContoursDetails = getProductInfo(depthContours.getSku()); + if (depthContoursDetails != null) { + fetchInAppPurchase(depthContours, depthContoursDetails, purchaseData); + } + } + + InAppPurchase contourLines = getContourLines(); + if (hasDetails(contourLines.getSku())) { + InAppPurchaseData purchaseData = getPurchaseData(contourLines.getSku()); + ProductInfo contourLinesDetails = getProductInfo(contourLines.getSku()); + if (contourLinesDetails != null) { + fetchInAppPurchase(contourLines, contourLinesDetails, purchaseData); + } + } + + InAppPurchaseData fullVersionPurchase = getPurchaseData(fullVersion.getSku()); + boolean fullVersionPurchased = fullVersionPurchase != null; + if (fullVersionPurchased) { + ctx.getSettings().FULL_VERSION_PURCHASED.set(true); + } + + InAppPurchaseData depthContoursPurchase = getPurchaseData(depthContours.getSku()); + boolean depthContoursPurchased = depthContoursPurchase != null; + if (depthContoursPurchased) { + ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); + } + + // Do we have the live updates? + boolean subscribedToLiveUpdates = false; + List liveUpdatesPurchases = new ArrayList<>(); + for (InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { + InAppPurchaseData purchaseData = getPurchaseData(p.getSku()); + if (purchaseData != null) { + liveUpdatesPurchases.add(purchaseData); + if (!subscribedToLiveUpdates) { + subscribedToLiveUpdates = true; + } + } + } + OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; + if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) { + if (subscriptionCancelledTime.get() == 0) { + subscriptionCancelledTime.set(System.currentTimeMillis()); + ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN.set(false); + ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN.set(false); + } else if (System.currentTimeMillis() - subscriptionCancelledTime.get() > SUBSCRIPTION_HOLDING_TIME_MSEC) { + ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false); + if (!isDepthContoursPurchased(ctx)) { + ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false); + } + } + } else if (subscribedToLiveUpdates) { + subscriptionCancelledTime.set(0L); + ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); + } + + lastValidationCheckTime = System.currentTimeMillis(); + logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") + + " live updates purchased."); + + OsmandSettings settings = ctx.getSettings(); + settings.INAPPS_READ.set(true); + + List tokensToSend = new ArrayList<>(); + if (liveUpdatesPurchases.size() > 0) { + List tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";")); + for (InAppPurchaseData purchase : liveUpdatesPurchases) { + if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) + && !Algorithms.isEmpty(purchase.getDeveloperPayload())) { + String payload = purchase.getDeveloperPayload(); + if (!Algorithms.isEmpty(payload)) { + String[] arr = payload.split(" "); + if (arr.length > 0) { + settings.BILLING_USER_ID.set(arr[0]); + } + if (arr.length > 1) { + token = arr[1]; + settings.BILLING_USER_TOKEN.set(token); + } + } + } + if (!tokensSent.contains(purchase.getProductId())) { + tokensToSend.add(purchase); + } + } + } + List purchaseInfoList = new ArrayList<>(); + for (InAppPurchaseData purchase : tokensToSend) { + purchaseInfoList.add(getPurchaseInfo(purchase)); + } + onSkuDetailsResponseDone(purchaseInfoList); } }; } + private IapClient getIapClient() { + return Iap.getIapClient((Activity) uiActivity); + } + // Call when a purchase is finished - private void onPurchaseFinished(Purchase purchase) { - logDebug("Purchase finished: " + purchase); - - // if we were disposed of in the meantime, quit. - if (getBillingManager() == null) { - stop(true); - return; - } - + private void onPurchaseFinished(InAppPurchaseData purchase) { + logDebug("Purchase finished: " + purchase.getProductId()); onPurchaseDone(getPurchaseInfo(purchase)); } @Override protected boolean isBillingManagerExists() { - return getBillingManager() != null; + return false; } @Override protected void destroyBillingManager() { - BillingManager billingManager = getBillingManager(); - if (billingManager != null) { - billingManager.destroy(); - this.billingManager = null; + // non implemented + } + + @Override + public boolean onActivityResult(@NonNull Activity activity, int requestCode, int resultCode, Intent data) { + if (requestCode == Constants.REQ_CODE_BUY_SUB) { + boolean succeed = false; + if (resultCode == Activity.RESULT_OK) { + PurchaseResultInfo result = SubscriptionUtils.getPurchaseResult(activity, data); + if (result != null) { + if (OrderStatusCode.ORDER_STATE_SUCCESS == result.getReturnCode()) { + InAppPurchaseData purchaseData = SubscriptionUtils.getInAppPurchaseData(null, + result.getInAppPurchaseData(), result.getInAppDataSignature()); + if (purchaseData != null) { + onPurchaseFinished(purchaseData); + succeed = true; + } else { + logDebug("Purchase failed"); + } + } else if (OrderStatusCode.ORDER_STATE_CANCEL == result.getReturnCode()) { + logDebug("Purchase cancelled"); + } + } else { + logDebug("Purchase failed"); + } + } else { + logDebug("Purchase cancelled"); + } + if (!succeed) { + stop(true); + } + return true; + } else if (requestCode == Constants.REQ_CODE_BUY_INAPP) { + boolean succeed = false; + if (data == null) { + logDebug("data is null"); + } else { + PurchaseResultInfo buyResultInfo = Iap.getIapClient(activity).parsePurchaseResultInfoFromIntent(data); + switch (buyResultInfo.getReturnCode()) { + case OrderStatusCode.ORDER_STATE_CANCEL: + logDebug("Order has been canceled"); + break; + case OrderStatusCode.ORDER_PRODUCT_OWNED: + logDebug("Product already owned"); + break; + case OrderStatusCode.ORDER_STATE_SUCCESS: + InAppPurchaseData purchaseData = InAppUtils.getInAppPurchaseData(null, + buyResultInfo.getInAppPurchaseData(), buyResultInfo.getInAppDataSignature()); + if (purchaseData != null) { + onPurchaseFinished(purchaseData); + succeed = true; + } else { + logDebug("Purchase failed"); + } + break; + default: + break; + } + } + if (!succeed) { + stop(true); + } + return true; } + return false; } } diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java new file mode 100644 index 0000000000..49ff72cd3b --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java @@ -0,0 +1,184 @@ +package net.osmand.plus.inapp; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; + +public class InAppPurchasesImpl extends InAppPurchases { + + private static final InAppPurchase FULL_VERSION = new InAppPurchaseFullVersion(); + private static final InAppPurchaseDepthContoursFree DEPTH_CONTOURS_FREE = new InAppPurchaseDepthContoursFree(); + private static final InAppPurchaseContourLinesFree CONTOUR_LINES_FREE = new InAppPurchaseContourLinesFree(); + + + private static final InAppSubscription[] LIVE_UPDATES_FREE = new InAppSubscription[]{ + new InAppPurchaseLiveUpdatesMonthlyFree(), + new InAppPurchaseLiveUpdates3MonthsFree(), + new InAppPurchaseLiveUpdatesAnnualFree() + }; + + public InAppPurchasesImpl(OsmandApplication ctx) { + super(ctx); + fullVersion = FULL_VERSION; + depthContours = DEPTH_CONTOURS_FREE; + contourLines = CONTOUR_LINES_FREE; + liveUpdates = new LiveUpdatesInAppPurchasesFree(); + inAppPurchases = new InAppPurchase[] { fullVersion, depthContours, contourLines }; + } + + @Override + public boolean isFullVersion(String sku) { + return FULL_VERSION.getSku().equals(sku); + } + + @Override + public boolean isDepthContours(String sku) { + return DEPTH_CONTOURS_FREE.getSku().equals(sku); + } + + @Override + public boolean isContourLines(String sku) { + return CONTOUR_LINES_FREE.getSku().equals(sku); + } + + @Override + public boolean isLiveUpdates(String sku) { + for (InAppPurchase p : LIVE_UPDATES_FREE) { + if (p.getSku().equals(sku)) { + return true; + } + } + return false; + } + + private static class InAppPurchaseFullVersion extends InAppPurchase { + + private static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price"; + + InAppPurchaseFullVersion() { + super(SKU_FULL_VERSION_PRICE); + } + + @Override + public String getDefaultPrice(Context ctx) { + return ctx.getString(R.string.full_version_price); + } + } + + private static class InAppPurchaseDepthContoursFree extends InAppPurchaseDepthContours { + + private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth"; + + InAppPurchaseDepthContoursFree() { + super(SKU_DEPTH_CONTOURS_FREE); + } + } + + private static class InAppPurchaseContourLinesFree extends InAppPurchaseContourLines { + + private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.contourlines"; + + InAppPurchaseContourLinesFree() { + super(SKU_CONTOUR_LINES_FREE); + } + } + + private static class InAppPurchaseLiveUpdatesMonthlyFree extends InAppPurchaseLiveUpdatesMonthly { + + private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.test.monthly"; + + InAppPurchaseLiveUpdatesMonthlyFree() { + super(SKU_LIVE_UPDATES_MONTHLY_HW_FREE, 1); + } + + private InAppPurchaseLiveUpdatesMonthlyFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyFree(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdates3MonthsFree extends InAppPurchaseLiveUpdates3Months { + + private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.test.3months"; + + InAppPurchaseLiveUpdates3MonthsFree() { + super(SKU_LIVE_UPDATES_3_MONTHS_HW_FREE, 1); + } + + private InAppPurchaseLiveUpdates3MonthsFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsFree(sku) : null; + } + } + + private static class InAppPurchaseLiveUpdatesAnnualFree extends InAppPurchaseLiveUpdatesAnnual { + + private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.test.annual"; + + InAppPurchaseLiveUpdatesAnnualFree() { + super(SKU_LIVE_UPDATES_ANNUAL_HW_FREE, 1); + } + + private InAppPurchaseLiveUpdatesAnnualFree(@NonNull String sku) { + super(sku); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualFree(sku) : null; + } + } + + public static class InAppPurchaseLiveUpdatesOldSubscription extends InAppSubscription { + + private ProductInfo info; + + InAppPurchaseLiveUpdatesOldSubscription(@NonNull ProductInfo info) { + super(info.getProductId(), true); + this.info = info; + } + + @Override + public String getDefaultPrice(Context ctx) { + return ""; + } + + @Override + public CharSequence getTitle(Context ctx) { + return info.getProductName(); + } + + @Override + public CharSequence getDescription(@NonNull Context ctx) { + return info.getProductDesc(); + } + + @Nullable + @Override + protected InAppSubscription newInstance(@NonNull String sku) { + return null; + } + } + + private static class LiveUpdatesInAppPurchasesFree extends InAppSubscriptionList { + + public LiveUpdatesInAppPurchasesFree() { + super(LIVE_UPDATES_FREE); + } + } +} diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppUtils.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppUtils.java new file mode 100644 index 0000000000..445727de96 --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppUtils.java @@ -0,0 +1,49 @@ +package net.osmand.plus.inapp; + +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.huawei.hms.iap.entity.InAppPurchaseData; +import com.huawei.hms.iap.entity.OwnedPurchasesResult; + +import org.json.JSONException; + +public class InAppUtils { + private static final String TAG = "InAppUtils"; + + @Nullable + public static InAppPurchaseData getPurchaseData(OwnedPurchasesResult result, String productId) { + if (result == null || result.getInAppPurchaseDataList() == null) { + Log.i(TAG, "result is null"); + return null; + } + int index = result.getItemList().indexOf(productId); + if (index != -1) { + String data = result.getInAppPurchaseDataList().get(index); + String signature = result.getInAppSignature().get(index); + return getInAppPurchaseData(productId, data, signature); + } + return null; + } + + @Nullable + public static InAppPurchaseData getInAppPurchaseData(@Nullable String productId, @NonNull String data, @NonNull String signature) { + if (CipherUtil.doCheck(data, signature, CipherUtil.getPublicKey())) { + try { + InAppPurchaseData purchaseData = new InAppPurchaseData(data); + if (purchaseData.getPurchaseState() == InAppPurchaseData.PurchaseState.PURCHASED) { + if (productId == null || productId.equals(purchaseData.getProductId())) { + return purchaseData; + } + } + } catch (JSONException e) { + Log.e(TAG, "delivery: " + e.getMessage()); + } + } else { + Log.e(TAG, "delivery: verify signature error"); + } + return null; + } +} \ No newline at end of file diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java new file mode 100755 index 0000000000..1dffffc252 --- /dev/null +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java @@ -0,0 +1,139 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.osmand.plus.inapp; + +import android.app.Activity; +import android.content.Intent; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.huawei.hms.iap.Iap; +import com.huawei.hms.iap.entity.InAppPurchaseData; +import com.huawei.hms.iap.entity.OrderStatusCode; +import com.huawei.hms.iap.entity.OwnedPurchasesResult; +import com.huawei.hms.iap.entity.PurchaseResultInfo; + +import org.json.JSONException; + +import java.util.List; + +/** + * Util for Subscription function. + * + * @since 2019/12/9 + */ +public class SubscriptionUtils { + private static final String TAG = "SubscriptionUtils"; + + /** + * Decide whether to offer subscription service + * + * @param result the OwnedPurchasesResult from IapClient.obtainOwnedPurchases + * @param productId subscription product id + * @return decision result + */ + @Nullable + public static InAppPurchaseData getPurchaseData(OwnedPurchasesResult result, String productId) { + if (null == result) { + Log.e(TAG, "OwnedPurchasesResult is null"); + return null; + } + List dataList = result.getInAppPurchaseDataList(); + List signatureList = result.getInAppSignature(); + for (int i = 0; i < dataList.size(); i++) { + String data = dataList.get(i); + String signature = signatureList.get(i); + InAppPurchaseData purchaseData = getInAppPurchaseData(productId, data, signature); + if (purchaseData != null) { + return purchaseData; + } + } + return null; + } + + @Nullable + public static InAppPurchaseData getInAppPurchaseData(@Nullable String productId, @NonNull String data, @NonNull String signature) { + try { + InAppPurchaseData purchaseData = new InAppPurchaseData(data); + if (productId == null || productId.equals(purchaseData.getProductId())) { + boolean credible = CipherUtil.doCheck(data, signature, CipherUtil.getPublicKey()); + if (credible) { + return purchaseData.isSubValid() ? purchaseData : null; + } else { + Log.e(TAG, "check the data signature fail"); + return null; + } + } + } catch (JSONException e) { + Log.e(TAG, "parse InAppPurchaseData JSONException", e); + return null; + } + return null; + } + + /** + * Parse PurchaseResult data from intent + * + * @param activity Activity + * @param data the intent from onActivityResult + * @return PurchaseResultInfo + */ + public static PurchaseResultInfo getPurchaseResult(Activity activity, Intent data) { + PurchaseResultInfo purchaseResultInfo = Iap.getIapClient(activity).parsePurchaseResultInfoFromIntent(data); + if (null == purchaseResultInfo) { + Log.e(TAG, "PurchaseResultInfo is null"); + } else { + int returnCode = purchaseResultInfo.getReturnCode(); + String errMsg = purchaseResultInfo.getErrMsg(); + switch (returnCode) { + case OrderStatusCode.ORDER_PRODUCT_OWNED: + Log.w(TAG, "you have owned this product"); + break; + case OrderStatusCode.ORDER_STATE_SUCCESS: + boolean credible = CipherUtil.doCheck(purchaseResultInfo.getInAppPurchaseData(), purchaseResultInfo.getInAppDataSignature(), CipherUtil + .getPublicKey()); + if (credible) { + try { + InAppPurchaseData inAppPurchaseData = new InAppPurchaseData(purchaseResultInfo.getInAppPurchaseData()); + if (!inAppPurchaseData.isSubValid()) { + return getFailedPurchaseResultInfo(); + } + } catch (JSONException e) { + Log.e(TAG, "parse InAppPurchaseData JSONException", e); + return getFailedPurchaseResultInfo(); + } + } else { + Log.e(TAG, "check the data signature fail"); + } + return getFailedPurchaseResultInfo(); + + default: + Log.e(TAG, "returnCode: " + returnCode + " , errMsg: " + errMsg); + break; + } + } + return purchaseResultInfo; + } + + private static PurchaseResultInfo getFailedPurchaseResultInfo() { + PurchaseResultInfo info = new PurchaseResultInfo(); + info.setReturnCode(OrderStatusCode.ORDER_STATE_FAILED); + return info; + } +} diff --git a/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java b/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java index cb91f7d167..3929307cb9 100644 --- a/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java @@ -5,7 +5,6 @@ import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.widget.Toast; import androidx.annotation.NonNull; @@ -14,12 +13,14 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseInitCallback; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType; import net.osmand.plus.liveupdates.OsmLiveRestartBottomSheetDialogFragment; @@ -27,6 +28,7 @@ import net.osmand.plus.srtmplugin.SRTMPlugin; import org.apache.commons.logging.Log; +import java.lang.ref.WeakReference; import java.util.List; @SuppressLint("Registered") @@ -34,14 +36,7 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In private static final Log LOG = PlatformUtil.getLog(OsmandInAppPurchaseActivity.class); private InAppPurchaseHelper purchaseHelper; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (isInAppPurchaseAllowed() && isInAppPurchaseSupported()) { - purchaseHelper = getMyApplication().getInAppPurchaseHelper(); - } - } + private boolean activityDestroyed; @Override protected void onResume() { @@ -53,17 +48,36 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In protected void onDestroy() { super.onDestroy(); deinitInAppPurchaseHelper(); + activityDestroyed = true; } private void initInAppPurchaseHelper() { deinitInAppPurchaseHelper(); - - if (purchaseHelper != null) { - purchaseHelper.setUiActivity(this); - if (purchaseHelper.needRequestInventory()) { - purchaseHelper.requestInventory(); + if (purchaseHelper == null) { + InAppPurchaseHelper purchaseHelper = getMyApplication().getInAppPurchaseHelper(); + if (isInAppPurchaseAllowed() && isInAppPurchaseSupported(purchaseHelper)) { + this.purchaseHelper = purchaseHelper; } } + if (purchaseHelper != null) { + final WeakReference activityRef = new WeakReference<>(this); + purchaseHelper.isInAppPurchaseSupported(this, new InAppPurchaseInitCallback() { + @Override + public void onSuccess() { + OsmandInAppPurchaseActivity activity = activityRef.get(); + if (!activityDestroyed && AndroidUtils.isActivityNotDestroyed(activity)) { + purchaseHelper.setUiActivity(activity); + if (purchaseHelper.needRequestInventory()) { + purchaseHelper.requestInventory(); + } + } + } + + @Override + public void onFail() { + } + }); + } } private void deinitInAppPurchaseHelper() { @@ -80,7 +94,11 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); if (purchaseHelper != null) { app.logEvent("in_app_purchase_redirect"); - purchaseHelper.purchaseFullVersion(activity); + try { + purchaseHelper.purchaseFullVersion(activity); + } catch (UnsupportedOperationException e) { + LOG.error("purchaseFullVersion is not supported", e); + } } } else { app.logEvent("paid_version_redirect"); @@ -101,7 +119,11 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); if (purchaseHelper != null) { app.logEvent("depth_contours_purchase_redirect"); - purchaseHelper.purchaseDepthContours(activity); + try { + purchaseHelper.purchaseDepthContours(activity); + } catch (UnsupportedOperationException e) { + LOG.error("purchaseDepthContours is not supported", e); + } } } } @@ -129,8 +151,9 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In return false; } - public boolean isInAppPurchaseSupported() { - return Version.isGooglePlayEnabled(getMyApplication()); + public boolean isInAppPurchaseSupported(InAppPurchaseHelper purchaseHelper) { + OsmandApplication app = getMyApplication(); + return Version.isGooglePlayEnabled(app) || Version.isHuawei(app); } @Override @@ -222,6 +245,17 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In } } + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + boolean handled = false; + if (purchaseHelper != null) { + handled = purchaseHelper.onActivityResult(this, requestCode, resultCode, data); + } + if (!handled) { + super.onActivityResult(requestCode, resultCode, data); + } + } + public void onInAppPurchaseError(InAppPurchaseTaskType taskType, String error) { // not implemented } diff --git a/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java b/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java index 855f648332..a4bb6ec74f 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/DiscountHelper.java @@ -20,12 +20,14 @@ import androidx.annotation.NonNull; import androidx.appcompat.content.res.AppCompatResources; import net.osmand.AndroidNetworkUtils; +import net.osmand.PlatformUtil; import net.osmand.osm.AbstractPoiType; import net.osmand.osm.MapPoiTypes; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.activities.OsmandInAppPurchaseActivity; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -56,7 +58,7 @@ import java.util.Map; public class DiscountHelper { private static final String TAG = "DiscountHelper"; - //private static final String DISCOUNT_JSON = "discount.json"; + private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(DiscountHelper.class); private static long mLastCheckTime; private static ControllerData mData; @@ -312,7 +314,11 @@ public class DiscountHelper { if (purchaseHelper != null) { if (url.contains(purchaseHelper.getFullVersion().getSku())) { app.logEvent("in_app_purchase_redirect"); - purchaseHelper.purchaseFullVersion(mapActivity); + try { + purchaseHelper.purchaseFullVersion(mapActivity); + } catch (UnsupportedOperationException e) { + LOG.error("purchaseFullVersion is not supported", e); + } } else { for (InAppPurchase p : purchaseHelper.getLiveUpdates().getAllSubscriptions()) { if (url.contains(p.getSku())) { diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java index c037c13d0a..ff734e6af5 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java @@ -2,6 +2,7 @@ package net.osmand.plus.inapp; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.Intent; import android.os.AsyncTask; import android.text.TextUtils; import android.util.Log; @@ -64,6 +65,7 @@ public abstract class InAppPurchaseHelper { protected InAppPurchaseListener uiActivity = null; public interface InAppPurchaseListener { + void onError(InAppPurchaseTaskType taskType, String error); void onGetItems(); @@ -75,6 +77,13 @@ public abstract class InAppPurchaseHelper { void dismissProgress(InAppPurchaseTaskType taskType); } + public interface InAppPurchaseInitCallback { + + void onSuccess(); + + void onFail(); + } + public enum InAppPurchaseTaskType { REQUEST_INVENTORY, PURCHASE_FULL_VERSION, @@ -82,9 +91,23 @@ public abstract class InAppPurchaseHelper { PURCHASE_DEPTH_CONTOURS } - public interface InAppRunnable { + public abstract class InAppCommand { + + InAppCommandResultHandler resultHandler; + // return true if done and false if async task started - boolean run(InAppPurchaseHelper helper); + abstract void run(InAppPurchaseHelper helper); + + protected void commandDone() { + InAppCommandResultHandler resultHandler = this.resultHandler; + if (resultHandler != null) { + resultHandler.onCommandDone(this); + } + } + } + + public interface InAppCommandResultHandler { + void onCommandDone(@NonNull InAppCommand command); } public static class PurchaseInfo { @@ -163,9 +186,10 @@ public abstract class InAppPurchaseHelper { public InAppPurchaseHelper(OsmandApplication ctx) { this.ctx = ctx; isDeveloperVersion = Version.isDeveloperVersion(ctx); - purchases = new InAppPurchases(ctx); } + public abstract void isInAppPurchaseSupported(@NonNull final Activity activity, @Nullable final InAppPurchaseInitCallback callback); + public boolean hasInventory() { return lastValidationCheckTime != 0; } @@ -181,7 +205,7 @@ public abstract class InAppPurchaseHelper { return false; } - protected void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppRunnable runnable) { + protected void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppCommand command) { if (isDeveloperVersion || !Version.isGooglePlayEnabled(ctx)) { notifyDismissProgress(taskType); stop(true); @@ -205,14 +229,20 @@ public abstract class InAppPurchaseHelper { try { processingTask = true; activeTask = taskType; - execImpl(taskType, runnable); + command.resultHandler = new InAppCommandResultHandler() { + @Override + public void onCommandDone(@NonNull InAppCommand command) { + processingTask = false; + } + }; + execImpl(taskType, command); } catch (Exception e) { logError("exec Error", e); stop(true); } } - protected abstract void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppRunnable runnable); + protected abstract void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppCommand command); public boolean needRequestInventory() { return !inventoryRequested && ((isSubscribedToLiveUpdates(ctx) && Algorithms.isEmpty(ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.get())) @@ -224,16 +254,16 @@ public abstract class InAppPurchaseHelper { new RequestInventoryTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); } - public abstract void purchaseFullVersion(final Activity activity) throws UnsupportedOperationException; + public abstract void purchaseFullVersion(@NonNull final Activity activity) throws UnsupportedOperationException; - public void purchaseLiveUpdates(Activity activity, String sku, String email, String userName, + public void purchaseLiveUpdates(@NonNull Activity activity, String sku, String email, String userName, String countryDownloadName, boolean hideUserName) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES); new LiveUpdatesPurchaseTask(activity, sku, email, userName, countryDownloadName, hideUserName) .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); } - public abstract void purchaseDepthContours(final Activity activity) throws UnsupportedOperationException; + public abstract void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException; @SuppressLint("StaticFieldLeak") private class LiveUpdatesPurchaseTask extends AsyncTask { @@ -329,8 +359,8 @@ public abstract class InAppPurchaseHelper { } } - protected abstract InAppRunnable getPurchaseLiveUpdatesCommand(final WeakReference activity, - final String sku, final String payload) throws UnsupportedOperationException; + protected abstract InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference activity, + final String sku, final String payload) throws UnsupportedOperationException; @SuppressLint("StaticFieldLeak") private class RequestInventoryTask extends AsyncTask { @@ -380,7 +410,7 @@ public abstract class InAppPurchaseHelper { } } - protected abstract InAppRunnable getRequestInventoryCommand() throws UnsupportedOperationException; + protected abstract InAppCommand getRequestInventoryCommand() throws UnsupportedOperationException; protected void onSkuDetailsResponseDone(List purchaseInfoList) { final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() { @@ -599,6 +629,10 @@ public abstract class InAppPurchaseHelper { } } + public boolean onActivityResult(@NonNull Activity activity, int requestCode, int resultCode, Intent data) { + return false; + } + protected void notifyError(InAppPurchaseTaskType taskType, String message) { if (uiActivity != null) { uiActivity.onError(taskType, message); diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java index 8c42448ec7..5ccb49a70e 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java @@ -11,14 +11,11 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.billingclient.api.SkuDetails; - import net.osmand.AndroidUtils; import net.osmand.Period; import net.osmand.Period.PeriodUnit; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.Version; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.widgets.style.CustomTypefaceSpan; import net.osmand.util.Algorithms; @@ -33,72 +30,17 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class InAppPurchases { +public abstract class InAppPurchases { - private static final InAppPurchase FULL_VERSION = new InAppPurchaseFullVersion(); - private static final InAppPurchaseDepthContoursFull DEPTH_CONTOURS_FULL = new InAppPurchaseDepthContoursFull(); - private static final InAppPurchaseDepthContoursFree DEPTH_CONTOURS_FREE = new InAppPurchaseDepthContoursFree(); - private static final InAppPurchaseContourLinesFull CONTOUR_LINES_FULL = new InAppPurchaseContourLinesFull(); - private static final InAppPurchaseContourLinesFree CONTOUR_LINES_FREE = new InAppPurchaseContourLinesFree(); + protected InAppPurchase fullVersion; + protected InAppPurchase depthContours; + protected InAppPurchase contourLines; + protected InAppSubscription monthlyLiveUpdates; + protected InAppSubscription discountedMonthlyLiveUpdates; + protected InAppSubscriptionList liveUpdates; + protected InAppPurchase[] inAppPurchases; - private static final InAppSubscription[] LIVE_UPDATES_FULL = new InAppSubscription[]{ - new InAppPurchaseLiveUpdatesOldMonthlyFull(), - new InAppPurchaseLiveUpdatesMonthlyFull(), - new InAppPurchaseLiveUpdates3MonthsFull(), - new InAppPurchaseLiveUpdatesAnnualFull() - }; - - private static final InAppSubscription[] LIVE_UPDATES_FREE = new InAppSubscription[]{ - new InAppPurchaseLiveUpdatesOldMonthlyFree(), - new InAppPurchaseLiveUpdatesMonthlyFree(), - new InAppPurchaseLiveUpdates3MonthsFree(), - new InAppPurchaseLiveUpdatesAnnualFree() - }; - - private static final InAppSubscription[] LIVE_UPDATES_HW_FREE = new InAppSubscription[]{ - new InAppPurchaseLiveUpdatesMonthlyHWFree(), - new InAppPurchaseLiveUpdates3MonthsHWFree(), - new InAppPurchaseLiveUpdatesAnnualHWFree() - }; - - private InAppPurchase fullVersion; - private InAppPurchase depthContours; - private InAppPurchase contourLines; - private InAppSubscription monthlyLiveUpdates; - private InAppSubscription discountedMonthlyLiveUpdates; - private InAppSubscriptionList liveUpdates; - private InAppPurchase[] inAppPurchases; - - InAppPurchases(OsmandApplication ctx) { - fullVersion = FULL_VERSION; - if (Version.isHuawei(ctx)) { - liveUpdates = new LiveUpdatesInAppPurchasesHWFree(); - } else if (Version.isFreeVersion(ctx)) { - liveUpdates = new LiveUpdatesInAppPurchasesFree(); - } else { - liveUpdates = new LiveUpdatesInAppPurchasesFull(); - } - for (InAppSubscription s : liveUpdates.getAllSubscriptions()) { - if (s instanceof InAppPurchaseLiveUpdatesMonthly) { - if (s.isDiscounted()) { - discountedMonthlyLiveUpdates = s; - } else { - monthlyLiveUpdates = s; - } - } - } - if (Version.isFreeVersion(ctx)) { - depthContours = DEPTH_CONTOURS_FREE; - } else { - depthContours = DEPTH_CONTOURS_FULL; - } - if (Version.isFreeVersion(ctx)) { - contourLines = CONTOUR_LINES_FREE; - } else { - contourLines = CONTOUR_LINES_FULL; - } - - inAppPurchases = new InAppPurchase[] { fullVersion, depthContours, contourLines }; + protected InAppPurchases(OsmandApplication ctx) { } public InAppPurchase getFullVersion() { @@ -166,31 +108,13 @@ public class InAppPurchases { return null; } - public boolean isFullVersion(String sku) { - return FULL_VERSION.getSku().equals(sku); - } + public abstract boolean isFullVersion(String sku); - public boolean isDepthContours(String sku) { - return DEPTH_CONTOURS_FULL.getSku().equals(sku) || DEPTH_CONTOURS_FREE.getSku().equals(sku); - } + public abstract boolean isDepthContours(String sku); - public boolean isContourLines(String sku) { - return CONTOUR_LINES_FULL.getSku().equals(sku) || CONTOUR_LINES_FREE.getSku().equals(sku); - } + public abstract boolean isContourLines(String sku); - public boolean isLiveUpdates(String sku) { - for (InAppPurchase p : LIVE_UPDATES_FULL) { - if (p.getSku().equals(sku)) { - return true; - } - } - for (InAppPurchase p : LIVE_UPDATES_FREE) { - if (p.getSku().equals(sku)) { - return true; - } - } - return false; - } + public abstract boolean isLiveUpdates(String sku); public abstract static class InAppSubscriptionList { @@ -268,27 +192,6 @@ public class InAppPurchases { } } - public static class LiveUpdatesInAppPurchasesFree extends InAppSubscriptionList { - - public LiveUpdatesInAppPurchasesFree() { - super(LIVE_UPDATES_FREE); - } - } - - public static class LiveUpdatesInAppPurchasesHWFree extends InAppSubscriptionList { - - public LiveUpdatesInAppPurchasesHWFree() { - super(LIVE_UPDATES_HW_FREE); - } - } - - public static class LiveUpdatesInAppPurchasesFull extends InAppSubscriptionList { - - public LiveUpdatesInAppPurchasesFull() { - super(LIVE_UPDATES_FULL); - } - } - public abstract static class InAppPurchase { public enum PurchaseState { @@ -310,11 +213,11 @@ public class InAppPurchases { private NumberFormat currencyFormatter; - private InAppPurchase(@NonNull String sku) { + protected InAppPurchase(@NonNull String sku) { this.sku = sku; } - private InAppPurchase(@NonNull String sku, boolean discounted) { + protected InAppPurchase(@NonNull String sku, boolean discounted) { this(sku); this.discounted = discounted; } @@ -792,23 +695,9 @@ public class InAppPurchases { } } - public static class InAppPurchaseFullVersion extends InAppPurchase { - - private static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price"; - - InAppPurchaseFullVersion() { - super(SKU_FULL_VERSION_PRICE); - } - - @Override - public String getDefaultPrice(Context ctx) { - return ctx.getString(R.string.full_version_price); - } - } - public static class InAppPurchaseDepthContours extends InAppPurchase { - private InAppPurchaseDepthContours(String sku) { + protected InAppPurchaseDepthContours(String sku) { super(sku); } @@ -818,27 +707,9 @@ public class InAppPurchases { } } - public static class InAppPurchaseDepthContoursFull extends InAppPurchaseDepthContours { - - private static final String SKU_DEPTH_CONTOURS_FULL = "net.osmand.seadepth_plus"; - - InAppPurchaseDepthContoursFull() { - super(SKU_DEPTH_CONTOURS_FULL); - } - } - - public static class InAppPurchaseDepthContoursFree extends InAppPurchaseDepthContours { - - private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth"; - - InAppPurchaseDepthContoursFree() { - super(SKU_DEPTH_CONTOURS_FREE); - } - } - public static class InAppPurchaseContourLines extends InAppPurchase { - private InAppPurchaseContourLines(String sku) { + protected InAppPurchaseContourLines(String sku) { super(sku); } @@ -848,25 +719,7 @@ public class InAppPurchases { } } - public static class InAppPurchaseContourLinesFull extends InAppPurchaseContourLines { - - private static final String SKU_CONTOUR_LINES_FULL = "net.osmand.contourlines_plus"; - - InAppPurchaseContourLinesFull() { - super(SKU_CONTOUR_LINES_FULL); - } - } - - public static class InAppPurchaseContourLinesFree extends InAppPurchaseContourLines { - - private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.contourlines"; - - InAppPurchaseContourLinesFree() { - super(SKU_CONTOUR_LINES_FREE); - } - } - - public static abstract class InAppPurchaseLiveUpdatesMonthly extends InAppSubscription { + protected static abstract class InAppPurchaseLiveUpdatesMonthly extends InAppSubscription { InAppPurchaseLiveUpdatesMonthly(String skuNoVersion, int version) { super(skuNoVersion, version); @@ -920,64 +773,7 @@ public class InAppPurchases { } } - public static class InAppPurchaseLiveUpdatesMonthlyFull extends InAppPurchaseLiveUpdatesMonthly { - - private static final String SKU_LIVE_UPDATES_MONTHLY_FULL = "osm_live_subscription_monthly_full"; - - InAppPurchaseLiveUpdatesMonthlyFull() { - super(SKU_LIVE_UPDATES_MONTHLY_FULL, 1); - } - - private InAppPurchaseLiveUpdatesMonthlyFull(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyFull(sku) : null; - } - } - - public static class InAppPurchaseLiveUpdatesMonthlyFree extends InAppPurchaseLiveUpdatesMonthly { - - private static final String SKU_LIVE_UPDATES_MONTHLY_FREE = "osm_live_subscription_monthly_free"; - - InAppPurchaseLiveUpdatesMonthlyFree() { - super(SKU_LIVE_UPDATES_MONTHLY_FREE, 1); - } - - private InAppPurchaseLiveUpdatesMonthlyFree(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyFree(sku) : null; - } - } - - public static class InAppPurchaseLiveUpdatesMonthlyHWFree extends InAppPurchaseLiveUpdatesMonthly { - - private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.test.monthly"; - - InAppPurchaseLiveUpdatesMonthlyHWFree() { - super(SKU_LIVE_UPDATES_MONTHLY_HW_FREE, 1); - } - - private InAppPurchaseLiveUpdatesMonthlyHWFree(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesMonthlyHWFree(sku) : null; - } - } - - public static abstract class InAppPurchaseLiveUpdates3Months extends InAppSubscription { + protected static abstract class InAppPurchaseLiveUpdates3Months extends InAppSubscription { InAppPurchaseLiveUpdates3Months(String skuNoVersion, int version) { super(skuNoVersion, version); @@ -1020,64 +816,7 @@ public class InAppPurchases { } } - public static class InAppPurchaseLiveUpdates3MonthsFull extends InAppPurchaseLiveUpdates3Months { - - private static final String SKU_LIVE_UPDATES_3_MONTHS_FULL = "osm_live_subscription_3_months_full"; - - InAppPurchaseLiveUpdates3MonthsFull() { - super(SKU_LIVE_UPDATES_3_MONTHS_FULL, 1); - } - - private InAppPurchaseLiveUpdates3MonthsFull(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsFull(sku) : null; - } - } - - public static class InAppPurchaseLiveUpdates3MonthsFree extends InAppPurchaseLiveUpdates3Months { - - private static final String SKU_LIVE_UPDATES_3_MONTHS_FREE = "osm_live_subscription_3_months_free"; - - InAppPurchaseLiveUpdates3MonthsFree() { - super(SKU_LIVE_UPDATES_3_MONTHS_FREE, 1); - } - - private InAppPurchaseLiveUpdates3MonthsFree(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsFree(sku) : null; - } - } - - public static class InAppPurchaseLiveUpdates3MonthsHWFree extends InAppPurchaseLiveUpdates3Months { - - private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.test.3months"; - - InAppPurchaseLiveUpdates3MonthsHWFree() { - super(SKU_LIVE_UPDATES_3_MONTHS_HW_FREE, 1); - } - - private InAppPurchaseLiveUpdates3MonthsHWFree(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdates3MonthsHWFree(sku) : null; - } - } - - public static abstract class InAppPurchaseLiveUpdatesAnnual extends InAppSubscription { + protected static abstract class InAppPurchaseLiveUpdatesAnnual extends InAppSubscription { InAppPurchaseLiveUpdatesAnnual(String skuNoVersion, int version) { super(skuNoVersion, version); @@ -1120,63 +859,6 @@ public class InAppPurchases { } } - public static class InAppPurchaseLiveUpdatesAnnualFull extends InAppPurchaseLiveUpdatesAnnual { - - private static final String SKU_LIVE_UPDATES_ANNUAL_FULL = "osm_live_subscription_annual_full"; - - InAppPurchaseLiveUpdatesAnnualFull() { - super(SKU_LIVE_UPDATES_ANNUAL_FULL, 1); - } - - private InAppPurchaseLiveUpdatesAnnualFull(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualFull(sku) : null; - } - } - - public static class InAppPurchaseLiveUpdatesAnnualFree extends InAppPurchaseLiveUpdatesAnnual { - - private static final String SKU_LIVE_UPDATES_ANNUAL_FREE = "osm_live_subscription_annual_free"; - - InAppPurchaseLiveUpdatesAnnualFree() { - super(SKU_LIVE_UPDATES_ANNUAL_FREE, 1); - } - - private InAppPurchaseLiveUpdatesAnnualFree(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualFree(sku) : null; - } - } - - public static class InAppPurchaseLiveUpdatesAnnualHWFree extends InAppPurchaseLiveUpdatesAnnual { - - private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.test.annual"; - - InAppPurchaseLiveUpdatesAnnualHWFree() { - super(SKU_LIVE_UPDATES_ANNUAL_HW_FREE, 1); - } - - private InAppPurchaseLiveUpdatesAnnualHWFree(@NonNull String sku) { - super(sku); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return sku.startsWith(getSkuNoVersion()) ? new InAppPurchaseLiveUpdatesAnnualHWFree(sku) : null; - } - } - public static class InAppPurchaseLiveUpdatesOldMonthly extends InAppPurchaseLiveUpdatesMonthly { InAppPurchaseLiveUpdatesOldMonthly(String sku) { @@ -1199,54 +881,5 @@ public class InAppPurchases { return null; } } - - public static class InAppPurchaseLiveUpdatesOldMonthlyFull extends InAppPurchaseLiveUpdatesOldMonthly { - - private static final String SKU_LIVE_UPDATES_OLD_MONTHLY_FULL = "osm_live_subscription_2"; - - InAppPurchaseLiveUpdatesOldMonthlyFull() { - super(SKU_LIVE_UPDATES_OLD_MONTHLY_FULL); - } - } - - public static class InAppPurchaseLiveUpdatesOldMonthlyFree extends InAppPurchaseLiveUpdatesOldMonthly { - - private static final String SKU_LIVE_UPDATES_OLD_MONTHLY_FREE = "osm_free_live_subscription_2"; - - InAppPurchaseLiveUpdatesOldMonthlyFree() { - super(SKU_LIVE_UPDATES_OLD_MONTHLY_FREE); - } - } - - public static class InAppPurchaseLiveUpdatesOldSubscription extends InAppSubscription { - - private SkuDetails details; - - InAppPurchaseLiveUpdatesOldSubscription(@NonNull SkuDetails details) { - super(details.getSku(), true); - this.details = details; - } - - @Override - public String getDefaultPrice(Context ctx) { - return ""; - } - - @Override - public CharSequence getTitle(Context ctx) { - return details.getTitle(); - } - - @Override - public CharSequence getDescription(@NonNull Context ctx) { - return details.getDescription(); - } - - @Nullable - @Override - protected InAppSubscription newInstance(@NonNull String sku) { - return null; - } - } } From 7ab1dcd7fb8f919dcc599818602d0d3382ce7a8a Mon Sep 17 00:00:00 2001 From: sergosm Date: Thu, 1 Oct 2020 22:26:32 +0300 Subject: [PATCH 0393/1366] Ability to divide Add support for 3-row buttons, with the ability to divide one of the buttons, to make it visually divided. --- .../plus/base/MenuBottomSheetDialogFragment.java | 16 ++++++++++++++-- .../ExitBottomSheetDialogFragment.java | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index 57378848f5..0d86993502 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -360,8 +360,14 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } }); } + View divider = buttonsContainer.findViewById(R.id.buttons_divider); + divider.getLayoutParams().height = getFirstDividerHeight(); AndroidUiHelper.updateVisibility(rightButton, buttonTextId != DEFAULT_VALUE); - AndroidUiHelper.updateVisibility(buttonsContainer.findViewById(R.id.buttons_divider), buttonTextId != DEFAULT_VALUE); + AndroidUiHelper.updateVisibility(divider, buttonTextId != DEFAULT_VALUE); + } + + protected int getFirstDividerHeight(){ + return getResources().getDimensionPixelSize(R.dimen.content_padding); } private void setupThirdButton() { @@ -376,8 +382,14 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } }); } + View divider = buttonsContainer.findViewById(R.id.buttons_divider_top); + divider.getLayoutParams().height = getSecondDividerHeight(); AndroidUiHelper.updateVisibility(thirdButton, buttonTextId != DEFAULT_VALUE); - AndroidUiHelper.updateVisibility(buttonsContainer.findViewById(R.id.buttons_divider_top), buttonTextId != DEFAULT_VALUE); + AndroidUiHelper.updateVisibility(divider, buttonTextId != DEFAULT_VALUE); + } + + protected int getSecondDividerHeight(){ + return getResources().getDimensionPixelSize(R.dimen.content_padding); } @ColorRes diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java index 94b5b16e46..7d88767964 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java @@ -14,6 +14,7 @@ import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemButton; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; +import net.osmand.plus.helpers.AndroidUiHelper; public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { @@ -53,6 +54,11 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment return R.string.shared_string_exit; } + @Override + public int getSecondDividerHeight() { + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large); + } + @Override protected void onRightBottomButtonClick() { Fragment targetFragment = getTargetFragment(); From 38ba94ee1c9b9bb4a9d994bceee44266c2ef0b16 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 2 Oct 2020 11:56:07 +0300 Subject: [PATCH 0394/1366] Add base import task --- .../net/osmand/plus/helpers/ImportHelper.java | 258 ++++++------------ 1 file changed, 89 insertions(+), 169 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index a8d621f9ed..febffa73bf 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -75,13 +75,13 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; -import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_CHART_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_EXT; +import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT; import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE; import static net.osmand.plus.AppInitializer.loadRoutingFiles; import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; @@ -92,17 +92,20 @@ import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; * @author Koen Rabaey */ public class ImportHelper { - public final static Log log = PlatformUtil.getLog(ImportHelper.class); + + public static final Log log = PlatformUtil.getLog(ImportHelper.class); + public static final String KML_SUFFIX = ".kml"; public static final String KMZ_SUFFIX = ".kmz"; - private final AppCompatActivity activity; + public static final int IMPORT_FILE_REQUEST = 1006; + private final OsmandApplication app; private final OsmandMapTileView mapView; + private final AppCompatActivity activity; + private OnGpxImportCompleteListener gpxImportCompleteListener; - public final static int IMPORT_FILE_REQUEST = 1006; - public enum ImportType { SETTINGS(OSMAND_SETTINGS_FILE_EXT), ROUTING(ROUTING_FILE_EXT), @@ -189,20 +192,19 @@ public class ImportHelper { } public void handleFileImport(Uri intentUri, String fileName, Bundle extras, boolean useImportDir) { - final boolean isFileIntent = "file".equals(intentUri.getScheme()); - final boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); - - final boolean saveFile = !isFileIntent || !isOsmandSubdir; + boolean isFileIntent = "file".equals(intentUri.getScheme()); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); + boolean saveFile = !isFileIntent || !isOsmandSubdir; if (fileName == null) { handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false); - } else if (fileName.endsWith(KML_SUFFIX)) { + } else if (fileName.endsWith(KML_SUFFIX)) { handleKmlImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(KMZ_SUFFIX)) { handleKmzImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { handleObfImport(intentUri, fileName); - } else if (fileName.endsWith(IndexConstants.SQLITE_EXT)) { + } else if (fileName.endsWith(SQLITE_EXT)) { handleSqliteTileImport(intentUri, fileName); } else if (fileName.endsWith(OSMAND_SETTINGS_FILE_EXT)) { handleOsmAndSettingsImport(intentUri, fileName, extras, null); @@ -220,7 +222,8 @@ public class ImportHelper { public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) { try { final String name; - final Cursor returnCursor = app.getContentResolver().query(contentUri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null); + final Cursor returnCursor = app.getContentResolver().query(contentUri, + new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); if (returnCursor != null && returnCursor.moveToFirst()) { int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (columnIndex != -1) { @@ -239,19 +242,12 @@ public class ImportHelper { log.error(e.getMessage(), e); return null; } - } @SuppressLint("StaticFieldLeak") private void handleGpxImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir, final boolean showInDetailsActivity) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask gpxImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -266,35 +262,25 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException ignore) { - } + Algorithms.closeStream(is); } return null; } @Override protected void onPostExecute(GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(gpxImportTask); } @SuppressLint("StaticFieldLeak") private void handleGpxOrFavouritesImport(final Uri fileUri, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + final boolean useImportDir, final boolean forceImportFavourites, + final boolean forceImportGpx) { + AsyncTask gpxOrFavouritesImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -340,40 +326,24 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException ignore) { - } - if (zis != null) try { - zis.close(); - } catch (IOException ignore) { - } + Algorithms.closeStream(is); + Algorithms.closeStream(zis); } return null; } @Override protected void onPostExecute(final GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(gpxOrFavouritesImportTask); } @SuppressLint("StaticFieldLeak") private void importFavoritesImpl(final GPXFile gpxFile, final String fileName, final boolean forceImportFavourites) { - final AsyncTask favoritesImportTask = new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), - app.getString(R.string.loading_data)); - } - } + AsyncTask favoritesImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -391,9 +361,7 @@ public class ImportHelper { @Override protected void onPostExecute(GPXFile result) { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG).show(); final Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity()); @@ -407,13 +375,7 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleKmzImport(final Uri kmzFile, final String name, final boolean save, final boolean useImportDir) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask kmzImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... voids) { @@ -441,39 +403,25 @@ public class ImportHelper { } catch (Exception e) { log.error(e.getMessage(), e); } finally { - try { - if (is != null) { - is.close(); - } - if (zis != null) { - zis.close(); - } - } catch (IOException ignore) { - } + Algorithms.closeStream(is); + Algorithms.closeStream(zis); } return null; } @Override protected void onPostExecute(GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); handleResult(result, name, save, useImportDir, false); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(kmzImportTask); } @SuppressLint("StaticFieldLeak") private void handleKmlImport(final Uri kmlFile, final String name, final boolean save, final boolean useImportDir) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask kmlImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -495,34 +443,23 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException ignore) { - } + Algorithms.closeStream(is); } return null; } @Override protected void onPostExecute(GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); handleResult(result, name, save, useImportDir, false); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(kmlImportTask); } @SuppressLint("StaticFieldLeak") private void handleObfImport(final Uri obfFile, final String name) { - new AsyncTask() { - - ProgressDialog progress; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask obfImportTask = new BaseImportAsyncTask() { @Override protected String doInBackground(Void... voids) { @@ -537,12 +474,11 @@ public class ImportHelper { @Override protected void onPostExecute(String message) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - Toast.makeText(app, message, Toast.LENGTH_SHORT).show(); + hideProgress(); + app.showShortToastMessage(message); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(obfImportTask); } @NonNull @@ -583,7 +519,7 @@ public class ImportHelper { } catch (SecurityException e) { e.printStackTrace(); error = e.getMessage(); - } finally { + } finally { if (in != null) { try { in.close(); @@ -604,14 +540,7 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleSqliteTileImport(final Uri uri, final String name) { - new AsyncTask() { - - ProgressDialog progress; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask sqliteTileImportTask = new BaseImportAsyncTask() { @Override protected String doInBackground(Void... voids) { @@ -620,9 +549,7 @@ public class ImportHelper { @Override protected void onPostExecute(String error) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); if (error == null) { OsmandRasterMapsPlugin plugin = OsmandPlugin.getPlugin(OsmandRasterMapsPlugin.class); if (plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { @@ -637,7 +564,8 @@ public class ImportHelper { Toast.makeText(app, app.getString(R.string.map_import_error) + ": " + error, Toast.LENGTH_SHORT).show(); } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(sqliteTileImportTask); } public void chooseFileToImport(final ImportType importType, final CallbackWithObject callback) { @@ -667,21 +595,21 @@ public class ImportHelper { } else if ("content".equals(scheme)) { fileName = getNameFromContentUri(app, data); } - + if (fileName.endsWith(importType.getExtension())) { if (importType.equals(ImportType.SETTINGS)) { handleOsmAndSettingsImport(data, fileName, resultData.getExtras(), callback); - } else if (importType.equals(ImportType.ROUTING)){ + } else if (importType.equals(ImportType.ROUTING)) { handleXmlFileImport(data, fileName, callback); } } else { - app.showToastMessage(app.getString(R.string.not_support_file_type_with_ext, + app.showToastMessage(app.getString(R.string.not_support_file_type_with_ext, importType.getExtension().replaceAll("\\.", "").toUpperCase())); } } } }); - + mapActivity.registerActivityResultListener(listener); mapActivity.startActivityForResult(intent, IMPORT_FILE_REQUEST); } @@ -712,16 +640,7 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, final CallbackWithObject> callback) { - final AsyncTask settingsImportTask = new AsyncTask() { - - ProgressDialog progress; - - @Override - protected void onPreExecute() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } - } + AsyncTask settingsImportTask = new BaseImportAsyncTask() { @Override protected String doInBackground(Void... voids) { @@ -741,9 +660,7 @@ public class ImportHelper { app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { @Override public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); if (succeed) { List pluginIndependentItems = new ArrayList<>(); List pluginSettingsItems = new ArrayList<>(); @@ -767,9 +684,7 @@ public class ImportHelper { } }); } else { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); } } @@ -835,17 +750,14 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleXmlFileImport(final Uri intentUri, final String fileName, final CallbackWithObject routingCallback) { - final AsyncTask renderingImportTask = new AsyncTask() { + AsyncTask renderingImportTask = new BaseImportAsyncTask() { private String destFileName; private ImportType importType; - private ProgressDialog progress; @Override protected void onPreExecute() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + showProgress(); destFileName = fileName; } @@ -893,12 +805,6 @@ public class ImportHelper { } } - private void hideProgress() { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - } - private File getDestinationDir() { if (importType == ImportType.ROUTING) { return app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); @@ -947,11 +853,7 @@ public class ImportHelper { break; } } - try { - is.close(); - } catch (IOException e) { - log.error(e); - } + Algorithms.closeStream(is); } } catch (FileNotFoundException | XmlPullParserException e) { log.error(e); @@ -960,11 +862,7 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException e) { - log.error(e); - } + Algorithms.closeStream(is); } } }; @@ -986,9 +884,8 @@ public class ImportHelper { } } else { if (save) { - new SaveAsyncTask(result, name, useImportDir, showInDetailsActivity) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else if (showInDetailsActivity) { + executeImportTask(new SaveAsyncTask(result, name, useImportDir, showInDetailsActivity)); + } else { showGpxInDetailsActivity(result); } if (gpxImportCompleteListener != null) { @@ -1162,8 +1059,8 @@ public class ImportHelper { } private void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { + final boolean useImportDir, final boolean forceImportFavourites, + final boolean forceImportGpx) { if (gpxFile == null || gpxFile.isPointsEmpty()) { if (forceImportFavourites) { final DialogInterface.OnClickListener importAsTrackListener = new DialogInterface.OnClickListener() { @@ -1258,4 +1155,27 @@ public class ImportHelper { importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); } } + + protected abstract class BaseImportAsyncTask extends AsyncTask { + + protected ProgressDialog progress; + + @Override + protected void onPreExecute() { + showProgress(); + } + + protected void showProgress() { + if (AndroidUtils.isActivityNotDestroyed(activity)) { + String title = app.getString(R.string.loading_smth, ""); + progress = ProgressDialog.show(activity, title, app.getString(R.string.loading_data)); + } + } + + protected void hideProgress() { + if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { + progress.dismiss(); + } + } + } } \ No newline at end of file From 689ebf5b75598182772139cbef7a71eb8544065d Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 2 Oct 2020 14:59:10 +0300 Subject: [PATCH 0395/1366] oauth finished --- OsmAnd-java/build.gradle | 5 +- .../java/net/osmand/osm/io/NetworkUtils.java | 142 ++++++++++-------- .../oauth/OsmOAuthAuthorizationClient.java | 134 +++++++++++++++++ OsmAnd/build.gradle | 2 +- .../plus/download/DownloadIndexesThread.java | 3 + .../plus/osmedit/EditPOIMenuController.java | 6 +- .../plus/osmedit/OpenstreetmapRemoteUtil.java | 108 +++++-------- .../plus/osmedit/OsmBugsRemoteUtil.java | 9 +- .../osmand/plus/osmedit/OsmEditingPlugin.java | 22 +-- .../osmedit/SettingsOsmEditingActivity.java | 9 +- .../oauth/OsmOAuthAuthorizationAdapter.java | 79 ++++++++++ .../oauth/OsmOAuthAuthorizationClient.java | 119 --------------- 12 files changed, 353 insertions(+), 285 deletions(-) create mode 100644 OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java create mode 100644 OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java delete mode 100644 OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java diff --git a/OsmAnd-java/build.gradle b/OsmAnd-java/build.gradle index 4385f9d0b0..0d0a3c265d 100644 --- a/OsmAnd-java/build.gradle +++ b/OsmAnd-java/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'java' apply plugin: 'maven-publish' - + configurations { android } @@ -104,6 +104,9 @@ dependencies { implementation 'com.moparisthebest:junidecode:0.1.1' implementation 'com.vividsolutions:jts-core:1.14.0' implementation 'com.google.openlocationcode:openlocationcode:1.0.4' + implementation('com.github.scribejava:scribejava-apis:7.1.1'){ + exclude group: "com.fasterxml.jackson.core" + } // turn off for now //implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0' implementation 'net.sf.kxml:kxml2:2.1.8' diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java index 282d6addbd..bdf5b6a70e 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java @@ -1,27 +1,19 @@ package net.osmand.osm.io; -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Proxy; -import java.net.URL; -import java.net.URLEncoder; -import java.util.Map; -import java.util.zip.GZIPOutputStream; - +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; import net.osmand.PlatformUtil; +import net.osmand.osm.oauth.OsmOAuthAuthorizationClient; import net.osmand.util.Algorithms; - import org.apache.commons.logging.Log; +import java.io.*; +import java.net.*; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.zip.GZIPOutputStream; + public class NetworkUtils { private static final Log log = PlatformUtil.getLog(NetworkUtils.class); @@ -55,7 +47,6 @@ public class NetworkUtils { responseBody.append("\n"); //$NON-NLS-1$ } responseBody.append(s); - } is.close(); } @@ -65,9 +56,10 @@ public class NetworkUtils { return e.getMessage(); } } - private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$ - public static String uploadFile(String urlText, File fileToUpload, String userNamePassword, String formName, boolean gzip, Map additionalMapData){ + public static String uploadFile(String urlText, File fileToUpload, String userNamePassword, + OsmOAuthAuthorizationClient client, + String formName, boolean gzip, Map additionalMapData){ URL url; try { boolean firstPrm =!urlText.contains("?"); @@ -77,47 +69,38 @@ public class NetworkUtils { } log.info("Start uploading file to " + urlText + " " +fileToUpload.getName()); url = new URL(urlText); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setDoInput(true); - conn.setDoOutput(true); - conn.setRequestMethod("POST"); - if(userNamePassword != null) { - conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$ + HttpURLConnection conn; + if (client != null && client.isValidToken()){ + OAuthRequest req = new OAuthRequest(Verb.POST, urlText); + req.setPayload(prepareStream(formName,fileToUpload,gzip)); + client.getService().signRequest(client.getAccessToken(), req); + req.addHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); + try { + Response r = client.getService().execute(req); + if(r.getCode() != 200){ + return r.getBody(); + } + return null; + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + return null; + } + else { + conn = (HttpURLConnection) url.openConnection(); + conn.setDoInput(true); + conn.setDoOutput(true); + conn.setRequestMethod("POST"); + if(userNamePassword != null) { + conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$ + } } - conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$ conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$ - OutputStream ous = conn.getOutputStream(); -// for (String key : additionalMapData.keySet()) { -// ous.write(("--" + BOUNDARY + "\r\n").getBytes()); -// ous.write(("content-disposition: form-data; name=\"" + key + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ -// ous.write((additionalMapData.get(key) + "\r\n").getBytes()); -// } - ous.write(("--" + BOUNDARY+"\r\n").getBytes()); - String filename = fileToUpload.getName(); - if(gzip){ - filename+=".gz"; - } - ous.write(("content-disposition: form-data; name=\""+formName+"\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ - ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$ - InputStream fis = new FileInputStream(fileToUpload); - BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024); - ous.flush(); - if(gzip){ - GZIPOutputStream gous = new GZIPOutputStream(ous, 1024); - Algorithms.streamCopy(bis, gous); - gous.flush(); - gous.finish(); - } else { - Algorithms.streamCopy(bis, ous); - } - - ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ - ous.flush(); - Algorithms.closeStream(bis); - Algorithms.closeStream(ous); - + ous.write(prepareStream(formName,fileToUpload,gzip)); log.info("Finish uploading file " + fileToUpload.getName()); log.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage()); if(conn.getResponseCode() != 200){ @@ -136,7 +119,6 @@ public class NetworkUtils { responseBody.append("\n"); //$NON-NLS-1$ } responseBody.append(s); - } is.close(); } @@ -149,6 +131,46 @@ public class NetworkUtils { } } + private static byte[] prepareStream(String formName, File fileToUpload, boolean gzip) { + try { + ByteArrayOutputStream ous = new ByteArrayOutputStream(); +// for (String key : additionalMapData.keySet()) { +// ous.write(("--" + BOUNDARY + "\r\n").getBytes()); +// ous.write(("content-disposition: form-data; name=\"" + key + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ +// ous.write((additionalMapData.get(key) + "\r\n").getBytes()); +// } + ous.write(("--" + BOUNDARY + "\r\n").getBytes()); + + String filename = fileToUpload.getName(); + if (gzip) { + filename += ".gz"; + } + ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ + ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$ + InputStream fis = new FileInputStream(fileToUpload); + BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024); + ous.flush(); + if (gzip) { + GZIPOutputStream gous = new GZIPOutputStream(ous, 1024); + Algorithms.streamCopy(bis, gous); + gous.flush(); + gous.finish(); + gous.close(); + } else { + Algorithms.streamCopy(bis, ous); + } + + ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ + ous.flush(); + Algorithms.closeStream(bis); + Algorithms.closeStream(ous); + return ous.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } + return new byte[0]; + } + public static void setProxy(String host, int port) { if(host != null && port > 0) { InetSocketAddress isa = new InetSocketAddress(host, port); @@ -157,7 +179,7 @@ public class NetworkUtils { proxy = null; } } - + public static Proxy getProxy() { return proxy; } diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java new file mode 100644 index 0000000000..bef043e1ce --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java @@ -0,0 +1,134 @@ +// License: GPL. For details, see LICENSE file. +package net.osmand.osm.oauth; + +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.builder.api.DefaultApi10a; +import com.github.scribejava.core.builder.api.OAuth1SignatureType; +import com.github.scribejava.core.model.*; +import com.github.scribejava.core.oauth.OAuth10aService; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +/** + * An OAuth 1.0 authorization client. + * + * @since 2746 + */ +public class OsmOAuthAuthorizationClient { + OAuth10aService service; + OAuth1RequestToken requestToken; + OAuth1AccessToken accessToken; + + public OsmOAuthAuthorizationClient(String key, String secret){ + service = new ServiceBuilder(key) + .apiSecret(secret) + .callback("osmand-oauth://example.com/oauth") + .build(new OsmApi()); + } + + static class OsmApi extends DefaultApi10a { + @Override + public OAuth1SignatureType getSignatureType() { + return OAuth1SignatureType.QUERY_STRING; + } + + @Override + public String getRequestTokenEndpoint() { + return "https://www.openstreetmap.org/oauth/request_token"; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://www.openstreetmap.org/oauth/access_token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://www.openstreetmap.org/oauth/authorize"; + } + } + + public OAuth10aService getService() { + return service; + } + + public void setAccessToken(OAuth1AccessToken accessToken) { this.accessToken = accessToken; } + + public OAuth1AccessToken getAccessToken() { return this.accessToken; } + + public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody) + throws InterruptedException, ExecutionException, IOException { + Verb verb = parseRequestMethod(requestMethod); + OAuthRequest req = new OAuthRequest(verb, url); + req.setPayload(requestBody); + return service.execute(req); + } + + public void performGetRequest(String url, OAuthAsyncRequestCallback callback) { + if (accessToken == null) { + throw new IllegalStateException("Access token is null"); + } + OAuthRequest req = new OAuthRequest(Verb.GET, url); + service.signRequest(accessToken, req); + service.execute(req, callback); + } + + public Response performRequest(String url, String method, String body) + throws InterruptedException, ExecutionException, IOException { + service.getApi().getSignatureType(); + if (accessToken == null) { + throw new IllegalStateException("Access token is null"); + } + Verb verbMethod = parseRequestMethod(method); + OAuthRequest req = new OAuthRequest(verbMethod, url); + req.setPayload(body); + service.signRequest(accessToken, req); + req.addHeader("Content-Type", "application/xml"); + return service.execute(req); + } + + private Verb parseRequestMethod(String method) { + Verb m = Verb.GET; + if (method.equals("POST")) { + m = Verb.POST; + } + if (method.equals("PUT")) { + m = Verb.PUT; + } + if (method.equals("DELETE")) { + m = Verb.DELETE; + } + return m; + } + + public OAuth1RequestToken startOAuth() { + try { + requestToken = service.getRequestToken(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + return requestToken; + } + + public OAuth1AccessToken authorize(String oauthVerifier) { + try { + setAccessToken(service.getAccessToken(requestToken, oauthVerifier)); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + return accessToken; + } + + public boolean isValidToken() { + return !(accessToken == null); + } +} diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 58803bac25..e18cb21e76 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -567,10 +567,10 @@ dependencies { implementation ("com.github.HITGIF:TextFieldBoxes:1.4.5"){ exclude group: 'com.android.support' } - implementation 'com.jaredrummler:colorpicker:1.1.0' implementation('com.github.scribejava:scribejava-apis:7.1.1'){ exclude group: "com.fasterxml.jackson.core" } + implementation 'com.jaredrummler:colorpicker:1.1.0' huaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar') freehuaweiImplementation files('libs/huawei-android-drm_v2.5.2.300.jar') diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 4b0dd632aa..8f826e76b1 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -5,6 +5,7 @@ import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; +import android.net.TrafficStats; import android.net.Uri; import android.os.AsyncTask; import android.os.AsyncTask.Status; @@ -336,6 +337,8 @@ public class DownloadIndexesThread { @Override protected DownloadResources doInBackground(Void... params) { + final int THREAD_ID = 10103; + TrafficStats.setThreadStatsTag(THREAD_ID); DownloadResources result = null; DownloadOsmandIndexesHelper.IndexFileList indexFileList = DownloadOsmandIndexesHelper.getIndexesList(ctx); if (indexFileList != null) { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java b/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java index b94ac7cc1c..7d04c73252 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java @@ -2,10 +2,8 @@ package net.osmand.plus.osmedit; import android.content.DialogInterface; import android.graphics.drawable.Drawable; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; - import net.osmand.data.PointDescription; import net.osmand.osm.PoiType; import net.osmand.plus.OsmandPlugin; @@ -14,7 +12,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.osmedit.OsmPoint.Action; import net.osmand.plus.osmedit.dialogs.SendPoiDialogFragment; -import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; import net.osmand.plus.render.RenderingIcons; import net.osmand.util.Algorithms; @@ -40,7 +38,7 @@ public class EditPOIMenuController extends MenuController { public void buttonPressed() { MapActivity activity = getMapActivity(); if (plugin != null && activity != null) { - OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(activity.getMyApplication()); + OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(activity.getMyApplication()); if (client.isValidToken()){ new SendPoiDialogFragment.SimpleProgressDialogPoiUploader(activity). showProgressDialog(new OsmPoint[] { getOsmPoint() }, false, false); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java index c8bf73e423..e550d25d73 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java @@ -2,7 +2,8 @@ package net.osmand.plus.osmedit; import android.util.Xml; import android.widget.Toast; - +import com.github.scribejava.core.model.Response; +import gnu.trove.list.array.TLongArrayList; import net.osmand.NativeLibrary; import net.osmand.PlatformUtil; import net.osmand.data.Amenity; @@ -17,39 +18,29 @@ import net.osmand.osm.edit.Entity.EntityType; import net.osmand.osm.edit.EntityInfo; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.Way; -import net.osmand.osm.io.Base64; import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.OsmBaseStorage; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.MapUtils; - import org.apache.commons.logging.Log; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; import java.io.StringWriter; -import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.text.MessageFormat; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; - -import gnu.trove.list.array.TLongArrayList; +import java.util.concurrent.ExecutionException; public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { @@ -100,12 +91,16 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { private final static String URL_TO_UPLOAD_GPX = getSiteApi() + "api/0.6/gpx/create"; public String uploadGPXFile(String tagstring, String description, String visibility, File f) { + OsmOAuthAuthorizationAdapter adapter = new OsmOAuthAuthorizationAdapter(ctx); String url = URL_TO_UPLOAD_GPX; Map additionalData = new LinkedHashMap(); additionalData.put("description", description); additionalData.put("tags", tagstring); additionalData.put("visibility", visibility); - return NetworkUtils.uploadFile(url, f, settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(), "file", + return NetworkUtils.uploadFile(url, f, + settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(), + adapter.getClient(), + "file", true, additionalData); } @@ -113,59 +108,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { boolean doAuthenticate) { log.info("Sending request " + url); //$NON-NLS-1$ try { - HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url); - - connection.setConnectTimeout(15000); - connection.setRequestMethod(requestMethod); - connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$ - StringBuilder responseBody = new StringBuilder(); - if (doAuthenticate) { - OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(ctx); - if (client.isValidToken()){ - connection.addRequestProperty("Authorization", "OAuth " + client.getAccessToken()); - } - else { - String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ - connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } + if (doAuthenticate){ + OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx); + Response response = client.performRequest(url,requestMethod,requestBody); + return response.getBody(); } - connection.setDoInput(true); - if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - connection.setDoOutput(true); - connection.setRequestProperty("Content-type", "text/xml"); //$NON-NLS-1$ //$NON-NLS-2$ - OutputStream out = connection.getOutputStream(); - if (requestBody != null) { - BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"), 1024); //$NON-NLS-1$ - bwr.write(requestBody); - bwr.flush(); - } - out.close(); - } - connection.connect(); - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { - String msg = userOperation - + " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage(); //$NON-NLS-1$//$NON-NLS-2$ - log.error(msg); - showWarning(msg); - } else { - log.info("Response : " + connection.getResponseMessage()); //$NON-NLS-1$ - // populate return fields. - responseBody.setLength(0); - InputStream i = connection.getInputStream(); - if (i != null) { - BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$ - String s; - boolean f = true; - while ((s = in.readLine()) != null) { - if (!f) { - responseBody.append("\n"); //$NON-NLS-1$ - } else { - f = false; - } - responseBody.append(s); - } - } - return responseBody.toString(); + else { + OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx); + client.performRequestWithoutAuth(url,requestMethod,requestBody); } } catch (NullPointerException e) { // that's tricky case why NPE is thrown to fix that problem httpClient could be used @@ -180,6 +130,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$ showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template) + ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation)); + } catch (InterruptedException e) { + log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$ + showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template) + + ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation)); + } catch (ExecutionException e) { + log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$ + showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template) + + ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation)); } return null; @@ -213,12 +171,16 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { } catch (IOException e) { log.error("Unhandled exception", e); //$NON-NLS-1$ } - String response = sendRequest( - getSiteApi() + "api/0.6/changeset/create/", "PUT", writer.getBuffer().toString(), ctx.getString(R.string.opening_changeset), true); //$NON-NLS-1$ //$NON-NLS-2$ - if (response != null && response.length() > 0) { - id = Long.parseLong(response); - } - + String response = sendRequest( + getSiteApi() + "api/0.6/changeset/create/", "PUT", writer.getBuffer().toString(), ctx.getString(R.string.opening_changeset), true); //$NON-NLS-1$ //$NON-NLS-2$ + try { + if (response != null && response.length() > 0) { + log.debug(response); + id = Long.parseLong(response); + } + } catch (Exception e) { + e.printStackTrace(); + } return id; } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java index 581206fb98..75b226eb3f 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java @@ -5,13 +5,12 @@ import net.osmand.PlatformUtil; import net.osmand.osm.io.Base64; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.osmedit.OsmPoint.Action; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; - import org.apache.commons.logging.Log; import java.io.FileNotFoundException; @@ -110,7 +109,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil { private OsmBugResult editingPOI(String url, String requestMethod, String userOperation, boolean anonymous) { - OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(this.app); + OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(this.app); OsmBugResult r = new OsmBugResult(); try { HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url); @@ -121,7 +120,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil { if (!anonymous) { if (client.isValidToken()){ - connection.addRequestProperty("Authorization", "OAuth " + client.getAccessToken()); + connection.addRequestProperty("Authorization", "OAuth " + client.getClient().getAccessToken().getToken()); } else { String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index 427831de54..f1b33b8f79 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -13,11 +13,9 @@ import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; import android.widget.Toast; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; - import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.data.Amenity; @@ -25,13 +23,8 @@ import net.osmand.data.MapObject; import net.osmand.data.TransportStop; import net.osmand.osm.PoiType; import net.osmand.osm.edit.Entity; -import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.*; import net.osmand.plus.ContextMenuAdapter.ItemClickListener; -import net.osmand.plus.ContextMenuItem; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.R; import net.osmand.plus.activities.EnumAdapter; import net.osmand.plus.activities.EnumAdapter.IEnumWithResource; import net.osmand.plus.activities.MapActivity; @@ -43,22 +36,16 @@ import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo; import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.osmedit.OsmPoint.Action; import net.osmand.plus.quickaction.QuickActionType; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.util.Algorithms; - import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_CREATE_POI; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MODIFY_OSM_CHANGE; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MODIFY_OSM_NOTE; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MODIFY_POI; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_OPEN_OSM_NOTE; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_EDITS; -import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_NOTES; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.*; import static net.osmand.plus.ContextMenuAdapter.makeDeleteAction; @@ -464,7 +451,8 @@ public class OsmEditingPlugin extends OsmandPlugin { public boolean sendGPXFiles(final Activity la, AvailableGPXFragment f, final GpxInfo... info) { String name = settings.USER_NAME.get(); String pwd = settings.USER_PASSWORD.get(); - if (Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) { + String authToken = settings.USER_ACCESS_TOKEN.get(); + if ((Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) && Algorithms.isEmpty(authToken)) { Toast.makeText(la, R.string.validate_gpx_upload_name_pwd, Toast.LENGTH_LONG).show(); return false; } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java index c0262e436f..651fc7ff07 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java @@ -17,20 +17,19 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; - import com.github.scribejava.core.model.OAuthAsyncRequestCallback; import com.github.scribejava.core.model.Response; -import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationClient; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; import net.osmand.plus.settings.backend.OsmAndAppCustomization; import java.io.IOException; public class SettingsOsmEditingActivity extends SettingsBaseActivity { - OsmOAuthAuthorizationClient client; + OsmOAuthAuthorizationAdapter client; @Override public void onCreate(Bundle savedInstanceState) { @@ -44,7 +43,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { ((OsmandApplication) getApplication()).applyTheme(this); super.onCreate(savedInstanceState); - client = new OsmOAuthAuthorizationClient(this.getMyApplication()); + client = new OsmOAuthAuthorizationAdapter(this.getMyApplication()); getToolbar().setTitle(R.string.osm_settings); @SuppressWarnings("deprecation") diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java new file mode 100644 index 0000000000..5d2313c078 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java @@ -0,0 +1,79 @@ +package net.osmand.plus.osmedit.oauth; + +import android.net.TrafficStats; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import com.github.scribejava.core.model.OAuth1AccessToken; +import com.github.scribejava.core.model.OAuth1RequestToken; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.Response; +import net.osmand.osm.oauth.OsmOAuthAuthorizationClient; +import net.osmand.plus.BuildConfig; +import net.osmand.plus.OsmandApplication; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class OsmOAuthAuthorizationAdapter { + OsmandApplication application; + OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET); + + public OsmOAuthAuthorizationAdapter(OsmandApplication application) { + final int THREAD_ID = 10101; + TrafficStats.setThreadStatsTag(THREAD_ID); + this.application = application; + restoreToken(); + } + + public OsmOAuthAuthorizationClient getClient() { + return client; + } + + public boolean isValidToken() { + return client.isValidToken(); + } + + public void restoreToken() { + String token = application.getSettings().USER_ACCESS_TOKEN.get(); + String tokenSecret = application.getSettings().USER_ACCESS_TOKEN_SECRET.get(); + client.setAccessToken(new OAuth1AccessToken(token, tokenSecret)); + } + + public void startOAuth(ViewGroup rootLayout) { + OAuth1RequestToken requestToken = client.startOAuth(); + loadWebView(rootLayout, client.getService().getAuthorizationUrl(requestToken)); + } + + private void saveToken() { + OAuth1AccessToken accessToken = client.getAccessToken(); + application.getSettings().USER_ACCESS_TOKEN.set(accessToken.getToken()); + application.getSettings().USER_ACCESS_TOKEN_SECRET.set(accessToken.getTokenSecret()); + } + + private void loadWebView(ViewGroup root, String url) { + WebView webView = new WebView(root.getContext()); + webView.requestFocus(View.FOCUS_DOWN); + webView.loadUrl(url); + root.addView(webView); + } + + public void performGetRequest(String url, OAuthAsyncRequestCallback callback) { + client.performGetRequest(url, callback); + } + + public Response performRequest(String url, String method, String body) + throws InterruptedException, ExecutionException, IOException { + return client.performRequest(url, method, body); + } + + public Response performRequestWithoutAuth(String url, String method, String body) + throws InterruptedException, ExecutionException, IOException { + return client.performRequestWithoutAuth(url, method, body); + } + + public void authorize(String oauthVerifier) { + client.authorize(oauthVerifier); + saveToken(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java deleted file mode 100644 index 1e53c48628..0000000000 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationClient.java +++ /dev/null @@ -1,119 +0,0 @@ -// License: GPL. For details, see LICENSE file. -package net.osmand.plus.osmedit.oauth; - - -import android.net.TrafficStats; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.WebView; -import com.github.scribejava.core.builder.ServiceBuilder; -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.*; -import com.github.scribejava.core.oauth.OAuth10aService; -import net.osmand.plus.BuildConfig; -import net.osmand.plus.OsmandApplication; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; - -/** - * An OAuth 1.0 authorization client. - * - * @since 2746 - */ -public class OsmOAuthAuthorizationClient { - - OAuth10aService service = new ServiceBuilder(BuildConfig.CONSUMER_KEY) - .apiSecret(BuildConfig.CONSUMER_SECRET) - .debug() - .callback("osmand-oauth://example.com/oauth") - .build(new OsmApi()); - - OAuth1RequestToken requestToken; - OAuth1AccessToken accessToken; - OsmandApplication application; - - static class OsmApi extends DefaultApi10a { - - @Override - public String getRequestTokenEndpoint() { return "https://www.openstreetmap.org/oauth/request_token"; } - - @Override - public String getAccessTokenEndpoint() { - return "https://www.openstreetmap.org/oauth/access_token"; - } - - @Override - protected String getAuthorizationBaseUrl() { - return "https://www.openstreetmap.org/oauth/authorize"; - } - } - - public OsmOAuthAuthorizationClient(OsmandApplication application) { - final int THREAD_ID = 10101; - TrafficStats.setThreadStatsTag(THREAD_ID); - this.application = application; - restoreToken(); - } - - public String getAccessToken() { - return this.accessToken.getToken(); - } - - public void performGetRequest(String url,OAuthAsyncRequestCallback callback) { - if (accessToken == null) { - throw new IllegalStateException("Access token is null"); - } - OAuthRequest req = new OAuthRequest(Verb.GET, url); - service.signRequest(accessToken, req); - service.execute(req, callback); - } - - public void startOAuth(ViewGroup rootLayout) { - try { - requestToken = service.getRequestToken(); - loadWebView(rootLayout, service.getAuthorizationUrl(requestToken)); - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } - } - - public void authorize(String oauthVerifier) { - try { - accessToken = service.getAccessToken(requestToken, oauthVerifier); - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } - saveToken(); - } - - public boolean isValidToken(){ - return !(accessToken == null); - } - - public void restoreToken() { - String token = application.getSettings().USER_ACCESS_TOKEN.get(); - String tokenSecret = application.getSettings().USER_ACCESS_TOKEN_SECRET.get(); - accessToken = new OAuth1AccessToken(token, tokenSecret); - } - - private void saveToken() { - application.getSettings().USER_ACCESS_TOKEN.set(accessToken.getToken()); - application.getSettings().USER_ACCESS_TOKEN_SECRET.set(accessToken.getTokenSecret()); - } - - private void loadWebView(ViewGroup root, String url) { - WebView webView = new WebView(root.getContext()); - webView.requestFocus(View.FOCUS_DOWN); - webView.loadUrl(url); - root.addView(webView); - } -} From 9af2ccea51643daceee9fa443c36d655b75b7bc4 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 2 Oct 2020 15:38:57 +0300 Subject: [PATCH 0396/1366] Update direction arrow icons for track direction --- OsmAnd/res/drawable/ic_action_direction_arrow.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/drawable/ic_action_direction_arrow.xml b/OsmAnd/res/drawable/ic_action_direction_arrow.xml index 5e97fe8338..b13a8692f7 100644 --- a/OsmAnd/res/drawable/ic_action_direction_arrow.xml +++ b/OsmAnd/res/drawable/ic_action_direction_arrow.xml @@ -1,9 +1,9 @@ + android:viewportHeight="9"> From 33f933e89d2bc56a0d9740da88464ae8bbe39542 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 2 Oct 2020 16:00:03 +0300 Subject: [PATCH 0397/1366] logout added --- .../oauth/OsmOAuthAuthorizationClient.java | 40 ++++++++++--------- OsmAnd/res/values/strings.xml | 6 +++ .../osmedit/SettingsOsmEditingActivity.java | 31 ++++++++++---- .../oauth/OsmOAuthAuthorizationAdapter.java | 10 ++++- 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java index bef043e1ce..ed2854bb02 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java @@ -20,7 +20,7 @@ public class OsmOAuthAuthorizationClient { OAuth1RequestToken requestToken; OAuth1AccessToken accessToken; - public OsmOAuthAuthorizationClient(String key, String secret){ + public OsmOAuthAuthorizationClient(String key, String secret) { service = new ServiceBuilder(key) .apiSecret(secret) .callback("osmand-oauth://example.com/oauth") @@ -53,9 +53,13 @@ public class OsmOAuthAuthorizationClient { return service; } - public void setAccessToken(OAuth1AccessToken accessToken) { this.accessToken = accessToken; } - - public OAuth1AccessToken getAccessToken() { return this.accessToken; } + public void setAccessToken(OAuth1AccessToken accessToken) { + this.accessToken = accessToken; + } + + public OAuth1AccessToken getAccessToken() { + return this.accessToken; + } public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody) throws InterruptedException, ExecutionException, IOException { @@ -88,20 +92,6 @@ public class OsmOAuthAuthorizationClient { return service.execute(req); } - private Verb parseRequestMethod(String method) { - Verb m = Verb.GET; - if (method.equals("POST")) { - m = Verb.POST; - } - if (method.equals("PUT")) { - m = Verb.PUT; - } - if (method.equals("DELETE")) { - m = Verb.DELETE; - } - return m; - } - public OAuth1RequestToken startOAuth() { try { requestToken = service.getRequestToken(); @@ -131,4 +121,18 @@ public class OsmOAuthAuthorizationClient { public boolean isValidToken() { return !(accessToken == null); } + + private Verb parseRequestMethod(String method) { + Verb m = Verb.GET; + if (method.equals("POST")) { + m = Verb.POST; + } + if (method.equals("PUT")) { + m = Verb.PUT; + } + if (method.equals("DELETE")) { + m = Verb.DELETE; + } + return m; + } } diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 14e08c0176..915e2a0f6d 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,12 @@ Thx - Hardy --> + Logout successful + Clear OpenStreetMap OAuth token + Test user request + Retrieve current user info + Log in via OAuth + Perform an OAuth Login to use osmedit features Name: A – Z Name: Z – A Last modified diff --git a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java index 651fc7ff07..c4c8cb8d38 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java @@ -81,8 +81,8 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { prefOAuth.setKey("local_openstreetmap_token"); final Preference prefTestUser = new Preference(this); - prefTestUser.setTitle("Test user request"); - prefTestUser.setSummary("Test user request"); + prefTestUser.setTitle(R.string.test_user_request); + prefTestUser.setSummary(R.string.test_user_request_description); prefTestUser.setKey("local_openstreetmap_token"); prefTestUser.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override @@ -92,8 +92,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { @Override public void onCompleted(Response response) { try { - Toast.makeText(SettingsOsmEditingActivity.this, - "DATA RETRIEVED: " + response.getBody().toString(),Toast.LENGTH_SHORT).show(); + Toast.makeText(SettingsOsmEditingActivity.this,response.getBody(),Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } @@ -108,11 +107,27 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { return true; } }); - grp.addPreference(prefTestUser); + final Preference prefClearToken = new Preference(this); + prefClearToken.setTitle(R.string.shared_string_logoff); + prefClearToken.setSummary(R.string.clear_osm_token); + prefClearToken.setKey("local_openstreetmap_token"); + prefClearToken.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + settings.USER_ACCESS_TOKEN.set(""); + settings.USER_ACCESS_TOKEN_SECRET.set(""); + client.resetToken(); + Toast.makeText(SettingsOsmEditingActivity.this, R.string.osm_edit_logout_success, Toast.LENGTH_SHORT).show(); + finish(); + startActivity(getIntent()); + return true; + } + }); + grp.addPreference(prefClearToken); } else { - prefOAuth.setTitle(R.string.osb_author_dialog_password); - prefOAuth.setSummary(R.string.osb_author_dialog_password); + prefOAuth.setTitle(R.string.perform_oauth_authorization); + prefOAuth.setSummary(R.string.perform_oauth_authorization_description); prefOAuth.setKey("local_openstreetmap_token"); prefOAuth.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override @@ -193,6 +208,8 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { if (uri != null && uri.toString().startsWith("osmand-oauth")) { String oauthVerifier = uri.getQueryParameter("oauth_verifier"); client.authorize(oauthVerifier); + finish(); + startActivity(getIntent()); } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java index 5d2313c078..47757317f7 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java @@ -34,10 +34,18 @@ public class OsmOAuthAuthorizationAdapter { return client.isValidToken(); } + public void resetToken() { + client.setAccessToken(null); + } + public void restoreToken() { String token = application.getSettings().USER_ACCESS_TOKEN.get(); String tokenSecret = application.getSettings().USER_ACCESS_TOKEN_SECRET.get(); - client.setAccessToken(new OAuth1AccessToken(token, tokenSecret)); + if (!(token.isEmpty() || tokenSecret.isEmpty())) { + client.setAccessToken(new OAuth1AccessToken(token, tokenSecret)); + } else { + client.setAccessToken(null); + } } public void startOAuth(ViewGroup rootLayout) { From dba64d631747bf90a125d8f8540f17f88abceb66 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 2 Oct 2020 16:49:03 +0300 Subject: [PATCH 0398/1366] bug fix --- .../src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java index e550d25d73..74eb48c1b4 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java @@ -115,7 +115,8 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { } else { OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx); - client.performRequestWithoutAuth(url,requestMethod,requestBody); + Response response = client.performRequestWithoutAuth(url,requestMethod,requestBody); + return response.getBody(); } } catch (NullPointerException e) { // that's tricky case why NPE is thrown to fix that problem httpClient could be used From 67952bdc63742397ae238f1a65783cbe8e6727f9 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 2 Oct 2020 18:15:22 +0300 Subject: [PATCH 0399/1366] Add AIDL copy file --- .../aidlapi/copyfile/CopyFileParams.java | 34 ++++++++++++++----- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 29 +++++++++++++++- .../net/osmand/aidl/OsmandAidlService.java | 2 +- .../net/osmand/aidl/OsmandAidlServiceV2.java | 3 +- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java b/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java index 1118a17f5c..ad122f60c6 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java @@ -9,12 +9,21 @@ import net.osmand.aidlapi.AidlParams; public class CopyFileParams extends AidlParams { + public static final String DESTINATION_DIR_KEY = "destinationDir"; + public static final String FILE_NAME_KEY = "fileName"; + public static final String FILE_PART_DATA_KEY = "filePartData"; + public static final String START_TIME_KEY = "startTime"; + public static final String DONE_KEY = "done"; + private String destinationDir; private String fileName; private byte[] filePartData; private long startTime; private boolean done; - public CopyFileParams(@NonNull String fileName, @NonNull byte[] filePartData, long startTime, boolean done) { + public CopyFileParams(@NonNull String destinationDir, @NonNull String fileName, @NonNull byte[] filePartData, + long startTime, boolean done) { + + this.destinationDir = destinationDir; this.fileName = fileName; this.filePartData = filePartData; this.startTime = startTime; @@ -37,6 +46,10 @@ public class CopyFileParams extends AidlParams { } }; + public String getDestinationDir() { + return destinationDir; + } + public String getFileName() { return fileName; } @@ -55,23 +68,26 @@ public class CopyFileParams extends AidlParams { @Override public void writeToBundle(Bundle bundle) { - bundle.putString("fileName", fileName); - bundle.putByteArray("filePartData", filePartData); - bundle.putLong("startTime", startTime); - bundle.putBoolean("done", done); + bundle.putString(DESTINATION_DIR_KEY, destinationDir); + bundle.putString(FILE_NAME_KEY, fileName); + bundle.putByteArray(FILE_PART_DATA_KEY, filePartData); + bundle.putLong(START_TIME_KEY, startTime); + bundle.putBoolean(DONE_KEY, done); } @Override protected void readFromBundle(Bundle bundle) { - fileName = bundle.getString("fileName"); - filePartData = bundle.getByteArray("filePartData"); - startTime = bundle.getLong("startTime"); - done = bundle.getBoolean("done"); + destinationDir = bundle.getString(DESTINATION_DIR_KEY); + fileName = bundle.getString(FILE_NAME_KEY); + filePartData = bundle.getByteArray(FILE_PART_DATA_KEY); + startTime = bundle.getLong(START_TIME_KEY); + done = bundle.getBoolean(DONE_KEY); } @Override public String toString() { return "CopyFileParams {" + + " destinationDir=" + destinationDir + " fileName=" + fileName + ", filePartData size=" + filePartData.length + ", startTime=" + startTime + diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index a86f48f714..6cb1dee762 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -30,6 +30,7 @@ import net.osmand.FileUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; +import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.Location; import net.osmand.PlatformUtil; @@ -131,6 +132,7 @@ import static net.osmand.aidlapi.OsmandAidlConstants.COPY_FILE_PART_SIZE_LIMIT_E import static net.osmand.aidlapi.OsmandAidlConstants.COPY_FILE_UNSUPPORTED_FILE_TYPE_ERROR; import static net.osmand.aidlapi.OsmandAidlConstants.COPY_FILE_WRITE_LOCK_ERROR; import static net.osmand.aidlapi.OsmandAidlConstants.OK_RESPONSE; +import static net.osmand.plus.FavouritesDbHelper.FILE_TO_SAVE; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_LANES; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_NAME; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_TURN; @@ -2360,7 +2362,7 @@ public class OsmandAidlApi { } } - int copyFile(String fileName, byte[] filePartData, long startTime, boolean done) { + int copyFileOld(String fileName, byte[] filePartData, long startTime, boolean done) { if (Algorithms.isEmpty(fileName) || filePartData == null) { return COPY_FILE_PARAMS_ERROR; } @@ -2374,6 +2376,31 @@ public class OsmandAidlApi { } } + int copyFile(String destinationDir, String fileName, byte[] filePartData, long startTime, boolean done) { + if (Algorithms.isEmpty(fileName) || filePartData == null) { + return COPY_FILE_PARAMS_ERROR; + } + if (filePartData.length > COPY_FILE_PART_SIZE_LIMIT) { + return COPY_FILE_PART_SIZE_LIMIT_ERROR; + } + int result = copyFileImpl(fileName, filePartData, startTime, done, destinationDir); + if (done) { + if (fileName.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT) && IndexConstants.MAPS_PATH.equals(destinationDir)) { + app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList()); + app.getDownloadThread().updateLoadedFiles(); + } else if (fileName.endsWith(IndexConstants.GPX_FILE_EXT)) { + if (destinationDir.startsWith(IndexConstants.GPX_INDEX_DIR) + && !FILE_TO_SAVE.equals(fileName)) { + GPXUtilities.loadGPXFile(new File(destinationDir, fileName)); + } else if (destinationDir.isEmpty() && FILE_TO_SAVE.equals(fileName)) { + GPXUtilities.loadGPXFile(new File(destinationDir, fileName)); + app.getFavorites().loadFavorites(); + } + } + } + return result; + } + private int copyFileImpl(String fileName, byte[] filePartData, long startTime, boolean done, String destinationDir) { File tempDir = FileUtils.getTempDir(app); File file = new File(tempDir, fileName); diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java index 17c87431e8..0d9e5d6961 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java @@ -1138,7 +1138,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { if (api == null) { return CANNOT_ACCESS_API_ERROR; } - return api.copyFile(params.getFileName(), params.getFilePartData(), params.getStartTime(), params.isDone()); + return api.copyFileOld(params.getFileName(), params.getFilePartData(), params.getStartTime(), params.isDone()); } catch (Exception e) { handleException(e); return UNKNOWN_API_ERROR; diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 4cd13d12da..8f6564a957 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -1092,7 +1092,8 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener if (api == null) { return CANNOT_ACCESS_API_ERROR; } - return api.copyFile(params.getFileName(), params.getFilePartData(), params.getStartTime(), params.isDone()); + return api.copyFile(params.getDestinationDir(), params.getFileName(), params.getFilePartData(), + params.getStartTime(), params.isDone()); } catch (Exception e) { handleException(e); return UNKNOWN_API_ERROR; From 8bec1264114ea15a6ee66629bcd1cd3ef7113d3d Mon Sep 17 00:00:00 2001 From: Evgenii Martynenko Date: Fri, 2 Oct 2020 16:00:53 +0000 Subject: [PATCH 0400/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 701641a64d..7e4833744e 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -171,7 +171,7 @@ Добавить источник карты Источник карты изменён на «%s». Удерживайте кнопку для перемещения её по экрану. - Показывать контуры и точки глубины. + Показывать контуры и точки глубин. Контуры морских глубин Частота горизонталей Частота горизонталей @@ -1739,7 +1739,7 @@ Отменить выбор всех Поделиться Мои места - Точки + Избранные Треки Текущий трек Поделиться заметкой From 8eaecb105a5f652d07f5026b94f45cbcc671537e Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Fri, 2 Oct 2020 14:51:30 +0000 Subject: [PATCH 0401/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 46 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 7e4833744e..8dcc9c13c0 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -115,7 +115,7 @@ Сбалансированный Предпочитать переулки Выберите предпочтительный рельеф. - Склон + Карта уклонов Добавить новую папку Точки удалены. Вы уверены, что хотите удалить %1$d точки\? @@ -368,9 +368,9 @@ Использовать онлайн-карты (загрузка и кеширование на SD-карте). Онлайн-карты Выберите источник онлайн или кешированных растровых карт. - Доступ ко множеству онлайн-карт (т. н. тайловых или растровых): от встроенных OSM (как Mapnik), до спутниковых снимков и слоёв специального назначения, таких как карты погоды, климатические, геологические карты, затенения рельефа и др. + Доступ ко множеству онлайн-карт (т. н. тайловых или растровых): от встроенных OSM (как Mapnik) до спутниковых снимков и слоёв специального назначения, таких как карты погоды, климатические, геологические карты, затенения рельефа и др. \n -\n Любая из этих карт может быть использована в качестве базовой либо как наложение или подложка к другой базовой карте (например стандартной локальной карте OsmAnd). Некоторые элементы векторной карты OsmAnd можно скрыть в меню «Настройки карты». +\n Любая из этих карт может быть использована как основная или в качестве подложки к другой карте (например стандартной локальной карте OsmAnd). Некоторые элементы векторной карты OsmAnd можно скрыть в меню «Настройки карты». \n \n Карты можно загрузить непосредственно из интернета или подготовить для использования в автономном режиме (и вручную скопировать в папку данных OsmAnd) в виде базы данных sqlite, которая может быть создана с помощью различных инструментов подготовки карт сторонних производителей. Показывает настройки для включения фонового отслеживания и навигации путём периодического пробуждения устройства GPS (с выключенным экраном). @@ -518,9 +518,9 @@ Обратное направление трека Использовать текущий пункт назначения Пройти весь путь - Для этого региона доступны локальные векторные карты. -\n\t -\n\tДля их использования выберите в \"Меню\" → \"Настройка карты\" → \"Источник карты…\" → \"Векторные карты\". + Для этого региона есть локальные векторные карты. +\n\t +\n\tДля использования выберите их в качестве источника (Меню → Настройка карты → Источник карты → Локальные векторные карты). Голосовые инструкции Выберите канал вывода голосовых подсказок. Канал голосовых звонков (прерывает автомобильную Bluetooth стереосистему) @@ -1205,8 +1205,8 @@ Сделать фото Синхронизация треков и медиазаметок с вашим аккаунтом Dropbox. Плагин Dropbox - Плагин обеспечивает наложение контурных линии и (рельефа) затемняющего слоя, которые будут отображаться поверх стандартных карт OsmAnd. Эта функция высоко оценится спортсменами, туристами, путешественниками и всеми, кто заинтересован в рельефной структуре ландшафта. -\n + Плагин обеспечивает наложение контурных линии и затемняющего слоя (рельефа), которые будут отображаться поверх стандартных карт OsmAnd. Эту функцию оценят спортсмены, туристы, путешественники и все, для кого рельеф местности имеет значение. +\n \nГлобальные данные (между 70° на севере и 70° на юге) основываются на измерениях SRTM (Shuttle Radar Topography Mission) и ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer), инструментом визуализации Terra, флагманского спутника Земли системы наблюдения NASA. ASTER является результатом совместных усилий NASA, министерства экономики Японии, торговли и промышленности (METI), космических систем Японии (J-spacesystems). Фото %1$s %2$s Медиаданные @@ -1227,7 +1227,7 @@ Время прибытия Информация GPS нет - Слой рельефа местности + Слой затенения рельефа Название улицы Номер дома Нет соединения по Wi-Fi. Использовать текущее интернет-соединение для загрузки\? @@ -1780,7 +1780,7 @@ \n \nВ случае активации этого вида, стиль карты меняется на «Зимний/лыжный», показывая все детали пейзажа так, как они выглядят зимой. Такой (зимний) вид может быть отменён либо путём деактивации здесь, либо если вы поменяете «Стиль карты» в меню «Настройки карты» на желаемый вид. Текущий маршрут - Скачать карты + Загрузка карт Для правильного отображения дорожных знаков и правил выберите свой регион вождения: Добро пожаловать Отметить для удаления @@ -1905,8 +1905,8 @@ Пропустить OsmAnd Плагины - Локальные карты -\nи Навигация + Офлайн-карты +\nи навигация Номер дома Тип лыжной трассы Автообновления @@ -2764,7 +2764,7 @@ Начать редактирование Получить неограниченный доступ Добро пожаловать на открытое бета-тестирование - Карты горизонталей и карты с отмывкой рельефа + Карты горизонталей и затенение рельефа Скачать статьи Википедии для %1$s, чтобы читать их в автономном режиме. Загрузка данных Википедии Открыть статью в интернете @@ -3366,7 +3366,7 @@ Маршруты, подготовленные для фристайла или катания только на коньках без классических треков. Разрешить только классические маршруты Маршруты, подготовленные только для классического стиля без конькобежных трасс. Сюда входят маршруты, подготовленные небольшим снегоходом с более свободной лыжнёй и трассами, подготовленные вручную лыжниками. - Предпочитать маршруты заданной сложности, хотя прокладка маршрута по более сложным или лёгким трассам всё же возможна, если они короче. + Предпочтительный уровень сложности маршрутов. Возможно использование более сложных или лёгких путей, если они короче. Включать на повороте Класс 1 Класс 2 @@ -3553,7 +3553,7 @@ Отклонение, при котором маршрут будет пересчитан. Легенда Невозможно разобрать геоссылку «%s». - Для отображения затенения рельефа на карте необходимы дополнительные карты. + Для отображения затенения рельефа требуются дополнительные карты. Мин. Отображение затенения рельефа или карты уклонов. Подробнее об этих типах карт вы можете прочитать на нашем сайте. Прозрачность @@ -3582,11 +3582,11 @@ Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. В этом случае будут записываться только точки, измеренные с минимальной точностью (в метрах/футах согласно настройкам устройства). Точность — это близость измерений к истинному местоположению и не имеет прямого отношения к точности, подразумевающейся под разбросом повторных замеров. Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться. - Уклон использует цвета для визуализации крутизны рельефа. + Для визуализации крутизны рельефа используются цвета. Подробнее об уклонах можно прочитать в %1$s. Затенение рельефа - Затенение рельефа использует тёмные оттенки для отображения склонов, вершин и низменностей. - Для отображения склонов на карте необходимы дополнительные карты. + Для отображения склонов, вершин и низменностей используются тёмные тени. + Для отображения склонов требуются дополнительные карты. Уклоны Заменить этой точкой другую. Изменения применены к профилю «%1$s». @@ -3883,17 +3883,17 @@ сохранен Добавьте хотя бы две точки. ПОВТОРИТЬ - • Обновлённый режим планирования маршрута позволяет использовать разные типы навигации для каждого сегмента и прикрепляет любой трек к дорогам + • Обновлённая функция планирования маршрута позволяет применять к сегментам разные режимы навигации и настраивать привязку к дорогам \n -\n • Новые параметры внешнего вида для треков: можно выбрать цвет, толщину, включите стрелки направления и отметки начала/окончания +\n • Новые настройки вида треков: выбор цвета и толщины линии, стрелки направления, метки начала и конца маршрута \n -\n • Улучшена видимость велосипедных узлов +\n • Повышенная видимость велосипедных узлов \n -\n • Контекстное меню для треков с основной информацией +\n • Контекстное меню с основной информацией для треков \n \n • Улучшенные алгоритмы поиска \n -\n • Улучшены параметры следования по треку в навигации +\n • Улучшенные настройки следования по треку в Навигации \n \n • Исправлены проблемы с импортом/экспортом настроек профиля \n From a528b16846c97dadc96e18f2f4824a88452b8a40 Mon Sep 17 00:00:00 2001 From: ssantos Date: Thu, 1 Oct 2020 21:02:14 +0000 Subject: [PATCH 0402/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-pt/strings.xml | 129 ++++++++++++++++--------------- 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index fe6c5d23b1..d700a97de6 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -239,7 +239,7 @@ Meio de transporte: Por favor, define o destino primeiro Navegação - A aplicação do estado do GPS não está instalada. Pesquisar na loja de aplicações\? + A app do estado do GPS não está instalada. Pesquisar na loja de apps\? Horas de abertura Abrindo conjunto de alterações … Fechando conjunto de alterações… @@ -294,7 +294,7 @@ Adicionar aos \'Favoritos\' Escolher entre os nomes nativos e inglês. Usar nomes em inglês - Configurações da aplicação + Configurações da app Pesquisar endereço Escolher edifício Escolher rua @@ -486,7 +486,7 @@ Usar cores fluorescentes para mostrar trajetos e rotas. Edição offline Usar sempre a edição offline. - As alterações de POI dentro da aplicação não afetam os ficheiros de mapas descarregados; essas alterações são guardadas num ficheiro separado no seu aparelho. + As alterações de POI dentro da app não afetam os ficheiros de mapas descarregados; essas alterações são guardadas num ficheiro separado no seu aparelho. A enviar… {0} POI/anotações enviados Enviar todos @@ -523,7 +523,7 @@ Já existe um ficheiro de favoritos exportados anteriormente. Quer substitui-lo\? Configurações específicas de Perfil Configurações Globais - Configurações globais da aplicação + Configurações globais da app Espaço livre insuficiente, precisa de %1$s MB (só tem: %2$s disponíveis). Descarregar {0} ficheiro(s)\? \n {1} MB (de {2} MB) será utilizado. @@ -554,7 +554,7 @@ O ficheiro POI \'%1$s\' é redundante e pode ser eliminado. Não foi encontrado (e não pôde ser criado) o ficheiro local para guardar as mudanças de POI. Upgrade para OsmAnd+ - Descarregue a nova versão da aplicação para poder usar os novos ficheiros de mapas. + Descarregue a nova versão da app para poder usar os novos ficheiros de mapas. Mudar o nome Online Nomeação Procurando posição… @@ -624,7 +624,7 @@ Áudio de chamada telefónica (para interromper os aparelhos de som Bluetooth do carro) Áudio de Notificação Áudio de mídia/navegação - A aplicação não conseguiu descarregar a camada do mapa %1$s, se a tornar a instalar pode resolver o problema. + A app não conseguiu descarregar a camada do mapa %1$s, se a tornar a instalar pode resolver o problema. Ajustar a transparência da sobreposição. Transparência da Sobreposição Ajustar a transparência do mapa base. @@ -646,7 +646,7 @@ Não foi possível executar a pesquisa offline. Pesquisa por localização geográfica Sistema - Idioma de exibição da aplicação (usado após OsmAnd ser reiniciado). + Idioma de exibição da app (usado após OsmAnd ser reiniciado). Linguagem Próximo Anterior @@ -671,7 +671,7 @@ \nO serviço de navegação está temporariamente mudado para CloudMade on-line. Não foi possível encontrar a pasta especificada. Local de armazenamento - Todos os dados offline na aplicação instalada antiga serão suportados pela nova aplicação, mas os pontos Favoritos devem ser exportados da aplicação antiga e depois importados na nova aplicação. + Todos os dados offline na app instalada antiga serão suportados pela nova, mas os pontos Favoritos devem ser exportados da app antiga e depois importados na nova. Build {0} foi instalado ({1}). Descarregando construção… Instalar OsmAnd - {0} de {1} {2} MB \? @@ -787,27 +787,27 @@ Widgets transparentes Contínuo e-mail - OsmAnd (direções automatizadas de navegação OSM) -\n -\nO OsmAnd é uma aplicação de navegação livre, com acesso a uma ampla variedade de dados globais do OSM. Todos os dados dos mapas (mapas vetoriais ou imagens raster) podem ser armazenados no cartão de memória do telemóvel para usar desligado da Internet. O OsmAnd também permite roteamento, tanto ligado como desligado da Internet, incluindo a funcionalidade de roteamento curva a curva com orientação por voz. -\n -\nAlgumas das características principais: -\n- Funcionalidade totalmente desligado da Internet (guarda os mapas obtidos, sejam eles vetoriais ou imagens, numa pasta selecionável). -\n- Mapas vetoriais compactados do mundo inteiro disponíveis. -\n- Descarregar mapas de países ou regiões diretamente na aplicação. -\n- Sobreposição de mapas diversos, como GPX ou trajetos de navegação, pontos de interesse (POI), favoritos, curvas de nível, paragens de transportes públicos, mapas adicionais com transparência personalizável. -\n- Pesquisa desligado da Internet para endereços e locais (POIs). -\n- Encaminhamento desligado da Internet para distâncias médias. -\n- Modo de carro, bicicleta e pedestre. -\n- Vista de dia/noite, com alteração automática (opcional). -\n- Ampliação do mapa dependente da velocidade. -\n- Orientação do mapa de acordo com bússola ou direção do movimento. -\n- Orientação de faixas de rodagem, aviso de limite de velocidade, vozes gravadas e vozes para a conversão de texto para voz. -\n -\nLimitações desta versão gratuita do OsmAnd: -\n- Quantidade de descarregamentos de mapas limitado. -\n- Sem acesso aos POIs da Wikipédia no modo desligado da Internet. -\n + OsmAnd (direções automatizadas de navegação OSM) +\n +\nO OsmAnd é uma app de navegação livre, com acesso a uma ampla variedade de dados globais do OSM. Todos os dados dos mapas (mapas vetoriais ou imagens raster) podem ser armazenados no cartão de memória do telemóvel para usar desligado da Internet. O OsmAnd também permite roteamento, tanto ligado como desligado da Internet, incluindo a funcionalidade de roteamento curva a curva com orientação por voz. +\n +\nAlgumas das características principais: +\n- Funcionalidade totalmente desligado da Internet (guarda os mapas obtidos, sejam eles vetoriais ou imagens, numa pasta selecionável). +\n- Mapas vetoriais compactados do mundo inteiro disponíveis. +\n- Descarregar mapas de países ou regiões diretamente na app. +\n- Sobreposição de mapas diversos, como GPX ou trajetos de navegação, pontos de interesse (POI), favoritos, curvas de nível, paragens de transportes públicos, mapas adicionais com transparência personalizável. +\n- Pesquisa desligado da Internet para endereços e locais (POIs). +\n- Encaminhamento desligado da Internet para distâncias médias. +\n- Modo de carro, bicicleta e pedestre. +\n- Vista de dia/noite, com alteração automática (opcional). +\n- Ampliação do mapa dependente da velocidade. +\n- Orientação do mapa de acordo com bússola ou direção do movimento. +\n- Orientação de faixas de rodagem, aviso de limite de velocidade, vozes gravadas e vozes para a conversão de texto para voz. +\n +\nLimitações desta versão gratuita do OsmAnd: +\n- Quantidade de descarregamentos de mapas limitado. +\n- Sem acesso aos POIs da Wikipédia no modo desligado da Internet. +\n \nO OsmAnd está em desenvolvimento ativo, mas o nosso projeto e o seu progresso ainda depende de contribuições financeiras para o desenvolvimento e testes de novas funcionalidades. Por favor, considere comprar o OsmAnd+, ou a ajudar a financiar novas funcionalidades específicas, ou fazer um donativo no osmand.net. Selecione um esquema de cores de estrada: Esquema de cores @@ -846,9 +846,9 @@ Só Estradas Mapa padrão Mapas só de estradas - Executar a aplicação no modo de segurança (usando o código do Android mais lento em vez do nativo). + Executar a app no modo de segurança (usando o código do Android mais lento em vez do nativo). Modo seguro - A aplicação está a ser executada no modo de segurança (desligue-a em \"Definições\"). + A app está a ser executada no modo de segurança (desligue-a em \"Definições\"). O serviço de segundo plano OsmAnd ainda está em execução. Tambẽm pará-lo\? Fechar conjunto de alterações Pesquisar mais povoações/códigos postais @@ -893,7 +893,7 @@ Sob demanda\? Formato de saída de vídeo: Usar gravador do sistema para vídeo. - Utilize aplicação do sistema para fotos. + Utilize a app do sistema para fotos. Usar aplicação da câmara A tocar o áudio da gravação. \n%1$s Indisponível @@ -927,14 +927,14 @@ desmarcado Limite de Velocidade Nenhum edifício encontrado. - A aplicação do leitor de código de barras ZXing não está instalada. Procurar no Google Play\? + A app do leitor de código de barras ZXing não está instalada. Procurar no Google Play\? Faça uma doação para ver novas funcionalidades implementadas nesta aplicação. incompleto Nome da rua Número de casa Gravação de viagem - Personalizar a aparência da aplicação. - Tema da aplicação + Personalizar a aparência da app. + Tema da app Opções de acessibilidade Especifique um endereço Selecione favorito @@ -1047,14 +1047,14 @@ Mapa mundial OsmAnd+ (Direções de Navegação Automatizada do OSM) \n -\n OsmAnd+ é uma aplicação de navegação livre, com acesso a uma ampla variedade de dados globais do OSM. Todos os dados dos mapas (mapas vetoriais ou imagens raster) podem ser armazenados no cartão de memória do telemóvel para usar desligado da Internet. O OsmAnd também permite roteamento, tanto ligado como desligado da Internet, incluindo a funcionalidade de roteamento curva a curva com orientação por voz. +\n OsmAnd+ é uma app de navegação livre, com acesso a uma ampla variedade de dados globais do OSM. Todos os dados dos mapas (mapas vetoriais ou imagens raster) podem ser armazenados no cartão de memória do telemóvel para usar desligado da Internet. O OsmAnd também permite roteamento, tanto ligado como desligado da Internet, incluindo a funcionalidade de roteamento curva a curva com orientação por voz. \n -\n OsmAnd+ é a versão paga da aplicação, ao comprá-lo está a apoiar o projeto, a financiar o desenvolvimento de novas funcionalidades e a receber as últimas atualizações. +\n OsmAnd+ é a versão paga da app, ao comprá-lo está a apoiar o projeto, a financiar o desenvolvimento de novas funcionalidades e a receber as últimas atualizações. \n \n Algumas das características principais: \n - Funcionalidade totalmente desligado da Internet (guarda os mapas obtidos, sejam eles vetoriais ou imagens, numa pasta selecionável). \n - Mapas vetoriais compactados do mundo inteiro disponíveis. -\n - Descarregamento de mapas de países ou regiões diretamente na aplicação. +\n - Descarregamento de mapas de países ou regiões diretamente na app. \n - Recurso Wikipédia desligado da Internet (descarregamento de POIs da Wikipédia), ótimo para passeios turísticos. \n - Possibilidade de sobreposição de várias camadas de mapas, como trilhos GPX ou navegação, pontos de Interesse, favoritos, curvas de nível, paragens de transporte público, mapas adicionais com transparência personalizável. \n @@ -1086,7 +1086,7 @@ Wikipédia (off-line) Marca Marítima Escolha perfis visíveis. - Perfis da aplicação + Perfis da app Destino Rosa Castanho @@ -1341,7 +1341,7 @@ Ver Norte Leste - Memória interna da aplicação + Memória interna da app Ir Configurações de navegação Configurações gerais @@ -1521,8 +1521,8 @@ O mapa %1$s está pronto para ser usado. Mapa descarregado Mostrar mapa - Define o sinalizador que indica a primeira inicialização da aplicação, mantém todas as outras configurações inalteradas. - Simular arranque inicial da aplicação + Define o sinalizador que indica a primeira inicialização da app, mantém todas as outras configurações inalteradas. + Simular arranque inicial da app geo: Partilhar Localização Enviar @@ -1572,7 +1572,7 @@ Escolher orientação por voz Escolher ou descarregar a orientação por voz para o seu idioma. Noite - Há uma nova opção para controlar principalmente a aplicação através do painel de controlo flexível ou um menu estático. A sua escolha pode ser alterada nas configurações do painel. + Há uma nova opção para controlar principalmente a app através do painel de controlo flexível ou um menu estático. A sua escolha pode ser alterada nas configurações do painel. Painel de controlo ou menu de controlo Atualizar Apenas descarregar com Wi-Fi @@ -1661,7 +1661,7 @@ Fino Média Negrito - Agora a aplicação está autorizada a escrever no armazenamento externo, mas primeiro é necessário reiniciar a aplicação. + Agora a app está autorizada a escrever no armazenamento externo, mas primeiro é necessário reiniciar a app. Mover ↑ Mover ↓ Terminar a navegação @@ -1959,7 +1959,7 @@ Sem sobreposição Sem subposição Erro - Assine a nossa lista de e-mail sobre descontos da aplicação e ganhe mais 3 descarregamentos de mapas! + Assine a nossa lista de e-mail sobre descontos da app e ganhe mais 3 descarregamentos de mapas! Curvas de nível de profundidade marítima e seamarks. Muito obrigado por comprar \'Contornos de profundidade náutica\' Contornos de profundidade náutica @@ -1973,10 +1973,10 @@ Fontes do mapa Circulação pela direita Automático - Não envie estatísticas anónimas de utilização da aplicação - OsmAnd recolhe informação sobre as secções da aplicação que abriu. Não são enviadas: a sua localização; a informação que introduz na aplicação; detalhes de áreas que veja, procure ou descarregue. + Não envie estatísticas anónimas de utilização da app + OsmAnd recolhe informação sobre as secções da app que abriu. Não são enviadas: a sua localização; a informação que introduz na app; detalhes de áreas que veja, procure ou descarregue. Não mostrar mensagens ao iniciar - Nâo mostrar descontos da aplicação e mensagens de eventos locais especiais. + Nâo mostrar descontos da app e mensagens de eventos locais especiais. Opções de estacionamento Muito obrigado por comprar a versão paga de OsmAnd. Inclinado @@ -2208,7 +2208,7 @@ Como abrir a hiperligação\? Ler a Wikipédia desligado da Internet Descarregar tudo - Reiniciar a aplicação + Reiniciar a app Mostrar imagens Cancelou a sua assinatura do OsmAnd Live Renovar assinatura para continuar a utilizar todas as funcionalidades: @@ -2232,7 +2232,7 @@ Guias para os lugares mais interessantes do mundo dentro do OsmAnd, sem uma conexão com a Internet. Atualizações de mapa mensais Atualizações de mapa a cada hora - Compra na aplicação + Compra na app Pagamento de uma só vez Uma vez comprado, estará sempre disponível para si. Comprar - %1$s @@ -2475,7 +2475,7 @@ \nRepresenta área: %1$s x %2$s Tolerância do limite de velocidade Selecione a margem de tolerância de limite de velocidade, acima do qual receberá um aviso de voz. - O nome do Favorito foi modificado para %1$s para facilitar gravar corretamente a sequência de caracteres com emoticons para um ficheiro. + O nome do favorito foi modificado para %1$s para facilitar gravar corretamente a cadeia de caracteres com emoticons num ficheiro. Imprimir rota Nome de favorito duplicado Nome favorito especificado já está em uso, foi alterado para %1$s para evitar a duplicação. @@ -2551,8 +2551,8 @@ Renderizar caminhos de acordo com a escala de SAC. Renderizar caminhos de acordo com traços OSMC. Hora intermediária - OsmAnd (sigla em inglês de direções de navegação automatizada do OSM) é uma aplicação de mapas e navegação com acesso a dados livres, mundiais e de alta qualidade do OSM. -\n + OsmAnd (sigla em inglês de direções de navegação automatizada do OSM) é uma app de mapas e navegação com acesso a dados livres, mundiais e de alta qualidade do OSM. +\n \nPoderá usar o navegador visual e por voz, ver POIs (pontos de interesse), criar e gerir trilhos GPX, usar (através de um suplemento) curvas de nível e dados de altitude, escolher entre os modos motorista, ciclista e pedestre, editar o OpenStreetMap e muito mais. Navegação GPS \n• Escolha entre modos off-line (sem tarifa de roaming quando estiver no exterior) ou on-line (mais rápido) @@ -2595,7 +2595,7 @@ \n • Envie trilhos GPX para o OpenStretMap diretamente da aplicação \n • Adicione POIs e envie-os diretamente para o OpenStretMap (ou mais tarde se estiver desconectado da Internet) \n - OsmAnd é um programa de fonte aberta desenvolvido ativamente. Todos podem contribuir para a aplicação reportando erros, melhorando as traduções ou programando novas funcionalidades. Além disso, o projeto conta com contribuições financeiras para financiar a programação e testes de novas funcionalidades. + OsmAnd é um programa de fonte aberta desenvolvido ativamente. Todos podem contribuir para a app reportando erros, melhorando as traduções ou programando novas funcionalidades. Além disso, o projeto conta com contribuições financeiras para financiar a programação e testes de novas funcionalidades. \n Cobertura de mapa e qualidade aproximada: \n • Europa Ocidental: **** \n • Europa Oriental: *** @@ -2609,11 +2609,11 @@ \n • Antártida: * \n A maioria dos países ao redor do globo está disponível para descarregar! \n Obtenha um navegador confiável no seu país - seja em França, Alemanha, México, Reino Unido, Espanha, Holanda, EUA, Rússia, Brasil ou qualquer outro. - OsmAnd+ (direções de navegação automatizada do OSM) é uma aplicação de mapas e navegação com acesso a dados livres do OSM, de todo o mundo e de alta qualidade. -\nDesfrute da navegação visual ou por voz, vendo POIs (pontos de interesse), criando e gerindo trilhos GPX, usando informação de altitude e curvas de nível, escolher entre modos dirigir, andar de bicicleta e pedestre, editar o OpenStreetMap e muito mais. -\n -\nOsmAnd+ é a versão paga da aplicação. Ao comprá-lo, está a apoiar o projeto, a financiar o desenvolvimento de novas funcionalidades e a receber as últimas atualizações. -\n + OsmAnd+ (direções de navegação automatizada do OSM) é uma app de mapas e navegação com acesso a dados livres do OSM, de todo o mundo e de alta qualidade. +\nDesfrute da navegação visual ou por voz, ver POIs (pontos de interesse), criando e gerindo trilhos GPX, usando informação de altitude e curvas de nível, escolher entre modos dirigir, andar de bicicleta e pedestre, editar o OpenStreetMap e muito mais. +\n +\nOsmAnd+ é a versão paga da app. Ao comprá-lo, está a apoiar o projeto, a financiar o desenvolvimento de novas funcionalidades e a receber as últimas atualizações. +\n \nAlgumas das características principais: Navegação \n• Funciona on-line (rápido) ou off-line (sem custos de roaming quando estiver no estrangeiro) @@ -2654,10 +2654,10 @@ \n• Visualização de curvas de nível e sombreamento de relevo (via suplemento adicional) Contribua diretamente para o OpenStreetMap \n • Envie relatórios de erros. -\n • Envie trilhos GPX para o OpenStretMap diretamente da aplicação. +\n • Envie trilhos GPX para o OpenStretMap diretamente da app. \n • Adicione POIs e envie-os diretamente para o OpenStretMap (ou mais tarde se estiver desconectado da Internet). \n • Gravação de viagem opcional também em plano de fundo (enquanto o aparelho está no modo adormecido). -\n OsmAnd é um programa de fonte aberta desenvolvido ativamente. Todos podem contribuir para a aplicação reportando erros, melhorando as traduções ou programando novas funcionalidades. Além disso, o projeto conta com contribuições financeiras para financiar a programação e testes de novas funcionalidades. +\n OsmAnd é um programa de fonte aberta desenvolvido ativamente. Todos podem contribuir para a app por reportar erros, a melhorar as traduções ou a programar novas funcionalidades. Além disso, o projeto conta com contribuições financeiras para financiar a programação e testes de novas funcionalidades. \n Cobertura de mapa e qualidade aproximada: \n• Europa Ocidental: **** @@ -3358,7 +3358,7 @@ Tocar em \'Aplicar\' apagará os perfis removidos permanentemente. Perfil principal Selecione a cor - Perfis padrão do OsmAnd não podem ser apagados, mas desativados (na tela anterior) ou classificados na parte inferior. + Perfis predefinidos do OsmAnd não podem ser apagados, mas desativados (no ecrã anterior) ou classificados na parte inferior. Editar perfis O \'Tipo de navegação\' controla como as rotas são calculadas. Aspeto do perfil @@ -3887,7 +3887,7 @@ Apenas a linha da rota será gravada, os pontos de passagem serão apagados. Nome do ficheiro %s ficheiros de faixa selecionados - Vai pausar o registo de faixas quando a aplicação for morta (através de aplicações recentes). (indicação de fundo de OsmAnd desaparece da barra de notificação do Android.) + Vai pausar o registo de faixas quando a app for morta (através de apps recentes). (indicação de fundo de OsmAnd desaparece da barra de notificação do Android.) - Função atualizada de Planear uma rota: permite utilizar diferentes tipos de navegação por segmento e a inclusão de faixas \n \n - Novo menu Aparência para trilhos: selecionar cor, espessura, setas de direção de visualização, ícones de início/fim @@ -3903,4 +3903,7 @@ \n - Problemas com as configurações de importação/exportação de perfis resolvidos \n \n + Última modificação + Nome: Z – A + Nome: A – Z \ No newline at end of file From cd73208f21586010d9650d83d9995400f1592f1b Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Fri, 2 Oct 2020 09:15:16 +0000 Subject: [PATCH 0403/1366] Translated using Weblate (Japanese) Currently translated at 98.7% (3443 of 3487 strings) --- OsmAnd/res/values-ja/strings.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 80f0b62286..565e5ae9d6 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -1190,7 +1190,7 @@ POIの更新は利用できません "出発時刻: %1$tF, %1$tT " "到着時刻: %1$tF, %1$tT " "平均速度: %1$s " - "最高速度: %1$s " + 最高速度: %1$s 平均標高: %1$s 標高差: %1$s 上り/下り: %1$s @@ -1350,7 +1350,7 @@ POIの更新は利用できません 画面の電源オン設定 方向転換地点に近づいたらデバイスの画面を(オフの場合指定時間)オンにします しない - 除外する道の指定… + 避ける道の指定… 電車でのルート 路面電車でのルート タクシーのルート共有 @@ -1816,7 +1816,7 @@ POIの更新は利用できません 上に移動 下に移動 ナビゲーションの終了 - 使用しない道路として指定 + 避ける道を指定 選択したデータ保存フォルダーが書き込み保護されているため、内部メモリに切り替えました。書き込み可能な保存用ディレクトリを選択してください。 共有記憶域 より詳細なレポートは以下サイトにて @@ -3010,9 +3010,9 @@ POIの更新は利用できません アイコン選択 基本プロファイル アイコン - 最低速度 - 最高速度 - 標準移動速度 + 予想最低速度 + 予想最高速度 + 予想標準速度 すべての道路の移動速度を制限し、種別や制限速度が不明な道路が多い場合の到着時間予測に役立ちます(ルート計算に影響します) オフロード プロファイルの個別設定 @@ -3590,7 +3590,7 @@ POIの更新は利用できません POIの作成/編集 駐車位置 お気に入りの追加/編集 - アイテム順序をデフォルトに戻す + アイテム順序を初期状態に戻します 編集に戻る 選択したプロファイルを切り替えるボタンです。 プロファイルの追加 @@ -3667,12 +3667,12 @@ POIの更新は利用できません コンテキストメニュー 項目の並べ替えや非表示するものを指定できます。 分割 - 分割線で区切られた部分より下にある項目が適用されます。 + ここで指定された項目は、区切り線より下に配置されます。 非表示 これらの項目はメニューに表示されなくなりますが、オプションやプラグインはそのまま機能します。 項目 設定を非表示にすると、元の状態にリセットされます。 - ボタンは4つしかありません。 + ボタンの数は4つ固定で変更できません。 主要機能 “%1$s”ボタンをタップすると、これらの機能にアクセスできます。 アイテムはこのカテゴリ内でのみ移動できます。 @@ -3794,7 +3794,7 @@ POIの更新は利用できません \n \n国の法律に基づいて、使用を望むかどうかを決定する必要があります。 \n -\n%1$sを選択すると、スピードカメラに関するアラートと警告が表示されます。 +\n%1$sを選択すると、スピードカメラに関するアラートと警告機能を使用できます。 \n \n%2$sを選択すると、スピードカメラに関するすべてのデータ(警告、通知、POI)が、OsmAndの再インストールを行うまで削除されます。 機能を維持 From a5bc166b1c96f919fba65a621f63a3b580926af2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 1 Oct 2020 17:17:00 +0000 Subject: [PATCH 0404/1366] Translated using Weblate (German) Currently translated at 99.9% (3486 of 3487 strings) --- OsmAnd/res/values-de/strings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 319e1c4f6f..6d0aeabcd6 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3876,9 +3876,7 @@ Track Datei zum Folgen auswählen, oder vom Gerät importieren. Die GPX-Aufzeichnung wird angehalten, wenn OsmAnd beendet wird (über „zuletzt verwendete Apps“). (Die Hintergrunddienst-Anzeige verschwindet aus der Android-Benachrichtigungsleiste.) Aufzeichnungsintervall für die generelle Track-Aufzeichnung festlegen (via Schaltfläche \'GPX\' auf dem Kartenbildschirm). - Um diese Option nutzen zu können, muss OsmAnd den Track auf die Straßen der Karte einrasten. -\n -\n Wählen Sie im nächsten Schritt ein Navigationsprofil um festzulegen, welche Straßentypen verwendet werden sollen, und wählen Sie einen Wert für die maximal zulässige Entfernung zwischen Track und Straße. + Als nächstes können Sie Ihren Track mit einem Ihrer Navigationsprofile auf die nächstgelegene erlaubte Straße einrasten lassen, um diese Option zu nutzen. Track-Wegpunkt hinzufügen %s Track Dateien ausgewählt Nur die Routenlinie wird gespeichert, die Wegpunkte werden gelöscht. From 3b0d1e469e85e8492e2e7e78896974d81f1e0a8e Mon Sep 17 00:00:00 2001 From: Evgenii Martynenko Date: Fri, 2 Oct 2020 16:01:48 +0000 Subject: [PATCH 0405/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 8dcc9c13c0..13d5ddd215 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3586,7 +3586,7 @@ Подробнее об уклонах можно прочитать в %1$s. Затенение рельефа Для отображения склонов, вершин и низменностей используются тёмные тени. - Для отображения склонов требуются дополнительные карты. + Для отображения уклонов требуются дополнительные карты. Уклоны Заменить этой точкой другую. Изменения применены к профилю «%1$s». From 4d317a54d38669d9f9afdeed320ca1348afdba5f Mon Sep 17 00:00:00 2001 From: Mirco Zorzo Date: Thu, 1 Oct 2020 06:47:35 +0000 Subject: [PATCH 0406/1366] Translated using Weblate (Italian) Currently translated at 90.2% (3146 of 3487 strings) --- OsmAnd/res/values-it/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index e806eff554..653874de7d 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -1954,7 +1954,7 @@ Navigazione OsmAnd Live Livello della batteria Ungherese (formale) - Tracciato attuale + Traccia attuale Cambia posizione del marcatore Spagnolo americano Asturiano @@ -3620,7 +3620,7 @@ Mappa mondiale generale (dettagliata) Mappe extra Azione non supportata %1$s - OsmAnd tracker + Tracker OsmAnd OsmAnd + Mapillary Azione veloce Righello radiale @@ -3900,7 +3900,7 @@ \n \n Traccia semplificata - Ultimo modificato + Cronologico Nome: Z – A Nome: A – Z \ No newline at end of file From 46c2458b182075fd88f0f506ea53fa77bce04e91 Mon Sep 17 00:00:00 2001 From: Roberto GEB Date: Wed, 30 Sep 2020 06:33:38 +0000 Subject: [PATCH 0407/1366] Translated using Weblate (Spanish) Currently translated at 99.0% (3453 of 3487 strings) --- OsmAnd/res/values-es/strings.xml | 98 ++++++++++++++++---------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index caf2e2ec40..7b571077f7 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -23,7 +23,7 @@ Borrar edición Edición asíncrona OSM: PDI/Notas de OSM guardados en el dispositivo - Muestra y gestiona PDI/notas de OSM guardadas en la base de datos del dispositivo. + Muestra y gestiona PDI/Notas de OSM en la base de datos de tu dispositivo. Indica el intervalo del seguimiento en línea. Intervalo del seguimiento en línea Indica la dirección web con sintaxis de parámetros : lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. @@ -163,7 +163,7 @@ El idioma elegido es incompatible con el motor TTS (texto a voz) instalado en Android, se usará el idioma TTS predefinido. ¿Buscar otro motor TTS en la tienda de aplicaciones\? Faltan datos ¿Ir a la tienda de aplicaciones para descargar el idioma elegido? - Invertir la dirección GPX + Invertir la dirección de la traza Usar destino actual Pasar a lo largo de la traza completa Mapa vectorial presente para esta ubicación. @@ -265,10 +265,7 @@ Todos los datos sin conexión en la versión vieja de OsmAnd son compatibles con la nueva versión, pero los puntos de Favoritos deben exportarse desde la versión vieja y luego, importarse en la nueva. Compilación {0} instalada ({1}). Descargando compilación… - ¿Instalar OsmAnd\? -\nVersión: {0} -\nFecha: {1} -\nTamaño: {2} MB + ¿Instalar OsmAnd - {0} de {1} {2} MB\? Error al recuperar la lista de compilaciones de OsmAnd Cargando compilaciones de OsmAnd… Instalar compilación de OsmAnd @@ -441,7 +438,7 @@ Búsqueda sin conexión Búsqueda en línea Máximo zoom en línea - No buscar en las teselas de mapas en línea para niveles de zoom más allá de esto. + No busca en los mapas en línea niveles de zoom más allá de éste. Distancia total %1$s, tiempo de viaje %2$d h %3$d min. Servicios de navegación con o sin conexión. Servicio de navegación @@ -606,7 +603,7 @@ Para países donde la gente conduce por el lado izquierdo del camino. Punto de partida aún no determinado. ¿Cancelar la descarga\? - El mapa base necesario para proporcionar la funcionalidad básica, está en la cola de descarga. + El mapa base necesario para proporcionar funcionalidad básica está en la cola de descargas. Activa el complemento «Mapas en línea», para elegir diferentes fuentes de mapas Mapas en línea y teselas Usa mapas en línea (descarga y guarda teselas en la tarjeta de memoria). @@ -729,8 +726,8 @@ PM AM Lugar de aparcamiento - Este complemento, registra dónde se ha aparcado el automóvil y cuánto tiempo queda (si hay un límite de tiempo). -\nTanto la ubicación como el tiempo del aparcamiento se muestran en el menú principal y en un widget sobre el mapa. Puedes añadir una notificación al calendario, en el caso de que desees tener un recordatorio al respecto. + Te permite egistrar dónde has aparcado el automóvil y cuánto tiempo queda (si hay un límite de tiempo). +\nTanto la ubicación como el tiempo del aparcamiento se muestran en el menú principal y en un control sobre el mapa. Puedes añadir un recordatorio al calendario, de Android. Aparcamiento Marcar como aparcamiento Quitar marcador de aparcamiento @@ -890,7 +887,7 @@ Curvas de nivel Otros mapas Curvas de nivel - Este complemento, proporciona la funcionalidad para tomar notas de audio, fotografía y/o video durante un viaje, usando un botón en el mapa, o directamente en el menú contextual para cualquier ubicación en el mapa. + Tomar notas de audio/foto/video durante un viaje, usando un botón de mapa o un menú contextual de la ubicación. Notas audio/vídeo Complemento OsmAnd para curvas de nivel sin conexión Este complemento proporciona una capa superpuesta de curvas de nivel y una capa (de relieve) sombreada, que se pueden visualizar sobre los mapas descargados de OsmAnd. Esta funcionalidad será muy apreciada por atletas, caminantes, excursionistas, y cualquiera interesado en la estructura de relieve de un paisaje. @@ -930,7 +927,7 @@ Grabando %1$s %3$s %2$s Por favor, considera pagar por el complemento «Curvas de nivel» para apoyar desarrollos adicionales. Complemento de curvas de nivel - El complemento de Dropbox, permite sincronizar trazas y notas multimedia con tu cuenta de Dropbox. + Sincroniza trazas y notas multimedia con tu cuenta de Dropbox. Complemento Dropbox Cambiar orden Mostrar @@ -1003,8 +1000,8 @@ Punto Nombre del archivo GPX Archivo GPX guardado en {0} - Este complemento proporciona un widget en el mapa, permitiendo crear caminos pulsando el mapa, usando o modificando archivos GPX existentes, para planificar un viaje y medir la distancia entre puntos. Los resultados pueden guardarse como un archivo GPX y usarse luego para la orientación. - Distancias y planificación + Crea caminos pulsando en el mapa, o usando o modificando archivos GPX existentes, para planificar un viaje y medir la distancia entre puntos. El resultado puede guardarse como un archivo GPX y usarse luego para la orientación. + Calculadora de distancias y herramienta de planificación * Pulse para marcar un punto. \n * Mantenga pulsado el mapa para quitar el punto anterior. \n * Mantenga pulsado en un punto para ver e incluir la descripción. @@ -1307,9 +1304,9 @@ Duración Distancia Grabación de viaje - Este complemento activa la funcionalidad para registrar y guardar tus trazas manualmente pulsando el widget de grabación GPX en el mapa, o automáticamente registrando todas tus rutas navegadas en un archivo GPX. -\n -\nLas trazas grabadas pueden ser compartidas con sus amigos o ser usadas para contribuir a OSM. Los atletas pueden usar las trazas grabadas para seguir sus entrenamientos. Algunos análisis básicos de trazas se pueden realizar directamente en OsmAnd, como tiempos por vuelta, velocidad media, etc., y por supuesto las trazas pueden analizarse posteriormente con herramientas de análisis de terceros. + Este complemento activa la funcionalidad para registrar y guardar tus trazas manualmente pulsando el widget de grabación GPX en el mapa, o automáticamente registrando todas tus rutas navegadas en un archivo GPX. +\n +\nLas trazas grabadas pueden ser compartidas con tus amigos o ser usadas para contribuir a OSM. Los atletas pueden usar las trazas grabadas para monitorizar sus entrenamientos. Algunos análisis básicos de trazas pueden realizarse directamente en OsmAnd, como tiempos por vuelta, velocidad media, etc., y por supuesto las trazas pueden analizarse posteriormente con herramientas de análisis de terceros. Rutas de autobús, trolebús y lanzadera Intervalo de registro Registra la ubicación en un archivo GPX, pudiendo des/activarlo usando el widget de grabación GPX en el mapa. @@ -1433,7 +1430,7 @@ Pista de entrenamiento Sólo caminos Compartir nota - Notas + Notas A/V Mapa en línea Exportar Audio @@ -1781,7 +1778,7 @@ Se ofrece la opción de controlar la aplicación principalmente a través del panel de control flexible o de un menú estático. Se puede cambiar esto luego, en los ajustes del panel. Usar panel de control Usar menú - El botón del menú, muestra el panel de control en lugar del menú + El botón del menú muestra el panel de control en lugar del menú Acceso desde el mapa Indica el tipo de PDI correcto u omítelo. Sin escaleras @@ -1880,7 +1877,7 @@ \nSe utiliza {3} MB temporalmente, {1} MB constantemente. (De {2} MB.) Elegir marcador del mapa Otros marcadores - Subir notas de OSM anónimas o usar el perfil de OpenStreetMap.org. + Sube tu nota de OSM de forma anónima o usando tu perfil de OpenStreetMap.org. Subir nota(s) de OSM Subir anónimamente Barra superior @@ -1910,7 +1907,7 @@ \nParte de los ingresos vuelven a la comunidad de OSM y se paga por cada contribución OSM. \nSi amas a OsmAnd, OSM y quieres apoyarlos y ser apoyado por ellos, esta es una perfecta manera de hacerlo. Mostrar barra de transparencia en el mapa - Se ha cambiado a la memoria interna, porque la carpeta de almacenamiento de datos elegida es de sólo lectura. Elige un directorio de almacenamiento válido. + Se ha cambiado a la memoria interna, porque la carpeta de almacenamiento de datos elegida está protegida de escritura. Elige un directorio de almacenamiento válido. Memoria compartida La aplicación ya permite escribir en el almacenamiento externo, pero se debe reiniciar la aplicación. Subir ↑ @@ -1918,7 +1915,7 @@ Finalizar navegación Evitar camino Informe completo - Nombre de usuario y contraseña de OpenStreetMap + Nombre de usuario y contraseña de OSM Informe Añade marcadores a través del mapa No se encontraron puntos de referencia @@ -2017,8 +2014,8 @@ Omite la búsqueda de nuevas versiones o descuentos relacionados con OsmAnd. Ocultar nuevas versiones Suscripción mensual. Puede cancelarlo en cualquier momento en Google Play. - Donaciones a la comunidad de OpenStreetMap - Parte de tu donación se envía a usuarios que realicen cambios en OpenStreetMap. El costo de la suscripción sigue siendo la misma. + Donación a la comunidad de OSM + Parte de tu donación se envía a los contribuidores a OSM. El coste de la suscripción sigue siendo el mismo. La suscripción permite actualizaciones cada hora, día o semana y descargas ilimitadas para los mapas de todo el mundo. Obtener Obtener por %1$s @@ -2121,7 +2118,7 @@ Un botón que añade una nota fotográfica en el centro de la pantalla. Un botón que añade una nota de OSM en el centro de la pantalla. Un botón que añade un PDI en el centro de la pantalla. - Un botón que des/activa las indicaciones por voz durante la navegación. + Un botón que activa o desactiva las indicaciones por voz durante la navegación. Un botón que añade la ubicación del aparcamiento en el centro de la pantalla. Mostrar un diálogo temporal " guardado como " @@ -2188,7 +2185,7 @@ \nProporciona un código completo OLC completo y válido. \nÁrea representada: %1$s x %2$s - Un botón que muestra la siguiente lista. + Un botón para paginar a través de la lista de abajo. Mapa superpuesto cambiado a «%s». Mapa subyacente cambiado a «%s». Pendiente @@ -2286,15 +2283,15 @@ \n ¡Más países alrededor del globo están disponibles para descargar! \n Obtén un navegador confiable en tu país - ya sea Francia, Alemania, México, Reino Unido, España, Países bajos, Estados Unidos, Rusia, Brasil o cualquier otro. Alternar zoom automático del mapa - Un botón que des/activa el zoom automático del mapa de acuerdo a la velocidad. - Activar zoom automático del mapa - Desactivar zoom automático del mapa + Botón para activar o desactivar el zoom automático controlado por la velocidad. + Activar zoom automático + Desactivar zoom automático Definir destino Reemplazar destino Añadir primer destino intermedio - Un botón que añade el destino de la ruta en el centro de la pantalla, cualquier destino previamente elegido se convierte en el último destino intermedio. - Este botón de acción, añade un nuevo destino de ruta en el centro de la pantalla, reemplazando el anterior destino (si existe). - Un botón que añade el primer destino intermedio en el centro de la pantalla. + Un botón que añade el centro de la pantalla como destino de la ruta, cualquier destino previamente elegido se convierte en el último destino intermedio. + Un botón que añade el centro de la pantalla como destino de la nueva ruta, reemplazando el anterior destino (si existe). + Un botón que añade el centro de la pantalla como el primer destino intermedio. Sin superposición Sin subyacencia Error @@ -2327,13 +2324,14 @@ Ubicación propia animada Activa el desplazamiento animado del mapa para «Mi ubicación» durante la navegación. Resumen - Navegación GPS + Navegación \n • Funciona en línea (rápido) o sin conexión (sin cargos de roaming al viajar al extranjero) \n • Guía por voz giro-a-giro (voces grabadas y sintetizadas) -\n • (Opcional) Guía de carriles, nombres de calles y tiempo estimado al destino -\n • Soporta puntos intermedios en el itinerario +\n • (Opcional) Guía de carriles, nombres de calles y tiempo estimado de llegada +\n • Soporta puntos intermedios en tu itinerario \n • La ruta se recalcula al salirse de la misma -\n • Busca destinos por dirección, por tipo (por ejemplo: Restaurantes, hoteles, gasolineras, museos), o por coordenada geográfica +\n • Busca lugares por dirección, por tipo (por ejemplo: Restaurantes, hoteles, gasolineras, museos), o por coordenadas geográficas +\n Vista del mapa \n • Muestra tu ubicación y orientación \n • (Opcional) Ajusta el mapa a la dirección del movimiento (o la brújula) @@ -2397,7 +2395,7 @@ Mostrar u ocultar notas de OSM Mostrar notas de OSM Ocultar notas de OSM - Un botón que muestra u oculta las notas de OSM en el mapa. + Botón para mostrar u ocultar las notas de OSM en el mapa. Ordenados por distancia Buscar en Favoritos Ocultar desde el nivel de zoom @@ -2449,10 +2447,10 @@ Min/Máx Rosa translúcido Pausar/reanudar navegación - Este botón de acción, pausa o reanuda la navegación. + Botón para pausar o reanudar navegación. Mostrar diálogo «Navegación finalizada» Iniciar/parar navegación - Este botón de acción, inicia o para la navegación. + Botón para iniciar o terminar la navegación. Tiempo del búfer para el seguimiento en línea Indica el tiempo que el búfer mantendrá los lugares para enviar sin conexión Añadir al menos un punto. @@ -2468,7 +2466,7 @@ Punto de ruta 1 Punto de referencia 1 Sin animaciones - Desactiva las animaciones en la aplicación. + Desactiva las animaciones de los mapas. Mantener en el mapa ¿Salir sin guardar? Línea @@ -2492,7 +2490,7 @@ Mover todo al historial Indicación de distancia Ordenar por - Elige cómo se indica la distancia y dirección a los marcadores del mapa en la pantalla del mapa: + Elige cómo se indica la distancia y dirección a los marcadores del mapa en el mapa: Umbral de orientación del mapa Velocidad a partir de la cual la orientación del mapa cambia de «Dirección del movimiento» a «Dirección de la brújula». Todos los marcadores del mapa movidos al historial @@ -2852,7 +2850,7 @@ Guaraní Está utilizando el mapa «{0}» que funciona con OsmAnd. ¿Quiere ejecutar la versión completa de OsmAnd\? ¿Ejecutar OsmAnd\? - Un botón que alterna entre el modo diurno y nocturno para OsmAnd. + Un botón que alterna entre los modos diurno y nocturno para OsmAnd. Modo diurno Modo nocturno Alternar modos diurno/nocturno @@ -3103,7 +3101,7 @@ Elegir el tipo de navegación Automóvil, camión, motocicleta Bicicleta de montaña, ciclomotor, caballo - Caminata, senderismo, correr + Caminata, senderismo, carrera Tipos de transporte público Barco, remo, vela Avión, ala delta @@ -3139,7 +3137,7 @@ Dificultad preferida Preferir rutas de esta dificultad, aunque el trazado sobre pistas más duras o más fáciles sigue siendo posible si son más cortas. Fuera de pista - Los senderos libres y fuera de pista son rutas y pasajes no oficiales. Típicamente descuidados, no mantenidos por los oficiales y no controlados por la noche. Entrar bajo su propio riesgo. + Los senderos libres y fuera de pista son rutas y pasajes no oficiales. Típicamente descuidados, no mantenidos y no controlados por la noche. Entra bajo tu propio riesgo. Geocodificación Error Todo terreno @@ -3361,7 +3359,7 @@ El nombre de archivo está vacío Traza guardada Revertir - Un botón para centrar en la pantalla el punto de partida y calcular la ruta hacia el destino o abre un cuadro de diálogo para elegir el destino si el marcador no está en el mapa. + Un botón que añade el centro de la pantalla como punto de partida. Pedirá luego que se fije el destino o iniciará el cálculo de la ruta. Mostrar nodo de la red de rutas ciclistas ¿Borrar %1$s\? Diálogo de descarga del mapa @@ -3394,7 +3392,7 @@ Elegir el color Los perfiles predefinidos de OsmAnd no pueden borrarse , pero sí desactivarse (en la pantalla anterior), o moverse a la parte inferior. Editar perfiles - El \'tipo de navegación\' domina como se calculan las ruta. + El \'Tipo de navegación\' determina cómo se calculan las rutas. Apariencia del perfil Icono, color y nombre Editar lista de perfiles @@ -3679,7 +3677,7 @@ Buscar tipos de PDI Acción %1$s no admitida Mapa general del mundo (detallado) - Tipo no admitido + Tipo no soportado Proporciona la anchura de tu vehículo, algunas restricciones de ruta pueden aplicarse para vehículos anchos. Proporciona la altura de tu vehículo, algunas restricciones de ruta pueden aplicarse para vehículos altos. Proporciona el peso de tu vehículo, algunas restricciones de ruta pueden aplicarse para vehículos pesados. @@ -3715,7 +3713,7 @@ Elige cómo se guardarán las teselas descargadas. Puede exportar o importar acciones rápidas con perfiles de aplicación. ¿Eliminar todo\? - ¿Estás seguro de que deseas eliminar irrevocablemente% d acciones rápidas\? + ¿Estás seguro deseas eliminar de forma irreversible %d acciones rápidas\? Tiempo de apagado de la pantalla Si \"%1$s\" está encendido, el tiempo de actividad dependerá de ello. metros @@ -3740,7 +3738,7 @@ Urdu Tayiko Bávaro - Rastreador OsmAnd + Trazador OsmAnd La guía para la simbología del mapa. Posiciones de estacionamiento Deshabilitado. Requiere \'Mantener la pantalla encendida\' dentro de \'Tiempo de espera después de la activación\'. @@ -3897,4 +3895,4 @@ Último modificado Nombre: Z – A Nombre: A - Z - + \ No newline at end of file From 1ef8c4e7a5407d3448c042de3714243c4e8112cc Mon Sep 17 00:00:00 2001 From: Ole Carlsen Date: Tue, 29 Sep 2020 18:28:03 +0000 Subject: [PATCH 0408/1366] Translated using Weblate (Danish) Currently translated at 93.7% (3270 of 3487 strings) --- OsmAnd/res/values-da/strings.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-da/strings.xml b/OsmAnd/res/values-da/strings.xml index 058b72d771..0ef92f7051 100644 --- a/OsmAnd/res/values-da/strings.xml +++ b/OsmAnd/res/values-da/strings.xml @@ -3756,8 +3756,8 @@ Slet adresse Tilføj adresse Angiv adresse - Trim før - Trim efter + Trimme før + Trimme efter Skift rutetype før Skift rutetype efter Forenklet spor @@ -3771,4 +3771,10 @@ er gemt Tilføj mindst to punkter. Omgøre + Navigere fra position til sporet + Punkt på sporet for at navigere + %s spor filer valgt + Sidst ændret + Navn: Z – A + Navn: A – Z \ No newline at end of file From 10c81a2347495d8830caaccb324c9223e5972b18 Mon Sep 17 00:00:00 2001 From: nasr pen Date: Wed, 30 Sep 2020 09:29:21 +0000 Subject: [PATCH 0409/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index f3bbf28ac6..68da535b68 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -721,9 +721,9 @@ عكس اتجاه المسار استخدم الوجهة الحالية يمر على طول المسار باكمله - خريطة التنقل متوفرة حالياً لهذا الموقع. + خريطة التنقل متوفرة لهذا الموقع فعلها عبر \n -\nلتفعليها \'القائمة\' ← \'ضبط الخريطة\' ← \'مصدر الخريطة\' ← \'الخريطة المحملة\'. +\n\'القائمة\' ← \'ضبط الخريطة\' ← \'مصدر الخريطة\' ← \'الخريطة المحملة\'. مصدر التوجيه الصوتي اختيار قناة لتشغيل التوجيه الصوتي. صوت المكالمة الهاتفية ( كما يحاول قطع ستريو بلوتوث السيارة ) @@ -1972,7 +1972,7 @@ بطاقة الذاكرة غير متاحة. \nلن تكون قادرا على رؤية الخرائط أو العثور على أماكن. بطاقة الذاكرة في وضع القراءة فقط. -\n يمكنك فقط مشاهدة الخريطة المحملة مسبقا ولا يمكنك التحميل من الإنترنت. +\n يمكنك فقط مشاهدة الخريطة المحملة مسبقاً ولا يمكنك التحميل من الإنترنت. انعطف يميناً بشكل حاد انعطف يساراً بشكل حاد قم بالدوران وواصل From 6cfd150555f1f5fb40dc5367ae641727acec29ad Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Mon, 28 Sep 2020 16:54:01 +0000 Subject: [PATCH 0410/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3487 of 3487 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 68da535b68..bd631a4b89 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1645,7 +1645,7 @@ الطريق محظور تحديد اعكس نقطة الانطلاق والوصول - أيقونات POI + أيقونات نقاط الاهتمام النوع غير محدد قسم مسجل From 92f4bce1756a3210fd6554ba96f896af6de72a08 Mon Sep 17 00:00:00 2001 From: iman Date: Thu, 1 Oct 2020 14:15:53 +0000 Subject: [PATCH 0411/1366] Translated using Weblate (Persian) Currently translated at 99.9% (3485 of 3487 strings) --- OsmAnd/res/values-fa/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index 4d8d47c875..3a12b3accf 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -3553,7 +3553,7 @@ پروفایل سفارشی زاویه: ‎%s° زاویه - تا مسیریابی مجدد انجام شود، از موقعیت من تا مسیر محاسبه‌شده پاره‌خط مستقیمی نمایش داده می‌شود + تا مسیریابی مجدد انجام نشده، از موقعیت من تا مسیر محاسبه‌شده پاره‌خط مستقیمی نمایش داده می‌شود کمترین زاویه میان موقعیت من و مسیر آماده‌سازی چیزی انتخاب نشده @@ -3873,7 +3873,7 @@ ذخیره به‌عنوان رد جدید برعکس‌کردن مسیر تمام رد با استفاده از پروفایل انتخابی بازمحاسبه خواهد شد. - با استفاده از پروفایل انتخابی فقط پارهٔ بعدی بازمحاسبه خواهد شد. + فقط پارهٔ بعدی با استفاده از پروفایل انتخابی بازمحاسبه خواهد شد. همهٔ پاره‌های بعدی پارهٔ قبلی همهٔ پاره‌های قبلی From 14cc2f8196a06131e41c48e301fe6d361641a89c Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 1 Oct 2020 10:50:15 +0000 Subject: [PATCH 0412/1366] Translated using Weblate (Persian) Currently translated at 99.9% (3485 of 3487 strings) --- OsmAnd/res/values-fa/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index 3a12b3accf..68b4a4511d 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -3278,7 +3278,7 @@ تور اسکی مسیرها برای تور اسکی. کمپر - ون کمپر + ون کمپر (RV) واگن کامیون پیک‌آپ تحلیل‌ها @@ -3928,4 +3928,9 @@ بازهٔ زمانی برای ضبط رد را انتخاب کنید (که از طریق ابزار ضبط سفر روی نقشه فعال می‌شود). نگه‌داشتن ضبط سفر ازسرگیری ضبط سفر + اسکیت این‌لاین + موتور پرشی + اسکوتر موتوری + ویلچر رو به جلو + فاصله آستانه \ No newline at end of file From d2e0d88d88646b0787953d507bd3046bc4894d9a Mon Sep 17 00:00:00 2001 From: Atrate Date: Wed, 30 Sep 2020 08:12:42 +0000 Subject: [PATCH 0413/1366] Translated using Weblate (Polish) Currently translated at 99.5% (3806 of 3824 strings) --- OsmAnd/res/values-pl/phrases.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-pl/phrases.xml b/OsmAnd/res/values-pl/phrases.xml index 4b3efcc10c..faec609ff4 100644 --- a/OsmAnd/res/values-pl/phrases.xml +++ b/OsmAnd/res/values-pl/phrases.xml @@ -3812,7 +3812,7 @@ Skontrastowane Uzupełnianie wody pitnej: woda z sieci Uzupełnianie wody pitnej: nie - Uzupełnianie wody pitnej: tak + Tak Poziom wody: utrzymujący się na powierzchni Poziom wody: poniżej średniego poziomu wody Poziom wody: obmywający falami @@ -3834,4 +3834,7 @@ Stan pompy: brak wiązki Strzałka: nie Winda + Małogabarytowe urządzenia elektryczne + Tablica odjazdów/odlotów + Uzupełnianie wody pitnej \ No newline at end of file From ca51a273fc001c2a067f8803994f7f33af30fc07 Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Wed, 30 Sep 2020 23:08:29 +0000 Subject: [PATCH 0414/1366] Translated using Weblate (Japanese) Currently translated at 99.7% (3816 of 3824 strings) --- OsmAnd/res/values-ja/phrases.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ja/phrases.xml b/OsmAnd/res/values-ja/phrases.xml index 680da76205..66c5cc2a31 100644 --- a/OsmAnd/res/values-ja/phrases.xml +++ b/OsmAnd/res/values-ja/phrases.xml @@ -1258,7 +1258,7 @@ 有り 掃除機:無し 掃除機 - アドブルー・尿素水還元剤 + ディーゼル排気用液(AdBlue・尿素水) ドライブスルー 有り 無し @@ -3822,4 +3822,16 @@ 吸引 加圧 地下水 + ナッツ専門店 + 養蜂箱 + リアルタイム時刻表 + 一般的な時刻表 + 大まかな時刻表 + 有り + 時刻表:無し + エレベーター + 街区 + 行政区 + ギブボックス(提供品置場) + 簡易給水栓 \ No newline at end of file From 5699c465f360cf36be87ad4806b26bd6c3da6987 Mon Sep 17 00:00:00 2001 From: Vincent Bergeot Date: Tue, 29 Sep 2020 12:22:29 +0000 Subject: [PATCH 0415/1366] Translated using Weblate (French) Currently translated at 99.7% (3813 of 3824 strings) --- OsmAnd/res/values-fr/phrases.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-fr/phrases.xml b/OsmAnd/res/values-fr/phrases.xml index 638995c1f2..91dc180070 100644 --- a/OsmAnd/res/values-fr/phrases.xml +++ b/OsmAnd/res/values-fr/phrases.xml @@ -1762,7 +1762,7 @@ Fournitures de plomberie Fournitures de bois Ancres pour vélo - Râtelier pour vélo + Arceaux pour vélo Terminal d\'informations Carte tactile Tableau d\'affichage @@ -3380,7 +3380,7 @@ Parc animalier Enceinte Parc safari - Râtelier pour vélo + Arceaux pour vélo Vélo de sport Hachoir Hors route From 43fabf896ff45dea1d3427e5e551b6b87a977798 Mon Sep 17 00:00:00 2001 From: iman Date: Thu, 1 Oct 2020 19:50:08 +0000 Subject: [PATCH 0416/1366] Translated using Weblate (Persian) Currently translated at 36.2% (1388 of 3824 strings) --- OsmAnd/res/values-fa/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fa/phrases.xml b/OsmAnd/res/values-fa/phrases.xml index eba643a4f9..dd6c374db3 100644 --- a/OsmAnd/res/values-fa/phrases.xml +++ b/OsmAnd/res/values-fa/phrases.xml @@ -9,7 +9,7 @@ فروشگاه گوشت بقالی فروشگاه محصولات دامی - سبزی فروشی + میوه و سبزی‌فروشی فروشگاه غذاهای دریایی شیرینی و آجیل فروشی بستنی فروشی From 8ba231d5f07d2e69df0b3c3198c3debf33129bdf Mon Sep 17 00:00:00 2001 From: Roberto GEB Date: Tue, 29 Sep 2020 18:29:02 +0000 Subject: [PATCH 0417/1366] Translated using Weblate (Spanish) Currently translated at 99.9% (3823 of 3824 strings) --- OsmAnd/res/values-es/phrases.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-es/phrases.xml b/OsmAnd/res/values-es/phrases.xml index d892b94f7e..cac7b4a36d 100644 --- a/OsmAnd/res/values-es/phrases.xml +++ b/OsmAnd/res/values-es/phrases.xml @@ -1588,7 +1588,7 @@ Koshinto Placa azul Jizo - Crucero (monumento) + Cruz Cantera histórica Agregado Antimonio @@ -1825,7 +1825,7 @@ Capacitación: artes marciales Capacitación: aviación Capacitación: peluquería - Monumento + Objeto monumental Tipo: industria petrolera Tipo: Área de pozos Tipo: fábrica @@ -1868,7 +1868,7 @@ 100LL (con plomo, para aviones) Autogas (Etanol libre de plomo) Jet A-1 (diésel) - AdBlue + Líquido de escape de diesel Combustible: madera Combustible: carbón vegetal Combustible: carbón @@ -3798,7 +3798,7 @@ Tubo Red de recarga de agua potable Recarga de agua potable: no - Recarga de agua potable: sí + Obstrucción Nivel de agua: por debajo del nivel medio del agua Nivel de agua: por encima del nivel medio del agua From b8197864511806c21dc7585f2d6e163c4fe120e8 Mon Sep 17 00:00:00 2001 From: Aulo Aasmaa Date: Mon, 28 Sep 2020 19:08:29 +0000 Subject: [PATCH 0418/1366] Translated using Weblate (Estonian) Currently translated at 99.4% (3468 of 3487 strings) --- OsmAnd/res/values-et/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index e219936c08..c2b36454b5 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -3497,7 +3497,7 @@ Kohandatud värv Jätkamiseks vali tööpäevad Teekond punktide vahel - Kavanda teekonda + Kavanda teekond Lisa rajale Näita alguse ja lõpu ikoone Vali laius @@ -3762,4 +3762,6 @@ Viimati muudetud Nimi: Z – A Nimi: A – Z + Ekraani väljalülitamine + Ratastool edasi \ No newline at end of file From 94aad1004c7ee9c0f663458f05651983d5b84104 Mon Sep 17 00:00:00 2001 From: ssantos Date: Thu, 1 Oct 2020 21:55:19 +0000 Subject: [PATCH 0419/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3824 of 3824 strings) --- OsmAnd/res/values-pt/phrases.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index 8d22b73dbe..e2866a9b26 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -436,7 +436,7 @@ Central telefônica Reciclagem Centro de reciclagem - Contêiner + Contentor Vidro Papel Roupas @@ -1775,7 +1775,7 @@ Brinquedos Sorvete Cartão SIM - Seção + Secção Memorial de guerra Placa comemorativa Estátua @@ -2400,7 +2400,7 @@ Passageiros Veículos Bicicletas - Contêineres + Contentor Veículos pesados Academia ao ar livre Hackerspace From a9aa1e5776bc6fa72a84b4bc37e445a3e5b10b3e Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sat, 3 Oct 2020 12:07:18 +0300 Subject: [PATCH 0420/1366] Fix import --- .../plus/inapp/InAppPurchaseHelperImpl.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index fc9b1056f6..7b0351b3a9 100644 --- a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -13,6 +13,7 @@ import com.android.billingclient.api.SkuDetailsResponseListener; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.inapp.util.BillingManager; @@ -106,7 +107,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { if (activeTask == InAppPurchaseTaskType.REQUEST_INVENTORY) { List skuInApps = new ArrayList<>(); - for (InAppPurchases.InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { + for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { skuInApps.add(purchase.getSku()); } for (Purchase p : purchases) { @@ -173,7 +174,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { }); } - public void purchaseFullVersion(final Activity activity) { + public void purchaseFullVersion(@NonNull final Activity activity) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppCommand() { @Override @@ -199,7 +200,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { }); } - public void purchaseDepthContours(final Activity activity) { + public void purchaseDepthContours(@NonNull final Activity activity) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppCommand() { @Override @@ -325,7 +326,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } - InAppPurchases.InAppPurchase fullVersion = getFullVersion(); + InAppPurchase fullVersion = getFullVersion(); if (hasDetails(fullVersion.getSku())) { Purchase purchase = getPurchase(fullVersion.getSku()); SkuDetails fullPriceDetails = getSkuDetails(fullVersion.getSku()); @@ -334,7 +335,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } - InAppPurchases.InAppPurchase depthContours = getDepthContours(); + InAppPurchase depthContours = getDepthContours(); if (hasDetails(depthContours.getSku())) { Purchase purchase = getPurchase(depthContours.getSku()); SkuDetails depthContoursDetails = getSkuDetails(depthContours.getSku()); @@ -343,7 +344,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } - InAppPurchases.InAppPurchase contourLines = getContourLines(); + InAppPurchase contourLines = getContourLines(); if (hasDetails(contourLines.getSku())) { Purchase purchase = getPurchase(contourLines.getSku()); SkuDetails contourLinesDetails = getSkuDetails(contourLines.getSku()); @@ -367,7 +368,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { // Do we have the live updates? boolean subscribedToLiveUpdates = false; List liveUpdatesPurchases = new ArrayList<>(); - for (InAppPurchases.InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { + for (InAppPurchase p : getLiveUpdates().getAllSubscriptions()) { Purchase purchase = getPurchase(p.getSku()); if (purchase != null) { liveUpdatesPurchases.add(purchase); @@ -435,12 +436,12 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken()); } - private void fetchInAppPurchase(@NonNull InAppPurchases.InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) { + private void fetchInAppPurchase(@NonNull InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) { if (purchase != null) { - inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.PURCHASED); + inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.PURCHASED); inAppPurchase.setPurchaseTime(purchase.getPurchaseTime()); } else { - inAppPurchase.setPurchaseState(InAppPurchases.InAppPurchase.PurchaseState.NOT_PURCHASED); + inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.NOT_PURCHASED); } inAppPurchase.setPrice(skuDetails.getPrice()); inAppPurchase.setPriceCurrencyCode(skuDetails.getPriceCurrencyCode()); From ceb5758e894a0b44d04fce0a83cc3ce8bb211be6 Mon Sep 17 00:00:00 2001 From: ssantos Date: Sat, 3 Oct 2020 12:41:53 +0000 Subject: [PATCH 0421/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-pt/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index d700a97de6..2772246d72 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -3906,4 +3906,5 @@ Última modificação Nome: Z – A Nome: A – Z + Ícones de início/fim \ No newline at end of file From f7de137011fb5bb40b382fcff7bbbbccc3830dfd Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Sat, 3 Oct 2020 16:08:36 +0000 Subject: [PATCH 0422/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 115 ++++++++++++++++--------------- 1 file changed, 58 insertions(+), 57 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 13d5ddd215..7419222d0a 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -71,7 +71,7 @@ Ближайшие города Выберите город Поиск почтового индекса - Аудио⁣заметка + Запись аудио⁣ Записать видео Фотозаметка OSM-заметка @@ -233,7 +233,7 @@ Сохранить фильтр Удалить фильтр Новый фильтр - Изменить позицию + Изменение позиции Текущий путь Навигация OsmAnd Live Уровень заряда батареи @@ -318,7 +318,7 @@ Удалить эту запись? недоступно Аудиозаметка - Видеозаметка + Запись видео Слой аудиозаписей Запись не может быть воспроизведена. Удалить запись @@ -328,7 +328,7 @@ Аудиозаметки OsmAnd-плагин для линий высот Измерение расстояний - Нажмите «Использовать местоположение…» чтобы добавить заметку к данному местоположению. + Нажмите «Использовать местоположение…» для добавления заметки к месту. Аудиозаметки Создавайте аудио-, видео- и фотозаметки в поездке, используя виджет или контекстное меню. Аудио/видеозаметки @@ -505,7 +505,7 @@ Голосовые подсказки (TTS) Голосовые подсказки (записанные) Данные POI - Голос TTS + TTS Новый поиск Размер текста для названий на карте: Размер текста @@ -726,13 +726,13 @@ Карта памяти доступна только для чтения. \nТеперь можно только просматривать предварительно загруженную карту, а не загружать новые области. Файл распаковывается… - Направо и прямо - Резко направо и прямо - Плавно направо и прямо - Налево и прямо - Резко налево и прямо - Плавно налево и прямо - Выполните разворот, затем прямо + Направо + Резко направо + Плавно направо + Налево + Резко налево + Плавно налево + Выполните разворот Двигайтесь прямо Продолжить Загрузить детальные карты регионов @@ -864,7 +864,7 @@ 3D вид Показать последние использованные POI на карте. Показывать POI - Выберите источник онлайн или кешированных тайлов карты + Выберите источник онлайн- или кешированных тайлов карт. Растровые карты Источник карты Использовать интернет @@ -901,7 +901,7 @@ Дом Пересечение улиц Обновить карту - Создать POI + POI Да Отмена Нет @@ -1163,7 +1163,7 @@ Привязываться к дорогам во время навигации. Привязка к дороге Промежуточный пункт %1$s слишком далеко от ближайшей дороги. - Достигнут промежуточный пункт + Вы прибыли в промежуточный пункт Промежуточный пункт Промежуточный пункт Конец маршрута слишком далеко от ближайшей дороги. @@ -1178,10 +1178,10 @@ Достопримечательности Последний промежуточный пункт Первый промежуточный пункт - Добавить последним промежуточным пунктом - Добавить первым промежуточным пунктом + Последний промежуточный пункт + Первый промежуточный пункт Заменить пункт назначения - Пункт назначения уже задан: + Вы уже задали пункт назначения Пункт %1$s Точки маршрута Промежуточный пункт %1$s @@ -1201,7 +1201,7 @@ Настройки аудио и видео Изменить порядок Просмотр - Сделать фото + Снимок Сделать фото Синхронизация треков и медиазаметок с вашим аккаунтом Dropbox. Плагин Dropbox @@ -1239,7 +1239,7 @@ Укажите адрес Выбор избранной Модификации OSM - Выбирать + Выбрать OsmAnd карты и навигация OsmAnd+ карты и навигация Уменьшает «шум» компаса, но добавляет инерцию. @@ -1272,10 +1272,10 @@ Резервное копирование как правка OSM высота OsmChange-файл создан за %1$s - * Нажмите, чтобы отметить точку. -\n* Удерживайте нажатие на карте, чтобы удалить предыдущую точку. -\n* Удерживайте нажатие на точке, чтобы просмотреть и добавить описание. -\n* Нажмите на виджет измерения, чтобы увидеть больше действий. + * Нажмите, чтобы отметить точку. +\n* Нажмите и удерживайте карту, чтобы удалить предыдущую точку. +\n* Удерживайте точку для просмотра и добавления описания. +\n* Нажмите на виджет измерения для других действий. Использовать магнитный датчик вместо датчика ориентации. Другие Контурные линии @@ -1301,9 +1301,9 @@ Дорожные предупреждения Очистить промежуточные пункты Оставить промежуточные пункты - К: + Назначение: Через: - От: + Отправление: Промежуточные пункты уже заданы. Названия улиц (TTS) Объявлять… @@ -1345,9 +1345,9 @@ Симуляция использования рассчитанного маршрута Симуляция использования трека GPX Без автомасштаба - Ближний план - Средний план - Дальний план + К ближнему плану + К среднему плану + К дальнему плану Избегать автомагистралей Без автомагистралей Предпочитать автомагистрали @@ -1386,7 +1386,7 @@ Задать пункт назначения Предпочтения маршрута Информация про маршрут - Добавить как новый пункт назначения + Добавить пункт назначения Использовать показанный путь для навигации? Рассчитать сегмент маршрута OsmAnd без интернета Рассчитать маршрут OsmAnd для первого и последнего сегмента маршрута @@ -1667,7 +1667,7 @@ Моё местоположение Статус GPS Точки - Место для парковки + Парковка УДАЛИТЬ ТЕГ Редактировать группу Вам необходимо подключение к сети для установки этого плагина. @@ -2036,7 +2036,7 @@ Обновить сейчас Приложение не имеет разрешения на использование SD-карты Доступные карты - Начальный пункт + Пункт отправления Не выбрано Размер хранилища Звук @@ -2134,7 +2134,7 @@ Переместить ↑ Переместить ↓ Завершить навигацию - Избегать дорог + Избегать Публичное имя Поддерживаемый регион Введите публичное имя @@ -2289,8 +2289,8 @@ Добавить фото Разрешения Онлайн-фото - Здесь нет фотографий. - Поделитесь вашим просмотром улиц через Mapillary. + Здесь нет фото. + Поделитесь своими уличными видами через Mapillary. Виджет Mapillary Позволяет быстро внести свой вклад в Mapillary. Фото с улиц онлайн для каждого. Открывайте места, взаимодействуйте, запечатлейте весь мир. @@ -2337,7 +2337,7 @@ Измерить расстояние Добавьте хотя бы одну точку. Фотография Mapillary - Улучшить фотопокрытие через Mapillary + Улучшить фотопокрытие в Mapillary Скрыть, начиная с уровня масштабирования Прозрачно-розовый Берберский @@ -2470,7 +2470,7 @@ Полноэкранный режим Отметить пройденным Файл %1$s не содержит путевых точек, импортировать его как трек? - Выберите трек, чтобы добавить в маркеры его точки. + Выберите трек, чтобы добавить в маркеры его точки. Трек путевых точек Направо Налево @@ -2520,14 +2520,14 @@ \n• Поддержка промежуточных точек маршрута \n• Запись собственного или отправка GPX трека и следование ему \n - Карта -\n• Отображает POI (точки интереса) около вас -\n• Адаптирует карту в направлении вашего движения (или компаса) -\n• Показывает, где вы находитесь и куда вы смотрите -\n• Делитесь своим расположением, чтобы друзья смогли найти вас -\n• Сохраняет ваши самые важные места в избранных -\n• Позволяет вам выбрать как отображать названия на карте: на английском, местным или с фонетическим написанием -\n• Отображает специальные онлайн-тайлы, спутниковые снимки (с Bing), различные метки, как туристические/навигационные треки GPX и дополнительные слои с настраиваемой прозрачностью + Карта +\n• Отображает POI (точки интереса) вокруг вас +\n• Поворачивает карту по направлению движения (или компаса) +\n• Показывает вашу позицию и направление взгляда +\n• Делитесь вашим местоположением, чтобы вас могли найти друзья +\n• Сохраняет важные для вас места в избранных +\n• Позволяет выбрать способ отображения названий на карте: на английском, местное или фонетическое написание. +\n• Отображает специальные онлайн-тайлы, спутниковые снимки (Bing), различные метки, как туристические/навигационные треки GPX и дополнительные слои с настраиваемой прозрачностью \n Катание на лыжах \n• OsmAnd-плагин лыжные карты позволяет видеть лыжные трассы с уровнем сложности и некоторой дополнительной информацией, как расположение подъёмников и других объектов. @@ -2670,7 +2670,7 @@ Текущий Добавляет промежуточную остановку Добавляет начальную остановку - Перемещает пункт назначения и создаёт промежуточную точку + Добавляет новый пункт назначения, делая выбранный ранее промежуточной точкой Показать закрытые заметки Показать/скрыть заметки OSM на карте. GPX — подходит для экспорта в JOSM и другие OSM редакторы. @@ -2802,7 +2802,7 @@ Модификация стиля по умолчанию для увеличения контраста пешеходных и велосипедных дорог. Использует старые цвета Mapnik. Получите OsmAnd Live, чтобы разблокировать все функции: ежедневные обновления карт с неограниченной загрузкой, все платные и бесплатные плагины, Википедия, Викигид и многое другое. Промежуточное время прибытия - Промежуточное время + Прибытие в промежуточный пункт Редактировать действие Пожалуйста, пришлите скриншот этого уведомления на support@osmand.net Редактировать точку @@ -2855,7 +2855,7 @@ Для продолжения дайте OsmAnd разрешение на определение местоположения. Чёрный Поиск улицы - Сначала выберите город/населённый пункт/местность + Укажите город/место/район Восстановить Маркеры, добавленные как группа избранных или путевых точек GPX и отмеченные как пройденные, останутся на карте. Если группа не активна, маркеры исчезнут с карты. Оставить пройденные маркеры на карте @@ -2917,13 +2917,13 @@ Предыдущий маршрут Сначала задайте пункт назначения Поменять - Показать больше + Ещё Отображаемые треки Показать/скрыть треки Скрыть треки Показать треки Время суток - Поворот за поворотом + По шагам Типы дорог Переключатель, чтобы показать или скрыть выбранные треки на карте. На %1$s @@ -3066,7 +3066,7 @@ Метро Лошадь Вертолёт - Вы можете добавить собственную модифицированную версию routing.xml в ..osmand/routing + Вы можете добавить свою модифицированную версию файла routing.xml в ..osmand/routing Выберите значок Лыжи Тип: %s @@ -3158,7 +3158,7 @@ Сбой Внедорожник Выбор настроек карты для профиля - Выбор настроек экрана для профиля + Настройка элементов экрана для профиля Выбор настроек навигации для профиля Выбор верхней границы изменений Использовать бесконтактный датчик (сенсорный выключатель) @@ -3233,7 +3233,7 @@ Карта во время навигации Скорость движения, размеры, масса транспортного средства Параметры транспортного средства - Голосовые оповещения происходят только во время навигации. + Голосовые инструкции работают только при навигации. Навигационные инструкции и объявления Голосовые подсказки Экранные оповещения @@ -3319,7 +3319,7 @@ «%1$s» уже существует. Перезаписать\? Не удалось экспортировать профиль. Импорт профиля - Чтобы добавить профиль, откройте его с помощью OsmAnd. + Для добавления профиля откройте файл профиля с помощью OsmAnd. %1$s импортирован. Белый Невозможно запустить механизм преобразования текста в речь. @@ -3366,7 +3366,7 @@ Маршруты, подготовленные для фристайла или катания только на коньках без классических треков. Разрешить только классические маршруты Маршруты, подготовленные только для классического стиля без конькобежных трасс. Сюда входят маршруты, подготовленные небольшим снегоходом с более свободной лыжнёй и трассами, подготовленные вручную лыжниками. - Предпочтительный уровень сложности маршрутов. Возможно использование более сложных или лёгких путей, если они короче. + Предпочтительный уровень сложности маршрутов. Более сложные или лёгкие трассы могут использоваться, если они короче. Включать на повороте Класс 1 Класс 2 @@ -3580,7 +3580,7 @@ Примечание: проверка скорости > 0: большинство модулей GPS сообщают значение скорости только в том случае, если алгоритм определяет, что вы движетесь, и ничего, если вы не перемещаетесь. Следовательно, использование параметра > 0 в этом фильтре в некотором смысле приводит к обнаружению факта перемещения модуля GPS. Но даже если мы не производим данную фильтрацию во время записи, то всё равно эта функция используется при анализе GPX для определения скорректированного расстояния, то есть значение, отображаемое в этом поле, является расстоянием, записанным во время движения. Разделение записи Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. - В этом случае будут записываться только точки, измеренные с минимальной точностью (в метрах/футах согласно настройкам устройства). Точность — это близость измерений к истинному местоположению и не имеет прямого отношения к точности, подразумевающейся под разбросом повторных замеров. + "Будут записываться только точки, измеренные с указанием минимальной точности (в метрах/футах —д зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться. Для визуализации крутизны рельефа используются цвета. Подробнее об уклонах можно прочитать в %1$s. @@ -3803,7 +3803,7 @@ Добавить к треку Для продолжения задайте рабочие дни Маршрут между точками - Составить маршрут + Составление маршрута Выберите способ разбиения: по времени или по расстоянию. Интервал между метками расстояния или времени на треке. Своё @@ -3901,4 +3901,5 @@ Последнее изменение Имя: Я - А Имя: А - Я + Значки старта и финиша \ No newline at end of file From f98649f669c2f14d4c8f8a015e2b27da79238256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 2 Oct 2020 17:22:25 +0000 Subject: [PATCH 0423/1366] Translated using Weblate (Turkish) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-tr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 9713a69b10..a63ed6830b 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3859,4 +3859,5 @@ Son değiştirme İsim: Z – A İsim: A – Z + Başlangıç/bitiş simgeleri \ No newline at end of file From d088bf832448a02c45ee325a883c00d1b16d1052 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Fri, 2 Oct 2020 18:33:05 +0000 Subject: [PATCH 0424/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 905af29b00..8e63be02be 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -3899,4 +3899,5 @@ Востаннє змінено За назвою: Я — А За назвою: А — Я + Піктограми початку/завершення \ No newline at end of file From d4dba5a489f1ba46b58339169645b1e60cc82156 Mon Sep 17 00:00:00 2001 From: Mirco Zorzo Date: Sat, 3 Oct 2020 07:56:36 +0000 Subject: [PATCH 0425/1366] Translated using Weblate (Italian) Currently translated at 90.2% (3149 of 3488 strings) --- OsmAnd/res/values-it/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 653874de7d..5543e68444 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -3903,4 +3903,5 @@ Cronologico Nome: Z – A Nome: A – Z + Icona Partenza/Arrivo \ No newline at end of file From df4951406976136d922d2561a532655806e95106 Mon Sep 17 00:00:00 2001 From: Roberto GEB Date: Sat, 3 Oct 2020 14:34:44 +0000 Subject: [PATCH 0426/1366] Translated using Weblate (Spanish) Currently translated at 99.2% (3463 of 3488 strings) --- OsmAnd/res/values-es/strings.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 7b571077f7..6041f2a95e 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -2006,14 +2006,14 @@ Necesario para descargar mapas. Buscando la ubicación… Espacio libre - Almacenamiento de datos de OsmAnd (para mapas, archivos GPX, etc.): %1$s. + Almacenamiento de datos de OsmAnd (para mapas, trazas, etc.): %1$s. Conceder permiso Permitir el acceso a la ubicación Obtenga direcciones y descubra lugares nuevos, sin una conexión a Internet Encontrar mi ubicación Omite la búsqueda de nuevas versiones o descuentos relacionados con OsmAnd. Ocultar nuevas versiones - Suscripción mensual. Puede cancelarlo en cualquier momento en Google Play. + Suscripción mensual. Puedes cancelarla en cualquier momento en Google Play. Donación a la comunidad de OSM Parte de tu donación se envía a los contribuidores a OSM. El coste de la suscripción sigue siendo el mismo. La suscripción permite actualizaciones cada hora, día o semana y descargas ilimitadas para los mapas de todo el mundo. @@ -2029,8 +2029,8 @@ Subir PDI Cálculo de la ruta Ciudad o región - Sin archivos GPX aún - También puedes añadir archivos GPX a la carpeta + No tienes archivos de trazas aún + También puedes añadir archivos de trazas a la carpeta Añadir más… Aspecto Notificaciones @@ -2044,7 +2044,7 @@ Usar autopistas Permite usar autopistas. Activar la grabación rápida - Muestra una notificación del sistema que permite la grabación del viaje. + Muestra una notificación del sistema que permite empezar la grabación del viaje. Viaje Grabado Grabar @@ -2417,7 +2417,7 @@ Abrir Mapillary Instalar Mejorar cobertura de fotos con Mapillary - Instala Mapillary para añadir una o más fotos a esta ubicación del mapa. + Instala Mapillary para añadir fotos a esta ubicación del mapa. Fotos en línea Imagen de Mapillary Permisos @@ -2492,7 +2492,7 @@ Ordenar por Elige cómo se indica la distancia y dirección a los marcadores del mapa en el mapa: Umbral de orientación del mapa - Velocidad a partir de la cual la orientación del mapa cambia de «Dirección del movimiento» a «Dirección de la brújula». + Selecciona la velocidad a partir de la que la orientación del mapa cambia de «Dirección del movimiento» a «Dirección de la brújula». Todos los marcadores del mapa movidos al historial Marcador del mapa movido al historial Marcador del mapa movido a los activos @@ -2601,8 +2601,8 @@ Pulsa un marcador en el mapa para moverlo al primer lugar de los marcadores activos, sin abrir el menú contextual. Activar «Una pulsación» ¡Toma notas! - Añade una nota de audio, vídeo o foto para cada punto del mapa, utilizando el widget o el menú contextual. - Notas por fecha + Añade una nota de audio, vídeo o foto a cualquier punto del mapa, utilizando el control o el menú contextual. + Notas A/V por fecha Por fecha Por tipo Aquí hay: @@ -2954,7 +2954,7 @@ Autopista Carretera/ruta estatal Carretera principal - Calle residencial + Calle Vía de servicio Acera Camino rural @@ -3847,7 +3847,7 @@ Distancia umbral Perfil de navegación Selecciona un archivo de traza al que agregar el nuevo segmento. - Imágenes a pie de calle + Fotos a pie de calle ¿Estás seguro de que quieres descartar todos los cambios en la ruta planeada cerrándola\? En caso de dirección contraria Guardar como nuevo archivo de traza From 3c65a8e986bbd610f7ad19f83873c7c97add4885 Mon Sep 17 00:00:00 2001 From: ace shadow Date: Fri, 2 Oct 2020 19:37:10 +0000 Subject: [PATCH 0427/1366] Translated using Weblate (Slovak) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-sk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index a9fbf672f4..9c2a49a143 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -3902,4 +3902,5 @@ Naposledy zmenené Názov: Z – A Názov: A – Z + Ikony štartu/cieľa \ No newline at end of file From fe68e826a5e294e2defd2675b99a53cd3680f634 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Fri, 2 Oct 2020 18:34:54 +0000 Subject: [PATCH 0428/1366] Translated using Weblate (Hebrew) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-iw/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 7f556c9926..8f3eb5c17c 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -3909,4 +3909,5 @@ שינוי אחרון שם: ת – א שם: א – ת + סמלי התחלה/סיום \ No newline at end of file From 6fd475851662bc8ff26080c3e5d8460ab97422a3 Mon Sep 17 00:00:00 2001 From: ovl-1 Date: Sat, 3 Oct 2020 14:05:19 +0000 Subject: [PATCH 0429/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 17.4% (607 of 3488 strings) --- OsmAnd/res/values-nb/strings.xml | 93 ++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index 32c34dd961..b334985f7d 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -1650,7 +1650,7 @@ Valgt valgte FJERN MERKELAPPEN - Last ned nattlige utviklerversjoner. + Last ned aktuelle utviklingsversjoner. Byggversjoner Spesifiser en mellomtjener. Innlogget som %1$s @@ -2142,7 +2142,7 @@ Vis/skjul OSM-notater Vis OSM-notater Skjul OSM-notater - Å trykke denne handlingsknappen viser eller skjuler OSM-notater på kartet. + Knapp til å vise eller skjule OSM-notater på kartet. Takk for at du kjøpte \'Havdybdekonturer\' Havdybdekonturer Havdybdekonturer @@ -2257,17 +2257,17 @@ Rediger handling Slett handling Navneforvalg - Trykk på denne handlingsknappen legger til en kartmarkør i skjermsenteret. - Trykking på denne handlingsknappen legger til et GPX-rutepunkt i midten av skjermen. - Trykking på denne handlingsknappen legger til et lydnotat i midten av skjermen. - Trykking på denne handlingsknappen legger til et videonotat i midten av skjermen. - Trykking på denne handlingsknappen legger til et bildenotat i midten av skjermen. - Trykking på denne handlingsknappen legger til et OSM-notat i midten av skjermen. - Trykking på denne handlingsknappen slår av eller på taleveiledning under navigering. - Trykking på denne handlingsknappen legger til en parkeringsplass i midten av skjermen. + En knapp for å legge til en kartmarkør i skjermsenteret. + En knapp for å legge til et GPX-rutepunkt i midten av skjermen. + En knapp for å legge til et lydnotat i midten av skjermen. + En knapp for å legge til et videonotat i midten av skjermen. + En knapp for å legge til et bildenotat i midten av skjermen. + En knapp for å legge til et OSM-notat i midten av skjermen. + En knapp til å slå av eller på taleveiledning under navigering. + En knapp for å legge til en parkeringsplass i midten av skjermen. Vis en midlertidig dialog " lagret i " - Trykking på denne handlingsknappen viser eller skjuler favorittpunktene på kartet. + En knapp til å vise eller skjule favorittpunktene på kartet. Opprett elementer La stå tomt for å bruke adressen eller stedsnavnet. Denne meldingen inkluderes i kommentarfeltet. @@ -2341,10 +2341,10 @@ Et trykk på kartet skjuler/viser kontrollknappene og miniprogrammene. Marker som passert Kunne ikke endre notatet. - Trykking på denne handlingsknappen slår av/på automatisk kartforstørrelse i henhold til hastigheten din. - Trykking på denne handlingsknappen gjør skjermsenteret til rutemål, ethvert tidligere valgt reisemål blir det siste mellomliggende målet. - Trykking på denne handlingsknappen gjør skjermsenteret det nye rutemålet, og erstatter det tidligere valgte reisemålet (hvis noe). - Trykking på denne handlingsknappen gjør skjermsenteret til det første mellomliggende reisemålet. + Knapp til å slå av eller på hastighetsbasert auto-zoom. + En knapp for å gjøre skjermsenteret til rutemålet, et tidligere valgt reisemål blir det siste mellomliggende målet. + En knapp for å gjøre skjermsenteret til det nye rutemålet, erstatter det tidligere valgte reisemålet (hvis noe). + En knapp for å gjøre skjermsenteret til det første mellomliggende reisemålet. Abonner på vår e-postliste om programrabatter og få tre kartnedlastinger til! Havdybdepunkter for sørlige halvkule Havdybdepunkter for nordlige halvkule @@ -2382,7 +2382,7 @@ Aktiver \"sjøkartvisning\" -tillegget Navnet inneholder for mange store bokstaver. Fortsett\? Legg til interessepunkt - Trykking på denne handlingsknappen viser eller skjuler interessepunkter på kartet. + En knapp til å vise eller skjule interessepunkter på kartet. En knapp til å bla gjennom listen nedenfor. Fyll ut alle parametere Ved å trykke lenge og dra knappen endres dens plassering på skjermen. @@ -2408,7 +2408,7 @@ Alle punkter i gruppen GPX-fil med de valgte notatenes koordinater og data. GPX-fil med alle notaters koordinater og data. - Trykking på denne handlingsknappen legger til et interessepunkt i midten av skjermen. + En knapp for å legge til et interessepunkt i midten av skjermen. Åpen fra Åpen til Stenger @@ -2859,10 +2859,10 @@ Du bruker {0} kart levert av OsmAnd. Vil du starte fullversjonen av OsmAnd\? Kjør OsmAnd\? Guaraní - Vekselvender mellom dag- og nattmodus i OsmAnd + En knapp til å skifte mellom dag- og nattmodus i OsmAnd. Dagmodus Nattmodus - Veksle dag-/nattmodus + Bytt dag/natt-modus Offentlig transport Sett reisemål Legg til mellomliggende @@ -3256,7 +3256,7 @@ OsmAnd-profil: %1$s Profil-import Hvit - Brukes til å estimere ankomsttid for ukjente veityper, og for å begrense farten på alle veier (kan endre rute) + Estimerer ankomsttid for ukjente veityper og begrenser farten for alle veier (kan påvirke ruting) Spor-lagringsmappe Spor kan lagres i \'rec\'-mappen, månedlige eller daglige mapper. Ta opp spor til \'rec\'-mappen @@ -3286,13 +3286,13 @@ \n \n Du kan bruke denne endringen på alle eller bare på den valgte profilen. - En bryter for å vise eller skjule koter på kartet. + Knapp som viser eller skjuler koter på kartet. Eksporter profil \"%1$s\" finnes allerede. Overskriv\? Kunne ikke eksportere profil. Legg til en profil ved å åpne profilfilen med OsmAnd. - %1$s feil under import: %2$s - %1$s ble importert. + %1$s importfeil: %2$s + %1$s importert. Bytt %1$s og %2$s Startpunkt Isvei @@ -3345,20 +3345,20 @@ Åpen plasseringskode (OLC) Valgt format vil benyttes i programmet. Denne innstillingen er valgt som forvalg for profiler: %s - Bruk kun for «%1$s» - Bruk for alle profiler + Bruk kun for \"%1$s\" + Bruk på alle profiler Analyseinstrumenter Vis kart på låseskjermen under navigering. - Innstillinger for ruting i valgt profil «%1$s». + Innstillinger for ruting i den valgte profilen \"%1$s\". Tidsavbrudd etter oppvåkning Varsler vises nede til venstre under navigering. Kart under navigasjon Kart under navigasjon Stemmekunngjøringer finner kun sted under navigasjon. Navigasjonsinstruks og kunngjøringer - Stemmekunngjøringer + Talemeldinger Sett opp ruteparameter - Ruteparameter + Ruteparametere Last ned detaljert %s-kart for å vise dette området. Slede Akebrett @@ -3398,13 +3398,13 @@ Personlig Laster ned %s Tykk - For ørkener og andre tynt befolkede områder. Høyere detaljnivå. + For ørkener og andre tynt befolkede områder. Mer detaljert. Posisjonsikon under bevegelse Posisjonsikon i hviletilstand Trykk på \'Bruk\' sletter fjernede profiler permanent. Hovedprofil Velg farge - Du kan ikke slette forvalgsprofilene, men du kan skru dem av før dette steget, eller flytte dem til bunnen. + OsmAnd-Standardprofiler kan ikke slettes, men deaktiveres (på forrige skjermbilde), eller bli sortert til bunnen. Rediger profiler Navigasjonstype har innvirkning på regler for ruteberegning. Profilutseende @@ -3418,8 +3418,8 @@ %1$s %2$s Importer profil OSM - \"%1$s\"-filen inneholder ingen ruteplanleggingsregler, velg en annen fil. - Ustøttet filtype. Du må velge en fil med %1$s-filendelse. + Ingen rutingsregler i \'%1$s\'. Velg en annen fil. + Velg en støttet fil med %1$s-endelse isteden. Importer fra fil Importer ruteplanleggingsfil Navigasjon, loggingsnøyaktighet @@ -3429,7 +3429,7 @@ Tillater deg å dele nåværende plassering ved bruk av turopptak. Nettbasert sporing Loggingsnøyaktighet - Du kan finne alle dine innspilte spor i %1$s, eller i OsmAnd-mappen. + Dine innspilte spor er i %1$s, eller i OsmAnd-mappen. Du finner alle dine OSM-notater i %1$s. Videonotater Bildenotater @@ -3601,7 +3601,7 @@ Sjekk og del detaljert loggføring fra programmet Bruk systemets skjermtidsavbrudd Programtillegg av - Ingen omregning + Ingen ny beregning Angi et navn for profilen Velg data å importere. Du kan lese mer om løyper i %1$s. @@ -3662,7 +3662,7 @@ Fotoboks-interessepunkter Avinstaller Du kan sette fartøyhøyde for å unngå lave broer. Hvis broen endrer høyde, brukes høyden i åpen tilstand. - Slett neste målpunkt + Slett nærmeste målpunkt Navngi punktet Vis/skjul Mapillary Skjul Mapillary @@ -3675,19 +3675,19 @@ Navigasjonsinstruks - + Avinstaller og start på nytt Rullestol Gokart Planlegg en rute Du får tilgang til disse handlingene ved å trykke på knappen “%1$s”. - Slå på for å stille inn zoomnivået på kartet med enhetens volumknapper. + Styr zoomnivået på kartet med enhetens volumknapper. Det tillagte punktet vil ikke være synlig på kartet, siden den valgte gruppen er skjult, du kan finne det i \"%s\". Scooter Rullestol framover - Du må definere arbeidsdagene for å fortsette + Still inn arbeidsdager for å fortsette Legg til i et spor - Vis ikoner for start-mål + Vis ikoner for start og mål Velg bredde Velg intervallet hvor markeringer med avstand eller tid på sporet vil vises. Velg det ønskede oppdelingsalternativet: etter tid eller etter avstand. @@ -3702,7 +3702,7 @@ Sist redigert Importer spor Åpne eksisterende spor - Velg en sporfil for åpning. + Velg en sporfil for å åpne. Snu rute Overskriv spor Hele sporet blir beregnet på nytt med den valgte profilen. @@ -3722,7 +3722,7 @@ Importer eller ta opp sporfiler Følg spor Velg sporfil å følge - Velg sporfil å følge, eller importer en. + Velg sporfil å følge eller importer fra enheten din. Velg et annet spor Starten av sporet Nærmeste punkt @@ -3747,4 +3747,15 @@ Sist endret Navn: Å - A Navn: A - Å + Start/mål-ikoner + Lagre som ny sporfil + Legg til i en sporfil + Spor + Spor + Spor + Turopptak + Lagre som sporfil + %s sporfiler valgt + Sett turopptak på pause + Gjenoppta turopptak \ No newline at end of file From a0afcb514c23d6c4c6d95d438c2dbb4095b0d386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sat, 3 Oct 2020 13:04:58 +0000 Subject: [PATCH 0430/1366] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 17.4% (607 of 3488 strings) --- OsmAnd/res/values-nb/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index b334985f7d..9c24c2aa7c 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -751,7 +751,7 @@ Sikker modus Programmet kjører i sikker modus (skru det av i \'Innstillinger\'). Talemeldinger stopper midlertidig musikkavspilling. - Avbryt musikk + Sett musikk på pause Offentlig Optimaliser kart for Vis fra zoom-nivå (krever kotedata): @@ -3627,7 +3627,7 @@ \nSkru av ubrukte programtillegg for å skjule alle deres styringskontroller. %1$s. Disse elementene er skjult fra menyen, men de representerte valgene eller programtilleggene vil fortsette å virke. Velg språkene Wikipedia-artikler skal vises på i kartet. Du kan bytte mellom alle tilgjengelige språk mens du leser artikkelen. - Veiledning til kartets merking. + Veiledning til kartets symbolbruk. Ruteplanlegging Minsteavstand for å beregne rute på nytt OsmAnd har allerede elementer med samme navn som de i importen. From 4a22b8751703e8c227b20b50e337027c5b482294 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Fri, 2 Oct 2020 18:30:34 +0000 Subject: [PATCH 0431/1366] Translated using Weblate (Sardinian) Currently translated at 99.7% (3480 of 3488 strings) --- OsmAnd/res/values-sc/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index accd1282b4..cf47d42af8 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3903,4 +3903,5 @@ Ùrtima modìfica Nùmene: Z – A Nùmene: A – Z + Iconas de incumintzu/fine \ No newline at end of file From 2e96ff82864a252745af44e6fae010df29a1ee54 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Fri, 2 Oct 2020 18:34:44 +0000 Subject: [PATCH 0432/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-uk/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml index 4375b43720..493e631c02 100644 --- a/OsmAnd/res/values-uk/phrases.xml +++ b/OsmAnd/res/values-uk/phrases.xml @@ -3832,4 +3832,5 @@ Невеликі електроприлади Вулик Насіннєвий магазин + СПГ \ No newline at end of file From 40ac63abac08912d95c771eacca44c580b2556cf Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Fri, 2 Oct 2020 18:32:12 +0000 Subject: [PATCH 0433/1366] Translated using Weblate (Sardinian) Currently translated at 99.4% (3805 of 3825 strings) --- OsmAnd/res/values-sc/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sc/phrases.xml b/OsmAnd/res/values-sc/phrases.xml index df52122c1e..62f4c1ece8 100644 --- a/OsmAnd/res/values-sc/phrases.xml +++ b/OsmAnd/res/values-sc/phrases.xml @@ -3840,4 +3840,5 @@ Eletrodomèsticos minores Tabellone de sas tzucadas Ricàrriga de abba potàbile + GNL (LNG) \ No newline at end of file From b9b2f615bd7fdfdb0701f8fc3e36039e68b61ddd Mon Sep 17 00:00:00 2001 From: ace shadow Date: Fri, 2 Oct 2020 23:24:11 +0000 Subject: [PATCH 0434/1366] Translated using Weblate (Slovak) Currently translated at 94.3% (3609 of 3825 strings) --- OsmAnd/res/values-sk/phrases.xml | 67 ++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-sk/phrases.xml b/OsmAnd/res/values-sk/phrases.xml index 14f1a5e6be..fc275bf7c3 100644 --- a/OsmAnd/res/values-sk/phrases.xml +++ b/OsmAnd/res/values-sk/phrases.xml @@ -3274,9 +3274,9 @@ Mahájana Zamrznutí Turistická/trasová značka - - - + Ko-Shintō + Jizō + Prasat Apoštolská cirkev Radiačná onkológia Nebezpečenstvo @@ -3567,4 +3567,65 @@ Šípka Vibrácie Tlak + Skvapalnený zemný plyn + Obchod s orechmi + Včelí úľ + Cestovný poriadok + Odjazdy v reálnom čase + Intervaly + Áno + Tabuľa odjazdov: nie + Výťah + Mestský blok + Mestský obvod + Šípka: nie + Nie + Áno + Vibrovanie: nie + Výber hotovosti: cudzie karty + Výber hotovosti: minimálny nákup + Poplatok za výber hotovosti: nie + Poplatok za výber hotovosti: áno + Výber hotovosti: nie je vyžadovaný nákup + Výber hotovosti: vyžadovaný nákup + Mena výberu hotovosti + Limit výberu hotovosti + Typ výberu hotovosti: samoobslužný výber + Typ výberu hotovosti: pri pokladni + Operátor výberu hotovosti + Výber hotovosti + Výber hotovosti: áno + Zmiešané: nie + Zmiešané: áno + Ľad: nie + Ľad: áno + Trvanlivosť vodného zdroja: núdzový + Trvanlivosť vodného zdroja: trvalý + Ordinácia pôrodnej asistentky + Opatrovateľská služba + Ordinácia psychológa + Ordinácia liečiteľa + Ordinácia terapeuta + Ordinácia lekára + Zdravotná služba: testovanie: nie + Zdravotná služba: testovanie: áno + Zdravotná služba: podpora: nie + Zdravotná služba: podpora: áno + Zdravotná služba: očkovanie: nie + Zdravotná služba: očkovanie: áno + Zdravotná služba: prevencia: nie + Zdravotná služba: prevencia: áno + Zdravotná služba: starostlivosť o deti: nie + Zdravotná služba: starostlivosť o deti: áno + Zdravotná služba: vyšetrenie: nie + Zdravotná služba: vyšetrenie: áno + Zdravotná služba: poradenstvo: nie + Zdravotná služba: poradenstvo: áno + Zdravotná služba: opatrovateľstvo: áno + Zdravotná služba: opatrovateľstvo: nie + Správanie + Športová medicína + Malé elektrické spotrebiče + Tabuľa odjazdov/cestovný poriadok + Doplnenie pitnej vody \ No newline at end of file From 8856e9c4c57eb38dc6799588e263f7e83ab049a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 2 Oct 2020 21:42:44 +0000 Subject: [PATCH 0435/1366] Translated using Weblate (Estonian) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-et/phrases.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml index 6d72d50576..4cb42eee67 100644 --- a/OsmAnd/res/values-et/phrases.xml +++ b/OsmAnd/res/values-et/phrases.xml @@ -524,7 +524,7 @@ Oktaan 95 Oktaan 98 Oktaan 100 - CNG + Surugaas 1:25 kütus 1:50 kütus Etanool @@ -3826,4 +3826,5 @@ Väikesed elektriseadmed Mesitaru Pähklipood + Veeldatud maagaas \ No newline at end of file From da688ccbb8d3722f1c087fc51bd2df8af7cb5063 Mon Sep 17 00:00:00 2001 From: Franco Date: Sat, 3 Oct 2020 15:49:54 +0000 Subject: [PATCH 0436/1366] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 99f789d362..21492272da 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -3907,4 +3907,5 @@ Último modificado Nombre: Z – A Nombre: A – Z + Iconos de inicio/fin \ No newline at end of file From 1ffa3b7f703aac35a6585438d4274c0f7099bb7c Mon Sep 17 00:00:00 2001 From: Franco Date: Sat, 3 Oct 2020 15:51:06 +0000 Subject: [PATCH 0437/1366] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-es-rAR/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml index 4019b950b2..88c35ef6f9 100644 --- a/OsmAnd/res/values-es-rAR/phrases.xml +++ b/OsmAnd/res/values-es-rAR/phrases.xml @@ -3851,4 +3851,5 @@ Pequeños electrodomésticos Panal de abejas Frutos secos + Gas natural licuado \ No newline at end of file From c8b442fb716ab98da93c3ce1d0e7af25aa4f35ce Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Fri, 2 Oct 2020 22:30:57 +0000 Subject: [PATCH 0438/1366] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index a2c4186817..3807266c57 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -3899,4 +3899,5 @@ Última modificação Nome: Z – A Nome: A – Z + Ícones de início/término \ No newline at end of file From e63863342c665444d3c40439e6201432cb8aec74 Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Fri, 2 Oct 2020 22:32:22 +0000 Subject: [PATCH 0439/1366] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-pt-rBR/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml index dd7c249f87..07c80c478d 100644 --- a/OsmAnd/res/values-pt-rBR/phrases.xml +++ b/OsmAnd/res/values-pt-rBR/phrases.xml @@ -3844,4 +3844,5 @@ Pequenos aparelhos elétricos Colmeia Loja de nozes + GNL \ No newline at end of file From 1b061f6e79a9328a543ef9f2412a964e654b80ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sat, 3 Oct 2020 10:05:54 +0000 Subject: [PATCH 0440/1366] Translated using Weblate (Turkish) Currently translated at 66.5% (2547 of 3825 strings) --- OsmAnd/res/values-tr/phrases.xml | 125 +++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index ed3292f096..dc31464e79 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -45,7 +45,7 @@ Kullanıcı tanımlı Paleontolojik alan Fırın - Likör dükkanı + İçki dükkanı Peynir dükkanı Çikolata dükkanı Kahve dükkanı @@ -362,7 +362,7 @@ Çocuk bezi Araba aküsü Arabalar - Bisiklet + Bisikletler Depolama Çöp bertaraf Çöp tenekesi @@ -766,7 +766,7 @@ Tarımsal motorlar Demirci Bira fabrikası - Boat builder + Gemi yapımcısı Ciltçi Marangoz Halı satıcısı @@ -866,7 +866,7 @@ Gün işareti Mesafe işareti Havuz - Lezbiyen + Su seti Simgesel Yapı Deniz işareti, ışık Deniz işareti, büyük ışık @@ -2148,7 +2148,7 @@ Kostüm Geleneksel Takım elbise - Hamile + Hamilelik Nostalji Büyük beden Okul @@ -2443,4 +2443,119 @@ Tarihi tren istasyonu Tarihi çiftlik Pa (müstahkem maori yerleşimi) + Futsal (salon futbolu) + ATM: hayır + ATM: evet + Boks + Lakros + Disk iteleme oyunu + Squash (duvar tenisi) + Uzaktan kumandalı araba yarışı + Disk golf + Judo + Badminton + Karting + Netbol + Koşma + Gal oyunları + Dojo + Resmi adı + Araç park çatısı + Garaj bölmeleri + Tür: yüzey + Su ısıtıcısı: hayır + Su ısıtıcısı: evet + Mikrodalga fırın: hayır + Mikrodalga fırın: evet + Bilardo + Yüzme: hayır + Yüzme: evet + Tekne depolama + Referans numarası + Tünel numarası + Köprü numarası + Taşıma: evet + Uzunluk + Havai fişek mağazası + Elektronik onarımı + Hackerspace + Fitness istasyonu + Bina türü: piramit + Palyatif tıp + Davranış + Derinlik psikolojisi + Naturopati + Kayropraktik + Bitkisel tıp + Reiki + Geleneksel Çin tıbbı + Homeopati + Akupunktur + Yetişkin psikiyatrisi + Podoloji + Spor hekimliği + Manuel terapi + Konuşma terapisi + Klinik patoloji + Optometri + Bağımlılık tedavisi + Sağlık uzmanlığı: obstetrik (sezaryen): hayır + Obstetrik (sezaryen) + Sağlık uzmanlığı: sosyal pediatri: hayır + Sosyal pediatri + Sağlık uzmanlığı: obstetrik (doğum öncesi): hayır + Obstetrik (doğum öncesi) + Sağlık uzmanlığı: obstetrik (doğum sonrası): hayır + Obstetrik (doğum sonrası) + Sağlık uzmanlığı: tropikal tıp: hayır + Tropikal tıp + Onkoloji + Patolojik anatomi + Nükleer tıp + Endokrinoloji + Nöropsikiyatri + Beyin ve sinir cerrahisi + Nefroloji (böbrek hastalıkları) + Diş hekimliği + Gastroenteroloji + Tıbbi görüntüleme + Çene-yüz cerrahisi + Fiziksel tıp ve rehabilitasyon + Çocuk psikiyatrisi + İş terapisi + Biyokimya + Fizyoterapi + Ortodonti + Plastik cerrahi + Sağlık uzmanlığı: kaza ve acil tıp: hayır + Kaza ve acil tıp + Hamilelik + Diş, ağız ve çene-yüz cerrahisi + Göğüs hastalıkları + Anesteziyoloji + Osteopati + Klinik biyoloji + Travmatoloji + Kardiyoloji + Dermato-venereoloji + Nöroloji + Psikiyatri + Radyoterapi + Radyoloji + Genel cerrahi + Üroloji + Dermatoloji + Sağlık uzmanlığı: pediatri: hayır + Pediatri + Kulak burun boğaz + Ortopedi + İç hastalıkları + Jinekoloji + Oftalmoloji + Pratisyen doktor + Ağır yük araçları + Bisikletler + Konteynerler + Araçlar + Yolcular \ No newline at end of file From 25f8c31834efbc6784042a9445340c4389836a67 Mon Sep 17 00:00:00 2001 From: Franco Date: Sat, 3 Oct 2020 15:52:25 +0000 Subject: [PATCH 0441/1366] Translated using Weblate (Spanish (American)) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-es-rUS/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es-rUS/strings.xml b/OsmAnd/res/values-es-rUS/strings.xml index a7750a3b93..6ba4dcc29e 100644 --- a/OsmAnd/res/values-es-rUS/strings.xml +++ b/OsmAnd/res/values-es-rUS/strings.xml @@ -3904,4 +3904,5 @@ Nombre: Z – A Nombre: A – Z Último modificado + Iconos de inicio/fin \ No newline at end of file From 780adbfc7b7956d268cfd2b1762109a43a29e400 Mon Sep 17 00:00:00 2001 From: Franco Date: Sat, 3 Oct 2020 15:52:09 +0000 Subject: [PATCH 0442/1366] Translated using Weblate (Spanish (American)) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-es-rUS/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es-rUS/phrases.xml b/OsmAnd/res/values-es-rUS/phrases.xml index 25786f2488..8c0dbc2414 100644 --- a/OsmAnd/res/values-es-rUS/phrases.xml +++ b/OsmAnd/res/values-es-rUS/phrases.xml @@ -3851,4 +3851,5 @@ Tablero de partidas Frutos secos Panal de abejas + Gas natural licuado \ No newline at end of file From 47b4e7dd91a4be01cd49d68a00fb664f70d75f50 Mon Sep 17 00:00:00 2001 From: ssantos Date: Sat, 3 Oct 2020 12:42:16 +0000 Subject: [PATCH 0443/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-pt/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index e2866a9b26..de9490478b 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -3829,4 +3829,5 @@ Pequenos aparelhos elétricos Colmeia Loja de nozes + GNL \ No newline at end of file From f87aa144d3a1432915c81bbd89ffa92f58c6291f Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Sat, 3 Oct 2020 16:16:11 +0000 Subject: [PATCH 0444/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 7419222d0a..cdc7518bfc 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -126,7 +126,7 @@ Средняя скорость Время в движении Общее время - Максимальная + Макс. Отправление Прибытие Цвет From b51cab5591d4db04001453c33ed2cc743fbec9d4 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sat, 3 Oct 2020 19:28:42 +0200 Subject: [PATCH 0445/1366] Update SRTMPlugin.java --- OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index 808c541523..9138e9879d 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -359,7 +359,7 @@ public class SRTMPlugin extends OsmandPlugin { .setTitleId(R.string.shared_string_terrain, mapActivity) .setDescription(app.getString(terrainMode == TerrainMode.HILLSHADE ? R.string.shared_string_hillshade - : R.string.shared_string_slope)) + : R.string.download_slope_maps)) .setSelected(terrainEnabled) .setColor(terrainEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_hillshade_dark) From ec53a8fc12d9b700e8412f09b041741a0a4593b9 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sat, 3 Oct 2020 20:48:55 +0300 Subject: [PATCH 0446/1366] Finished huawei inapps --- OsmAnd/.gitignore | 3 + OsmAnd/build.gradle | 13 +- .../plus/inapp/InAppPurchaseHelperImpl.java | 10 + .../net/osmand/plus/inapp/CipherUtil.java | 4 +- .../plus/inapp/InAppPurchaseHelperImpl.java | 291 +++++++++++------- .../osmand/plus/inapp/InAppPurchasesImpl.java | 26 +- .../osmand/plus/inapp/SubscriptionUtils.java | 3 +- .../chooseplan/ChoosePlanDialogFragment.java | 11 +- .../plus/inapp/InAppPurchaseHelper.java | 3 + .../net/osmand/plus/inapp/InAppPurchases.java | 2 +- 10 files changed, 226 insertions(+), 140 deletions(-) diff --git a/OsmAnd/.gitignore b/OsmAnd/.gitignore index e3071e5fbf..8bfbd5b688 100644 --- a/OsmAnd/.gitignore +++ b/OsmAnd/.gitignore @@ -13,10 +13,13 @@ libs/it.unibo.alice.tuprolog-tuprolog-3.2.1.jar libs/commons-codec-commons-codec-1.11.jar libs/OsmAndCore_android-0.1-SNAPSHOT.jar +# Huawei libs/huawei-*.jar huaweidrmlib/ HwDRM_SDK_* drm_strings.xml +agconnect-services.json +OsmAndHms.jks # copy_widget_icons.sh res/drawable-large/map_* diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 1232b9661f..15f5a07439 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -28,10 +28,15 @@ android { signingConfigs { development { - storeFile file("../keystores/debug.keystore") - storePassword "android" - keyAlias "androiddebugkey" - keyPassword "android" + storeFile file('OsmAndHms.jks') + keyAlias 'OsmAndHms' + keyPassword 'targeting' + storePassword 'targeting' + +// storeFile file("../keystores/debug.keystore") +// storePassword "android" +// keyAlias "androiddebugkey" +// keyPassword "android" } publishing { diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index 7b0351b3a9..1eb62956f1 100644 --- a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -226,6 +226,16 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { }); } + @Override + public void manageSubscription(@NonNull Context ctx, @Nullable String sku) { + String url = "https://play.google.com/store/account/subscriptions?package=" + ctx.getPackageName(); + if (!Algorithms.isEmpty(sku)) { + url += "&sku=" + sku; + } + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + ctx.startActivity(intent); + } + @Nullable private SkuDetails getSkuDetails(@NonNull String sku) { List skuDetailsList = this.skuDetailsList; diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java index 2bfef4b76b..c7e6cd11be 100755 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/CipherUtil.java @@ -37,7 +37,7 @@ import java.security.spec.X509EncodedKeySpec; public class CipherUtil { private static final String TAG = "CipherUtil"; private static final String SIGN_ALGORITHMS = "SHA256WithRSA"; - private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAooen3X9jSWarxugznzzMSvp4zir1Pg6uPOm7fqlLOL0Ix52e5FpeotMx871pQ9hrCkiyFg2e6UxD8IXXjvK6QJQbjNJ2jIfKkCusm90yloSEfvyLeiq5y7zg4+DoPglHi8RxZ9y308YIqnRDoslfGm5DnWa8RKUvFRVRiu1p3FN4SYIa/FWLtS5yygemtqMJi8I14V7xqQ5wExCGeSA6j1/AAWXEwZncJwKn0BTXQSvwVBPBRM5ksgt4q+Sc484ZIbntATyxsUipnEBFxq1OXn5Zw5/vVxUC8RSyDMQ/kC2RaEcFtA1tlIIjIdurbpNg3tyViPfQUQndvOs4nDrFzwIDAQAB"; + private static final String PUBLIC_KEY = "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsB+oH8rYQncwpTqGa0kS/5E725HJrq2sW1ThAZtmorYVi52Yt9PmZvNDz7284ol9C2skrKQR34eIer8Tr7Qqq3mlNo+/LVUpq9sa++kB2glaG6jj5NNjM3w4nVYHFIYkd5AQhodJgmqFvnp2s7r7YmyQVXZSehei5bA1G70Bs+El9cSv9shNNGTCaU3ARUu2hy3Ltkc/ov7/ZYYpiwjbyD3cmoMh9jO1++zztXb2phjv1h9zeJOp1i6HsotZll+c9J4jjV3GhrF+ZJm5WrSzGLDLtwSldRpMZFxrSvAJJstjzhDz3LpUM+nPV3HZ5VQ/xosmwWYmiibo89E1gw8p73NTBXHzuQMJcTJ6vTjD8LeMskpXHZUAGhifmFLGN1LbNP9662ulCV12kIbXuzWCwwi/h0DWqmnjKmLvzc88e4BrGrp2zZUnHz7m15voPG+4cQ3z9+cwS4gEI3SUTiFyQGE539SO/11VkkQAJ8P7du1JFNqQw5ZEW3AoE1iUsp5XAgMBAAE="; /** * the method to check the signature for the data returned from the interface @@ -65,7 +65,7 @@ public class CipherUtil { java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); - signature.update(content.getBytes("utf-8")); + signature.update(content.getBytes("UTF-8")); boolean bverify = signature.verify(Base64.decode(sign, Base64.DEFAULT)); return bverify; diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index 61de5125c0..2894309c17 100644 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -8,6 +8,9 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.huawei.hmf.tasks.OnFailureListener; +import com.huawei.hmf.tasks.OnSuccessListener; +import com.huawei.hmf.tasks.Task; import com.huawei.hms.iap.Iap; import com.huawei.hms.iap.IapClient; import com.huawei.hms.iap.entity.InAppPurchaseData; @@ -18,12 +21,15 @@ import com.huawei.hms.iap.entity.ProductInfo; import com.huawei.hms.iap.entity.ProductInfoResult; import com.huawei.hms.iap.entity.PurchaseIntentResult; import com.huawei.hms.iap.entity.PurchaseResultInfo; +import com.huawei.hms.iap.entity.StartIapActivityReq; +import com.huawei.hms.iap.entity.StartIapActivityResult; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo; +import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.util.Algorithms; @@ -109,33 +115,37 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { public void run(InAppPurchaseHelper helper) { try { ProductInfo productInfo = getProductInfo(productId); - IapRequestHelper.createPurchaseIntent(getIapClient(), productInfo.getProductId(), - IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback() { - @Override - public void onSuccess(PurchaseIntentResult result) { - if (result == null) { - logError("result is null"); - } else { - // you should pull up the page to complete the payment process - IapRequestHelper.startResolutionForResult(activity, result.getStatus(), Constants.REQ_CODE_BUY_INAPP); - } - commandDone(); - } - - @Override - public void onFail(Exception e) { - int errorCode = ExceptionHandle.handle(activity, e); - if (errorCode != ExceptionHandle.SOLVED) { - logDebug("createPurchaseIntent, returnCode: " + errorCode); - if (OrderStatusCode.ORDER_PRODUCT_OWNED == errorCode) { - logError("already own this product"); + if (productInfo != null) { + IapRequestHelper.createPurchaseIntent(getIapClient(), productInfo.getProductId(), + IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback() { + @Override + public void onSuccess(PurchaseIntentResult result) { + if (result == null) { + logError("result is null"); } else { - logError("unknown error"); + // you should pull up the page to complete the payment process + IapRequestHelper.startResolutionForResult(activity, result.getStatus(), Constants.REQ_CODE_BUY_INAPP); } + commandDone(); } - commandDone(); - } - }); + + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle(activity, e); + if (errorCode != ExceptionHandle.SOLVED) { + logDebug("createPurchaseIntent, returnCode: " + errorCode); + if (OrderStatusCode.ORDER_PRODUCT_OWNED == errorCode) { + logError("already own this product"); + } else { + logError("unknown error"); + } + } + commandDone(); + } + }); + } else { + commandDone(); + } } catch (Exception e) { complain("Cannot launch full version purchase!"); logError("purchaseFullVersion Error", e); @@ -148,13 +158,42 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { @Override public void purchaseFullVersion(@NonNull final Activity activity) throws UnsupportedOperationException { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); - exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, getPurchaseInAppCommand(activity, "")); + exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, getPurchaseInAppCommand(activity, purchases.getFullVersion().getSku())); } @Override public void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); - exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, getPurchaseInAppCommand(activity, "")); + exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, getPurchaseInAppCommand(activity, purchases.getDepthContours().getSku())); + } + + @Override + public void manageSubscription(@NonNull Context ctx, @Nullable String sku) { + if (uiActivity != null) { + StartIapActivityReq req = new StartIapActivityReq(); + if (!Algorithms.isEmpty(sku)) { + req.setSubscribeProductId(sku); + req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_EDIT_ACTIVITY); + } else { + req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_MANAGER_ACTIVITY); + } + Task task = getIapClient().startIapActivity(req); + task.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(StartIapActivityResult result) { + logDebug("startIapActivity: onSuccess"); + Activity activity = (Activity) uiActivity; + if (result != null && AndroidUtils.isActivityNotDestroyed(activity)) { + result.startActivity(activity); + } + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(Exception e) { + logDebug("startIapActivity: onFailure"); + } + }); + } } @Nullable @@ -285,16 +324,18 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { protected InAppCommand getRequestInventoryCommand() { return new InAppCommand() { + @Override + protected void commandDone() { + super.commandDone(); + inventoryRequested = false; + } + @Override public void run(InAppPurchaseHelper helper) { logDebug("Setup successful. Querying inventory."); try { productInfos = new ArrayList<>(); - if (uiActivity != null) { - obtainOwnedSubscriptions(); - } else { - commandDone(); - } + obtainOwnedSubscriptions(); } catch (Exception e) { logError("queryInventoryAsync Error", e); notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); @@ -326,92 +367,95 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } private void obtainOwnedInApps(final String continuationToken) { - // Query users' purchased non-consumable products. - IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_NONCONSUMABLE, - continuationToken, new IapApiCallback() { - @Override - public void onSuccess(OwnedPurchasesResult result) { - ownedInApps.add(result); - if (result != null && !TextUtils.isEmpty(result.getContinuationToken())) { - obtainOwnedInApps(result.getContinuationToken()); - } else { - obtainSubscriptionsInfo(); + if (uiActivity != null) { + // Query users' purchased non-consumable products. + IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_NONCONSUMABLE, + continuationToken, new IapApiCallback() { + @Override + public void onSuccess(OwnedPurchasesResult result) { + ownedInApps.add(result); + if (result != null && !TextUtils.isEmpty(result.getContinuationToken())) { + obtainOwnedInApps(result.getContinuationToken()); + } else { + obtainSubscriptionsInfo(); + } } - } - - @Override - public void onFail(Exception e) { - logError("obtainOwnedInApps exception", e); - ExceptionHandle.handle((Activity) uiActivity, e); - commandDone(); - } - }); + @Override + public void onFail(Exception e) { + logError("obtainOwnedInApps exception", e); + ExceptionHandle.handle((Activity) uiActivity, e); + commandDone(); + } + }); + } else { + commandDone(); + } } private void obtainSubscriptionsInfo() { - Set productIds = new HashSet<>(); - List subscriptions = purchases.getLiveUpdates().getAllSubscriptions(); - for (InAppSubscription s : subscriptions) { - productIds.add(s.getSku()); - } - productIds.addAll(ownedSubscriptions.getItemList()); - IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), - IapClient.PriceType.IN_APP_SUBSCRIPTION, new IapApiCallback() { - @Override - public void onSuccess(final ProductInfoResult result) { - if (result == null) { - logError("obtainSubscriptionsInfo: ProductInfoResult is null"); - commandDone(); - return; + if (uiActivity != null) { + Set productIds = new HashSet<>(); + List subscriptions = purchases.getLiveUpdates().getAllSubscriptions(); + for (InAppSubscription s : subscriptions) { + productIds.add(s.getSku()); + } + productIds.addAll(ownedSubscriptions.getItemList()); + IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), + IapClient.PriceType.IN_APP_SUBSCRIPTION, new IapApiCallback() { + @Override + public void onSuccess(final ProductInfoResult result) { + if (result != null && result.getProductInfoList() != null) { + productInfos.addAll(result.getProductInfoList()); + } + obtainInAppsInfo(); } - productInfos.addAll(result.getProductInfoList()); - obtainInAppsInfo(); - } - @Override - public void onFail(Exception e) { - int errorCode = ExceptionHandle.handle((Activity) uiActivity, e); - if (ExceptionHandle.SOLVED != errorCode) { - LOG.error("Unknown error"); + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle((Activity) uiActivity, e); + if (ExceptionHandle.SOLVED != errorCode) { + LOG.error("Unknown error"); + } + commandDone(); } - commandDone(); - } - }); + }); + } else { + commandDone(); + } } private void obtainInAppsInfo() { - Set productIds = new HashSet<>(); - for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { - productIds.add(purchase.getSku()); - } - for (OwnedPurchasesResult result : ownedInApps) { - productIds.addAll(result.getItemList()); - } - IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), - IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback() { - @Override - public void onSuccess(ProductInfoResult result) { - if (result == null || result.getProductInfoList() == null) { - logError("obtainInAppsInfo: ProductInfoResult is null"); + if (uiActivity != null) { + Set productIds = new HashSet<>(); + for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) { + productIds.add(purchase.getSku()); + } + for (OwnedPurchasesResult result : ownedInApps) { + productIds.addAll(result.getItemList()); + } + IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), + IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback() { + @Override + public void onSuccess(ProductInfoResult result) { + if (result != null && result.getProductInfoList() != null) { + productInfos.addAll(result.getProductInfoList()); + } + processInventory(); + } + + @Override + public void onFail(Exception e) { + int errorCode = ExceptionHandle.handle((Activity) uiActivity, e); + if (ExceptionHandle.SOLVED != errorCode) { + LOG.error("Unknown error"); + } commandDone(); - return; } - productInfos.addAll(result.getProductInfoList()); - - processInventory(); - commandDone(); - } - - @Override - public void onFail(Exception e) { - int errorCode = ExceptionHandle.handle((Activity) uiActivity, e); - if (ExceptionHandle.SOLVED != errorCode) { - LOG.error("Unknown error"); - } - commandDone(); - } - }); + }); + } else { + commandDone(); + } } private void processInventory() { @@ -579,17 +623,31 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { if (resultCode == Activity.RESULT_OK) { PurchaseResultInfo result = SubscriptionUtils.getPurchaseResult(activity, data); if (result != null) { - if (OrderStatusCode.ORDER_STATE_SUCCESS == result.getReturnCode()) { - InAppPurchaseData purchaseData = SubscriptionUtils.getInAppPurchaseData(null, - result.getInAppPurchaseData(), result.getInAppDataSignature()); - if (purchaseData != null) { - onPurchaseFinished(purchaseData); - succeed = true; - } else { + switch (result.getReturnCode()) { + case OrderStatusCode.ORDER_STATE_CANCEL: + logDebug("Purchase cancelled"); + break; + case OrderStatusCode.ORDER_STATE_FAILED: + inventoryRequestPending = true; logDebug("Purchase failed"); - } - } else if (OrderStatusCode.ORDER_STATE_CANCEL == result.getReturnCode()) { - logDebug("Purchase cancelled"); + break; + case OrderStatusCode.ORDER_PRODUCT_OWNED: + inventoryRequestPending = true; + logDebug("Product already owned"); + break; + case OrderStatusCode.ORDER_STATE_SUCCESS: + inventoryRequestPending = true; + InAppPurchaseData purchaseData = SubscriptionUtils.getInAppPurchaseData(null, + result.getInAppPurchaseData(), result.getInAppDataSignature()); + if (purchaseData != null) { + onPurchaseFinished(purchaseData); + succeed = true; + } else { + logDebug("Purchase failed"); + } + break; + default: + break; } } else { logDebug("Purchase failed"); @@ -611,7 +669,12 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { case OrderStatusCode.ORDER_STATE_CANCEL: logDebug("Order has been canceled"); break; + case OrderStatusCode.ORDER_STATE_FAILED: + inventoryRequestPending = true; + logDebug("Order has been failed"); + break; case OrderStatusCode.ORDER_PRODUCT_OWNED: + inventoryRequestPending = true; logDebug("Product already owned"); break; case OrderStatusCode.ORDER_STATE_SUCCESS: diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java index 49ff72cd3b..4ed0021b6f 100644 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java @@ -5,6 +5,8 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.huawei.hms.iap.entity.ProductInfo; + import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -26,8 +28,18 @@ public class InAppPurchasesImpl extends InAppPurchases { fullVersion = FULL_VERSION; depthContours = DEPTH_CONTOURS_FREE; contourLines = CONTOUR_LINES_FREE; - liveUpdates = new LiveUpdatesInAppPurchasesFree(); inAppPurchases = new InAppPurchase[] { fullVersion, depthContours, contourLines }; + + liveUpdates = new LiveUpdatesInAppPurchasesFree(); + for (InAppSubscription s : liveUpdates.getAllSubscriptions()) { + if (s instanceof InAppPurchaseLiveUpdatesMonthly) { + if (s.isDiscounted()) { + discountedMonthlyLiveUpdates = s; + } else { + monthlyLiveUpdates = s; + } + } + } } @Override @@ -57,7 +69,7 @@ public class InAppPurchasesImpl extends InAppPurchases { private static class InAppPurchaseFullVersion extends InAppPurchase { - private static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price"; + private static final String SKU_FULL_VERSION_PRICE = "net.osmand.huawei.full"; InAppPurchaseFullVersion() { super(SKU_FULL_VERSION_PRICE); @@ -71,7 +83,7 @@ public class InAppPurchasesImpl extends InAppPurchases { private static class InAppPurchaseDepthContoursFree extends InAppPurchaseDepthContours { - private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth"; + private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.huawei.seadepth"; InAppPurchaseDepthContoursFree() { super(SKU_DEPTH_CONTOURS_FREE); @@ -80,7 +92,7 @@ public class InAppPurchasesImpl extends InAppPurchases { private static class InAppPurchaseContourLinesFree extends InAppPurchaseContourLines { - private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.contourlines"; + private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.huawei.contourlines"; InAppPurchaseContourLinesFree() { super(SKU_CONTOUR_LINES_FREE); @@ -89,7 +101,7 @@ public class InAppPurchasesImpl extends InAppPurchases { private static class InAppPurchaseLiveUpdatesMonthlyFree extends InAppPurchaseLiveUpdatesMonthly { - private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.test.monthly"; + private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.huawei.monthly"; InAppPurchaseLiveUpdatesMonthlyFree() { super(SKU_LIVE_UPDATES_MONTHLY_HW_FREE, 1); @@ -108,7 +120,7 @@ public class InAppPurchasesImpl extends InAppPurchases { private static class InAppPurchaseLiveUpdates3MonthsFree extends InAppPurchaseLiveUpdates3Months { - private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.test.3months"; + private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.huawei.3months"; InAppPurchaseLiveUpdates3MonthsFree() { super(SKU_LIVE_UPDATES_3_MONTHS_HW_FREE, 1); @@ -127,7 +139,7 @@ public class InAppPurchasesImpl extends InAppPurchases { private static class InAppPurchaseLiveUpdatesAnnualFree extends InAppPurchaseLiveUpdatesAnnual { - private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.test.annual"; + private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.huawei.annual"; InAppPurchaseLiveUpdatesAnnualFree() { super(SKU_LIVE_UPDATES_ANNUAL_HW_FREE, 1); diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java index 1dffffc252..3b249cb300 100755 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/SubscriptionUtils.java @@ -120,9 +120,8 @@ public class SubscriptionUtils { } } else { Log.e(TAG, "check the data signature fail"); + return getFailedPurchaseResultInfo(); } - return getFailedPurchaseResultInfo(); - default: Log.e(TAG, "returnCode: " + returnCode + " , errMsg: " + errMsg); break; diff --git a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java index 1e3b650a8f..c909d50845 100644 --- a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java @@ -428,7 +428,7 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment buttonCancelView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - manageSubscription(ctx, s.getSku()); + purchaseHelper.manageSubscription(ctx, s.getSku()); } }); div.setVisibility(View.VISIBLE); @@ -538,15 +538,6 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment } } - private void manageSubscription(@NonNull Context ctx, @Nullable String sku) { - String url = "https://play.google.com/store/account/subscriptions?package=" + ctx.getPackageName(); - if (!Algorithms.isEmpty(sku)) { - url += "&sku=" + sku; - } - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - startActivity(intent); - } - private ViewGroup buildPlanTypeCard(@NonNull Context ctx, ViewGroup container) { if (getPlanTypeFeatures().length == 0) { return null; diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java index ff734e6af5..e99bed63b7 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java @@ -2,6 +2,7 @@ package net.osmand.plus.inapp; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.text.TextUtils; @@ -265,6 +266,8 @@ public abstract class InAppPurchaseHelper { public abstract void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException; + public abstract void manageSubscription(@NonNull Context ctx, @Nullable String sku); + @SuppressLint("StaticFieldLeak") private class LiveUpdatesPurchaseTask extends AsyncTask { diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java index 5ccb49a70e..5004e97165 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java @@ -73,7 +73,7 @@ public abstract class InAppPurchases { public InAppSubscription getPurchasedMonthlyLiveUpdates() { if (monthlyLiveUpdates.isAnyPurchased()) { return monthlyLiveUpdates; - } else if (discountedMonthlyLiveUpdates.isAnyPurchased()) { + } else if (discountedMonthlyLiveUpdates != null && discountedMonthlyLiveUpdates.isAnyPurchased()) { return discountedMonthlyLiveUpdates; } return null; From 82b4009fe314548cc27048d7483bec5d14361897 Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Sun, 4 Oct 2020 06:24:41 +0000 Subject: [PATCH 0447/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3486 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 74 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index cdc7518bfc..5a8d26fe8c 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -86,7 +86,7 @@ Видимые Восстановить покупки Шрифты карты - Посмотреть на карте + Анализ на карте Морские карты Контуры морских глубин Контуры морских глубин @@ -115,7 +115,7 @@ Сбалансированный Предпочитать переулки Выберите предпочтительный рельеф. - Карта уклонов + Уклон Добавить новую папку Точки удалены. Вы уверены, что хотите удалить %1$d точки\? @@ -317,15 +317,15 @@ Открыть внешний проигрыватель Удалить эту запись? недоступно - Аудиозаметка + Запись аудио Запись видео - Слой аудиозаписей - Запись не может быть воспроизведена. + Слой медиазаписей + Не удаётся воспроизвести запись. Удалить запись Проиграть Запись %1$s %3$s %2$s Запись - Аудиозаметки + Медиазаметки OsmAnd-плагин для линий высот Измерение расстояний Нажмите «Использовать местоположение…» для добавления заметки к месту. @@ -521,11 +521,11 @@ Для этого региона есть локальные векторные карты. \n\t \n\tДля использования выберите их в качестве источника (Меню → Настройка карты → Источник карты → Локальные векторные карты). - Голосовые инструкции + Аудиоканал голосовых инструкций Выберите канал вывода голосовых подсказок. - Канал голосовых звонков (прерывает автомобильную Bluetooth стереосистему) - Канал уведомлений - Канал медиа/навигации + Голосовые звонки (для прерывания автомобильной стереосистемы Bluetooth) + Уведомления + Мультимедиа, навигация Приложение не может загрузить слой карты %1$s, переустановка может решить проблему. Отрегулируйте прозрачность наложения. Прозрачность наложения @@ -669,9 +669,9 @@ Локальные векторные карты Редактировать POI Удалить POI - По направлению компаса - По направлению движения - Не вращать (север сверху) + по компасу + по направлению движения + не вращать (север сверху) Выравнивание карты: Ориентация карты Детали маршрута @@ -1258,7 +1258,7 @@ Отменить маршрут Очистить пункт назначения Искать улицу в ближайших населённых пунктах - В порядке следования домов + Расположить в оптимальном порядке Доступно %1$d файлов для скачивания осталось %1$d файлов Подождите, пока завершится текущая операция @@ -1358,7 +1358,7 @@ Избегать грунтовых дорог Без паромов Исключить паромные переправы - Максимальная масса + Предельная масса Укажите допустимый предел массы автомобиля для учёта при построении маршрута. Отображение карты Навигационные знаки (водоёмы) @@ -1446,14 +1446,14 @@ Разное Локализация Голосовые подсказки приостанавливают воспроизведение музыки. - Приостановить музыку + Приостанавливать музыку Поделиться маршрутом используя файл GPX Неправильный формат: %s Маршрут предоставленный через OsmAnd - Только вручную (нажатием «стрелочки») + При нажатии на стрелку (вручную) Повторять навигационные инструкции с регулярными интервалами. - Повторять навигационные инструкции - Объявление прибытия + Повтор инструкций при навигации + Объявление о прибытии Как скоро следует сообщать о прибытии? Места, отправленные в OsmAnd Рассчитать маршрут между точками @@ -1540,10 +1540,10 @@ Продолжить навигацию Приостановить навигацию Визуализация пути по шкале SAC. - Визуализация пути согласно трассам OSMC. - Пораньше - Как обычно - Попозже + Отрисовка дорог согласно трассам OSMC. + Раннее + По умолчанию + Позднее На последних метрах Пеший горный туризм по шкале (SAC) Наложение туристических меток @@ -1816,7 +1816,7 @@ Напечатайте для поиска Номера домов Избегать перехода границы - Максимальная высота + Предельная высота Укажите высоту транспортного средства для учёта при построении маршрута. Умный пересчёт маршрута Для больших маршрутов пересчитывать только начало. @@ -2065,7 +2065,7 @@ Разбиение на клипы Использовать разбиение на клипы Циклическая перезапись клипов при превышении заданного объёма хранилища. - Поменять местами пункты отправления и назначения + Поменять местами пункты отправления и назначения Удалить Подземные объекты Данные недоступны @@ -2380,7 +2380,7 @@ Избегать ледовых дорог и бродов. Моё местоположение Финиш - Сортировать + Сортировка Экспорт маркеров в следующий файл GPX: Маркеры Изменить заметку @@ -2392,7 +2392,7 @@ Критерий сортировки: Выберите способ указания расстояния и направления до маркеров на карте: Смена ориентации карты - Выберите скорость, при которой переключается ориентация карты с «По направлению движения» на «По направлению компаса». + Выберите скорость, при которой ориентация по направлению движения переключится на ориентацию по компасу. Все маркеры перемещены в историю Маркер перемещён в историю Маркер перемещён в действующие @@ -2683,7 +2683,7 @@ OSM-заметки Впереди туннель Туннели - Сделать отправной точкой + Сделать пунктом отправления Введите имя файла. Ошибка импорта карты Карта импортирована @@ -2788,7 +2788,7 @@ Для катания на лыжах. Выделяет горнолыжные трассы, подъёмники, трассы для беговых лыж и прочее. Меньше отвлекающих второстепенных объектов на карте. Скачать все Простой стиль для вождения. Мягкий ночной режим, контурные линии, контрастные дороги в оранжевом стиле, тусклые второстепенные объекты карты. - Для пеших походов, трекинга и велосипедных прогулок на природе. Читабельный на открытом воздухе и при сложном освещении. Контрастные дороги и природные объекты, различные типы маршрутов, контурные линии с расширенными настройками, дополнительные детали. Функция «Качество дорожного покрытия» позволяет различать дороги с различным качеством поверхности. Нет ночного режима. + Для пеших походов, трекинга и велопоездок на природе. Хорошо читается при сложном освещении. Контрастные дороги и природные объекты, различные типы маршрутов, контурные линии с расширенными настройками, дополнительные детали. Параметр «Дорожное покрытие» позволяет различать поверхность и качество дорог. Ночной режим отсутствует. Старый стиль по умолчанию «Mapnik». Похожие цвета на «Mapnik». Стиль общего назначения. Густонаселённые города показаны упрощённо. Выделяет контурные линии, маршруты, качество поверхности, ограничения доступа, дорожные щиты, визуализация пешеходных маршрутов по шкале SAC, объекты спортивных сплавов. Открыть ссылку Википедии в онлайн @@ -2796,7 +2796,7 @@ Получите подписку на OsmAnd Live, чтобы читать статьи в Википедии и Викигиде в автономном режиме. Как открыть ссылку? Читать Википедию в автономном режиме - Туристический стиль с высоким контрастом и максимальной детализацией. Включает все функции стиля OsmAnd по умолчанию, также отображая как можно больше деталей, в частности дороги, тропы и другие пути для передвижения. Чёткое различие между типами дорог, как во многих туристических атласах. Подходит для дневного, ночного и уличного использования. + Туристический стиль с высоким контрастом и максимальной детализацией. Включает все функции стиля OsmAnd по умолчанию, отображая максимальное количество деталей, в частности дороги, тропы и другие пути передвижения. Чёткое различие между типами дорог (как в туристических атласах). Подходит для использования днём, ночью и при ярком освещении. Сохранить Для езды по бездорожью, основано на топографическом стиле (англ. «Topo»), можно использовать с зелёными спутниковыми снимками в качестве подложки. Уменьшенная толщина основных дорог, увеличенная толщина путей, дорожек, велосипедных и других маршрутов. Модификация стиля по умолчанию для увеличения контраста пешеходных и велосипедных дорог. Использует старые цвета Mapnik. @@ -2987,7 +2987,7 @@ Ступеньки Тропа Велодорожка - Неопределённая + Не определено Узнайте больше о маршрутизации OsmAnd в нашем блоге. Навигация на общественном транспорте в настоящее время проходит бета-тестирование, возможны ошибки и неточности. Добавить промежуточную точку @@ -3101,7 +3101,7 @@ Использовать WunderLINQ для контроля Значок Собранные данные - Нажмите ещё раз, чтобы изменить ориентацию карты + Нажмите дважды для смены ориентации карты Последний запуск OsmAnd завершился ошибкой. Пожалуйста, помогите нам улучшить OsmAnd, отправив нам отчёт об ошибке. Режим: %s Режим пользователя, полученный из: %s @@ -3233,7 +3233,7 @@ Карта во время навигации Скорость движения, размеры, масса транспортного средства Параметры транспортного средства - Голосовые инструкции работают только при навигации. + Голосовые инструкции работают только во время навигации. Навигационные инструкции и объявления Голосовые подсказки Экранные оповещения @@ -3390,7 +3390,7 @@ Эксперт Фрирайд Экстрим - Неопределённо + Неопределённая Канатная дорога Соединение Симулировать свою позицию используя записанный GPX трек. @@ -3555,7 +3555,7 @@ Невозможно разобрать геоссылку «%s». Для отображения затенения рельефа требуются дополнительные карты. Мин. - Отображение затенения рельефа или карты уклонов. Подробнее об этих типах карт вы можете прочитать на нашем сайте. + Способы отображения рельефа местности: посредством теней (затенение рельефа) или цветов (карта уклонов). Подробнее об этих типах карт вы можете прочитать на нашем сайте. Прозрачность Уровни масштаба Пересчитывать маршрут в случае отклонения @@ -3587,7 +3587,7 @@ Затенение рельефа Для отображения склонов, вершин и низменностей используются тёмные тени. Для отображения уклонов требуются дополнительные карты. - Уклоны + Карта уклонов Заменить этой точкой другую. Изменения применены к профилю «%1$s». Невозможно прочитать из «%1$s». @@ -3885,7 +3885,7 @@ ПОВТОРИТЬ • Обновлённая функция планирования маршрута позволяет применять к сегментам разные режимы навигации и настраивать привязку к дорогам \n -\n • Новые настройки вида треков: выбор цвета и толщины линии, стрелки направления, метки начала и конца маршрута +\n • Новые настройки вида треков: выбор цвета и толщины линии, указатели направления, метки начала и конца маршрута \n \n • Повышенная видимость велосипедных узлов \n From 95ba1e91edc5b1d81292a56c77bb21c513f808e9 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Sat, 3 Oct 2020 16:59:10 +0000 Subject: [PATCH 0448/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3486 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 5a8d26fe8c..f387316703 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -126,7 +126,7 @@ Средняя скорость Время в движении Общее время - Макс. + Максимальная Отправление Прибытие Цвет @@ -901,7 +901,7 @@ Дом Пересечение улиц Обновить карту - POI + Добавление POI Да Отмена Нет @@ -1178,7 +1178,7 @@ Достопримечательности Последний промежуточный пункт Первый промежуточный пункт - Последний промежуточный пункт + Добавить последним промежуточным пунктом Первый промежуточный пункт Заменить пункт назначения Вы уже задали пункт назначения @@ -1386,7 +1386,7 @@ Задать пункт назначения Предпочтения маршрута Информация про маршрут - Добавить пункт назначения + Добавить новым пунктом назначения Использовать показанный путь для навигации? Рассчитать сегмент маршрута OsmAnd без интернета Рассчитать маршрут OsmAnd для первого и последнего сегмента маршрута @@ -1667,7 +1667,7 @@ Моё местоположение Статус GPS Точки - Парковка + Место для парковки УДАЛИТЬ ТЕГ Редактировать группу Вам необходимо подключение к сети для установки этого плагина. @@ -2134,7 +2134,7 @@ Переместить ↑ Переместить ↓ Завершить навигацию - Избегать + Избегать дорог Публичное имя Поддерживаемый регион Введите публичное имя @@ -2917,7 +2917,7 @@ Предыдущий маршрут Сначала задайте пункт назначения Поменять - Ещё + Показать больше Отображаемые треки Показать/скрыть треки Скрыть треки From 5b6f2692a352c3ac52fba05cc76386c895b8c20b Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Sun, 4 Oct 2020 06:40:43 +0000 Subject: [PATCH 0449/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3486 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index f387316703..299cf1df71 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -669,7 +669,7 @@ Локальные векторные карты Редактировать POI Удалить POI - по компасу + по направлению компаса по направлению движения не вращать (север сверху) Выравнивание карты: From dbf68d2872d0a089b8206ace392a92a3b97d9d21 Mon Sep 17 00:00:00 2001 From: ace shadow Date: Sat, 3 Oct 2020 20:19:33 +0000 Subject: [PATCH 0450/1366] Translated using Weblate (Slovak) Currently translated at 94.9% (3633 of 3825 strings) --- OsmAnd/res/values-sk/phrases.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/OsmAnd/res/values-sk/phrases.xml b/OsmAnd/res/values-sk/phrases.xml index fc275bf7c3..28ac2c4297 100644 --- a/OsmAnd/res/values-sk/phrases.xml +++ b/OsmAnd/res/values-sk/phrases.xml @@ -3628,4 +3628,28 @@ Malé elektrické spotrebiče Tabuľa odjazdov/cestovný poriadok Doplnenie pitnej vody + Nasávanie + Pod tlakom + Spodná voda + Potrubie + Sieť doplnenia pitnej vody + Doplnenie pitnej vody: nie + Áno + Prekážka + Výška vody: pod strednou hladinou + Výška vody: nad strednou hladinou + Výška vody: prekrýva + Výška vody: suché + Výška vody: ponorené + Výška vody: čiastočne ponorené + Nesprávne + Primitívne + Kontrastné + Len keď je povolená chôdza + Nie + Áno + Typ búdky + Búdka + Nie + Áno \ No newline at end of file From 1b2e9c3061b0021b4b5ef919cb99a91c0060c95c Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Sun, 4 Oct 2020 05:34:58 +0000 Subject: [PATCH 0451/1366] Translated using Weblate (Russian) Currently translated at 100.0% (267 of 267 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/ru/ --- OsmAnd-telegram/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-telegram/res/values-ru/strings.xml b/OsmAnd-telegram/res/values-ru/strings.xml index daff0e950b..a494bf809b 100644 --- a/OsmAnd-telegram/res/values-ru/strings.xml +++ b/OsmAnd-telegram/res/values-ru/strings.xml @@ -75,7 +75,7 @@ По расстоянию По имени По группе - Сортировать + Сортировка Сортировать по Отстановить все Выход From 2b72d19048e6d31a511b6cba252de664c96bc62f Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Sun, 4 Oct 2020 10:29:12 +0000 Subject: [PATCH 0452/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3486 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 299cf1df71..8b167f73b2 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -844,7 +844,7 @@ Сохранить текущий трек Укажите интервал фиксирования точек для записи трека во время навигации Интервал записи во время навигации - Во время навигации GPX треки будут автоматически сохранены в папку с треками. + Во время навигации GPX-треки будут автоматически сохранены в папку с треками. Автозапись трека во время навигации Обновить карту Обновить часть карты @@ -1160,7 +1160,7 @@ \n — подсказки полосы движения, отображение ограничения скорости, предварительно записанные и синтезированные голосовые подсказки \n Без автомагистралей - Привязываться к дорогам во время навигации. + Привязывать позицию к дороге во время навигации. Привязка к дороге Промежуточный пункт %1$s слишком далеко от ближайшей дороги. Вы прибыли в промежуточный пункт @@ -1445,8 +1445,8 @@ Голос Разное Локализация - Голосовые подсказки приостанавливают воспроизведение музыки. - Приостанавливать музыку + Приостановка воспроизведения во время подсказок. + Прерывать музыку Поделиться маршрутом используя файл GPX Неправильный формат: %s Маршрут предоставленный через OsmAnd @@ -1492,7 +1492,7 @@ %1$s точек Точка %1$s %1$s \nМаршрутных точек %2$s - Показывать кнопки изменения масштаба во время навигации. + Показывать кнопки масштаба во время навигации. Кнопки масштаба Сортировать по расстоянию Сортировать по имени @@ -2801,7 +2801,7 @@ Для езды по бездорожью, основано на топографическом стиле (англ. «Topo»), можно использовать с зелёными спутниковыми снимками в качестве подложки. Уменьшенная толщина основных дорог, увеличенная толщина путей, дорожек, велосипедных и других маршрутов. Модификация стиля по умолчанию для увеличения контраста пешеходных и велосипедных дорог. Использует старые цвета Mapnik. Получите OsmAnd Live, чтобы разблокировать все функции: ежедневные обновления карт с неограниченной загрузкой, все платные и бесплатные плагины, Википедия, Викигид и многое другое. - Промежуточное время прибытия + Прибытие в промежуточный пункт Прибытие в промежуточный пункт Редактировать действие Пожалуйста, пришлите скриншот этого уведомления на support@osmand.net @@ -2891,7 +2891,7 @@ Точки интереса (POI) Расчёт маршрута… Общественный транспорт - Выберите дорогу на карте или из списка ниже, которую вы хотите избежать во время навигации: + Выберите на карте или в списке ниже дорогу, которой хотите избежать при навигации: Моделировать навигацию Выберите файл трека для следования Голосовые подсказки @@ -3237,7 +3237,7 @@ Навигационные инструкции и объявления Голосовые подсказки Экранные оповещения - Настройка параметров маршрута + Настройки маршрутизации Параметры маршрута Буфер Logcat Настройки плагинов From 197d30b584e3e5e678e551acea474ad6ccc2dbd5 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Sun, 4 Oct 2020 06:47:54 +0000 Subject: [PATCH 0453/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3486 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 8b167f73b2..9992fd35fb 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -1452,7 +1452,7 @@ Маршрут предоставленный через OsmAnd При нажатии на стрелку (вручную) Повторять навигационные инструкции с регулярными интервалами. - Повтор инструкций при навигации + Повторять навигационные инструкции Объявление о прибытии Как скоро следует сообщать о прибытии? Места, отправленные в OsmAnd @@ -3101,7 +3101,7 @@ Использовать WunderLINQ для контроля Значок Собранные данные - Нажмите дважды для смены ориентации карты + Нажмите ещё раз для смены ориентации карты Последний запуск OsmAnd завершился ошибкой. Пожалуйста, помогите нам улучшить OsmAnd, отправив нам отчёт об ошибке. Режим: %s Режим пользователя, полученный из: %s From 1acf5f41c748397e6f5fc0ddadffe1ac99f82723 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sun, 4 Oct 2020 16:00:07 +0300 Subject: [PATCH 0454/1366] Finished huawei integration --- OsmAnd/build.gradle | 17 ++++------ OsmAnd/res/values/strings.xml | 1 + .../plus/inapp/InAppPurchaseHelperImpl.java | 20 ++++++++++++ .../plus/inapp/InAppPurchaseHelperImpl.java | 22 +++++++------ .../plus/activities/MapActivityActions.java | 2 +- .../OsmandInAppPurchaseActivity.java | 32 +++++++++++++------ ...ChoosePlanHillshadeSrtmDialogFragment.java | 2 +- .../plus/inapp/InAppPurchaseHelper.java | 22 +++++++++++-- .../plus/settings/backend/OsmandSettings.java | 1 + .../osmand/plus/srtmplugin/SRTMPlugin.java | 4 ++- 10 files changed, 88 insertions(+), 35 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 15f5a07439..a87a05b117 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -28,15 +28,10 @@ android { signingConfigs { development { - storeFile file('OsmAndHms.jks') - keyAlias 'OsmAndHms' - keyPassword 'targeting' - storePassword 'targeting' - -// storeFile file("../keystores/debug.keystore") -// storePassword "android" -// keyAlias "androiddebugkey" -// keyPassword "android" + storeFile file("../keystores/debug.keystore") + storePassword "android" + keyAlias "androiddebugkey" + keyPassword "android" } publishing { @@ -49,13 +44,13 @@ android { publishingHuawei { storeFile file("/var/lib/jenkins/osmand_hw_key") storePassword System.getenv("OSMAND_HW_APK_PASSWORD") - keyAlias "OsmAndHms" + keyAlias "osmand" keyPassword System.getenv("OSMAND_HW_APK_PASSWORD") } } defaultConfig { - minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 17 + minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15 targetSdkVersion 28 versionCode 390 versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 14e08c0176..b110f8df1e 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Thank you for purchasing \'Contour lines\' Name: A – Z Name: Z – A Last modified diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index 1eb62956f1..c6925a5e63 100644 --- a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -1,6 +1,10 @@ package net.osmand.plus.inapp; import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -13,11 +17,14 @@ import com.android.billingclient.api.SkuDetailsResponseListener; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.inapp.util.BillingManager; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.srtmplugin.SRTMPlugin; import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; @@ -174,6 +181,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { }); } + @Override public void purchaseFullVersion(@NonNull final Activity activity) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION); exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppCommand() { @@ -200,6 +208,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { }); } + @Override public void purchaseDepthContours(@NonNull final Activity activity) { notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS); exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppCommand() { @@ -226,6 +235,17 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { }); } + @Override + public void purchaseContourLines(@NonNull Activity activity) throws UnsupportedOperationException { + OsmandPlugin plugin = OsmandPlugin.getPlugin(SRTMPlugin.class); + if(plugin == null || plugin.getInstallURL() == null) { + Toast.makeText(activity.getApplicationContext(), + activity.getString(R.string.activate_srtm_plugin), Toast.LENGTH_LONG).show(); + } else { + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(plugin.getInstallURL()))); + } + } + @Override public void manageSubscription(@NonNull Context ctx, @Nullable String sku) { String url = "https://play.google.com/store/account/subscriptions?package=" + ctx.getPackageName(); diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index 2894309c17..c3d6fc193c 100644 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -167,6 +167,12 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, getPurchaseInAppCommand(activity, purchases.getDepthContours().getSku())); } + @Override + public void purchaseContourLines(@NonNull Activity activity) throws UnsupportedOperationException { + notifyShowProgress(InAppPurchaseTaskType.PURCHASE_CONTOUR_LINES); + exec(InAppPurchaseTaskType.PURCHASE_CONTOUR_LINES, getPurchaseInAppCommand(activity, purchases.getContourLines().getSku())); + } + @Override public void manageSubscription(@NonNull Context ctx, @Nullable String sku) { if (uiActivity != null) { @@ -255,7 +261,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } if (inAppPurchase instanceof InAppSubscription) { String introductoryPrice = productInfo.getSubSpecialPrice(); - String introductoryPricePeriod = productInfo.getSubSpecialPeriod(); + String introductoryPricePeriod = productInfo.getSubPeriod(); int introductoryPriceCycles = productInfo.getSubSpecialPeriodCycles(); long introductoryPriceAmountMicros = productInfo.getSubSpecialPriceMicros(); if (!Algorithms.isEmpty(introductoryPrice)) { @@ -497,7 +503,6 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { fetchInAppPurchase(fullVersion, fullPriceDetails, purchaseData); } } - InAppPurchase depthContours = getDepthContours(); if (hasDetails(depthContours.getSku())) { InAppPurchaseData purchaseData = getPurchaseData(depthContours.getSku()); @@ -506,7 +511,6 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { fetchInAppPurchase(depthContours, depthContoursDetails, purchaseData); } } - InAppPurchase contourLines = getContourLines(); if (hasDetails(contourLines.getSku())) { InAppPurchaseData purchaseData = getPurchaseData(contourLines.getSku()); @@ -516,17 +520,15 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } - InAppPurchaseData fullVersionPurchase = getPurchaseData(fullVersion.getSku()); - boolean fullVersionPurchased = fullVersionPurchase != null; - if (fullVersionPurchased) { + if (getPurchaseData(fullVersion.getSku()) != null) { ctx.getSettings().FULL_VERSION_PURCHASED.set(true); } - - InAppPurchaseData depthContoursPurchase = getPurchaseData(depthContours.getSku()); - boolean depthContoursPurchased = depthContoursPurchase != null; - if (depthContoursPurchased) { + if (getPurchaseData(depthContours.getSku()) != null) { ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); } + if (getPurchaseData(contourLines.getSku()) != null) { + ctx.getSettings().CONTOUR_LINES_PURCHASED.set(true); + } // Do we have the live updates? boolean subscribedToLiveUpdates = false; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index dbd0f133fa..1d6e2c2dc7 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -899,7 +899,7 @@ public class MapActivityActions implements DialogProvider { } }).createItem()); - if (Version.isGooglePlayEnabled(app) || Version.isDeveloperVersion(app)) { + if (Version.isGooglePlayEnabled(app) || Version.isHuawei(app) || Version.isDeveloperVersion(app)) { optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.osm_live, mapActivity) .setId(DRAWER_OSMAND_LIVE_ID) .setIcon(R.drawable.ic_action_osm_live) diff --git a/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java b/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java index 3929307cb9..47f7a17444 100644 --- a/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/OsmandInAppPurchaseActivity.java @@ -19,6 +19,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.Version; +import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseInitCallback; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; @@ -54,8 +55,11 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In private void initInAppPurchaseHelper() { deinitInAppPurchaseHelper(); if (purchaseHelper == null) { - InAppPurchaseHelper purchaseHelper = getMyApplication().getInAppPurchaseHelper(); - if (isInAppPurchaseAllowed() && isInAppPurchaseSupported(purchaseHelper)) { + OsmandApplication app = getMyApplication(); + InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); + if (app.getSettings().isInternetConnectionAvailable() + && isInAppPurchaseAllowed() + && isInAppPurchaseSupported(purchaseHelper)) { this.purchaseHelper = purchaseHelper; } } @@ -128,13 +132,18 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In } } - public static void purchaseSrtmPlugin(@NonNull final Activity activity) { - OsmandPlugin plugin = OsmandPlugin.getPlugin(SRTMPlugin.class); - if(plugin == null || plugin.getInstallURL() == null) { - Toast.makeText(activity.getApplicationContext(), - activity.getString(R.string.activate_srtm_plugin), Toast.LENGTH_LONG).show(); - } else { - activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(plugin.getInstallURL()))); + public static void purchaseContourLines(@NonNull final Activity activity) { + OsmandApplication app = (OsmandApplication) activity.getApplication(); + if (app != null) { + InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); + if (purchaseHelper != null) { + app.logEvent("contour_lines_purchase_redirect"); + try { + purchaseHelper.purchaseContourLines(activity); + } catch (UnsupportedOperationException e) { + LOG.error("purchaseContourLines is not supported", e); + } + } } } @@ -201,6 +210,11 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In } onInAppPurchaseItemPurchased(sku); fireInAppPurchaseItemPurchasedOnFragments(fragmentManager, sku, active); + if (purchaseHelper != null && purchaseHelper.getContourLines().getSku().equals(sku)) { + if (!(this instanceof MapActivity)) { + finish(); + } + } } public void fireInAppPurchaseItemPurchasedOnFragments(@NonNull FragmentManager fragmentManager, diff --git a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanHillshadeSrtmDialogFragment.java b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanHillshadeSrtmDialogFragment.java index b2858b53b8..d3a48a5a15 100644 --- a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanHillshadeSrtmDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanHillshadeSrtmDialogFragment.java @@ -79,7 +79,7 @@ public class ChoosePlanHillshadeSrtmDialogFragment extends ChoosePlanDialogFragm public void onClick(View v) { Activity activity = getActivity(); if (activity != null) { - OsmandInAppPurchaseActivity.purchaseSrtmPlugin(activity); + OsmandInAppPurchaseActivity.purchaseContourLines(activity); dismiss(); } } diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java index e99bed63b7..1364d7b154 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java @@ -89,7 +89,8 @@ public abstract class InAppPurchaseHelper { REQUEST_INVENTORY, PURCHASE_FULL_VERSION, PURCHASE_LIVE_UPDATES, - PURCHASE_DEPTH_CONTOURS + PURCHASE_DEPTH_CONTOURS, + PURCHASE_CONTOUR_LINES } public abstract class InAppCommand { @@ -155,6 +156,10 @@ public abstract class InAppPurchaseHelper { return Version.isDeveloperBuild(ctx) || ctx.getSettings().DEPTH_CONTOURS_PURCHASED.get(); } + public static boolean isContourLinesPurchased(@NonNull OsmandApplication ctx) { + return Version.isDeveloperBuild(ctx) || ctx.getSettings().CONTOUR_LINES_PURCHASED.get(); + } + public InAppPurchases getInAppPurchases() { return purchases; } @@ -207,7 +212,7 @@ public abstract class InAppPurchaseHelper { } protected void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppCommand command) { - if (isDeveloperVersion || !Version.isGooglePlayEnabled(ctx)) { + if (isDeveloperVersion || (!Version.isGooglePlayEnabled(ctx) && !Version.isHuawei(ctx))) { notifyDismissProgress(taskType); stop(true); return; @@ -266,6 +271,8 @@ public abstract class InAppPurchaseHelper { public abstract void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException; + public abstract void purchaseContourLines(@NonNull final Activity activity) throws UnsupportedOperationException; + public abstract void manageSubscription(@NonNull Context ctx, @Nullable String sku); @SuppressLint("StaticFieldLeak") @@ -491,6 +498,17 @@ public abstract class InAppPurchaseHelper { notifyItemPurchased(getDepthContours().getSku(), false); stop(true); + } else if (info.getSku().equals(getContourLines().getSku())) { + // bought contour lines + getContourLines().setPurchaseState(PurchaseState.PURCHASED); + logDebug("Contours lines purchased."); + showToast(ctx.getString(R.string.contour_lines_thanks)); + ctx.getSettings().CONTOUR_LINES_PURCHASED.set(true); + + notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_CONTOUR_LINES); + notifyItemPurchased(getContourLines().getSku(), false); + stop(true); + } else { notifyDismissProgress(activeTask); stop(true); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index e41c7d58df..82bf5667be 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -2008,6 +2008,7 @@ public class OsmandSettings { public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN = new BooleanPreference("live_updates_purchase_cancelled_second_dlg_shown", false).makeGlobal(); public final OsmandPreference FULL_VERSION_PURCHASED = new BooleanPreference("billing_full_version_purchased", false).makeGlobal(); public final OsmandPreference DEPTH_CONTOURS_PURCHASED = new BooleanPreference("billing_sea_depth_purchased", false).makeGlobal(); + public final OsmandPreference CONTOUR_LINES_PURCHASED = new BooleanPreference("billing_srtm_purchased", false).makeGlobal(); public final OsmandPreference EMAIL_SUBSCRIBED = new BooleanPreference("email_subscribed", false).makeGlobal(); public final OsmandPreference DISCOUNT_ID = new IntPreference("discount_id", 0).makeGlobal(); diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index 808c541523..cd54b83948 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -95,7 +95,9 @@ public class SRTMPlugin extends OsmandPlugin { @Override protected boolean pluginAvailable(OsmandApplication app) { - return super.pluginAvailable(app) || InAppPurchaseHelper.isSubscribedToLiveUpdates(app); + return super.pluginAvailable(app) + || InAppPurchaseHelper.isSubscribedToLiveUpdates(app) + || InAppPurchaseHelper.isContourLinesPurchased(app); } @Override From 1e4f630090f0f5315de03c16d15ee6695369b2bc Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sun, 4 Oct 2020 16:48:11 +0300 Subject: [PATCH 0455/1366] Fix build.gradle (drop content) --- build.gradle | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build.gradle b/build.gradle index e75ca7d5b8..a64480346c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,11 +6,6 @@ buildscript { jcenter() maven { url 'https://developer.huawei.com/repo/' - content { - includeGroup 'com.huawei.agconnect' - includeGroup 'com.huawei.hms' - includeGroup 'com.huawei.hmf' - } } } dependencies { @@ -45,11 +40,6 @@ allprojects { } maven { url 'https://developer.huawei.com/repo/' - content { - includeGroup 'com.huawei.agconnect' - includeGroup 'com.huawei.hms' - includeGroup 'com.huawei.hmf' - } } } } From b3bdd7cf0487a97ae77a02f1237a43051e7a09b3 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sun, 4 Oct 2020 19:09:40 +0200 Subject: [PATCH 0456/1366] Update build.gradle --- OsmAnd/build.gradle | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index a87a05b117..2db548a71b 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -196,17 +196,16 @@ android { dimension "version" applicationId "net.osmand.plus" } - fulldev { - dimension "version" - applicationId "net.osmand.plus" - resConfig "en" - //resConfigs "xxhdpi", "nodpi" - } + fulldev { + dimension "version" + applicationId "net.osmand.plus" + resConfig "en" + // resConfigs "xxhdpi", "nodpi" + } freehuawei { dimension "version" applicationId "net.osmand.huawei" } - // CoreVersion legacy { dimension "coreversion" From fb15b53f7e1774f4774fe3f4d3871af86dbb6421 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sun, 4 Oct 2020 20:17:19 +0300 Subject: [PATCH 0457/1366] Fix build.gradle (buildType) --- OsmAnd/build.gradle | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 2db548a71b..9faf1b38aa 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -225,10 +225,11 @@ android { signingConfig signingConfigs.development } release { - productFlavors.all { flavor -> - flavor.signingConfig signingConfigs.publishing + if (gradle.startParameter.taskNames.toString().contains("huawei")) { + signingConfig signingConfigs.publishingHuawei + } else { + signingConfig signingConfigs.publishing } - productFlavors.freehuawei.signingConfig signingConfigs.publishingHuawei } } From dd09d6453818fb29c166ee03910e08238785d03d Mon Sep 17 00:00:00 2001 From: sergosm Date: Sun, 4 Oct 2020 23:28:34 +0300 Subject: [PATCH 0458/1366] Try to refactor MeasurementToolFragment --- .../MeasurementToolFragment.java | 268 +--------------- .../osmand/plus/measurementtool/SaveGPX.java | 297 ++++++++++++++++++ 2 files changed, 310 insertions(+), 255 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/measurementtool/SaveGPX.java diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 7d6818a9d6..83ef171fda 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -2,7 +2,6 @@ package net.osmand.plus.measurementtool; import android.annotation.SuppressLint; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; @@ -38,7 +37,6 @@ import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; -import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; import net.osmand.LocationsHolder; @@ -83,13 +81,9 @@ import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControll import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView; import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation; -import net.osmand.util.Algorithms; import java.io.File; -import java.lang.ref.WeakReference; -import java.text.MessageFormat; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; @@ -151,13 +145,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route private MeasurementEditingContext editingCtx = new MeasurementEditingContext(); private LatLon initialPoint; + private OsmandApplication app; + private MapActivity mapActivity; + private MeasurementToolLayer measurementToolLayer; - private enum SaveType { + enum SaveType { ROUTE_POINT, LINE } - private enum FinalSaveAction { + enum FinalSaveAction { SHOW_SNACK_BAR_AND_CLOSE, SHOW_TOAST, SHOW_IS_SAVED_FRAGMENT @@ -171,7 +168,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route this.initialPoint = initialPoint; } - private void setMode(int mode, boolean on) { + void setMode(int mode, boolean on) { int modes = this.modes; if (on) { modes |= mode; @@ -181,7 +178,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route this.modes = modes; } - private boolean isPlanRouteMode() { + boolean isPlanRouteMode() { return (this.modes & PLAN_ROUTE_MODE) == PLAN_ROUTE_MODE; } @@ -1062,7 +1059,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } @Nullable - private GpxData setupGpxData(@Nullable GPXFile gpxFile) { + GpxData setupGpxData(@Nullable GPXFile gpxFile) { GpxData gpxData = null; if (gpxFile != null) { QuadRect rect = gpxFile.getRect(); @@ -1284,7 +1281,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size()); } - private void cancelModes() { + void cancelModes() { if (editingCtx.getOriginalPointToMove() != null) { cancelMovePointMode(); } else if (editingCtx.isInAddPointMode()) { @@ -1545,247 +1542,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route final SaveType saveType, final FinalSaveAction finalSaveAction) { - new AsyncTask() { - - private ProgressDialog progressDialog; - private File backupFile; - private File outFile; - private GPXFile savedGpxFile; - - @Override - protected void onPreExecute() { - cancelModes(); - MapActivity activity = getMapActivity(); - if (activity != null) { - progressDialog = new ProgressDialog(activity); - progressDialog.setMessage(getString(R.string.saving_gpx_tracks)); - progressDialog.show(); - } - } - - @Override - protected Exception doInBackground(Void... voids) { - MeasurementToolLayer measurementLayer = getMeasurementLayer(); - OsmandApplication app = getMyApplication(); - if (app == null) { - return null; - } - List points = editingCtx.getPoints(); - TrkSegment before = editingCtx.getBeforeTrkSegmentLine(); - TrkSegment after = editingCtx.getAfterTrkSegmentLine(); - if (gpxFile == null) { - outFile = new File(dir, fileName); - String trackName = fileName.substring(0, fileName.length() - GPX_FILE_EXT.length()); - GPXFile gpx = new GPXFile(Version.getFullVersion(app)); - if (measurementLayer != null) { - if (saveType == SaveType.LINE) { - TrkSegment segment = new TrkSegment(); - if (editingCtx.hasRoute()) { - segment.points.addAll(editingCtx.getRoutePoints()); - } else { - segment.points.addAll(before.points); - segment.points.addAll(after.points); - } - Track track = new Track(); - track.name = trackName; - track.segments.add(segment); - gpx.tracks.add(track); - } else if (saveType == SaveType.ROUTE_POINT) { - if (editingCtx.hasRoute()) { - GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName); - if (newGpx != null) { - gpx = newGpx; - } - } - gpx.addRoutePoints(points); - } - } - Exception res = GPXUtilities.writeGpxFile(outFile, gpx); - gpx.path = outFile.getAbsolutePath(); - savedGpxFile = gpx; - if (showOnMap) { - showGpxOnMap(app, gpx, true); - } - return res; - } else { - GPXFile gpx = gpxFile; - outFile = new File(gpx.path); - backupFile = FileUtils.backupFile(app, outFile); - String trackName = Algorithms.getFileNameWithoutExtension(outFile); - if (measurementLayer != null) { - if (isPlanRouteMode()) { - if (saveType == SaveType.LINE) { - TrkSegment segment = new TrkSegment(); - if (editingCtx.hasRoute()) { - segment.points.addAll(editingCtx.getRoutePoints()); - } else { - segment.points.addAll(before.points); - segment.points.addAll(after.points); - } - Track track = new Track(); - track.name = trackName; - track.segments.add(segment); - gpx.tracks.add(track); - } else if (saveType == SaveType.ROUTE_POINT) { - if (editingCtx.hasRoute()) { - GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName); - if (newGpx != null) { - gpx = newGpx; - } - } - gpx.addRoutePoints(points); - } - } else if (actionType != null) { - GpxData gpxData = editingCtx.getGpxData(); - switch (actionType) { - case ADD_SEGMENT: { - List snappedPoints = new ArrayList<>(); - snappedPoints.addAll(before.points); - snappedPoints.addAll(after.points); - gpx.addTrkSegment(snappedPoints); - break; - } - case ADD_ROUTE_POINTS: { - gpx.replaceRoutePoints(points); - break; - } - case EDIT_SEGMENT: { - if (gpxData != null) { - TrkSegment segment = new TrkSegment(); - segment.points.addAll(points); - gpx.replaceSegment(gpxData.getTrkSegment(), segment); - } - break; - } - case OVERWRITE_SEGMENT: { - if (gpxData != null) { - List snappedPoints = new ArrayList<>(); - snappedPoints.addAll(before.points); - snappedPoints.addAll(after.points); - TrkSegment segment = new TrkSegment(); - segment.points.addAll(snappedPoints); - gpx.replaceSegment(gpxData.getTrkSegment(), segment); - } - break; - } - } - } else { - gpx.addRoutePoints(points); - } - } - Exception res = null; - if (!gpx.showCurrentTrack) { - res = GPXUtilities.writeGpxFile(outFile, gpx); - } - savedGpxFile = gpx; - if (showOnMap) { - showGpxOnMap(app, gpx, false); - } - return res; - } - } - - private void showGpxOnMap(OsmandApplication app, GPXFile gpx, boolean isNewGpx) { - SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false); - if (sf != null && !isNewGpx) { - if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) { - sf.processPoints(getMyApplication()); - } - } - } - - @Override - protected void onPostExecute(Exception warning) { - onGpxSaved(warning); - } - - private void onGpxSaved(Exception warning) { - MapActivity mapActivity = getMapActivity(); - if (mapActivity == null) { - return; - } - if (progressDialog != null && progressDialog.isShowing()) { - progressDialog.dismiss(); - } - mapActivity.refreshMap(); - if (warning == null) { - if (editingCtx.isNewData() && savedGpxFile != null) { - QuadRect rect = savedGpxFile.getRect(); - TrkSegment segment = savedGpxFile.getNonEmptyTrkSegment(); - GpxData gpxData = new GpxData(savedGpxFile, rect, ActionType.EDIT_SEGMENT, segment); - editingCtx.setGpxData(gpxData); - updateToolbar(); - } - if (isInEditMode()) { - editingCtx.setChangesSaved(); - dismiss(mapActivity); - } else { - switch (finalSaveAction) { - case SHOW_SNACK_BAR_AND_CLOSE: - final WeakReference mapActivityRef = new WeakReference<>(mapActivity); - snackbar = Snackbar.make(mapActivity.getLayout(), - MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getName()), - Snackbar.LENGTH_LONG) - .setAction(R.string.shared_string_undo, new OnClickListener() { - @Override - public void onClick(View view) { - MapActivity mapActivity = mapActivityRef.get(); - if (mapActivity != null) { - if (outFile != null) { - OsmandApplication app = mapActivity.getMyApplication(); - FileUtils.removeGpxFile(app, outFile); - if (backupFile != null) { - FileUtils.renameGpxFile(app, backupFile, outFile); - GPXFile gpx = GPXUtilities.loadGPXFile(outFile); - setupGpxData(gpx); - if (showOnMap) { - showGpxOnMap(app, gpx, false); - } - } else { - setupGpxData(null); - } - } - setMode(UNDO_MODE, true); - MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), - editingCtx, modes); - } - } - }) - .addCallback(new Snackbar.Callback() { - @Override - public void onDismissed(Snackbar transientBottomBar, int event) { - if (event != DISMISS_EVENT_ACTION) { - editingCtx.setChangesSaved(); - } - super.onDismissed(transientBottomBar, event); - } - }); - snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_action) - .setAllCaps(false); - UiUtilities.setupSnackbar(snackbar, nightMode); - snackbar.show(); - dismiss(mapActivity, false); - break; - case SHOW_IS_SAVED_FRAGMENT: - editingCtx.setChangesSaved(); - SavedTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), - outFile.getAbsolutePath()); - dismiss(mapActivity); - break; - case SHOW_TOAST: - editingCtx.setChangesSaved(); - if (!savedGpxFile.showCurrentTrack) { - Toast.makeText(mapActivity, - MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getAbsolutePath()), - Toast.LENGTH_LONG).show(); - } - } - } - } else { - Toast.makeText(mapActivity, warning.getMessage(), Toast.LENGTH_LONG).show(); - } - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new SaveGPX(this, gpxFile, dir, fileName, saveType, showOnMap, actionType, finalSaveAction, app, mapActivity, measurementToolLayer, nightMode).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private void updateUndoRedoButton(boolean enable, View view) { @@ -1818,7 +1575,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route updateToolbar(); } - private void updateToolbar() { + void updateToolbar() { MapActivity mapActivity = getMapActivity(); if (mapActivity == null) { return; @@ -1949,7 +1706,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } } - private void dismiss(@NonNull MapActivity mapActivity) { + void dismiss(@NonNull MapActivity mapActivity) { dismiss(mapActivity, true); } @@ -2171,4 +1928,5 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route public boolean isNightModeForMapControls() { return nightMode; } + } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveGPX.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveGPX.java new file mode 100644 index 0000000000..de47191ab5 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveGPX.java @@ -0,0 +1,297 @@ +package net.osmand.plus.measurementtool; + +import android.annotation.SuppressLint; +import android.app.ProgressDialog; +import android.os.AsyncTask; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.material.snackbar.Snackbar; + +import net.osmand.FileUtils; +import net.osmand.GPXUtilities; +import net.osmand.data.QuadRect; +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.Version; +import net.osmand.plus.activities.MapActivity; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.lang.ref.WeakReference; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.IndexConstants.GPX_FILE_EXT; + +class SaveGPX extends AsyncTask { + + private final MeasurementToolFragment measurementToolFragment; + private final GPXUtilities.GPXFile gpxFile; + private final File dir; + private final String fileName; + private final MeasurementToolFragment.SaveType saveType; + private final boolean showOnMap; + private final GpxData.ActionType actionType; + private final MeasurementToolFragment.FinalSaveAction finalSaveAction; + private final OsmandApplication app; + @SuppressLint("StaticFieldLeak") + private final MapActivity mapActivity; + private MeasurementToolLayer measurementToolLayer; + private boolean nightMode; + private ProgressDialog progressDialog; + private File backupFile; + private File outFile; + private GPXUtilities.GPXFile savedGpxFile; + public MeasurementEditingContext editingCtx = new MeasurementEditingContext(); + private static final int UNDO_MODE = 0x8; + + public SaveGPX(MeasurementToolFragment measurementToolFragment, GPXUtilities.GPXFile gpxFile, File dir, String fileName, MeasurementToolFragment.SaveType saveType, boolean showOnMap, GpxData.ActionType actionType, MeasurementToolFragment.FinalSaveAction finalSaveAction, OsmandApplication app, MapActivity mapActivity, MeasurementToolLayer measurementToolLayer, boolean nightMode) { + this.measurementToolFragment = measurementToolFragment; + this.gpxFile = gpxFile; + this.dir = dir; + this.fileName = fileName; + this.saveType = saveType; + this.showOnMap = showOnMap; + this.actionType = actionType; + this.finalSaveAction = finalSaveAction; + this.app = app; + this.mapActivity = mapActivity; + this.measurementToolLayer = measurementToolLayer; + this.nightMode = nightMode; + } + + @Override + protected void onPreExecute() { + measurementToolFragment.cancelModes(); + if (mapActivity != null) { + progressDialog = new ProgressDialog(mapActivity); + progressDialog.setMessage(measurementToolFragment.getString(R.string.saving_gpx_tracks)); + progressDialog.show(); + } + } + + @Override + protected Exception doInBackground(Void... voids) { + if (app == null) { + return null; + } + List points = editingCtx.getPoints(); + GPXUtilities.TrkSegment before = editingCtx.getBeforeTrkSegmentLine(); + GPXUtilities.TrkSegment after = editingCtx.getAfterTrkSegmentLine(); + if (gpxFile == null) { + outFile = new File(dir, fileName); + String trackName = fileName.substring(0, fileName.length() - GPX_FILE_EXT.length()); + GPXUtilities.GPXFile gpx = new GPXUtilities.GPXFile(Version.getFullVersion(app)); + if (measurementToolLayer != null) { + if (saveType == MeasurementToolFragment.SaveType.LINE) { + GPXUtilities.TrkSegment segment = new GPXUtilities.TrkSegment(); + if (editingCtx.hasRoute()) { + segment.points.addAll(editingCtx.getRoutePoints()); + } else { + segment.points.addAll(before.points); + segment.points.addAll(after.points); + } + GPXUtilities.Track track = new GPXUtilities.Track(); + track.name = trackName; + track.segments.add(segment); + gpx.tracks.add(track); + } else if (saveType == MeasurementToolFragment.SaveType.ROUTE_POINT) { + if (editingCtx.hasRoute()) { + GPXUtilities.GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName); + if (newGpx != null) { + gpx = newGpx; + } + } + gpx.addRoutePoints(points); + } + } + Exception res = GPXUtilities.writeGpxFile(outFile, gpx); + gpx.path = outFile.getAbsolutePath(); + savedGpxFile = gpx; + if (showOnMap) { + showGpxOnMap(app, gpx, true); + } + return res; + } else { + GPXUtilities.GPXFile gpx = gpxFile; + outFile = new File(gpx.path); + backupFile = FileUtils.backupFile(app, outFile); + String trackName = Algorithms.getFileNameWithoutExtension(outFile); + if (measurementToolLayer != null) { + if (measurementToolFragment.isPlanRouteMode()) { + if (saveType == MeasurementToolFragment.SaveType.LINE) { + GPXUtilities.TrkSegment segment = new GPXUtilities.TrkSegment(); + if (editingCtx.hasRoute()) { + segment.points.addAll(editingCtx.getRoutePoints()); + } else { + segment.points.addAll(before.points); + segment.points.addAll(after.points); + } + GPXUtilities.Track track = new GPXUtilities.Track(); + track.name = trackName; + track.segments.add(segment); + gpx.tracks.add(track); + } else if (saveType == MeasurementToolFragment.SaveType.ROUTE_POINT) { + if (editingCtx.hasRoute()) { + GPXUtilities.GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName); + if (newGpx != null) { + gpx = newGpx; + } + } + gpx.addRoutePoints(points); + } + } else if (actionType != null) { + GpxData gpxData = editingCtx.getGpxData(); + switch (actionType) { + case ADD_SEGMENT: { + List snappedPoints = new ArrayList<>(); + snappedPoints.addAll(before.points); + snappedPoints.addAll(after.points); + gpx.addTrkSegment(snappedPoints); + break; + } + case ADD_ROUTE_POINTS: { + gpx.replaceRoutePoints(points); + break; + } + case EDIT_SEGMENT: { + if (gpxData != null) { + GPXUtilities.TrkSegment segment = new GPXUtilities.TrkSegment(); + segment.points.addAll(points); + gpx.replaceSegment(gpxData.getTrkSegment(), segment); + } + break; + } + case OVERWRITE_SEGMENT: { + if (gpxData != null) { + List snappedPoints = new ArrayList<>(); + snappedPoints.addAll(before.points); + snappedPoints.addAll(after.points); + GPXUtilities.TrkSegment segment = new GPXUtilities.TrkSegment(); + segment.points.addAll(snappedPoints); + gpx.replaceSegment(gpxData.getTrkSegment(), segment); + } + break; + } + } + } else { + gpx.addRoutePoints(points); + } + } + Exception res = null; + if (!gpx.showCurrentTrack) { + res = GPXUtilities.writeGpxFile(outFile, gpx); + } + savedGpxFile = gpx; + if (showOnMap) { + showGpxOnMap(app, gpx, false); + } + return res; + } + } + + private void showGpxOnMap(OsmandApplication app, GPXUtilities.GPXFile gpx, boolean isNewGpx) { + GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false); + if (sf != null && !isNewGpx) { + if (actionType == GpxData.ActionType.ADD_SEGMENT || actionType == GpxData.ActionType.EDIT_SEGMENT) { + sf.processPoints(app); + } + } + } + + @Override + protected void onPostExecute(Exception warning) { + onGpxSaved(warning); + } + + private void onGpxSaved(Exception warning) { + if (mapActivity == null) { + return; + } + if (progressDialog != null && progressDialog.isShowing()) { + progressDialog.dismiss(); + } + mapActivity.refreshMap(); + if (warning == null) { + if (editingCtx.isNewData() && savedGpxFile != null) { + QuadRect rect = savedGpxFile.getRect(); + GPXUtilities.TrkSegment segment = savedGpxFile.getNonEmptyTrkSegment(); + GpxData gpxData = new GpxData(savedGpxFile, rect, GpxData.ActionType.EDIT_SEGMENT, segment); + editingCtx.setGpxData(gpxData); + measurementToolFragment.updateToolbar(); + } + if (measurementToolFragment.isInEditMode()) { + editingCtx.setChangesSaved(); + measurementToolFragment.dismiss(mapActivity); + } else { + switch (finalSaveAction) { + case SHOW_SNACK_BAR_AND_CLOSE: + final WeakReference mapActivityRef = new WeakReference<>(mapActivity); + Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), + MessageFormat.format(measurementToolFragment.getString(R.string.gpx_saved_sucessfully), outFile.getName()), + Snackbar.LENGTH_LONG) + .setAction(R.string.shared_string_undo, new View.OnClickListener() { + @Override + public void onClick(View view) { + MapActivity mapActivity = mapActivityRef.get(); + if (mapActivity != null) { + if (outFile != null) { + OsmandApplication app = mapActivity.getMyApplication(); + FileUtils.removeGpxFile(app, outFile); + if (backupFile != null) { + FileUtils.renameGpxFile(app, backupFile, outFile); + GPXUtilities.GPXFile gpx = GPXUtilities.loadGPXFile(outFile); + measurementToolFragment.setupGpxData(gpx); + if (showOnMap) { + showGpxOnMap(app, gpx, false); + } + } else { + measurementToolFragment.setupGpxData(null); + } + } + measurementToolFragment.setMode(UNDO_MODE, true); + MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager() + ); + } + } + }) + .addCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar transientBottomBar, int event) { + if (event != DISMISS_EVENT_ACTION) { + editingCtx.setChangesSaved(); + } + super.onDismissed(transientBottomBar, event); + } + }); + snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_action) + .setAllCaps(false); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); + measurementToolFragment.dismiss(mapActivity); + break; + case SHOW_IS_SAVED_FRAGMENT: + editingCtx.setChangesSaved(); + SavedTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), + outFile.getAbsolutePath()); + measurementToolFragment.dismiss(mapActivity); + break; + case SHOW_TOAST: + editingCtx.setChangesSaved(); + if (!savedGpxFile.showCurrentTrack) { + Toast.makeText(mapActivity, + MessageFormat.format(measurementToolFragment.getString(R.string.gpx_saved_sucessfully), outFile.getAbsolutePath()), + Toast.LENGTH_LONG).show(); + } + } + } + } else { + Toast.makeText(mapActivity, warning.getMessage(), Toast.LENGTH_LONG).show(); + } + } +} From 0948476bf8bcb8f945c1834390f18217807d7ac1 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 5 Oct 2020 09:54:25 +0300 Subject: [PATCH 0459/1366] style issues fixed --- .../java/net/osmand/osm/io/NetworkUtils.java | 6 ++--- .../oauth/OsmOAuthAuthorizationClient.java | 23 +++++++++++-------- .../plus/download/DownloadIndexesThread.java | 3 +-- .../plus/osmedit/OpenstreetmapRemoteUtil.java | 2 +- .../plus/osmedit/OsmBugsRemoteUtil.java | 2 +- .../osmedit/SettingsOsmEditingActivity.java | 17 ++++++++------ .../UploadOpenstreetmapPointAsyncTask.java | 2 +- .../oauth/OsmOAuthAuthorizationAdapter.java | 6 ++--- 8 files changed, 33 insertions(+), 28 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java index bdf5b6a70e..8880184f96 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java @@ -82,9 +82,9 @@ public class NetworkUtils { } return null; } catch (InterruptedException e) { - e.printStackTrace(); + log.error(e); } catch (ExecutionException e) { - e.printStackTrace(); + log.error(e); } return null; } @@ -166,7 +166,7 @@ public class NetworkUtils { Algorithms.closeStream(ous); return ous.toByteArray(); } catch (IOException e) { - e.printStackTrace(); + log.error(e); } return new byte[0]; } diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java index ed2854bb02..5726855f72 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java @@ -6,6 +6,8 @@ import com.github.scribejava.core.builder.api.DefaultApi10a; import com.github.scribejava.core.builder.api.OAuth1SignatureType; import com.github.scribejava.core.model.*; import com.github.scribejava.core.oauth.OAuth10aService; +import net.osmand.PlatformUtil; +import org.apache.commons.logging.Log; import java.io.IOException; import java.util.concurrent.ExecutionException; @@ -16,9 +18,10 @@ import java.util.concurrent.ExecutionException; * @since 2746 */ public class OsmOAuthAuthorizationClient { - OAuth10aService service; - OAuth1RequestToken requestToken; - OAuth1AccessToken accessToken; + private OAuth1RequestToken requestToken; + private OAuth1AccessToken accessToken; + private final OAuth10aService service; + public final static Log log = PlatformUtil.getLog(OsmOAuthAuthorizationClient.class); public OsmOAuthAuthorizationClient(String key, String secret) { service = new ServiceBuilder(key) @@ -58,7 +61,7 @@ public class OsmOAuthAuthorizationClient { } public OAuth1AccessToken getAccessToken() { - return this.accessToken; + return accessToken; } public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody) @@ -96,11 +99,11 @@ public class OsmOAuthAuthorizationClient { try { requestToken = service.getRequestToken(); } catch (IOException e) { - e.printStackTrace(); + log.error(e); } catch (InterruptedException e) { - e.printStackTrace(); + log.error(e); } catch (ExecutionException e) { - e.printStackTrace(); + log.error(e); } return requestToken; } @@ -109,11 +112,11 @@ public class OsmOAuthAuthorizationClient { try { setAccessToken(service.getAccessToken(requestToken, oauthVerifier)); } catch (IOException e) { - e.printStackTrace(); + log.error(e); } catch (InterruptedException e) { - e.printStackTrace(); + log.error(e); } catch (ExecutionException e) { - e.printStackTrace(); + log.error(e); } return accessToken; } diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 8f826e76b1..450d7e4b0d 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -59,8 +59,8 @@ public class DownloadIndexesThread { private ConcurrentLinkedQueue indexItemDownloading = new ConcurrentLinkedQueue(); private IndexItem currentDownloadingItem = null; private int currentDownloadingItemProgress = 0; - private DownloadResources indexes; + private static final int THREAD_ID = 10103; public interface DownloadEvents { @@ -337,7 +337,6 @@ public class DownloadIndexesThread { @Override protected DownloadResources doInBackground(Void... params) { - final int THREAD_ID = 10103; TrafficStats.setThreadStatsTag(THREAD_ID); DownloadResources result = null; DownloadOsmandIndexesHelper.IndexFileList indexFileList = DownloadOsmandIndexesHelper.getIndexesList(ctx); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java index 74eb48c1b4..e978c3841b 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java @@ -180,7 +180,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { id = Long.parseLong(response); } } catch (Exception e) { - e.printStackTrace(); + log.error(e); } return id; } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java index 75b226eb3f..724f798bf7 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java @@ -109,7 +109,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil { private OsmBugResult editingPOI(String url, String requestMethod, String userOperation, boolean anonymous) { - OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(this.app); + OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(app); OsmBugResult r = new OsmBugResult(); try { HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java index c4c8cb8d38..6be8066553 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java @@ -19,17 +19,20 @@ import android.widget.TextView; import android.widget.Toast; import com.github.scribejava.core.model.OAuthAsyncRequestCallback; import com.github.scribejava.core.model.Response; +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; import net.osmand.plus.settings.backend.OsmAndAppCustomization; +import org.apache.commons.logging.Log; import java.io.IOException; public class SettingsOsmEditingActivity extends SettingsBaseActivity { - OsmOAuthAuthorizationAdapter client; + private OsmOAuthAuthorizationAdapter client; + private static final Log log = PlatformUtil.getLog(SettingsOsmEditingActivity.class); @Override public void onCreate(Bundle savedInstanceState) { @@ -43,7 +46,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { ((OsmandApplication) getApplication()).applyTheme(this); super.onCreate(savedInstanceState); - client = new OsmOAuthAuthorizationAdapter(this.getMyApplication()); + client = new OsmOAuthAuthorizationAdapter(getMyApplication()); getToolbar().setTitle(R.string.osm_settings); @SuppressWarnings("deprecation") @@ -78,12 +81,12 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { if (client.isValidToken()){ prefOAuth.setTitle(R.string.osm_authorization_success); prefOAuth.setSummary(R.string.osm_authorization_success); - prefOAuth.setKey("local_openstreetmap_token"); + prefOAuth.setKey("local_openstreetmap_oauth_success"); final Preference prefTestUser = new Preference(this); prefTestUser.setTitle(R.string.test_user_request); prefTestUser.setSummary(R.string.test_user_request_description); - prefTestUser.setKey("local_openstreetmap_token"); + prefTestUser.setKey("local_openstreetmap_oauth_user"); prefTestUser.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { @@ -94,7 +97,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { try { Toast.makeText(SettingsOsmEditingActivity.this,response.getBody(),Toast.LENGTH_SHORT).show(); } catch (IOException e) { - e.printStackTrace(); + log.error(e); } } @@ -110,7 +113,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { final Preference prefClearToken = new Preference(this); prefClearToken.setTitle(R.string.shared_string_logoff); prefClearToken.setSummary(R.string.clear_osm_token); - prefClearToken.setKey("local_openstreetmap_token"); + prefClearToken.setKey("local_openstreetmap_oauth_clear"); prefClearToken.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { @@ -128,7 +131,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { else { prefOAuth.setTitle(R.string.perform_oauth_authorization); prefOAuth.setSummary(R.string.perform_oauth_authorization_description); - prefOAuth.setKey("local_openstreetmap_token"); + prefOAuth.setKey("local_openstreetmap_oauth_login"); prefOAuth.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java b/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java index 3824d060c7..285c359656 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/UploadOpenstreetmapPointAsyncTask.java @@ -25,6 +25,7 @@ public class UploadOpenstreetmapPointAsyncTask private OsmEditingPlugin plugin; private final boolean closeChangeSet; private final boolean loadAnonymous; + private static final int THREAD_ID = 10102; public UploadOpenstreetmapPointAsyncTask(ProgressDialogFragment progress, OsmEditsUploadListener listener, @@ -44,7 +45,6 @@ public class UploadOpenstreetmapPointAsyncTask @Override protected Map doInBackground(OsmPoint... points) { - final int THREAD_ID = 10102; TrafficStats.setThreadStatsTag(THREAD_ID); Map loadErrorsMap = new HashMap<>(); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java index 47757317f7..09a3dba0c4 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java @@ -16,11 +16,11 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; public class OsmOAuthAuthorizationAdapter { - OsmandApplication application; - OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET); + private OsmandApplication application; + private OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET); + private static final int THREAD_ID = 10101; public OsmOAuthAuthorizationAdapter(OsmandApplication application) { - final int THREAD_ID = 10101; TrafficStats.setThreadStatsTag(THREAD_ID); this.application = application; restoreToken(); From 447259b80b3b90081f451a4e39da1d7be6aff4b4 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 5 Oct 2020 12:13:21 +0300 Subject: [PATCH 0460/1366] Small pr fixes --- OsmAnd/res/layout/bottom_buttons_vertical.xml | 85 ++++++++++--------- .../base/MenuBottomSheetDialogFragment.java | 23 +++-- .../ExitBottomSheetDialogFragment.java | 16 ++-- 3 files changed, 64 insertions(+), 60 deletions(-) diff --git a/OsmAnd/res/layout/bottom_buttons_vertical.xml b/OsmAnd/res/layout/bottom_buttons_vertical.xml index 5ea2d4954c..0de7d48389 100644 --- a/OsmAnd/res/layout/bottom_buttons_vertical.xml +++ b/OsmAnd/res/layout/bottom_buttons_vertical.xml @@ -1,51 +1,52 @@ + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/buttons_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:gravity="center" + android:orientation="vertical" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingTop="@dimen/content_padding_small" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" + android:paddingBottom="@dimen/content_padding_small"> - + - + - + - + - + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index 0d86993502..307cfb3bbe 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -52,9 +52,9 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra protected View rightButton; protected View thirdButton; + private View buttonsShadow; private LinearLayout itemsContainer; private LinearLayout buttonsContainer; - protected View buttonsShadow; @StringRes protected int dismissButtonStringRes = R.string.shared_string_cancel; @@ -162,6 +162,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } final int screenHeight = AndroidUtils.getScreenHeight(activity); final int statusBarHeight = AndroidUtils.getStatusBarHeight(activity); + final int contentHeight = getContentHeight(screenHeight - statusBarHeight); mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override @@ -172,7 +173,6 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } else { obs.removeGlobalOnLayoutListener(this); } - final int contentHeight = getContentHeight(screenHeight - statusBarHeight); final View contentView = useScrollableItemsContainer() ? mainView.findViewById(R.id.scroll_view) : itemsContainer; if (contentView.getHeight() > contentHeight) { @@ -201,9 +201,14 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private int getContentHeight(int availableScreenHeight) { int customHeight = getCustomHeight(); - int buttonsHeight = 0; + int buttonsHeight; if (useVerticalButtons()) { - buttonsHeight = AndroidUtils.dpToPx(getContext(), 112); + int padding = getResources().getDimensionPixelSize(R.dimen.content_padding_small); + int buttonHeight = getResources().getDimensionPixelSize(R.dimen.dialog_button_height); + buttonsHeight = (buttonHeight + padding) * 2 + getFirstDividerHeight(); + if (getThirdBottomButtonTextId() != DEFAULT_VALUE) { + buttonsHeight += buttonHeight + getSecondDividerHeight(); + } } else { buttonsHeight = getResources().getDimensionPixelSize(R.dimen.dialog_button_ex_height); } @@ -310,10 +315,12 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra } String rightButtonText = getString(rightBottomButtonTextId); boolean portrait = AndroidUiHelper.isOrientationPortrait(activity); + int outerPadding = getResources().getDimensionPixelSize(R.dimen.content_padding); + int innerPadding = getResources().getDimensionPixelSize(R.dimen.content_padding_small); int dialogWidth = portrait ? AndroidUtils.getScreenWidth(activity) : getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width); - int measuredTextWidth = AndroidUtils.getTextWidth(getResources().getDimensionPixelSize(R.dimen.default_desc_text_size), rightButtonText); - int availableTextWidth = (dialogWidth - AndroidUtils.dpToPx(activity, 96)) / 2; + int availableTextWidth = (dialogWidth - (outerPadding * 3 + innerPadding * 4)) / 2; + int measuredTextWidth = AndroidUtils.getTextWidth(getResources().getDimensionPixelSize(R.dimen.default_desc_text_size), rightButtonText); return measuredTextWidth > availableTextWidth; } return false; @@ -366,7 +373,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra AndroidUiHelper.updateVisibility(divider, buttonTextId != DEFAULT_VALUE); } - protected int getFirstDividerHeight(){ + protected int getFirstDividerHeight() { return getResources().getDimensionPixelSize(R.dimen.content_padding); } @@ -388,7 +395,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra AndroidUiHelper.updateVisibility(divider, buttonTextId != DEFAULT_VALUE); } - protected int getSecondDividerHeight(){ + protected int getSecondDividerHeight() { return getResources().getDimensionPixelSize(R.dimen.content_padding); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java index 7d88767964..1bdd3ffdf2 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/ExitBottomSheetDialogFragment.java @@ -1,7 +1,6 @@ package net.osmand.plus.measurementtool; import android.os.Bundle; -import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -9,12 +8,10 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.base.MenuBottomSheetDialogFragment; -import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemButton; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; -import net.osmand.plus.helpers.AndroidUiHelper; public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { @@ -29,8 +26,7 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment items.add(new ShortDescriptionItem.Builder() .setDescription(getString(R.string.plan_route_exit_dialog_descr)) - .setTitle(getString(R.string. - exit_without_saving)) + .setTitle(getString(R.string.exit_without_saving)) .setLayoutId(R.layout.bottom_sheet_item_list_title_with_descr) .create()); @@ -56,7 +52,7 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment @Override public int getSecondDividerHeight() { - return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large); + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin); } @Override @@ -78,8 +74,8 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment } @Override - protected UiUtilities.DialogButtonType getThirdBottomButtonType() { - return (UiUtilities.DialogButtonType.SECONDARY); + protected DialogButtonType getThirdBottomButtonType() { + return (DialogButtonType.SECONDARY); } public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment targetFragment) { @@ -89,4 +85,4 @@ public class ExitBottomSheetDialogFragment extends MenuBottomSheetDialogFragment fragment.show(fragmentManager, TAG); } } -} +} \ No newline at end of file From 950bc1bd4a1126b64bc1422f416818b01d6b4d35 Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Mon, 5 Oct 2020 13:03:18 +0300 Subject: [PATCH 0461/1366] Add Logcat Buffer to Telegram Tracker --- OsmAnd-telegram/AndroidManifest.xml | 2 +- .../res/layout/activity_tracker_logcat.xml | 44 +++ .../res/layout/fragement_settings_dialog.xml | 44 +++ .../res/layout/item_description_long.xml | 18 ++ OsmAnd-telegram/res/values/dimens.xml | 2 +- OsmAnd-telegram/res/values/strings.xml | 4 + .../src/net/osmand/TrackerLogcatActivity.kt | 270 ++++++++++++++++++ .../osmand/telegram/TelegramApplication.kt | 33 +++ .../telegram/ui/SettingsDialogFragment.kt | 7 + 9 files changed, 422 insertions(+), 2 deletions(-) create mode 100644 OsmAnd-telegram/res/layout/activity_tracker_logcat.xml create mode 100644 OsmAnd-telegram/res/layout/item_description_long.xml create mode 100644 OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml index 7b2a96c236..2146f9b89a 100644 --- a/OsmAnd-telegram/AndroidManifest.xml +++ b/OsmAnd-telegram/AndroidManifest.xml @@ -20,7 +20,7 @@ android:screenOrientation="unspecified" android:supportsRtl="true" android:theme="@style/AppTheme"> - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml b/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml index 928ad6f319..1c5738a313 100644 --- a/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml +++ b/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml @@ -447,6 +447,50 @@ + + + + + + + + + + + + + + diff --git a/OsmAnd-telegram/res/layout/item_description_long.xml b/OsmAnd-telegram/res/layout/item_description_long.xml new file mode 100644 index 0000000000..4dbc4d7165 --- /dev/null +++ b/OsmAnd-telegram/res/layout/item_description_long.xml @@ -0,0 +1,18 @@ + + diff --git a/OsmAnd-telegram/res/values/dimens.xml b/OsmAnd-telegram/res/values/dimens.xml index 7f4942dc3e..c7e0bd6b9c 100644 --- a/OsmAnd-telegram/res/values/dimens.xml +++ b/OsmAnd-telegram/res/values/dimens.xml @@ -27,7 +27,7 @@ 89dp 48dp - 42dp + 44dp 56dp 48dp diff --git a/OsmAnd-telegram/res/values/strings.xml b/OsmAnd-telegram/res/values/strings.xml index 2b5eca334e..8bccf957ce 100644 --- a/OsmAnd-telegram/res/values/strings.xml +++ b/OsmAnd-telegram/res/values/strings.xml @@ -1,5 +1,9 @@ + Send report + Check and share detailed logs of the app + Logcat buffer + Export ERR Last update from Telegram: %1$s Last response: %1$s diff --git a/OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt b/OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt new file mode 100644 index 0000000000..5ed551636a --- /dev/null +++ b/OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt @@ -0,0 +1,270 @@ +package net.osmand + +import android.os.AsyncTask +import android.os.Bundle +import android.view.* +import android.widget.ProgressBar +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import net.osmand.telegram.R +import net.osmand.telegram.TelegramApplication +import java.io.* +import java.lang.ref.WeakReference +import java.util.* + +private const val LOGCAT_PATH = "logcat.log" +private const val MAX_BUFFER_LOG = 10000 +private const val SHARE_ID = 0 +private const val LEVEL_ID = 1 +private val log = PlatformUtil.getLog(TrackerLogcatActivity::class.java) + +class TrackerLogcatActivity : AppCompatActivity() { + private var logcatAsyncTask: LogcatAsyncTask? = null + private val logs: MutableList = ArrayList() + private var adapter: LogcatAdapter? = null + private val LEVELS = arrayOf("D", "I", "W", "E") + private var filterLevel = 1 + private var recyclerView: RecyclerView? = null + + override fun onCreate(savedInstanceState: Bundle?) { + val app: TelegramApplication = getApplication() as TelegramApplication + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_tracker_logcat) + + log.debug("text to test") + + val toolbar = findViewById(R.id.toolbar).apply { + navigationIcon = app.uiUtils.getThemedIcon(R.drawable.ic_arrow_back) + setNavigationOnClickListener { onBackPressed() } + } + setSupportActionBar(toolbar) + setupIntermediateProgressBar() + + adapter = LogcatAdapter() + recyclerView = findViewById(R.id.recycler_view) as RecyclerView? + recyclerView!!.layoutManager = LinearLayoutManager(this) + recyclerView!!.adapter = adapter + } + + protected fun setupIntermediateProgressBar() { + val progressBar = ProgressBar(this) + progressBar.visibility = View.GONE + progressBar.isIndeterminate = true + val supportActionBar = supportActionBar + if (supportActionBar != null) { + supportActionBar.setDisplayShowCustomEnabled(true) + supportActionBar.customView = progressBar + setSupportProgressBarIndeterminateVisibility(false) + } + } + + override fun setSupportProgressBarIndeterminateVisibility(visible: Boolean) { + val supportActionBar = supportActionBar + if (supportActionBar != null) { + supportActionBar.customView.visibility = if (visible) View.VISIBLE else View.GONE + } + } + + override fun onResume() { + super.onResume() + startLogcatAsyncTask() + } + + override fun onPause() { + super.onPause() + stopLogcatAsyncTask() + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + val app: TelegramApplication = applicationContext as TelegramApplication + val share: MenuItem = menu.add(0, SHARE_ID, 0, R.string.shared_string_export) + share.icon = app.uiUtils.getThemedIcon(R.drawable.ic_action_share) + share.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) + val level = menu.add(0, LEVEL_ID, 0, "") + level.title = getFilterLevel() + level.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) + return super.onCreateOptionsMenu(menu) + } + + private fun getFilterLevel(): String { + return "*:" + LEVELS[filterLevel] + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val itemId = item.itemId + when (itemId) { + android.R.id.home -> { + finish() + return true + } + LEVEL_ID -> { + filterLevel++ + if (filterLevel >= LEVELS.size) { + filterLevel = 0 + } + item.title = getFilterLevel() + stopLogcatAsyncTask() + logs.clear() + adapter!!.notifyDataSetChanged() + startLogcatAsyncTask() + return true + } + SHARE_ID -> { + startSaveLogsAsyncTask() + return true + } + } + return false + } + + private fun startSaveLogsAsyncTask() { + val saveLogsAsyncTask = SaveLogsAsyncTask(this, logs) + saveLogsAsyncTask.execute() + } + + private fun startLogcatAsyncTask() { + logcatAsyncTask = LogcatAsyncTask(this, getFilterLevel()) + logcatAsyncTask!!.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) + } + + private fun stopLogcatAsyncTask() { + if (logcatAsyncTask != null && logcatAsyncTask!!.status == AsyncTask.Status.RUNNING) { + logcatAsyncTask!!.cancel(false) + logcatAsyncTask!!.stopLogging() + } + } + + private inner class LogcatAdapter : RecyclerView.Adapter() { + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val inflater = LayoutInflater.from(viewGroup.context) + val itemView = inflater.inflate(R.layout.item_description_long, viewGroup, false) as TextView + itemView.gravity = Gravity.CENTER_VERTICAL + return LogViewHolder(itemView) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is LogViewHolder) { + val log = getLog(position) + holder.logTextView.text = log + } + } + + override fun getItemCount(): Int { + return logs.size + } + + private fun getLog(position: Int): String { + return logs[position] + } + + private inner class LogViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val logTextView: TextView = itemView.findViewById(R.id.description) + } + } + + class SaveLogsAsyncTask internal constructor(logcatActivity: TrackerLogcatActivity, logs: Collection) : AsyncTask() { + private val logcatActivity: WeakReference + private val logs: Collection + + override fun onPreExecute() { + val activity = logcatActivity.get() + activity?.setSupportProgressBarIndeterminateVisibility(true) + } + + override fun doInBackground(vararg voids: Void?): File { + val app: TelegramApplication = logcatActivity.get()?.applicationContext as TelegramApplication + val file = File(app.getExternalFilesDir(null), LOGCAT_PATH) + try { + if (file.exists()) { + file.delete() + } + val stringBuilder = StringBuilder() + for (log in logs) { + stringBuilder.append(log) + stringBuilder.append("\n") + } + if (file.parentFile.canWrite()) { + val writer = BufferedWriter(FileWriter(file, true)) + writer.write(stringBuilder.toString()) + writer.close() + } + } catch (e: Exception) { + log.error(e) + } + return file + } + + override fun onPostExecute(file: File?) { + val activity = logcatActivity.get() + if (activity != null && file != null) { + val app: TelegramApplication = activity.applicationContext as TelegramApplication + activity.setSupportProgressBarIndeterminateVisibility(false) + app.sendCrashLog(file) + } + } + + init { + this.logcatActivity = WeakReference(logcatActivity) + this.logs = logs + } + } + + class LogcatAsyncTask internal constructor(logcatActivity: TrackerLogcatActivity?, filterLevel: String) : AsyncTask() { + private var processLogcat: Process? = null + private val logcatActivity: WeakReference + private val filterLevel: String + + override fun doInBackground(vararg voids: Void?): Void? { + try { + val filter = android.os.Process.myPid().toString() + val command = arrayOf("logcat", filterLevel, "--pid=$filter", "-T", MAX_BUFFER_LOG.toString()) + processLogcat = Runtime.getRuntime().exec(command) + val bufferedReader = BufferedReader(InputStreamReader(processLogcat?.inputStream)) + var line: String? + while (bufferedReader.readLine().also { line = it } != null && logcatActivity.get() != null) { + if (isCancelled) { + break + } + publishProgress(line) + } + stopLogging() + } catch (e: IOException) { // ignore + } catch (e: Exception) { + log.error(e) + } + return null + } + + override fun onProgressUpdate(vararg values: String?) { + if (values.size > 0 && !isCancelled) { + val activity = logcatActivity.get() + if (activity != null) { + val autoscroll = !activity.recyclerView!!.canScrollVertically(1) + for (s in values) { + if (s != null) { + activity.logs.add(s) + } + } + activity.adapter!!.notifyDataSetChanged() + if (autoscroll) { + activity.recyclerView!!.scrollToPosition(activity.logs.size - 1) + } + } + } + } + + fun stopLogging() { + if (processLogcat != null) { + processLogcat!!.destroy() + } + } + + init { + this.logcatActivity = WeakReference(logcatActivity) + this.filterLevel = filterLevel + } + } +} diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt index ee6bbb29d4..97652148b2 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt @@ -3,16 +3,20 @@ package net.osmand.telegram import android.app.Application import android.content.Context import android.content.Intent +import android.content.pm.PackageManager import android.net.ConnectivityManager import android.net.NetworkInfo import android.os.Build import android.os.Handler +import net.osmand.PlatformUtil +import net.osmand.TrackerLogcatActivity import net.osmand.telegram.helpers.* import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener import net.osmand.telegram.notifications.NotificationHelper import net.osmand.telegram.utils.AndroidUtils import net.osmand.telegram.utils.UiUtils +import java.io.File class TelegramApplication : Application() { @@ -200,4 +204,33 @@ class TelegramApplication : Application() { fun runInUIThread(action: (() -> Unit), delay: Long) { uiHandler.postDelayed(action, delay) } + + fun sendCrashLog(file: File) { + val intent = Intent(Intent.ACTION_SEND) + intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("crash@osmand.net")) + intent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(this, file)) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + intent.type = "vnd.android.cursor.dir/email" + intent.putExtra(Intent.EXTRA_SUBJECT, "OsmAnd bug") + val text = StringBuilder() + text.append("\nDevice : ").append(Build.DEVICE) + text.append("\nBrand : ").append(Build.BRAND) + text.append("\nModel : ").append(Build.MODEL) + text.append("\nProduct : ").append(Build.PRODUCT) + text.append("\nBuild : ").append(Build.DISPLAY) + text.append("\nVersion : ").append(Build.VERSION.RELEASE) + text.append("\nApp : ").append(getString(R.string.app_name_short)) + try { + val info = packageManager.getPackageInfo(packageName, 0) + if (info != null) { + text.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode) + } + } catch (e: PackageManager.NameNotFoundException) { + PlatformUtil.getLog(TrackerLogcatActivity::class.java).error("", e) + } + intent.putExtra(Intent.EXTRA_TEXT, text.toString()) + val chooserIntent = Intent.createChooser(intent, getString(R.string.send_report)) + chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(chooserIntent) + } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt index a5bf5993e9..2e8793bcb3 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt @@ -14,6 +14,7 @@ import android.widget.* import androidx.appcompat.widget.ListPopupWindow import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat +import net.osmand.TrackerLogcatActivity import net.osmand.telegram.R import net.osmand.telegram.TelegramSettings import net.osmand.telegram.TelegramSettings.ListPreference @@ -213,6 +214,12 @@ class SettingsDialogFragment : BaseDialogFragment() { DisconnectTelegramBottomSheet.showInstance(childFragmentManager) } + mainView.findViewById(R.id.logcat_row).setOnClickListener { + val intent = Intent(activity, TrackerLogcatActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + app.startActivity(intent) + } + return mainView } From 3651be249ee460fa01c79cb21c40ad0d219c0137 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 4 Oct 2020 08:01:10 +0000 Subject: [PATCH 0462/1366] Translated using Weblate (German) Currently translated at 99.9% (3487 of 3488 strings) --- OsmAnd/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 6d0aeabcd6..02786b8d2a 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3908,4 +3908,5 @@ Zuletzt geändert Name: Z – A Name: A – Z + Start-/Ziel-Symbole \ No newline at end of file From 5d6ab41dae7766bcd9bd8f7566e75a52a99bfb73 Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Mon, 5 Oct 2020 11:53:59 +0000 Subject: [PATCH 0463/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3487 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 9992fd35fb..c1d074f560 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -52,7 +52,7 @@ Плагин Приобретите и установите плагин «Контурные линии» для отображения градуированных вертикальных областей. Цветовая схема - Показывать, начиная с уровня масштабирования + Показывать начиная с масштаба Анимация моего положения Включить анимацию прокрутки карты с моим положением во время навигации. Масштаб: %1$s @@ -605,8 +605,8 @@ Чтение кешированных растровых карт… Недостаточно памяти для локальной карты «{0}» Версия локальной карты «{0}» не поддерживается - Локальная навигация OsmAnd является экспериментальной функцией и не работает на длинные расстояния более 20 километров. -\n + Офлайн навигация OsmAnd является экспериментальной функцией и не работает на длинные расстояния более 20 километров. +\n \nНавигация временно переключена на онлайн-сервис CloudMade. Невозможно найти указанную папку. Папка хранилища данных @@ -616,7 +616,7 @@ Установить OsmAnd — {0} из {1} {2} МБ\? Не удалось получить список сборок OsmAnd Загружаются сборки OsmAnd… - Выберите сборку OsmAnd для установки + Выберите сборку для установки Голосовая навигация недоступна. Перейдите в «Настройки» → «Настройки навигации», выберите профиль → «Голосовые данные» и выберите или загрузите пакет голосовых подсказок. Выберите пакет голосовых подсказок Показывать производительность отрисовки. @@ -638,7 +638,7 @@ Самый быстрый маршрут Расчёт скоростного маршрута вместо кратчайшего. На масштабе {0} загрузить {1} тайлов ({2} МБ) - Загрузить карту + Скачать карту Наибольший масштаб для предварительной загрузки Выбранная карта не может быть загружена Непрерывная отрисовка @@ -1536,7 +1536,7 @@ Сербский (кириллица) Китайский (упрощённый) Китайский (традиционный) - Маршруты метро + Линии метро Продолжить навигацию Приостановить навигацию Визуализация пути по шкале SAC. From efabf48edf54b5a21fc7ee6093efa7e7b6f92cf8 Mon Sep 17 00:00:00 2001 From: sergio Date: Sun, 4 Oct 2020 12:34:58 +0000 Subject: [PATCH 0464/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3487 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index c1d074f560..f669f46579 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -1539,7 +1539,7 @@ Линии метро Продолжить навигацию Приостановить навигацию - Визуализация пути по шкале SAC. + Визуализация маршрута по шкале SAC. Отрисовка дорог согласно трассам OSMC. Раннее По умолчанию From 17eac3200f8baa921bfcfddfbf859e613da1941d Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Sun, 4 Oct 2020 10:56:14 +0000 Subject: [PATCH 0465/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3487 of 3488 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index f669f46579..615ba2f341 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -2801,7 +2801,7 @@ Для езды по бездорожью, основано на топографическом стиле (англ. «Topo»), можно использовать с зелёными спутниковыми снимками в качестве подложки. Уменьшенная толщина основных дорог, увеличенная толщина путей, дорожек, велосипедных и других маршрутов. Модификация стиля по умолчанию для увеличения контраста пешеходных и велосипедных дорог. Использует старые цвета Mapnik. Получите OsmAnd Live, чтобы разблокировать все функции: ежедневные обновления карт с неограниченной загрузкой, все платные и бесплатные плагины, Википедия, Викигид и многое другое. - Прибытие в промежуточный пункт + Промежуточное время прибытия Прибытие в промежуточный пункт Редактировать действие Пожалуйста, пришлите скриншот этого уведомления на support@osmand.net From 92721855159f4cdb394c61cf32508c11f3b7fd9d Mon Sep 17 00:00:00 2001 From: Tymofij Lytvynenko Date: Sun, 4 Oct 2020 08:20:06 +0000 Subject: [PATCH 0466/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-uk/strings.xml | 83 ++++++++++++++++---------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 8e63be02be..4d48e49512 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -42,7 +42,7 @@ \nБудь яка з цих мап може використовуватись як основна мапа в OsmAnd, або як покриття чи підкладка до іншої основної мапи (наприклад усталена безмережева мапа OsmAnd). Для того, щоб зробити більш помітною будь-яку мапу-підкладку, певні елементи векторної мапи OsmAnd можна легко сховати через меню „Налаштування мапи“ за бажанням, щоб зробити будь-яку підкладку мапи помітнішою.. \n \nКвадрати мап можна отримувати безпосередньо з мережевих джерел або підготувати їх для безмережевого використання (та вручну скопіювати в теку даних OsmAnd) у вигляді бази даних SQLite, яку можна створити за допомогою різноманітних сторонніх знаряддь підготовки мап. - Показує налаштування для увімкнення фонового трекінгу та навігації шляхом періодичного пробудження GPS-передавача (з вимкненим екраном). + Показує налаштування для увімкнення відстеження у тлі та навігації шляхом періодичного пробудження GPS-передавача (з вимкненим екраном). Робить спеціальні можливості пристрою доступними безпосередньо в OsmAnd. Це полегшує, наприклад, налаштування частоти мовлення для голосу синтезу мовлення, настроювання D-Pad навігації, за допомогою трекбола для контролю масштабу або зворотного зв\'язку синтезу мовлення, наприклад, щоб автоматично оголосити свою позицію. Налаштування функцій розробки та налагодження, як-от навігаційне моделювання, дієвість відмальовування чи голосові підказки. Призначений для розробників, не потрібний для звичайного використання застосунку. Втулки @@ -158,7 +158,7 @@ Файл з раніше імпортованими Закладками вже існує. Замінити його? Налаштування профілю Усталений профіль - Вид мапи й налаштування навігації зберігаються для кожного окремого профілю. Встановіть ваш типовий профіль. + Вид мапи й налаштування навігації зберігаються для кожного окремого профілю. Встановіть ваш усталений профіль. Навігація Визначити налаштування навігації. Загальні налаштування @@ -169,8 +169,8 @@ Ім\'я користувача OSM Потрібно для входу на openstreetmap.org. Пароль - Фоновий режим - OsmAnd працює у фоновому режимі з вимкненим екраном. + Режим тла + OsmAnd працює у режимі тла з вимкненим екраном. Не вистачає місця на диску для завантаження %1$s MB (вільно: %2$s). Завантажити {0} файл(ів)\? \n{1} МБ (із {2} МБ) буде використано. @@ -281,8 +281,8 @@ Прозорість Змінити прозорість основної мапи. Прозорість мапи - Фонова мапа… - Фонова мапа + Мапа підкладки… + Мапа підкладки Виберіть тлову мапу Верхній шар… Нема @@ -456,7 +456,7 @@ Виберіть метод позиціонування, що використовується тловою службою: Джерело позиціювання Відслідковує Ваше місцерозташування, поки екран вимкнено. - Запустити OsmAnd у фоні + Запустити OsmAnd у тлі Службі навігації у тлі необхідно, аби постачальник позиціювання був активним. Сховати фільтр Показати фільтр @@ -759,8 +759,9 @@ Торкніться значка блокування, щоб розблокувати Розблокувати Запустити -\n застосунок у фоновому режимі - Вимкнути\nфоновий режим +\n застосунок у режимі тла + Вимкнути +\nрежим тла Час прибуття не відмічено Мапа @@ -846,7 +847,7 @@ Безпечний режим Програму запущено в безпечному режимі (вимкніть його в \'Налаштуваннях\'). Оберіть \"Використати місцезнаходження...\" для прив\'язки нотатки до даного місцезнаходження. - Фоновий режим OsmAnd досі запущений. Зупинити його роботу також? + Службу OsmAnd у тлі досі запущено. Зупинити її роботу також\? Закрити набір змін Програма \'ZXing Barcode Scanner\' не встановлена. Шукати в Google Play? Виберіть кольорову схему доріг: @@ -1078,9 +1079,9 @@ Колір Продовжувати Зупинити - Ввімкнути фоновий режим GPS + Увімкнути режим GPS у тлі Інтервал вмикання GPS - Зупинити фоновий режим GPS? + Зупинити режим GPS у тлі\? Бажана мова для підписів на мапі (якщо вона недоступна, будуть використані англійська чи місцева мови). Бажана мова мапи Назви місцевою мовою @@ -1686,7 +1687,7 @@ м/с Запис подорожі Навігація - Працює у фоновому режимі + Працює у тлі Відомості про закладки Зупинити симуляцію Вашої позиції. Пошук адреси @@ -2390,12 +2391,12 @@ \n• Опціональний запис подорожі в локальний GPX-файл чи онлайн-сервіс \n• Опціональне відображення швидкості та висотного розташування \n• Відображення горизонталей та рельєфу (через додатковий втулок) - Безпосередній вклад у OSM -\n• Звітуйте про помилки в даних -\n• Вивантажуйте GPX-треки в OSM безпосередньо з програми -\n• Додавайте POI (цікаві точки) та безпосередньо вивантажуйте їх в OSM (чи пізніше, якщо зараз Ви в офлайні) -\n• Опція запису подорожі також і у фоновому режимі (в той час як пристрій знаходиться в сплячому режимі) -\nOsmAnd — вільне й відкрите програмне забезпечення, що активно розвивається. Кожен може внести свій вклад, звітуючи про помилки, поліпшуючи переклад чи розробляючи нові функції. Також проєкт покладається на фінансові внески для оплати розробки та тестування нових функціональних можливостей. + Безпосередній вклад у OSM +\n• Звітуйте про помилки в даних +\n• Вивантажуйте GPX-треки в OSM безпосередньо з програми +\n• Додавайте POI (цікаві точки) та безпосередньо вивантажуйте їх в OSM (чи пізніше, якщо зараз Ви в офлайні) +\n• Опція запису подорожі також і в режимі тла (в той час як пристрій знаходиться в сплячому режимі) +\nOsmAnd — вільне й відкрите програмне забезпечення, що активно розвивається. Кожен може внести свій вклад, звітуючи про помилки, поліпшуючи переклад чи розробляючи нові функції. Також проєкт покладається на фінансові внески для оплати розробки та тестування нових функціональних можливостей. \n Приблизне охоплення мап та якість: \n • Західна Європа: **** @@ -3043,7 +3044,7 @@ Лижі Показати компас-лінійку Приховати компас-лінійку - Оберіть піктограму + Оберіть значок Режим: %s Користувацький режим, похідний від: %s Лижі @@ -3068,31 +3069,31 @@ Натисніть ще раз для зміни орієнтації мапи Мінімальна швидкість Максимальна швидкість - Типова швидкість + Усталена швидкість Змінити налаштування усталеної швидкості Встановити мінімальну/максимальну швидкість Новий профіль Збій Під час останнього запуску OsmAnd сталася помилка. Допоможіть нам покращити OsmAnd - надішліть повідомлення про помилку. НЛО - • Профілі застосунку: створюйте власний профіль з довільною піктограмою та кольором для ваших особистих потреб -\n -\n• Налаштуйте типову мінімальну/максимальну швидкості профілю -\n -\n• Додано віджет з поточними координатами -\n + • Профілі застосунку: створюйте власний профіль з довільним значком та кольором для ваших особистих потреб +\n +\n• Налаштуйте усталену найменшу/найбільшу швидкості профілю +\n +\n• Додано віджет з поточними координатами +\n \n• Додано можливість показувати на мапі компас і радіус-лінійку -\n +\n \n• Виправлено записування шляху у тлі -\n -\n• Покращено завантаження мап у тлі +\n +\n• Покращено завантаження мап у тлі \n \n• Повернено параметр \'Увімкнути екран\' \n -\n• Виправлено вибір мови Wikipedia -\n +\n• Виправлено вибір мови Wikipedia +\n \n• Виправлено поведінку кнопки компаса під час навігації -\n +\n \n• Інші виправлення помилок \n \n @@ -3670,7 +3671,7 @@ Профілі навігації • Нові автономні мапи схилів \n -\n• Налаштування вибраних та GPX шляхових точок - спеціальні кольори, піктограми, форми +\n• Налаштування вибраних та GPX шляхових точок - спеціальні кольори, значки, форми \n \n• Налаштування порядку елементів меню \"Контекстне меню\", \"Налаштувати мапу\" та \"Скринька\" \n @@ -3694,7 +3695,7 @@ Кнопка показу або приховування громадського транспорту на мапі. Створити / змінити POI Додати / правити вибране - Відновити типовий порядок елементів + Відновити усталене впорядкування Повернутися до редагування Ви можете отримати доступ до цих дій, торкнувшись кнопки “%1$s”. Продовжити @@ -3741,7 +3742,7 @@ \nОдин тиждень - 10 080 хвилин. \nОдин місяць - 43 829 хвилин. Виберіть спосіб зберігання завантажених плиток. - Типовий час до вимкнення екрану + Усталений час до вимкнення екрану Ви можете експортувати або імпортувати швидкі дії з профілями застосунку. Видалити все\? Ви дійсно бажаєте безповоротно видалити %d швидких дій\? @@ -3805,7 +3806,7 @@ Маршрут між точками Планування маршруту Додати до треку - Показувати піктограми старт та фініш + Показувати значки початку та завершення Встановити ширину Виберіть інтервал показу міток часу або відстані для показу поверх треку. Виберіть власний варіант поділу: за часом чи відстанню. @@ -3863,7 +3864,7 @@ Змінити вид маршруту раніше Змінити вид маршруту після Вкажіть інтервал для загального запису поїздки (включається через віджет запису подорожі на мапі). - Типова системи + Усталена системна Всі наступні сегменти Попередній сегмент Усі попередні сегменти @@ -3876,14 +3877,14 @@ Відкрити збережений трек збережено Додайте принаймні дві точки. - Запис треку буде зупинено після припинення роботи застосунку через меню з переліком нещодавно запущених застосунків. (Індикатор, який інформує про роботу OsmAnd у фоні зникне з панелі сповіщень Android) + Запис треку буде зупинено після припинення роботи застосунку через меню з переліком нещодавно запущених застосунків. (Індикатор, що повідомляє про роботу OsmAnd у тлі зникне з панелі сповіщень Android) Спрощений трек Буде збережено лише лінію маршруту, а проміжні точки буде видалено. Назва файлу Повторити • Оновлено функції планування маршруту: дозволено застосувати різні типи переходів для кожного сегмента і прив\'язати будь-який трек до доріг \n -\n• Нове меню вигляду треків: вибір кольору, товщина, вигляд стрілки напрямку, піктограми початку/завершення +\n• Нове меню вигляду треків: вибір кольору, товщина, вигляд стрілки напрямку, значки початку/завершення \n \n• Покращено оглядовість велосипедних вузлів \n @@ -3899,5 +3900,5 @@ Востаннє змінено За назвою: Я — А За назвою: А — Я - Піктограми початку/завершення + Значки початку/завершення \ No newline at end of file From 245d77367785defa1dee5c0dd92d821a5d32e593 Mon Sep 17 00:00:00 2001 From: Mirco Zorzo Date: Mon, 5 Oct 2020 10:41:54 +0000 Subject: [PATCH 0467/1366] Translated using Weblate (Italian) Currently translated at 90.2% (3149 of 3488 strings) --- OsmAnd/res/values-it/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 5543e68444..b392fc8392 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -3812,7 +3812,7 @@ Aggiungi ad una Traccia Seleziona l\'intervallo a cui i segnaposti con distanza o orario sulla traccia verranno mostrati. Seleziona l\'opzione desiderata per la divisione: per tempo o per distanza. - Frecce delle direzioni + Frecce della direzione Seleziona larghezza Ultima modificata Importa una traccia From bea0702bfb2fe83775dbd145af5d52876112fbf9 Mon Sep 17 00:00:00 2001 From: jan madsen Date: Sun, 4 Oct 2020 18:14:38 +0000 Subject: [PATCH 0468/1366] Translated using Weblate (Danish) Currently translated at 94.0% (3281 of 3488 strings) --- OsmAnd/res/values-da/strings.xml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-da/strings.xml b/OsmAnd/res/values-da/strings.xml index 0ef92f7051..0e05949cf0 100644 --- a/OsmAnd/res/values-da/strings.xml +++ b/OsmAnd/res/values-da/strings.xml @@ -3243,7 +3243,7 @@ Advarsler vises nederst til venstre under navigationen. Skift profil Sprog og output - Gendan standardværdi + Nulstil til standard Opret, importer, rediger profiler Administrer programprofiler… Påvirker hele programmet @@ -3773,8 +3773,19 @@ Omgøre Navigere fra position til sporet Punkt på sporet for at navigere - %s spor filer valgt + %s sporfiler valgt Sidst ændret Navn: Z – A Navn: A – Z + Vælg en sporfil, der skal åbnes. + Vælg en sporfil, som det nye segment skal føjes til. + Kasser alle ændringer i den planlagte rute ved at lukke den\? + Føj til en sporfil + Vælg sporfil, der skal følges eller importeres fra enheden. + Kun rutelinjen gemmes, rutepunkter slettes. + Alle efterfølgende segmenter + Kun det valgte segment genberegnes igen ved hjælp af den valgte profil. + Alle efterfølgende segmenter genberegnes ved hjælp af den valgte profil. + Alle tidligere segmenter genberegnes ved hjælp af den valgte profil. + Start-/slutikoner \ No newline at end of file From 897a330e743a9901873443c943b952f93ef53e47 Mon Sep 17 00:00:00 2001 From: Softmap Date: Sun, 4 Oct 2020 14:38:06 +0000 Subject: [PATCH 0469/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-ar/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index bd631a4b89..201497708a 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3891,4 +3891,5 @@ آخر تعديل الاسم: أ – ي الاسم: أ – ي + رموز البدء/الانتهاء \ No newline at end of file From 8eb73fa5cbe1b0a293dcfe1fbd701de8c33a9d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Sun, 4 Oct 2020 09:16:12 +0000 Subject: [PATCH 0470/1366] Translated using Weblate (Czech) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-cs/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-cs/phrases.xml b/OsmAnd/res/values-cs/phrases.xml index e63732cdc6..8d64234b3a 100644 --- a/OsmAnd/res/values-cs/phrases.xml +++ b/OsmAnd/res/values-cs/phrases.xml @@ -3844,4 +3844,5 @@ Šipka Vibrace Tlak + Zkapalněný zemní plyn \ No newline at end of file From 0754ed5218447f4096a20590037b9f8aca9ce97d Mon Sep 17 00:00:00 2001 From: jan madsen Date: Sun, 4 Oct 2020 17:46:24 +0000 Subject: [PATCH 0471/1366] Translated using Weblate (Danish) Currently translated at 99.3% (3802 of 3825 strings) --- OsmAnd/res/values-da/phrases.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OsmAnd/res/values-da/phrases.xml b/OsmAnd/res/values-da/phrases.xml index 3e1f8c0d81..9f26ab3b43 100644 --- a/OsmAnd/res/values-da/phrases.xml +++ b/OsmAnd/res/values-da/phrases.xml @@ -3842,4 +3842,14 @@ Donationsboks Pil: nej Elevator + Nøddebutik + Bikube + Tidsplan + Realtid + Forsinkelse + Ja + Afgangstavle: nej + Små elektriske apparater + Afgangstavle + Genopfyldning af drikkevand \ No newline at end of file From 5df3c98270ab87292470bb139b9df2ce283a4c8c Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 4 Oct 2020 08:06:28 +0000 Subject: [PATCH 0472/1366] Translated using Weblate (German) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-de/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml index d091dc7fd5..d40597ca63 100644 --- a/OsmAnd/res/values-de/phrases.xml +++ b/OsmAnd/res/values-de/phrases.xml @@ -3847,4 +3847,5 @@ Bienenstock Kleine Elektrogeräte Nussladen + Flüssigerdgas \ No newline at end of file From 247ad17d144953b8e06a9e258c02d9f951badc35 Mon Sep 17 00:00:00 2001 From: ssantos Date: Sun, 4 Oct 2020 08:02:08 +0000 Subject: [PATCH 0473/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-pt/phrases.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index de9490478b..fc6f81cb62 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -2808,9 +2808,9 @@ Tipo de bomba: gravidade Estilo de bomba: moderno Estilo de bomba: histórico - Status da bomba: ok - Status da bomba: quebrado - Status da bomba: bloqueado + Estado da bomba: ok + Estado da bomba: quebrado + Estado da bomba: bloqueado Troika Cartão Troika não aceito Telescópio @@ -3563,7 +3563,7 @@ 3B 3B* Explosão de gás;Queimador de gás - Objeto excluído + Objeto apagado Caixa de resgate Sim Reddit From cb0a9b919facc999a510a64f857ea2a83cd1ebc2 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 5 Oct 2020 03:04:58 +0000 Subject: [PATCH 0474/1366] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3488 of 3488 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index b12cc12a51..47137ac203 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3899,4 +3899,5 @@ 最後修改時間 名稱:Z – A 名稱:A – Z + 開始/結束圖示 \ No newline at end of file From 28acf361e6fa4e29f11f28a79ccd1083e3e2ff1f Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 5 Oct 2020 03:05:30 +0000 Subject: [PATCH 0475/1366] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-zh-rTW/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml index 25766f928e..e36aa4414d 100644 --- a/OsmAnd/res/values-zh-rTW/phrases.xml +++ b/OsmAnd/res/values-zh-rTW/phrases.xml @@ -3843,4 +3843,5 @@ 小電器 蜂箱 堅果店 + LNG \ No newline at end of file From c50f171425ae91fd526eb0e98b86ef115679943b Mon Sep 17 00:00:00 2001 From: Tymofij Lytvynenko Date: Sun, 4 Oct 2020 08:14:52 +0000 Subject: [PATCH 0476/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (267 of 267 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/uk/ --- OsmAnd-telegram/res/values-uk/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-telegram/res/values-uk/strings.xml b/OsmAnd-telegram/res/values-uk/strings.xml index 1ff2bebb09..9a2d31a4e7 100644 --- a/OsmAnd-telegram/res/values-uk/strings.xml +++ b/OsmAnd-telegram/res/values-uk/strings.xml @@ -118,7 +118,7 @@ Налаштування Застосунок не має дозволу до отримання даних позиціювання. Будь ласка, увімкніть «Позиціювання» у системних налаштуваннях - Фоновий режим + Режим тла OsmAnd Tracker працює у фоновому режимі з вимкненим екраном. Відстань Поділитися позицією From 7407e9cd040a86738e129e9d27c95edf9fe00355 Mon Sep 17 00:00:00 2001 From: ssantos Date: Sun, 4 Oct 2020 07:24:13 +0000 Subject: [PATCH 0477/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (267 of 267 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/pt/ --- OsmAnd-telegram/res/values-pt/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-telegram/res/values-pt/strings.xml b/OsmAnd-telegram/res/values-pt/strings.xml index 6076bfee91..21dfc6b4e9 100644 --- a/OsmAnd-telegram/res/values-pt/strings.xml +++ b/OsmAnd-telegram/res/values-pt/strings.xml @@ -108,7 +108,7 @@ Ainda não encontrado Reenvie o local Última localização disponível - Status de compartilhamento + Estado de compartilhamento Compartilhamento: %1$s Ativado Sem conexão GPS From bf75dba1761942695a93f6c0ed62fb7105be1c72 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 4 Oct 2020 18:45:48 +0000 Subject: [PATCH 0478/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3825 of 3825 strings) --- OsmAnd/res/values-ru/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml index f67e31fb94..d87b1f7c05 100644 --- a/OsmAnd/res/values-ru/phrases.xml +++ b/OsmAnd/res/values-ru/phrases.xml @@ -3832,4 +3832,5 @@ Малые электроприборы Магазин орехов Улей + СПГ \ No newline at end of file From 925c708b6706b9993c6a8dd2b7d26bf3e10de99a Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Mon, 5 Oct 2020 15:35:51 +0300 Subject: [PATCH 0479/1366] logging share errors --- .../net/osmand/telegram/TelegramSettings.kt | 24 +++++++++++++------ .../osmand/telegram/helpers/TelegramHelper.kt | 3 ++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index d8ec28a9c0..042fb03d11 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -540,14 +540,24 @@ class TelegramSettings(private val app: TelegramApplication) { if (initTime && initSending) { initializing = true } else { + var waitingTimeError = false val maxWaitingTime = WAITING_TDLIB_TIME * MAX_MESSAGES_IN_TDLIB_PER_CHAT * max(1, chatsCount) - val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > maxWaitingTime - val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > maxWaitingTime - if (shareInfo.hasSharingError - || (shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError)) - || textSharingError && (shareTypeValue == SHARE_TYPE_TEXT) - || mapSharingError && (shareTypeValue == SHARE_TYPE_MAP) - ) { + val textSharingWaitingTime = currentTime - shareInfo.lastSendTextMessageTime + val mapSharingWaitingTime = currentTime - shareInfo.lastSendMapMessageTime + val textSharingError = !shareInfo.lastTextMessageHandled && textSharingWaitingTime > maxWaitingTime + val mapSharingError = !shareInfo.lastMapMessageHandled && mapSharingWaitingTime > maxWaitingTime + if ((shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError)) + || textSharingError && (shareTypeValue == SHARE_TYPE_TEXT) + || mapSharingError && (shareTypeValue == SHARE_TYPE_MAP)) { + waitingTimeError = true + log.debug("Send chats error for share type \"$shareTypeValue\"" + + "\nMax waiting time: ${maxWaitingTime}s" + + "\nLast text message handled: ${shareInfo.lastTextMessageHandled}" + + "\nText sharing waiting time: ${textSharingWaitingTime}s" + + "\nLast map message handled: ${shareInfo.lastMapMessageHandled}" + + "\nMap sharing waiting time: ${mapSharingWaitingTime}s") + } + if (shareInfo.hasSharingError || waitingTimeError) { sendChatsErrors = true locationTime = max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime) chatsIds.add(shareInfo.chatId) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index e4d5188a2b..704a797af2 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -776,6 +776,7 @@ class TelegramHelper private constructor() { client?.send(TdApi.CreatePrivateChat(userId, false)) { obj -> when (obj.constructor) { TdApi.Error.CONSTRUCTOR -> { + log.debug("createPrivateChatWithUser ERROR $obj") val error = obj as TdApi.Error if (error.code != IGNORED_ERROR_CODE) { shareInfo.hasSharingError = true @@ -969,7 +970,7 @@ class TelegramHelper private constructor() { val messageType = if (isBot) MESSAGE_TYPE_BOT else MESSAGE_TYPE_TEXT when (obj.constructor) { TdApi.Error.CONSTRUCTOR -> { - log.debug("handleTextLocationMessageUpdate - ERROR") + log.debug("handleTextLocationMessageUpdate - ERROR $obj") val error = obj as TdApi.Error if (error.code != IGNORED_ERROR_CODE) { shareInfo.hasSharingError = true From 22ff4f581bbd5cfe7337ffdb822d719f615b50cb Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Mon, 5 Oct 2020 21:43:08 +0300 Subject: [PATCH 0480/1366] Fix LogcatActivity after review --- OsmAnd-telegram/AndroidManifest.xml | 2 +- .../res/layout/item_description_long.xml | 2 +- OsmAnd-telegram/res/values/dimens.xml | 3 ++- .../osmand/telegram/TelegramApplication.kt | 2 +- .../telegram/ui/SettingsDialogFragment.kt | 1 - .../ui}/TrackerLogcatActivity.kt | 23 ++++++++++--------- 6 files changed, 17 insertions(+), 16 deletions(-) rename OsmAnd-telegram/src/net/osmand/{ => telegram/ui}/TrackerLogcatActivity.kt (95%) diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml index 2146f9b89a..73e2e856ca 100644 --- a/OsmAnd-telegram/AndroidManifest.xml +++ b/OsmAnd-telegram/AndroidManifest.xml @@ -20,7 +20,7 @@ android:screenOrientation="unspecified" android:supportsRtl="true" android:theme="@style/AppTheme"> - + 89dp 48dp - 44dp + 44dp + 42dp 56dp 48dp diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt index 97652148b2..b6927dc610 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt @@ -9,7 +9,7 @@ import android.net.NetworkInfo import android.os.Build import android.os.Handler import net.osmand.PlatformUtil -import net.osmand.TrackerLogcatActivity +import net.osmand.telegram.ui.TrackerLogcatActivity import net.osmand.telegram.helpers.* import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt index 2e8793bcb3..447275815e 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt @@ -14,7 +14,6 @@ import android.widget.* import androidx.appcompat.widget.ListPopupWindow import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat -import net.osmand.TrackerLogcatActivity import net.osmand.telegram.R import net.osmand.telegram.TelegramSettings import net.osmand.telegram.TelegramSettings.ListPreference diff --git a/OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/TrackerLogcatActivity.kt similarity index 95% rename from OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt rename to OsmAnd-telegram/src/net/osmand/telegram/ui/TrackerLogcatActivity.kt index 5ed551636a..ee62ab4407 100644 --- a/OsmAnd-telegram/src/net/osmand/TrackerLogcatActivity.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/TrackerLogcatActivity.kt @@ -1,4 +1,4 @@ -package net.osmand +package net.osmand.telegram.ui import android.os.AsyncTask import android.os.Bundle @@ -9,33 +9,26 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import net.osmand.PlatformUtil import net.osmand.telegram.R import net.osmand.telegram.TelegramApplication import java.io.* import java.lang.ref.WeakReference import java.util.* -private const val LOGCAT_PATH = "logcat.log" -private const val MAX_BUFFER_LOG = 10000 -private const val SHARE_ID = 0 -private const val LEVEL_ID = 1 -private val log = PlatformUtil.getLog(TrackerLogcatActivity::class.java) - class TrackerLogcatActivity : AppCompatActivity() { private var logcatAsyncTask: LogcatAsyncTask? = null private val logs: MutableList = ArrayList() private var adapter: LogcatAdapter? = null private val LEVELS = arrayOf("D", "I", "W", "E") private var filterLevel = 1 - private var recyclerView: RecyclerView? = null + private lateinit var recyclerView: RecyclerView override fun onCreate(savedInstanceState: Bundle?) { val app: TelegramApplication = getApplication() as TelegramApplication super.onCreate(savedInstanceState) setContentView(R.layout.activity_tracker_logcat) - log.debug("text to test") - val toolbar = findViewById(R.id.toolbar).apply { navigationIcon = app.uiUtils.getThemedIcon(R.drawable.ic_arrow_back) setNavigationOnClickListener { onBackPressed() } @@ -44,7 +37,7 @@ class TrackerLogcatActivity : AppCompatActivity() { setupIntermediateProgressBar() adapter = LogcatAdapter() - recyclerView = findViewById(R.id.recycler_view) as RecyclerView? + recyclerView = findViewById(R.id.recycler_view) as RecyclerView recyclerView!!.layoutManager = LinearLayoutManager(this) recyclerView!!.adapter = adapter } @@ -267,4 +260,12 @@ class TrackerLogcatActivity : AppCompatActivity() { this.filterLevel = filterLevel } } + + companion object { + private const val LOGCAT_PATH = "logcat.log" + private const val MAX_BUFFER_LOG = 10000 + private const val SHARE_ID = 0 + private const val LEVEL_ID = 1 + private val log = PlatformUtil.getLog(TrackerLogcatActivity::class.java) + } } From 322fd7a9fdba919dda36e1c307bddd1e763232ee Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Tue, 6 Oct 2020 02:50:44 +0000 Subject: [PATCH 0481/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3488 of 3489 strings) --- OsmAnd/res/values-ru/strings.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 615ba2f341..a91e8e56a6 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -605,7 +605,7 @@ Чтение кешированных растровых карт… Недостаточно памяти для локальной карты «{0}» Версия локальной карты «{0}» не поддерживается - Офлайн навигация OsmAnd является экспериментальной функцией и не работает на длинные расстояния более 20 километров. + Офлайн-навигация OsmAnd — это экспериментальная функция, и она не работает на дистанциях больше 20 км. \n \nНавигация временно переключена на онлайн-сервис CloudMade. Невозможно найти указанную папку. @@ -3534,12 +3534,12 @@ Сохранение нового профиля Не удалось создать резервную копию профиля. Очистить записанные данные\? - Побочный эффект: в записи трека будут отсутствовать все участки, где критерий минимальной скорости не был соблюдён (например, когда вы толкаете велосипед вверх по крутому склону). Также не будет информации о периодах покоя, например, во время отдыха. Это влияет на любой анализ или последующую обработку, например, при попытке определить общую продолжительность поездки, время в движении или среднюю скорость. + Побочный эффект: в треке будут отсутствовать все участки, где не соблюдён критерий минимальной скорости (например где вы толкаете велосипед вверх по крутому склону). Также не будет информации о периодах покоя, например во время отдыха. Это влияет на любой анализ или последующую обработку, например при попытке определить общую продолжительность поездки, время в движении или среднюю скорость. Побочный эффект: в результате фильтрации по точности, точки могут быть полностью пропущены, например, под мостами, под деревьями, между высокими зданиями или при определённых погодных условиях. Примечание: при включении GPS непосредственно перед записью точность определения первой точки может быть снижена, поэтому мы рассматриваем добавление секундной задержки перед записью точки (либо записи лучшей из трёх последовательных точек и т. д.), но пока это не реализовано. Фильтр предотвращает запись точек при отсутствии фактического перемещения и улучшает вид треков без обработки. Побочные эффекты: периоды в состоянии покоя не записываются вообще или только по одной точке каждый. Небольшие (в реальности) перемещения (например, в сторону, указывающие возможное изменение направления движения) могут быть отфильтрованы. Файл содержит меньше информации для последующей обработки и имеет худшую статистику, отфильтровывая явно избыточные точки во время записи, при этом потенциально сохраняя артефакты, вызванные плохим приёмом или эффектами модуля GPS. - Рекомендация: настройка 5 метров может должна вас устроить, если нет необходимости учитывать более короткие перемещения, и вы точное не хотите записывать данные в состоянии покоя. + Рекомендация: настройка 5 метров может подойти вам, если нет необходимости учитывать более короткие перемещения, и вы точно не хотите записывать данные в состоянии покоя. Указанные %1$s уже существуют в OsmAnd. Импорт данных из %1$s Импортирование @@ -3580,7 +3580,8 @@ Примечание: проверка скорости > 0: большинство модулей GPS сообщают значение скорости только в том случае, если алгоритм определяет, что вы движетесь, и ничего, если вы не перемещаетесь. Следовательно, использование параметра > 0 в этом фильтре в некотором смысле приводит к обнаружению факта перемещения модуля GPS. Но даже если мы не производим данную фильтрацию во время записи, то всё равно эта функция используется при анализе GPX для определения скорректированного расстояния, то есть значение, отображаемое в этом поле, является расстоянием, записанным во время движения. Разделение записи Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. - "Будут записываться только точки, измеренные с указанием минимальной точности (в метрах/футах —д зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." + "Будут записываться только точки, отвечающие +\n в минимальной точностью (в метрах/футах —д зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться. Для визуализации крутизны рельефа используются цвета. Подробнее об уклонах можно прочитать в %1$s. @@ -3870,7 +3871,7 @@ Выбрано файлов треков: %s Укажите интервал общей записи трека (включается через виджет «Запись поездки» на карте). Остановить запись - Возобновить запись поездки + Возобновить запись По выбору системы Все последующие сегменты Предыдущий сегмент From adefc5009a256714da66c178064476eb67bf225a Mon Sep 17 00:00:00 2001 From: ssantos Date: Mon, 5 Oct 2020 17:04:18 +0000 Subject: [PATCH 0482/1366] Translated using Weblate (Portuguese) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-pt/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index 2772246d72..08c39f206e 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -3907,4 +3907,5 @@ Nome: Z – A Nome: A – Z Ícones de início/fim + Obrigado por comprar \'Curvas de nível\' \ No newline at end of file From 129e12b3aa37751a08d7b3e0cd6781af6704c129 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Mon, 5 Oct 2020 19:48:15 +0000 Subject: [PATCH 0483/1366] Translated using Weblate (French) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-fr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 91daebce7f..73e8c40be0 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3883,4 +3883,6 @@ Dernière modification Nom : Z – A Nom : A – Z + Icônes de départ / arrivée + Merci pour votre achat de \'Courbes de niveaux\' \ No newline at end of file From abac2982926ba4dbcb2f6b4037ee6412f565a6a3 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 5 Oct 2020 13:12:46 +0000 Subject: [PATCH 0484/1366] Translated using Weblate (German) Currently translated at 99.9% (3488 of 3489 strings) --- OsmAnd/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 02786b8d2a..1fcf32f445 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3909,4 +3909,5 @@ Name: Z – A Name: A – Z Start-/Ziel-Symbole + Vielen Dank für den Kauf von \'Höhenlinien\' \ No newline at end of file From aa649095e49082b53f3379f4b8ef50a36fc99c4c Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Tue, 6 Oct 2020 04:31:57 +0000 Subject: [PATCH 0485/1366] Translated using Weblate (Russian) Currently translated at 99.9% (3488 of 3489 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index a91e8e56a6..26dae657c6 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3871,7 +3871,7 @@ Выбрано файлов треков: %s Укажите интервал общей записи трека (включается через виджет «Запись поездки» на карте). Остановить запись - Возобновить запись + Возобновить запись поездки По выбору системы Все последующие сегменты Предыдущий сегмент From 80ed191d15f72e72f61ac0cd9c81ce25c718e04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Mon, 5 Oct 2020 13:40:29 +0000 Subject: [PATCH 0486/1366] Translated using Weblate (Turkish) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-tr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index a63ed6830b..5c1607f332 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3860,4 +3860,5 @@ İsim: Z – A İsim: A – Z Başlangıç/bitiş simgeleri + \'Eş yükselti eğrileri\'ni satın aldığınız için teşekkürler \ No newline at end of file From dd0632e2652648cb8ba8a353e28cd975c9b9ea62 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Mon, 5 Oct 2020 19:17:24 +0000 Subject: [PATCH 0487/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 4d48e49512..6d73e13701 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -3901,4 +3901,5 @@ За назвою: Я — А За назвою: А — Я Значки початку/завершення + Дякуємо за придбання «Горизонталей» \ No newline at end of file From c5f587dd1d1f26f032aaeb9061f2064496a89754 Mon Sep 17 00:00:00 2001 From: Mirco Zorzo Date: Mon, 5 Oct 2020 17:36:39 +0000 Subject: [PATCH 0488/1366] Translated using Weblate (Italian) Currently translated at 90.2% (3150 of 3489 strings) --- OsmAnd/res/values-it/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index b392fc8392..919b6123a8 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -3904,4 +3904,5 @@ Nome: Z – A Nome: A – Z Icona Partenza/Arrivo + Grazie per l\'acquisto del \'Plugin delle curve di livello\' \ No newline at end of file From ad97e8a4273a0683ee7d3af4bc3d436178b9d505 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 5 Oct 2020 13:13:52 +0000 Subject: [PATCH 0489/1366] Translated using Weblate (Hebrew) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-iw/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 8f3eb5c17c..31795c6dc2 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -3910,4 +3910,5 @@ שם: ת – א שם: א – ת סמלי התחלה/סיום + תודה לך על רכישת ‚קווי מתאר’ \ No newline at end of file From dfb4242f1013d9ac3ad3ec35f77a5ccdf47c634d Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Mon, 5 Oct 2020 14:00:03 +0000 Subject: [PATCH 0490/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-ar/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 201497708a..c1426b8483 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3892,4 +3892,5 @@ الاسم: أ – ي الاسم: أ – ي رموز البدء/الانتهاء + شكرا لشرائك \"خطوط الكنتور\" \ No newline at end of file From d90ef334691b83b1ed756ac40ca2400630ca148c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Mon, 5 Oct 2020 19:19:09 +0000 Subject: [PATCH 0491/1366] Translated using Weblate (Czech) Currently translated at 79.6% (2780 of 3489 strings) --- OsmAnd/res/values-cs/strings.xml | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 64f1dc8949..59b0baf68d 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -3525,4 +3525,57 @@ Zobrazená oblast: %1$s x %2$s Smazat následující cílový bod Umožní ovládat úroveň přiblížení mapy pomocí tlačítek hlasitosti zařízení. Tlačítka hlasitosti pro přibližování + Mezní vzdálenost + Navigační profil + Vyberte soubor stopy, do níž se nový úsek přidá. + Snímky z úrovně ulice + Opravdu chcete zavřít plánovanou trasu a zahodit tak všechny změny\? + V případě opačného směru + Uložit jako nový soubor stopy + Přidat do souboru stopy + Stopy + Stopy + Stopy + "Ukládat trasu do GPX souboru" + Trasa ze stopy + Přidat soubory stop + Zjednodušená trasa + Uloží se pouze linie trasy, mezicíle budou odstraněny. + Název souboru + %s vybraných souborů stop + REC + Pozastaví záznam trasy, pokud je aplikace ukončena (přes nedávné aplikace). (Ikona režimu na pozadí zmizí z notifikační oblasti Androidu.) + Pozastavit záznam trasy + Pokračovat v záznamu trasy + Výchozí + Všechny následující úseky + Přecházející úsek + Všechny předcházející úseky + Pouze vybraný úsek bude přepočítán pomocí vybraného profilu. + Všechny následující úseky budou přepočítány pomocí vybraného profilu. + Všechny předcházející úseky budou přepočítány pomocí vybraného profilu. + Otevřít uloženou trasu + je uloženo + Přidejte prosím alespoň dva body. + Znovu + • Vylepšená funkce plánování trasy: umožňuje použít různé typy navigace pro úseky trasy a přidává stopy +\n +\n • Nové menu pro vzhled stop: zvolte barvu, tloušťku, směrové šipky, ikony startu a cíle +\n +\n • Vylepšená viditelnost bodů pro cyklistiku. +\n +\n • Stopy je nyní možné aktivovat, nabízejí kontextové menu se základními údaji. +\n +\n • Vylepšený algoritmus vyhledávání +\n +\n • Vylepšené možnosti následování stopy v navigaci +\n +\n • Opravené problémy s importem a exportem nastavení profilů +\n +\n + Naposledy změněno + Název: Z – A + Název: A – Z + Ikony startu/cíle + Děkujeme za zakoupení modulu \'Vrstevnice\' \ No newline at end of file From f96f55dbaada97ec0a503008efc4d21c8a4226db Mon Sep 17 00:00:00 2001 From: Franco Date: Mon, 5 Oct 2020 16:28:08 +0000 Subject: [PATCH 0492/1366] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 21492272da..fcdccf360a 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -385,15 +385,15 @@ \nCualquiera de estos mapas puede usarse como el mapa predefinido que se mostrará, o como una superposición o subyacencia de otro mapa base (como los mapas estándar de OsmAnd en línea). Ciertos elementos de los mapas vectoriales de OsmAnd pueden ocultarse a través del menú «Configurar mapa» para hacer cualquier subyacencia mas visible. \n \nDescarga las teselas de los mapas directamente en línea, o prepáralo para su uso sin conexión (copiar manualmente en la carpeta de datos OsmAnd) como una base de datos SQLite que puede ser producida por una variedad de herramientas de preparación de mapas de terceros. - Este complemento activa la funcionalidad para registrar y guardar tus trazas manualmente pulsando el widget de grabación GPX en el mapa, o automáticamente registrando todas tus rutas navegadas en un archivo GPX. -\n + Activa la funcionalidad para registrar y guardar tus trazas manualmente pulsando el widget de grabación GPX en el mapa, o automáticamente registrando todas tus rutas navegadas en un archivo GPX. +\n \nLas trazas grabadas pueden ser compartidas con tus amigos o ser usadas para contribuir a OSM. Los atletas pueden usar las trazas grabadas para seguir sus entrenamientos. Algunos análisis básicos de trazas se pueden realizar directamente en OsmAnd, como tiempos por vuelta, velocidad media, etc., y por supuesto las trazas pueden analizarse posteriormente con herramientas de análisis de terceros. Complemento de curvas de nivel - Este complemento proporciona una capa superpuesta de curvas de nivel y una capa (de relieve) sombreada, que se pueden visualizar sobre los mapas descargados de OsmAnd. Esta funcionalidad será muy apreciada por atletas, caminantes, excursionistas, y cualquiera interesado en la estructura de relieve de un paisaje. -\n + Proporciona una capa superpuesta de curvas de nivel y una capa (de relieve) sombreada, que se pueden visualizar sobre los mapas descargados de OsmAnd. Esta funcionalidad será muy apreciada por atletas, caminantes, excursionistas, y cualquiera interesado en la estructura de relieve de un paisaje. +\n \nLos datos globales (entre 70° norte y 70° sur) se basan en mediciones de SRTM (Shuttle Radar Topography Mission, o en español Misión de Topografía por Radar desde Transbordador) y ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer, o en español Radiómetro Espacial Avanzado de Emisión Térmica y Reflexión), un instrumento de captura de imágenes a bordo de Terra, el satélite insignia del Sistema de Observación de la Tierra de la NASA. ASTER es un esfuerzo cooperativo entre la NASA, el Ministerio de Economía, Comercio e Industria de Japón (METI) y Sistemas Espaciales de Japón (J-spacesystems). - Este complemento proporciona tanto una capa superpuesta de curvas de nivel y una capa (de relieve) sombreada, que se pueden visualizar sobre los mapas descargados de OsmAnd. Esta funcionalidad será muy apreciada por atletas, caminantes, excursionistas, y cualquiera interesado en la estructura de relieve de un paisaje. (Note que las curvas de nivel y/o los datos de relieve están disponibles en descargas adicionales separadas luego de activar el complemento.) -\n + Proporciona tanto una capa superpuesta de curvas de nivel y una capa (de relieve) sombreada, que se pueden visualizar sobre los mapas descargados de OsmAnd. Esta funcionalidad será muy apreciada por atletas, caminantes, excursionistas, y cualquiera interesado en la estructura de relieve de un paisaje. (Note que las curvas de nivel y/o los datos de relieve están disponibles en descargas adicionales separadas luego de activar el complemento.) +\n \nLos datos globales (entre 70° norte y 70° sur) se basan en mediciones de SRTM (Shuttle Radar Topography Mission, o en español Misión de Topografía por Radar Shuffle) y ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer, o en español Radiómetro Espacial Avanzado de Emisión Térmica y Reflexión), un instrumento de captura de imágenes a bordo de Terra, el satélite insignia del Sistema de Observación de la Tierra de la NASA. ASTER es un esfuerzo cooperativo entre la NASA, el Ministerio de Economía, Comercio e Industria de Japón (METI) y Sistemas Espaciales de Japón (J-spacesystems). Activando esta vista cambia el estilo del mapa OsmAnd a la «Vista turística», que es una vista de alto detalle especial para viajeros y conductores profesionales. \n @@ -406,13 +406,13 @@ \nNo es necesario descargar un mapa especial, la vista es creada a partir de nuestros mapas estándar. \n \nEsta vista puede ser revertida desactivando de nuevo aquí, o cambiando el «Estilo del mapa» desde «Configurar mapa» cuando lo desees. - Este complemento enriquece el mapa y la navegación de OsmAnd al producir también mapas náuticos para el canotaje, vela y otros tipos de deportes acuáticos. -\n -\nUn mapa especial complementado para OsmAnd proporcionará toda las marcas de navegación náutica y símbolos cartográficos para el interior, así como para la navegación cerca de la costa. La descripción de cada marca de navegación proporciona los datos necesarios para su identificación y su significado (categoría, forma, color, número, referencia, etc.). -\n + Enriquece el mapa y la navegación de OsmAnd al producir también mapas náuticos para el canotaje, vela y otros tipos de deportes acuáticos. +\n +\nUn mapa especial complementado para OsmAnd proporcionará toda las marcas de navegación náutica y símbolos cartográficos para el interior, así como para la navegación cerca de la costa. La descripción de cada marca de navegación proporciona los datos necesarios para su identificación y su significado (categoría, forma, color, número, referencia, etc.). +\n \nPara volver a uno de los estilos del mapas convencionales de OsmAnd, simplemente desactiva este complemento de nuevo, o cambia el «Estilo del mapa» en «Configurar mapa» cuando lo desees. - Este complemento para OsmAnd pone a tu alcance detalles sobre pistas de esquí de descenso, de travesía, rutas de esquí alpino, teleféricos y remontes a nivel mundial. Las rutas y pistas se muestran por código de color en función de su dificultad y representados con un estilo del mapa especial «Invierno» que lo asemeja a un paisaje invernal nevado. -\n + Detalles sobre pistas de esquí de descenso, de travesía, rutas de esquí alpino, teleféricos y remontes a nivel mundial. Las rutas y pistas se muestran por código de color en función de su dificultad y representados con un estilo del mapa especial «Invierno» que lo asemeja a un paisaje invernal nevado. +\n \nActivando esta vista, cambia el estilo del mapa a «Invierno y esquí», mostrando las características del terreno en condiciones invernales. Esta vista se puede revertir desactivando de nuevo aquí o cambiando el «Estilo del mapa» en «Configurar mapa» cuando lo desees. Toma notas de audio, fotografía y/o video durante un viaje, usando un botón en el mapa o el menú contextual de la ubicación. Registra dónde se ha estacionado el automóvil, incluyendo cuánto tiempo queda. @@ -3908,4 +3908,5 @@ Nombre: Z – A Nombre: A – Z Iconos de inicio/fin + Gracias por comprar las «Curvas de nivel» \ No newline at end of file From 60b80568672741ef85d94c0d445357d3573da195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20=C3=87akmak?= Date: Mon, 5 Oct 2020 22:14:01 +0000 Subject: [PATCH 0493/1366] Translated using Weblate (Turkish) Currently translated at 73.8% (2824 of 3825 strings) --- OsmAnd/res/values-tr/phrases.xml | 278 +++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index dc31464e79..3fd2637960 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -2558,4 +2558,282 @@ Konteynerler Araçlar Yolcular + Apartman + Ok: hayır + Evet + Evet + Titreşim: hayır + Evet + Evet + Hayır + Evet + Göl + Irmak + Hamam + Konum + Feribot + Tramvay + Otobüs + Tren + Evet + Çocuk + Akademik + Din + Kan bağışı + Toptancı + Yalnızca + Evet + Ayakkabı tamiri + Kaya + Tekerlek + Araba tamiri + Tür: tarım + Posta kodu + Ev numarası + Posta kutusu + Park ücreti + Park ücreti: hayır + Park ücreti: evet + Tır: hayır + Tır: evet + Bisiklet: hayır + Bisiklet: evet + Araba: hayır + Araba: evet + Kısıtlı + Kapalı + Açık + Görünürlük: sokak + Görünürlük: ev + Konu: duvar + Konum: yerüstü + Konum: sualtı + Konum: yeraltı + Metal ızgara + Yapay çimen + Kil + Hazine + Kamu hizmeti + Bakanlık + Arşiv + + + Yön: her + Yön: çıkış + Yön: giriş + Yön: aşağı + Yön: yukarı + Yön: saat yönünün tersi + Yön: saat yönü + Yön: geri + Yön: ileri + Yön: kuzey-kuzeybatı + Yön: kuzeybatı + Yön: batı-kuzeybatı + Yön: batı + Yön: batı-güneybatı + Yön: güneybatı + Yön: güney-güneybatı + Gün: güney + Yön güney-güneydoğu + Yön: güneydoğu + Yön: doğu-güneydoğu + Yön: doğu + Yön: doğu-kuzeydoğu + Yön: kuzeydoğu + Yön: kuzey-kuzeydoğu + Yön: kuzey + Sürüngen + Kuşhane + Kuşlar + Elektronik tamir: televizyon + Elektronik tamir: telefon + Elektronik tamir: bilgisayar + Şarap: perakende + Şarap: evet + Evet + Çilingir + Elektronik mağazası + Tibet + Bulgar + Yahudi + Senegal + Mısır + Avustralya + Suriye + Hollanda + Tayvan + Pakistan + İngiliz + Hawaii + Ermeni + Jamaika + İsveç + Kanton + İsviçre + Bask + Belçika + Afgan + Ukrayna + Orta Doğu + Moğol + Nepal + Latin Amerika + Britanya + Küba + Çek + Özbek + Avrupa + Lao + Macar + Etiyopya + İrlanda + Malezya + Avusturya + Fas + Madagaskar + Fars + Bolivya + Hırvat + Peru + Balkan + Arjantina + Karayip + Afrika + Endonez + Dan + Arap + Brezilya + Leh + Gürcü + Portekiz + Filipin + Rus + Lübnan + Bavyera + Akdeniz + Kore + Vietnam + İspanyol + Türk + Uluslararası + Tay + Yunan + Fransız + Asya + Amerikan + Hint + Alman + Japon + Meksika + Çin + İtalyan + Bölgesel + Patates + Şarap + Çikolata + Kanat + Et + Yoğurt + Tatlı + Salata + Çorba + Çay + Makarna + Biftek + Kahvaltı + Barbekü + Suşi + Dondurma + Tavuk + Döner + Kebap + Sandviç + Pizza + Hamburger + Kahve + Noel ağacı + Noel + Vikipedi + Uzunluk + Su deposu + Delegasyon + Başkonsolosluk + Konsolosluk + Yalnızca + Evet + Su kültür: midye + Su kültürü: balık + Su kültürü: karides + Su kültürü + Termometre: hayır + Termometre + Barometre: hayır + Barometre + Teleskop + Özel + Ordu/kamusal + Ordu + Kamusal + Bölgesel + Uluslararası + Yaz kampı + Tuz: hayır + Tuz + Derinlik + Otizm: hayır + Otizm: evet + Ebola: hayır + Ebola: evet + Sıtma: hayır + Sıtma: evet + Evet + Acil: hayır + Acil: evet + Danışma: hayır + Danışma: evet + Kapasite (yatak) + Danışma (evsiz): hayır + Danışma (evsiz): evet + Danışma (aile): hayır + Danışma (aile): evet + Danışma (uyuşturucu): hayır + Danışma (uyuşturucu): evet + Danışma (bağımlılık): evet + Danışma (bağımlılık): evet + Sağlık çalışanının işi: psikolog + İlk yardım çantası + Duvar + Yeraltı + Sağlık merkezi türü: sahra hastanesi + Sağlık merkezi türü: laboratuvar + Sağlık hizmeti: aşılama: hayır + Sağlık hizmeti: aşılama: evet + Sağlık hizmeti: danışma: hayır + Sağlık hizmeti: danışma: evet + Sağlık hizmeti: hasta bakıcılık: hayır + Sağlık hizmeti: hasta bakıcılık: evet + Geleneksel Tibet + Geleneksel Moğol + Geleneksel Çin + Batılı + Solaryum + Çeşme + Elektrikli süpürtge: hayır + Elektrikli süpürge + Evet + Evet + Evet + Ev adı + Patlama zamanı (UTC) + Patlama tarihi (UTC) + Patlama türü: yeraltı + Patlama türü: yeraltı, tünel + Patlama: ülke + Korunan nesne: su + Korunan nesne: yaşam alanı + Korunan nesne: doğa + Korunan nesne: tarihi + Koruma alanı + Yapım aşamasında \ No newline at end of file From 48ff103fbbcfd030f02d15d4f9b5989f06b705d0 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 5 Oct 2020 13:21:02 +0000 Subject: [PATCH 0494/1366] Translated using Weblate (Hebrew) Currently translated at 56.7% (2171 of 3825 strings) --- OsmAnd/res/values-iw/phrases.xml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-iw/phrases.xml b/OsmAnd/res/values-iw/phrases.xml index c625ca9fdd..d593ffb9d0 100644 --- a/OsmAnd/res/values-iw/phrases.xml +++ b/OsmAnd/res/values-iw/phrases.xml @@ -1390,7 +1390,7 @@ שיתוף רכב שיתוף סירות מעגן - בית שימוש + בית שימוש;אסלה;טואלט מקלחת סאונה בית בושת @@ -2043,7 +2043,7 @@ אגרה למשאיות כן כן - לא + שמע: לא רק כאשר מותר לחצות תחנת הצלה אזור שירות @@ -2119,7 +2119,7 @@ דלק 100LL גפ״מ דלק מטוסים A-1 - תוסף AdBlue + נוזל מפלט לדיזל כספומט מקום בנסיעה שיתופית וסליאן @@ -2159,4 +2159,19 @@ כן מצוק טיפוס קטגוריית קושי + צינור + רשת מילוי מי שתייה + מילוי מי שתייה: אין + כן + תיבת תרומה + חץ: אין + כן + כן + מעלית + זמן אמת + השהיה + כן + לוח זמנים + כוורת דבורים + חנות אגוזים \ No newline at end of file From 6f5019f03f835827f0e491bcbd1fc4bf2ae016c8 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 6 Oct 2020 09:59:03 +0300 Subject: [PATCH 0495/1366] style issues and cleanup --- OsmAnd/build.gradle | 8 +++--- OsmAnd/res/values/strings.xml | 2 -- .../plus/osmedit/OpenstreetmapRemoteUtil.java | 16 +++++------ .../plus/osmedit/OsmBugsRemoteUtil.java | 5 ++-- .../osmedit/SettingsOsmEditingActivity.java | 28 ------------------- .../oauth/OsmOAuthAuthorizationAdapter.java | 3 +- 6 files changed, 16 insertions(+), 46 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index e18cb21e76..ddac6aee41 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -216,13 +216,13 @@ android { buildTypes { debug { - buildConfigField "String", "CONSUMER_KEY", "\"Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y\"" - buildConfigField "String", "CONSUMER_SECRET", "\"lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM\"" + buildConfigField "String", "OSM_OAUTH_CONSUMER_KEY", "\"Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y\"" + buildConfigField "String", "OSM_OAUTH_CONSUMER_SECRET", "\"lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM\"" signingConfig signingConfigs.development } release { - buildConfigField "String", "CONSUMER_KEY", "\"Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y\"" - buildConfigField "String", "CONSUMER_SECRET", "\"lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM\"" + buildConfigField "String", "OSM_OAUTH_CONSUMER_KEY", "\"Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y\"" + buildConfigField "String", "OSM_OAUTH_CONSUMER_SECRET", "\"lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM\"" signingConfig signingConfigs.publishing } } diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 915e2a0f6d..a8b3d34fbe 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -13,8 +13,6 @@ --> Logout successful Clear OpenStreetMap OAuth token - Test user request - Retrieve current user info Log in via OAuth Perform an OAuth Login to use osmedit features Name: A – Z diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java index e978c3841b..393dd7d965 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OpenstreetmapRemoteUtil.java @@ -174,14 +174,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { } String response = sendRequest( getSiteApi() + "api/0.6/changeset/create/", "PUT", writer.getBuffer().toString(), ctx.getString(R.string.opening_changeset), true); //$NON-NLS-1$ //$NON-NLS-2$ - try { - if (response != null && response.length() > 0) { - log.debug(response); - id = Long.parseLong(response); - } - } catch (Exception e) { - log.error(e); - } + try { + if (response != null && response.length() > 0) { + log.debug(response); + id = Long.parseLong(response); + } + } catch (Exception e) { + log.error(e); + } return id; } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java index 724f798bf7..a6e2dd5ca8 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsRemoteUtil.java @@ -119,10 +119,9 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil { connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); //$NON-NLS-1$ if (!anonymous) { - if (client.isValidToken()){ + if (client.isValidToken()) { connection.addRequestProperty("Authorization", "OAuth " + client.getClient().getAccessToken().getToken()); - } - else { + } else { String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java index 6be8066553..4f1410dc4c 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/SettingsOsmEditingActivity.java @@ -82,34 +82,6 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity { prefOAuth.setTitle(R.string.osm_authorization_success); prefOAuth.setSummary(R.string.osm_authorization_success); prefOAuth.setKey("local_openstreetmap_oauth_success"); - - final Preference prefTestUser = new Preference(this); - prefTestUser.setTitle(R.string.test_user_request); - prefTestUser.setSummary(R.string.test_user_request_description); - prefTestUser.setKey("local_openstreetmap_oauth_user"); - prefTestUser.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - String url = "https://api.openstreetmap.org/api/0.6/user/details"; - client.performGetRequest(url, new OAuthAsyncRequestCallback() { - @Override - public void onCompleted(Response response) { - try { - Toast.makeText(SettingsOsmEditingActivity.this,response.getBody(),Toast.LENGTH_SHORT).show(); - } catch (IOException e) { - log.error(e); - } - } - - @Override - public void onThrowable(Throwable t) { - Toast.makeText(SettingsOsmEditingActivity.this, - "ERROR happened",Toast.LENGTH_SHORT).show(); - } - }); - return true; - } - }); final Preference prefClearToken = new Preference(this); prefClearToken.setTitle(R.string.shared_string_logoff); prefClearToken.setSummary(R.string.clear_osm_token); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java index 09a3dba0c4..8d687f9604 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java @@ -17,7 +17,8 @@ import java.util.concurrent.ExecutionException; public class OsmOAuthAuthorizationAdapter { private OsmandApplication application; - private OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET); + private OsmOAuthAuthorizationClient client = + new OsmOAuthAuthorizationClient(BuildConfig.OSM_OAUTH_CONSUMER_KEY, BuildConfig.OSM_OAUTH_CONSUMER_SECRET); private static final int THREAD_ID = 10101; public OsmOAuthAuthorizationAdapter(OsmandApplication application) { From a5776ae07a527c64ffc8936a42e8f31d65c0b1e4 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 6 Oct 2020 10:30:10 +0300 Subject: [PATCH 0496/1366] cleanup --- OsmAnd-java/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/build.gradle b/OsmAnd-java/build.gradle index 0d0a3c265d..2c5415a84f 100644 --- a/OsmAnd-java/build.gradle +++ b/OsmAnd-java/build.gradle @@ -104,7 +104,7 @@ dependencies { implementation 'com.moparisthebest:junidecode:0.1.1' implementation 'com.vividsolutions:jts-core:1.14.0' implementation 'com.google.openlocationcode:openlocationcode:1.0.4' - implementation('com.github.scribejava:scribejava-apis:7.1.1'){ + implementation ('com.github.scribejava:scribejava-apis:7.1.1') { exclude group: "com.fasterxml.jackson.core" } // turn off for now From be83917aa7886ed0d0c91913de434a8f90a3356f Mon Sep 17 00:00:00 2001 From: Alexander Sytnyk Date: Tue, 6 Oct 2020 11:03:19 +0300 Subject: [PATCH 0497/1366] #9783 Fix broken app theme icon --- .../plus/settings/fragments/GeneralProfileSettingsFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java index e870fed149..0cd1e628bb 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java @@ -123,7 +123,7 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment impleme if (settings.isSystemDefaultThemeUsedForMode(mode)) { iconId = R.drawable.ic_action_android; } else { - iconId = settings.isLightContent() ? R.drawable.ic_action_sun : R.drawable.ic_action_moon; + iconId = settings.isLightContentForMode(mode) ? R.drawable.ic_action_sun : R.drawable.ic_action_moon; } return getActiveIcon(iconId); } From b940dc6ad56081435ff1331898ba8131c395617e Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 6 Oct 2020 12:05:50 +0300 Subject: [PATCH 0498/1366] Update direction arrow for tracks --- OsmAnd/res/drawable/ic_action_direction_arrow.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/drawable/ic_action_direction_arrow.xml b/OsmAnd/res/drawable/ic_action_direction_arrow.xml index b13a8692f7..49bec48f22 100644 --- a/OsmAnd/res/drawable/ic_action_direction_arrow.xml +++ b/OsmAnd/res/drawable/ic_action_direction_arrow.xml @@ -1,9 +1,9 @@ + android:viewportHeight="12"> From ad31b0842af222bfefbb30645bd21c8c2e2a2795 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 6 Oct 2020 14:04:48 +0300 Subject: [PATCH 0499/1366] Fix review --- .../osmand/aidlapi/IOsmAndAidlInterface.aidl | 2 -- .../customization/ProfileSettingsParams.java | 8 +++---- ...ingsType.java => AExportSettingsType.java} | 2 +- .../aidlapi/profile/ExportProfileParams.java | 6 ++--- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 24 ++++++++++++++----- .../net/osmand/aidl/OsmandAidlService.java | 6 ++--- .../net/osmand/aidl/OsmandAidlServiceV2.java | 4 ++-- .../customization/ProfileSettingsParams.java | 21 +--------------- .../net/osmand/plus/helpers/ImportHelper.java | 10 ++------ .../plus/settings/backend/SettingsHelper.java | 9 ++++--- .../fragments/ImportSettingsFragment.java | 6 +---- 11 files changed, 39 insertions(+), 59 deletions(-) rename OsmAnd-api/src/net/osmand/aidlapi/profile/{ExportSettingsType.java => AExportSettingsType.java} (80%) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl index 3a8edb6d80..72a3035b60 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl @@ -106,8 +106,6 @@ import net.osmand.aidlapi.events.AKeyEventsParams; import net.osmand.aidlapi.info.AppInfoParams; import net.osmand.aidlapi.profile.ExportProfileParams; -import net.osmand.aidlapi.profile.ExportSettingsType; - // NOTE: Add new methods at the end of file!!! diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java index 427ccc71fd..00c68851e7 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java @@ -5,7 +5,7 @@ import android.os.Bundle; import android.os.Parcel; import net.osmand.aidlapi.AidlParams; -import net.osmand.aidlapi.profile.ExportSettingsType; +import net.osmand.aidlapi.profile.AExportSettingsType; import java.util.ArrayList; @@ -20,13 +20,13 @@ public class ProfileSettingsParams extends AidlParams { private Uri profileSettingsUri; private String latestChanges; private int version; - ArrayList settingsTypeKeyList = new ArrayList<>(); + private ArrayList settingsTypeKeyList = new ArrayList<>(); boolean replace; - public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, boolean replace, + public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, boolean replace, String latestChanges, int version) { this.profileSettingsUri = profileSettingsUri; - for (ExportSettingsType settingsType : settingsTypeList) { + for (AExportSettingsType settingsType : settingsTypeList) { settingsTypeKeyList.add(settingsType.name()); } this.replace = replace; diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.java similarity index 80% rename from OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java rename to OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.java index 19bdad37dc..23c0189615 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.java @@ -1,6 +1,6 @@ package net.osmand.aidlapi.profile; -public enum ExportSettingsType { +public enum AExportSettingsType { PROFILE, QUICK_ACTIONS, POI_TYPES, diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java index 6298ccba04..931f52eeb8 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java @@ -13,12 +13,12 @@ public class ExportProfileParams extends AidlParams { public static final String PROFILE_KEY = "profile"; public static final String SETTINGS_TYPE_KEY = "settings_type"; private String profile; - ArrayList settingsTypeKeyList = new ArrayList<>(); + private ArrayList settingsTypeKeyList = new ArrayList<>(); - public ExportProfileParams(String profile, ArrayList settingsTypeList) { + public ExportProfileParams(String profile, ArrayList settingsTypeList) { this.profile = profile; - for (ExportSettingsType settingsType : settingsTypeList) { + for (AExportSettingsType settingsType : settingsTypeList) { settingsTypeKeyList.add(settingsType.name()); } } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 6cb1dee762..e1aecf5500 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -2253,8 +2253,20 @@ public class OsmandAidlApi { private Map copyFilesCache = new ConcurrentHashMap<>(); - public boolean importProfile(final Uri profileUri, ArrayList settingsTypeKeys, boolean replace, - String latestChanges, int version) { + public boolean importProfile(final Uri profileUri, String latestChanges, int version) { + if (profileUri != null) { + Bundle bundle = new Bundle(); + bundle.putString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY, latestChanges); + bundle.putInt(SettingsHelper.SETTINGS_VERSION_KEY, version); + + MapActivity.launchMapActivityMoveToTop(app, null, profileUri, bundle); + return true; + } + return false; + } + + public boolean importProfileV2(final Uri profileUri, ArrayList settingsTypeKeys, boolean replace, + String latestChanges, int version) { if (profileUri != null) { Bundle bundle = new Bundle(); bundle.putStringArrayList(SettingsHelper.SETTINGS_TYPE_LIST_KEY, settingsTypeKeys); @@ -2362,7 +2374,7 @@ public class OsmandAidlApi { } } - int copyFileOld(String fileName, byte[] filePartData, long startTime, boolean done) { + int copyFile(String fileName, byte[] filePartData, long startTime, boolean done) { if (Algorithms.isEmpty(fileName) || filePartData == null) { return COPY_FILE_PARAMS_ERROR; } @@ -2376,7 +2388,7 @@ public class OsmandAidlApi { } } - int copyFile(String destinationDir, String fileName, byte[] filePartData, long startTime, boolean done) { + int copyFileV2(String destinationDir, String fileName, byte[] filePartData, long startTime, boolean done) { if (Algorithms.isEmpty(fileName) || filePartData == null) { return COPY_FILE_PARAMS_ERROR; } @@ -2391,7 +2403,7 @@ public class OsmandAidlApi { } else if (fileName.endsWith(IndexConstants.GPX_FILE_EXT)) { if (destinationDir.startsWith(IndexConstants.GPX_INDEX_DIR) && !FILE_TO_SAVE.equals(fileName)) { - GPXUtilities.loadGPXFile(new File(destinationDir, fileName)); + showGpx(new File(destinationDir, fileName).getName()); } else if (destinationDir.isEmpty() && FILE_TO_SAVE.equals(fileName)) { GPXUtilities.loadGPXFile(new File(destinationDir, fileName)); app.getFavorites().loadFavorites(); @@ -2404,7 +2416,7 @@ public class OsmandAidlApi { private int copyFileImpl(String fileName, byte[] filePartData, long startTime, boolean done, String destinationDir) { File tempDir = FileUtils.getTempDir(app); File file = new File(tempDir, fileName); - File destFile = app.getAppPath(destinationDir + fileName); + File destFile = app.getAppPath(new File(destinationDir, fileName).getPath()); long currentTime = System.currentTimeMillis(); try { FileCopyInfo info = copyFilesCache.get(fileName); diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java index 0d9e5d6961..99e888973f 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java @@ -1138,7 +1138,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { if (api == null) { return CANNOT_ACCESS_API_ERROR; } - return api.copyFileOld(params.getFileName(), params.getFilePartData(), params.getStartTime(), params.isDone()); + return api.copyFile(params.getFileName(), params.getFilePartData(), params.getStartTime(), params.isDone()); } catch (Exception e) { handleException(e); return UNKNOWN_API_ERROR; @@ -1299,8 +1299,8 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { public boolean importProfile(ProfileSettingsParams params) { try { OsmandAidlApi api = getApi("importProfile"); - return api != null && api.importProfile(params.getProfileSettingsUri(), params.getSettingsTypeKeys(), - params.isReplace(), params.getLatestChanges(), params.getVersion()); + return api != null && api.importProfile(params.getProfileSettingsUri(), params.getLatestChanges(), + params.getVersion()); } catch (Exception e) { handleException(e); return false; diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 8f6564a957..7c69be1e94 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -1092,7 +1092,7 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener if (api == null) { return CANNOT_ACCESS_API_ERROR; } - return api.copyFile(params.getDestinationDir(), params.getFileName(), params.getFilePartData(), + return api.copyFileV2(params.getDestinationDir(), params.getFileName(), params.getFilePartData(), params.getStartTime(), params.isDone()); } catch (Exception e) { handleException(e); @@ -1260,7 +1260,7 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener public boolean importProfile(ProfileSettingsParams params) { try { OsmandAidlApi api = getApi("importProfile"); - return api != null && api.importProfile(params.getProfileSettingsUri(), params.getSettingsTypeKeys(), + return api != null && api.importProfileV2(params.getProfileSettingsUri(), params.getSettingsTypeKeys(), params.isReplace(), params.getLatestChanges(), params.getVersion()); } catch (Exception e) { handleException(e); diff --git a/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java b/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java index cd5cfecddf..6c2f82cd8f 100644 --- a/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java +++ b/OsmAnd/src/net/osmand/aidl/customization/ProfileSettingsParams.java @@ -4,20 +4,13 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -import net.osmand.aidlapi.profile.ExportSettingsType; - -import java.util.ArrayList; - public class ProfileSettingsParams implements Parcelable { private Uri profileSettingsUri; private String latestChanges; private int version; - ArrayList settingsTypeKeyList = new ArrayList<>(); - boolean replace; - public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, - boolean replace, String latestChanges, int version) { + public ProfileSettingsParams(Uri profileSettingsUri, String latestChanges, int version) { this.profileSettingsUri = profileSettingsUri; this.latestChanges = latestChanges; this.version = version; @@ -51,29 +44,17 @@ public class ProfileSettingsParams implements Parcelable { return profileSettingsUri; } - public ArrayList getSettingsTypeKeys() { - return settingsTypeKeyList; - } - - public boolean isReplace() { - return replace; - } - @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(version); out.writeString(latestChanges); out.writeParcelable(profileSettingsUri, flags); - out.writeStringList(settingsTypeKeyList); - out.writeInt(replace ? 1 : 0); } private void readFromParcel(Parcel in) { version = in.readInt(); latestChanges = in.readString(); profileSettingsUri = in.readParcelable(Uri.class.getClassLoader()); - in.readStringList(settingsTypeKeyList); - replace = in.readInt() == 1; } @Override diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index ec2cf92031..686a56233f 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -701,9 +701,7 @@ public class ImportHelper { private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject> callback) { if (extras != null && extras.containsKey(SETTINGS_VERSION_KEY) - && extras.containsKey(REPLACE_KEY) - && extras.containsKey(SETTINGS_LATEST_CHANGES_KEY) - && extras.containsKey(SETTINGS_TYPE_LIST_KEY)) { + && extras.containsKey(SETTINGS_LATEST_CHANGES_KEY)) { int version = extras.getInt(SETTINGS_VERSION_KEY, -1); String latestChanges = extras.getString(SETTINGS_LATEST_CHANGES_KEY); boolean replace = extras.getBoolean(REPLACE_KEY); @@ -817,11 +815,7 @@ public class ImportHelper { if (mapActivity != null && succeed) { FragmentManager fm = mapActivity.getSupportFragmentManager(); app.getRendererRegistry().updateExternalRenderers(); - AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { - @Override - public void onRoutingFilesLoaded() { - } - }); + AppInitializer.loadRoutingFiles(app, null); if (file != null) { ImportCompleteFragment.showInstance(fm, items, file.getName()); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java index 01ca1cb38c..0172531139 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java @@ -2931,14 +2931,13 @@ public class SettingsHelper { IMPORT } - public List getFilteredSettingsItems(Map> additionalData, - List settingsTypes) { - List settingsItems = new ArrayList<>(); + public List getFilteredSettingsItems(Map> additionalData, + List settingsTypes) { + List settingsItems = new ArrayList<>(); for (ExportSettingsType settingsType : settingsTypes) { List settingsDataObjects = additionalData.get(settingsType); if (settingsDataObjects != null) { - settingsItems.addAll(app.getSettingsHelper().prepareAdditionalSettingsItems( - new ArrayList<>(settingsDataObjects))); + settingsItems.addAll(prepareAdditionalSettingsItems(new ArrayList<>(settingsDataObjects))); } } return settingsItems; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java index 051bf422f8..7e8f6bb934 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java @@ -267,11 +267,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment FragmentManager fm = getFragmentManager(); if (succeed) { app.getRendererRegistry().updateExternalRenderers(); - AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { - @Override - public void onRoutingFilesLoaded() { - } - }); + AppInitializer.loadRoutingFiles(app, null); if (fm != null && file != null) { ImportCompleteFragment.showInstance(fm, items, file.getName()); } From 3e5d5a71e169b17596cc4ec42d84288b0d5e4f33 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 5 Oct 2020 10:47:39 +0300 Subject: [PATCH 0500/1366] Fix hw signing --- OsmAnd/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 9faf1b38aa..ed8cd71a9c 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -46,6 +46,8 @@ android { storePassword System.getenv("OSMAND_HW_APK_PASSWORD") keyAlias "osmand" keyPassword System.getenv("OSMAND_HW_APK_PASSWORD") + v1SigningEnabled true + v2SigningEnabled true } } From 762b1b069233c460549379fa6c64a441fba6287a Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 13:10:45 +0300 Subject: [PATCH 0501/1366] Added error code to the toast --- OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java index 06fa78b260..585c6b8404 100755 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/ExceptionHandle.java @@ -85,7 +85,7 @@ public class ExceptionHandle { return SOLVED; default: // handle other error scenarios - showToast(activity, "Order unknown error!"); + showToast(activity, "Order unknown error (" + iapApiException.getStatusCode() + ")"); return SOLVED; } } else { From 21c6358b583e891a33b23809bc382f0863def2d4 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 14:03:20 +0300 Subject: [PATCH 0502/1366] Fix hw gradle build --- OsmAnd/build.gradle | 2 +- OsmAnd/osmand_hw_key | Bin 0 -> 2244 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 OsmAnd/osmand_hw_key diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index ed8cd71a9c..046b449f2e 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -291,7 +291,7 @@ task downloadWorldMiniBasemap { task setupHuaweiConfig { doLast { if (System.getenv("HUAWEI_SDK_JSON")) { - new File("agconnect-services.json").text = System.getenv("HUAWEI_SDK_JSON") + new File("OsmAnd/agconnect-services.json").text = System.getenv("HUAWEI_SDK_JSON") } } } diff --git a/OsmAnd/osmand_hw_key b/OsmAnd/osmand_hw_key new file mode 100644 index 0000000000000000000000000000000000000000..7dace502e790fe07cd1496b6558cce2b60e9011e GIT binary patch literal 2244 zcmchY`8S&h7svBN?1F~IQnZ%ZqfhKhh;2}m8tc?vp}ZoN+NPl@EovQGOKVH*OH^%* zE{Y&2+Nze?qj)W)v~LxogfVmGJ!j7Q2fRPrAHJV+&pr2i?>+Y(ZX9kvAQ0$r0DlEX z=+zKk0`6EwZpD0HK_Ki<}0Uw&vA*31@B79CD!TZINES z({r@8Rko;1k8xhfeRX6PpYDjg-#T`oz$W8?2) z1Bm0j2QUiRw`V5$g+YT2vuU_?|`o)r$y*Y)Mv0PLQFS7c0T!yGT{MCadwW zeFPOEkm}&EG9)Dz+1xU^G73axnN@Ld+NBCiM5-uclEZYqrAZMKk$L_&AHMM1YSA1E zlT9~rrS2PoIqlg=_L1??k%h@UR4nOyP-vcsVE2iqNDjq+kw&6>7P~N?sb_kA`SI)S z2W|S-hPf=A2)7>J1?$OH5);Opo>fvuCg)@@3K`lb%%j66hTs)yZVUTE(V1P*=yMWZ zm6s&O@_&Z}3?9Vnm@hbfjO00 zrw_0=9+&?J$(*^33nq(Zjn+fsqPlYP-Cpy!nH`aq!L%21l=?S_mb+zCW}9c;#q5sd z%m)R;;D^fbw+g9ftUFCc+R4Fo=@&%cQ}%f|`HPZ+v8Y{~856QEdNOrL`h(OCIEM+B zzsTcC)fzQ|D|L72m*FN|;Y}(&ebAoDB&_B8RXu$l_Dy+{C6C7oo`Eswg=_0~g*)Dx+hCxRSr)Oig@$~^|inNGum#XJ@K6l3qt2@k9 z(zACM=JeC@Fv69^I>D}#QVSNsxPEgTr?7)HL(vHj0^c}%L=6%l?Lm*o728El14kk{ zl^Vg9bK^x_)b%x}l2`Or46F$D`*IO$%lz?Vzk$iI{P}0o`UVXI&9W^Dsw0ty3sa)^ zYHxJCCWd80iG$jI4)I9{@^|*YIrsWG59+kuRYuVW0ko#1bl3iOh_1d9ZCm2A^ZT5Y zt*h5^CqjpaeksJ(CfhlW#V%P0@^3@DZ}Dz*@)uWQ>vX zRu~}u_`KMu7FE951;=ZRoEnnd7TP*P4D3PTeSmqCA>?@7`*R^PEjylQ-wR%An!pFa zCu?42REnx@x}?4rp<)`C(3wTvn0uA24xiMM8@(FC@PsskWo#`~j%KNE8@{~m)eQT- z_mk5I33fA2CZ$*PT;r3GayjFV&7G(@8&5*XZ;XcG^7~#@S8y*h;77GkAPpzibrAf&*p21MDD*EpHlM|L*dkQk)C+~Fpbs5>+)U-f72!xFY zlGtKE64aZ_1_hu{7O6vr_G~ z3%(LQYXjX2T0o+VRb5Qma;k{qiQI^JO*y61Utaft7K7B&RpMrf=fF z!h|t~O5?mpyA{N=(cv65v$}od2AfmBB|B+P^?RSDDsm#FzCAUo_VCvb?1!=e5THUD zJPk@74_cBRhJ*=!4&YX}F3aXMTr}}cu+*?*yZ3PapC%sf)Uk;G#B&`}!(ZGsr{_-* zPPh$?Al`idzpWLyH>HKnIdGX*QA|}dn@Q&te^s}M|rkzAFjs6zlQVaQRbW=eTZC8aOqod9*v@lZbmF*m9QRIU41i_>m#$4BB z|9wAB6xAnDS6$jXrSU);;Azj2cX3VMpcNlVwG0@%6`N>mgRF8mcVBhbU!Ik({=vxb In)|W-2Roh77ytkO literal 0 HcmV?d00001 From 9cc9c3ca6200a253de789a3ae5ede0e9f8acdbc0 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 14:06:36 +0300 Subject: [PATCH 0503/1366] Drop unused file --- OsmAnd/osmand_hw_key | Bin 2244 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 OsmAnd/osmand_hw_key diff --git a/OsmAnd/osmand_hw_key b/OsmAnd/osmand_hw_key deleted file mode 100644 index 7dace502e790fe07cd1496b6558cce2b60e9011e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2244 zcmchY`8S&h7svBN?1F~IQnZ%ZqfhKhh;2}m8tc?vp}ZoN+NPl@EovQGOKVH*OH^%* zE{Y&2+Nze?qj)W)v~LxogfVmGJ!j7Q2fRPrAHJV+&pr2i?>+Y(ZX9kvAQ0$r0DlEX z=+zKk0`6EwZpD0HK_Ki<}0Uw&vA*31@B79CD!TZINES z({r@8Rko;1k8xhfeRX6PpYDjg-#T`oz$W8?2) z1Bm0j2QUiRw`V5$g+YT2vuU_?|`o)r$y*Y)Mv0PLQFS7c0T!yGT{MCadwW zeFPOEkm}&EG9)Dz+1xU^G73axnN@Ld+NBCiM5-uclEZYqrAZMKk$L_&AHMM1YSA1E zlT9~rrS2PoIqlg=_L1??k%h@UR4nOyP-vcsVE2iqNDjq+kw&6>7P~N?sb_kA`SI)S z2W|S-hPf=A2)7>J1?$OH5);Opo>fvuCg)@@3K`lb%%j66hTs)yZVUTE(V1P*=yMWZ zm6s&O@_&Z}3?9Vnm@hbfjO00 zrw_0=9+&?J$(*^33nq(Zjn+fsqPlYP-Cpy!nH`aq!L%21l=?S_mb+zCW}9c;#q5sd z%m)R;;D^fbw+g9ftUFCc+R4Fo=@&%cQ}%f|`HPZ+v8Y{~856QEdNOrL`h(OCIEM+B zzsTcC)fzQ|D|L72m*FN|;Y}(&ebAoDB&_B8RXu$l_Dy+{C6C7oo`Eswg=_0~g*)Dx+hCxRSr)Oig@$~^|inNGum#XJ@K6l3qt2@k9 z(zACM=JeC@Fv69^I>D}#QVSNsxPEgTr?7)HL(vHj0^c}%L=6%l?Lm*o728El14kk{ zl^Vg9bK^x_)b%x}l2`Or46F$D`*IO$%lz?Vzk$iI{P}0o`UVXI&9W^Dsw0ty3sa)^ zYHxJCCWd80iG$jI4)I9{@^|*YIrsWG59+kuRYuVW0ko#1bl3iOh_1d9ZCm2A^ZT5Y zt*h5^CqjpaeksJ(CfhlW#V%P0@^3@DZ}Dz*@)uWQ>vX zRu~}u_`KMu7FE951;=ZRoEnnd7TP*P4D3PTeSmqCA>?@7`*R^PEjylQ-wR%An!pFa zCu?42REnx@x}?4rp<)`C(3wTvn0uA24xiMM8@(FC@PsskWo#`~j%KNE8@{~m)eQT- z_mk5I33fA2CZ$*PT;r3GayjFV&7G(@8&5*XZ;XcG^7~#@S8y*h;77GkAPpzibrAf&*p21MDD*EpHlM|L*dkQk)C+~Fpbs5>+)U-f72!xFY zlGtKE64aZ_1_hu{7O6vr_G~ z3%(LQYXjX2T0o+VRb5Qma;k{qiQI^JO*y61Utaft7K7B&RpMrf=fF z!h|t~O5?mpyA{N=(cv65v$}od2AfmBB|B+P^?RSDDsm#FzCAUo_VCvb?1!=e5THUD zJPk@74_cBRhJ*=!4&YX}F3aXMTr}}cu+*?*yZ3PapC%sf)Uk;G#B&`}!(ZGsr{_-* zPPh$?Al`idzpWLyH>HKnIdGX*QA|}dn@Q&te^s}M|rkzAFjs6zlQVaQRbW=eTZC8aOqod9*v@lZbmF*m9QRIU41i_>m#$4BB z|9wAB6xAnDS6$jXrSU);;Azj2cX3VMpcNlVwG0@%6`N>mgRF8mcVBhbU!Ik({=vxb In)|W-2Roh77ytkO From b7e04acb7fa374d3d1f837473033f607bb85d315 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 14:57:37 +0300 Subject: [PATCH 0504/1366] Fix hw build --- OsmAnd/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 046b449f2e..3175b9354d 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -291,7 +291,7 @@ task downloadWorldMiniBasemap { task setupHuaweiConfig { doLast { if (System.getenv("HUAWEI_SDK_JSON")) { - new File("OsmAnd/agconnect-services.json").text = System.getenv("HUAWEI_SDK_JSON") + file("agconnect-services.json").text = System.getenv("HUAWEI_SDK_JSON") } } } From aea3959a7e8b8272d6924417a24877ebc42dc89d Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 15:51:24 +0300 Subject: [PATCH 0505/1366] Fix hw build (drop hw sdk config writing) --- OsmAnd/build.gradle | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 3175b9354d..79132cb79a 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -288,14 +288,6 @@ task downloadWorldMiniBasemap { } } -task setupHuaweiConfig { - doLast { - if (System.getenv("HUAWEI_SDK_JSON")) { - file("agconnect-services.json").text = System.getenv("HUAWEI_SDK_JSON") - } - } -} - task collectVoiceAssets(type: Sync) { from "../../resources/voice" into "assets/voice" @@ -422,11 +414,6 @@ task collectExternalResources { copyWidgetIconsXhdpi, copyPoiCategories, downloadWorldMiniBasemap - - String tskReqStr = gradle.startParameter.taskNames.toString() - if (tskReqStr.contains("huawei")) { - dependsOn setupHuaweiConfig - } } // Legacy core build From 1801e0add91bd941b9926235738f52e675a644ba Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 16:49:10 +0300 Subject: [PATCH 0506/1366] Fix fulldev build --- OsmAnd/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 79132cb79a..2775f1a2c2 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -119,6 +119,9 @@ android { full { java.srcDirs = ["src-google"] } + fulldev { + java.srcDirs = ["src-google"] + } free { java.srcDirs = ["src-google"] manifest.srcFile "AndroidManifest-free.xml" From ba5b407cea5efff921390779ec525e9cbd76819c Mon Sep 17 00:00:00 2001 From: sergosm Date: Tue, 6 Oct 2020 16:51:45 +0300 Subject: [PATCH 0507/1366] Move development settings Preview --- OsmAnd/res/values/strings.xml | 10 ++- OsmAnd/res/xml/development_settings.xml | 35 --------- .../DevelopmentSettingsFragment.java | 54 +++---------- .../SettingsDevelopmentActivity.java | 37 +++------ .../plus/settings/backend/OsmandSettings.java | 10 +-- .../fragments/RouteParametersFragment.java | 76 ++++++++++++++++++- 6 files changed, 111 insertions(+), 111 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 086a7470d5..b01a0ef58c 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,14 @@ Thx - Hardy --> + Switch to Java (safe) Public Transport routing calculation + Native Public Transport development + Recalculates only the initial part of the route. Can be used for long trips. + Two-phase routing for car navigation. + Complex routing + OsmAnd Live data + OsmAnd Live data + Development Start/finish icons Name: A – Z Name: Z – A @@ -2463,7 +2471,6 @@ Specify the speech rate for text-to-speech. Speech Rate Fast route calculation failed (%s), fallback to slow calculation. - Disable two-phase routing for car navigation. Disable complex routing Seamark Select shown profiles. @@ -3657,7 +3664,6 @@ You need to be online to install this plugin. Get Smart route recalculation - For long trips, only recalculate the initial part of the route. Do you like OsmAnd? Your opinion and feedback is valued. Rate this app diff --git a/OsmAnd/res/xml/development_settings.xml b/OsmAnd/res/xml/development_settings.xml index d01a1f169d..231bd469bc 100644 --- a/OsmAnd/res/xml/development_settings.xml +++ b/OsmAnd/res/xml/development_settings.xml @@ -25,46 +25,11 @@ android:summaryOn="@string/shared_string_enabled" android:title="@string/safe_mode" /> - - - - - - - - - - MAPILLARY_FILTER_TO_DATE = new LongPreference("mapillary_filter_to_date", 0).makeGlobal(); public final CommonPreference MAPILLARY_FILTER_PANO = new BooleanPreference("mapillary_filter_pano", false).makeGlobal(); - public final CommonPreference USE_FAST_RECALCULATION = new BooleanPreference("use_fast_recalculation", true).makeGlobal().cache(); + public final CommonPreference USE_FAST_RECALCULATION = new BooleanPreference("use_fast_recalculation", true).makeProfile().cache(); public final CommonPreference FORCE_PRIVATE_ACCESS_ROUTING_ASKED = new BooleanPreference("force_private_access_routing", false).makeProfile().cache(); public final CommonPreference SHOW_CARD_TO_CHOOSE_DRAWER = new BooleanPreference("show_card_to_choose_drawer", false).makeGlobal(); @@ -2117,7 +2117,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile(); // dev version - public final CommonPreference DISABLE_COMPLEX_ROUTING = new BooleanPreference("disable_complex_routing", false).makeGlobal(); + public final CommonPreference DISABLE_COMPLEX_ROUTING = new BooleanPreference("disable_complex_routing", false).makeProfile(); public final CommonPreference ENABLE_TIME_CONDITIONAL_ROUTING = new BooleanPreference("enable_time_conditional_routing", true).makeProfile(); public boolean simulateNavigation = false; @@ -3852,9 +3852,9 @@ public class OsmandSettings { public final CommonPreference ROUTE_RECALCULATION_DISTANCE = new FloatPreference("routing_recalc_distance", 0.f).makeProfile(); public final CommonPreference ROUTE_STRAIGHT_ANGLE = new FloatPreference("routing_straight_angle", 30.f).makeProfile(); - public final OsmandPreference USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference("enable_osmc_routing", true).makeGlobal(); + public final OsmandPreference USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference("enable_osmc_routing", true).makeProfile(); - public final OsmandPreference USE_OSM_LIVE_FOR_PUBLIC_TRANSPORT = new BooleanPreference("enable_osmc_public_transport", false).makeGlobal(); + public final OsmandPreference USE_OSM_LIVE_FOR_PUBLIC_TRANSPORT = new BooleanPreference("enable_osmc_public_transport", false).makeProfile(); public final OsmandPreference VOICE_MUTE = new BooleanPreference("voice_mute", false).makeProfile().cache(); @@ -3863,7 +3863,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference SAFE_MODE = new BooleanPreference("safe_mode", false).makeGlobal(); - public final OsmandPreference PT_SAFE_MODE = new BooleanPreference("pt_safe_mode", false).makeGlobal(); + public final OsmandPreference PT_SAFE_MODE = new BooleanPreference("pt_safe_mode", false).makeProfile(); public final OsmandPreference NATIVE_RENDERING_FAILED = new BooleanPreference("native_rendering_failed_init", false).makeGlobal(); public final OsmandPreference USE_OPENGL_RENDER = new BooleanPreference("use_opengl_render", diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java index 198e6e13eb..70dc81c23e 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java @@ -6,6 +6,7 @@ import android.content.DialogInterface; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -25,6 +26,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.slider.Slider; import net.osmand.StateChangedListener; +import net.osmand.plus.Version; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -155,6 +157,60 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP getPreferenceScreen().addPreference(timeConditionalRouting); } + private void setupOsmLiveForPublicTransportPref() { + SwitchPreferenceEx useOsmLiveForPublicTransport = createSwitchPreferenceEx(settings.USE_OSM_LIVE_FOR_PUBLIC_TRANSPORT.getId(), + R.string.use_live_public_transport, R.layout.preference_with_descr_dialog_and_switch); + useOsmLiveForPublicTransport.setDescription(getString(R.string.use_osm_live_public_transport_description)); + useOsmLiveForPublicTransport.setSummaryOn(R.string.shared_string_enabled); + useOsmLiveForPublicTransport.setSummaryOff(R.string.shared_string_disabled); + useOsmLiveForPublicTransport.setIconSpaceReserved(true); + getPreferenceScreen().addPreference(useOsmLiveForPublicTransport); + } + + private void setupNativePublicTransport() { + SwitchPreferenceEx setupNativePublicTransport = createSwitchPreferenceEx(settings.PT_SAFE_MODE.getId(), + R.string.use_native_pt, R.layout.preference_with_descr_dialog_and_switch); + if (!Version.isBlackberry(app)) { + setupNativePublicTransport.setDescription(getString(R.string.use_native_pt_desc)); + setupNativePublicTransport.setSummaryOn(R.string.shared_string_enabled); + setupNativePublicTransport.setSummaryOff(R.string.shared_string_disabled); + setupNativePublicTransport.setIconSpaceReserved(true); + getPreferenceScreen().addPreference(setupNativePublicTransport); + } else { + setupNativePublicTransport.setVisible(false); + } + } + + private void setupOsmLiveForRoutingPref() { + SwitchPreferenceEx useOsmLiveForRouting = createSwitchPreferenceEx(settings.USE_OSM_LIVE_FOR_ROUTING.getId(), + R.string.use_live_routing, R.layout.preference_with_descr_dialog_and_switch); + useOsmLiveForRouting.setDescription(getString(R.string.use_osm_live_routing_description)); + useOsmLiveForRouting.setSummaryOn(R.string.shared_string_enabled); + useOsmLiveForRouting.setSummaryOff(R.string.shared_string_disabled); + useOsmLiveForRouting.setIconSpaceReserved(true); + getPreferenceScreen().addPreference(useOsmLiveForRouting); + } + + private void setupDisableComplexRoutingPref() { + SwitchPreferenceEx disableComplexRouting = createSwitchPreferenceEx(settings.DISABLE_COMPLEX_ROUTING.getId(), + R.string.use_complex_routing, R.layout.preference_with_descr_dialog_and_switch); + disableComplexRouting.setDescription(getString(R.string.disable_complex_routing_descr)); + disableComplexRouting.setSummaryOn(R.string.shared_string_enabled); + disableComplexRouting.setSummaryOff(R.string.shared_string_disabled); + disableComplexRouting.setIconSpaceReserved(true); + getPreferenceScreen().addPreference(disableComplexRouting); + } + + private void setupFastRecalculationPref() { + SwitchPreferenceEx useFastRecalculation = createSwitchPreferenceEx(settings.USE_FAST_RECALCULATION.getId(), + R.string.use_fast_recalculation, R.layout.preference_with_descr_dialog_and_switch); + useFastRecalculation.setDescription(getString(R.string.use_fast_recalculation_desc)); + useFastRecalculation.setSummaryOn(R.string.shared_string_enabled); + useFastRecalculation.setSummaryOff(R.string.shared_string_disabled); + useFastRecalculation.setIconSpaceReserved(true); + getPreferenceScreen().addPreference(useFastRecalculation); + } + private void setupRoutingPrefs() { OsmandApplication app = getMyApplication(); if (app == null) { @@ -170,7 +226,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP fastRoute.setSummaryOn(R.string.shared_string_on); fastRoute.setSummaryOff(R.string.shared_string_off); - if (am.getRouteService() == RouteProvider.RouteService.OSMAND){ + if (am.getRouteService() == RouteProvider.RouteService.OSMAND) { GeneralRouter router = app.getRouter(am); clearParameters(); if (router != null) { @@ -273,6 +329,17 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP setupRouteRecalcHeader(screen); setupSelectRouteRecalcDistance(screen); setupReverseDirectionRecalculation(screen); + addDivider(screen); + setupDevelopmentcategoryHeader(screen); + if (am.isDerivedRoutingFrom(ApplicationMode.PUBLIC_TRANSPORT)) { + setupOsmLiveForPublicTransportPref(); + setupNativePublicTransport(); + } + if (am.isDerivedRoutingFrom(ApplicationMode.CAR)) { + setupOsmLiveForRoutingPref(); + setupDisableComplexRoutingPref(); + } + setupFastRecalculationPref(); } private void addDivider(PreferenceScreen screen) { @@ -300,6 +367,13 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP screen.addPreference(routingCategory); } + private void setupDevelopmentcategoryHeader (PreferenceScreen screen) { + PreferenceCategory developmentCategory = new PreferenceCategory(requireContext()); + developmentCategory.setLayoutResource(R.layout.preference_category_with_descr); + developmentCategory.setTitle(R.string.development); + screen.addPreference(developmentCategory); + } + @Override public boolean onPreferenceClick(Preference preference) { if (preference.getKey().equals(settings.ROUTE_STRAIGHT_ANGLE.getId())) { From 4ef3667c59914bc67e207097051bae5b146d605e Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 6 Oct 2020 17:41:59 +0300 Subject: [PATCH 0508/1366] Fix review --- .../{ExportSettingsType.aidl => AExportSettingsType.aidl} | 2 +- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename OsmAnd-api/src/net/osmand/aidlapi/profile/{ExportSettingsType.aidl => AExportSettingsType.aidl} (54%) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.aidl similarity index 54% rename from OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl rename to OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.aidl index 13ac783db1..99c59bba2a 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportSettingsType.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.aidl @@ -1,3 +1,3 @@ package net.osmand.aidlapi.profile; -parcelable ExportSettingsType; \ No newline at end of file +parcelable AExportSettingsType; \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index e1aecf5500..6329d5db2e 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -2352,11 +2352,11 @@ public class OsmandAidlApi { } List settingsItems = new ArrayList<>(); settingsItems.add(new SettingsHelper.ProfileSettingsItem(app, appMode)); - File tempDir = FileUtils.getTempDir(app); + File exportDir = app.getSettings().getExternalStorageDirectory(); String fileName = appMode.toHumanString(); SettingsHelper settingsHelper = app.getSettingsHelper(); settingsItems.addAll(settingsHelper.getFilteredSettingsItems(settingsHelper.getAdditionalData(), settingsTypes)); - settingsHelper.exportSettings(tempDir, fileName, null, settingsItems, true); + settingsHelper.exportSettings(exportDir, fileName, null, settingsItems, true); return true; } return false; @@ -2403,9 +2403,9 @@ public class OsmandAidlApi { } else if (fileName.endsWith(IndexConstants.GPX_FILE_EXT)) { if (destinationDir.startsWith(IndexConstants.GPX_INDEX_DIR) && !FILE_TO_SAVE.equals(fileName)) { - showGpx(new File(destinationDir, fileName).getName()); + destinationDir = destinationDir.replaceFirst(IndexConstants.GPX_INDEX_DIR, ""); + showGpx(new File(destinationDir, fileName).getPath()); } else if (destinationDir.isEmpty() && FILE_TO_SAVE.equals(fileName)) { - GPXUtilities.loadGPXFile(new File(destinationDir, fileName)); app.getFavorites().loadFavorites(); } } From 9834038c44ac354aee076800c685c3b85eae674c Mon Sep 17 00:00:00 2001 From: Alexander Sytnyk Date: Tue, 6 Oct 2020 17:58:16 +0300 Subject: [PATCH 0509/1366] #9537 Use a profile color to highlight the selected profile --- .../plus/settings/fragments/MainSettingsFragment.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java index 6aac50bc9c..1c176e3172 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.view.View; import androidx.annotation.ColorRes; +import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.preference.Preference; @@ -86,7 +87,8 @@ public class MainSettingsFragment extends BaseSettingsFragment { if (CONFIGURE_PROFILE.equals(key)) { View selectedProfile = holder.itemView.findViewById(R.id.selectable_list_item); if (selectedProfile != null) { - int activeProfileColor = getActiveProfileColor(); + int activeProfileColorId = getSelectedAppMode().getIconColorInfo().getColor(isNightMode()); + int activeProfileColor = ContextCompat.getColor(app, activeProfileColorId); Drawable backgroundDrawable = new ColorDrawable(UiUtilities.getColorWithAlpha(activeProfileColor, 0.15f)); AndroidUtils.setBackground(selectedProfile, backgroundDrawable); } @@ -153,9 +155,8 @@ public class MainSettingsFragment extends BaseSettingsFragment { ApplicationMode selectedMode = app.getSettings().APPLICATION_MODE.get(); String title = selectedMode.toHumanString(); String profileType = getAppModeDescription(getContext(), selectedMode); - int iconRes = selectedMode.getIconRes(); Preference configureProfile = findPreference(CONFIGURE_PROFILE); - configureProfile.setIcon(getPaintedIcon(iconRes, getActiveProfileColor())); + configureProfile.setIcon(getAppProfilesIcon(selectedMode, true)); configureProfile.setTitle(title); configureProfile.setSummary(profileType); } From 81a9d0b82ce5481135fedeed3d9ab3d3651c10a3 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 6 Oct 2020 18:21:47 +0300 Subject: [PATCH 0510/1366] Added meta-data in manifest for hw build --- OsmAnd/AndroidManifest-freehuawei.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OsmAnd/AndroidManifest-freehuawei.xml b/OsmAnd/AndroidManifest-freehuawei.xml index c234628537..c557d5fe2a 100644 --- a/OsmAnd/AndroidManifest-freehuawei.xml +++ b/OsmAnd/AndroidManifest-freehuawei.xml @@ -7,6 +7,13 @@ android:label="@string/app_name_free" tools:replace="android:icon, android:label"> + + + Date: Tue, 6 Oct 2020 19:48:33 +0300 Subject: [PATCH 0511/1366] Move import async tasks and ImportHelper to separate package --- .../osmand/plus/activities/MapActivity.java | 2 +- .../ImportGpxBottomSheetDialogFragment.java | 2 +- .../plus/importfiles/BaseImportAsyncTask.java | 45 ++ .../plus/importfiles/FavoritesImportTask.java | 59 ++ .../plus/importfiles/GpxImportTask.java | 59 ++ .../GpxOrFavouritesImportTask.java | 83 +++ .../ImportHelper.java | 625 ++---------------- .../plus/importfiles/KmlImportTask.java | 71 ++ .../plus/importfiles/KmzImportTask.java | 67 ++ .../plus/importfiles/ObfImportTask.java | 52 ++ .../plus/importfiles/SettingsImportTask.java | 158 +++++ .../importfiles/SqliteTileImportTask.java | 50 ++ .../plus/importfiles/XmlImportTask.java | 149 +++++ .../StartPlanRouteBottomSheet.java | 4 +- .../plus/myplaces/FavoritesActivity.java | 4 +- ...electProfileBottomSheetDialogFragment.java | 2 +- .../FollowTrackFragment.java | 4 +- .../backend/OsmAndAppCustomization.java | 2 +- .../fragments/MainSettingsFragment.java | 2 +- 19 files changed, 858 insertions(+), 582 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java rename OsmAnd/src/net/osmand/plus/{helpers => importfiles}/ImportHelper.java (50%) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 2816e7d5b0..2e840f8b64 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -99,7 +99,7 @@ import net.osmand.plus.firstusage.FirstUsageWelcomeFragment; import net.osmand.plus.firstusage.FirstUsageWizardFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.DiscountHelper; -import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper; import net.osmand.plus.helpers.IntentHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.LockHelper.LockUIAdapter; diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java index cf371f006e..4bc4e1589a 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java @@ -13,7 +13,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; -import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper; public class ImportGpxBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java b/OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java new file mode 100644 index 0000000000..4ebafcb8cc --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java @@ -0,0 +1,45 @@ +package net.osmand.plus.importfiles; + +import android.app.ProgressDialog; +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; + +import java.lang.ref.WeakReference; + +abstract class BaseImportAsyncTask extends AsyncTask { + + protected OsmandApplication app; + protected WeakReference activityRef; + protected ProgressDialog progress; + + public BaseImportAsyncTask(@NonNull FragmentActivity activity) { + app = (OsmandApplication) activity.getApplicationContext(); + activityRef = new WeakReference<>(activity); + } + + @Override + protected void onPreExecute() { + showProgress(); + } + + protected void showProgress() { + FragmentActivity activity = activityRef.get(); + if (AndroidUtils.isActivityNotDestroyed(activity)) { + String title = app.getString(R.string.loading_smth, ""); + progress = ProgressDialog.show(activity, title, app.getString(R.string.loading_data)); + } + } + + protected void hideProgress() { + FragmentActivity activity = activityRef.get(); + if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { + progress.dismiss(); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java new file mode 100644 index 0000000000..2793e1e0ab --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java @@ -0,0 +1,59 @@ +package net.osmand.plus.importfiles; + +import android.content.Intent; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.data.FavouritePoint; +import net.osmand.plus.FavouritesDbHelper; +import net.osmand.plus.R; + +import java.util.List; + +import static net.osmand.plus.importfiles.ImportHelper.asFavourites; +import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; +import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; + +class FavoritesImportTask extends BaseImportAsyncTask { + + private GPXFile gpxFile; + private String fileName; + private boolean forceImportFavourites; + + public FavoritesImportTask(@NonNull FragmentActivity activity, @NonNull GPXFile gpxFile, + @NonNull String fileName, boolean forceImportFavourites) { + super(activity); + this.gpxFile = gpxFile; + this.fileName = fileName; + this.forceImportFavourites = forceImportFavourites; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + List favourites = asFavourites(app, gpxFile.getPoints(), fileName, forceImportFavourites); + FavouritesDbHelper favoritesHelper = app.getFavorites(); + for (FavouritePoint favourite : favourites) { + favoritesHelper.deleteFavourite(favourite, false); + favoritesHelper.addFavourite(favourite, false); + } + favoritesHelper.sortAll(); + favoritesHelper.saveCurrentPointsIntoFile(); + return null; + } + + @Override + protected void onPostExecute(GPXUtilities.GPXFile result) { + hideProgress(); + FragmentActivity activity = activityRef.get(); + if (activity != null) { + app.showToastMessage(R.string.fav_imported_sucessfully); + Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity()); + newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + newIntent.putExtra(TAB_ID, FAV_TAB); + activity.startActivity(newIntent); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java new file mode 100644 index 0000000000..1e76f15a26 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java @@ -0,0 +1,59 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.util.Algorithms; + +import java.io.FileNotFoundException; +import java.io.InputStream; + +class GpxImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri gpxFile; + private String fileName; + private boolean save; + private boolean useImportDir; + private boolean showInDetailsActivity; + + public GpxImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri gpxFile, @NonNull String fileName, boolean save, boolean useImportDir, + boolean showInDetailsActivity) { + super(activity); + this.importHelper = importHelper; + this.gpxFile = gpxFile; + this.fileName = fileName; + this.save = save; + this.useImportDir = useImportDir; + this.showInDetailsActivity = showInDetailsActivity; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + InputStream is = null; + try { + is = app.getContentResolver().openInputStream(gpxFile); + if (is != null) { + return GPXUtilities.loadGPXFile(is); + } + } catch (FileNotFoundException e) { + // + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + } + return null; + } + + @Override + protected void onPostExecute(GPXUtilities.GPXFile result) { + hideProgress(); + importHelper.handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java new file mode 100644 index 0000000000..48eadfb5b1 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java @@ -0,0 +1,83 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.util.Algorithms; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; + +class GpxOrFavouritesImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri fileUri; + private String fileName; + private boolean save; + private boolean useImportDir; + private boolean forceImportFavourites; + private boolean forceImportGpx; + + public GpxOrFavouritesImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri fileUri, String fileName, boolean save, boolean useImportDir, + boolean forceImportFavourites, boolean forceImportGpx) { + super(activity); + this.importHelper = importHelper; + this.fileUri = fileUri; + this.fileName = fileName; + this.save = save; + this.useImportDir = useImportDir; + this.forceImportFavourites = forceImportFavourites; + this.forceImportGpx = forceImportGpx; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + InputStream is = null; + ZipInputStream zis = null; + try { + is = app.getContentResolver().openInputStream(fileUri); + if (is != null) { + if (fileName != null && fileName.endsWith(ImportHelper.KML_SUFFIX)) { + return loadGpxFromKml(is); + } else if (fileName != null && fileName.endsWith(ImportHelper.KMZ_SUFFIX)) { + try { + zis = new ZipInputStream(is); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(ImportHelper.KML_SUFFIX)) { + return loadGpxFromKml(zis); + } + } + } catch (Exception e) { + return null; + } + } else { + return GPXUtilities.loadGPXFile(is); + } + } + } catch (FileNotFoundException e) { + // + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(zis); + } + return null; + } + + @Override + protected void onPostExecute(final GPXUtilities.GPXFile result) { + hideProgress(); + importHelper.importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java similarity index 50% rename from OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java rename to OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index febffa73bf..f5b47604ac 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -1,7 +1,5 @@ -package net.osmand.plus.helpers; +package net.osmand.plus.importfiles; -import android.annotation.SuppressLint; -import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; @@ -17,65 +15,47 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.FragmentManager; -import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; -import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint.BackgroundType; import net.osmand.plus.AppInitializer; -import net.osmand.plus.CustomOsmandPlugin; -import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment; import net.osmand.plus.measurementtool.MeasurementToolFragment; -import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; import net.osmand.plus.settings.backend.SettingsHelper; -import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener; -import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener; -import net.osmand.plus.settings.backend.SettingsHelper.SettingsImportListener; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; -import net.osmand.plus.settings.fragments.ImportSettingsFragment; import net.osmand.plus.views.OsmandMapTileView; -import net.osmand.router.RoutingConfiguration; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; +import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT; +import static net.osmand.IndexConstants.GPX_INDEX_DIR; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; @@ -83,8 +63,6 @@ import static net.osmand.IndexConstants.SQLITE_CHART_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_EXT; import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT; import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE; -import static net.osmand.plus.AppInitializer.loadRoutingFiles; -import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; @@ -124,6 +102,7 @@ public class ImportHelper { public interface OnGpxImportCompleteListener { void onImportComplete(boolean success); + void onSaveComplete(boolean success, GPXFile result); } @@ -138,7 +117,7 @@ public class ImportHelper { } public void handleContentImport(final Uri contentUri, Bundle extras, final boolean useImportDir) { - final String name = getNameFromContentUri(app, contentUri); + String name = getNameFromContentUri(app, contentUri); handleFileImport(contentUri, name, extras, useImportDir); } @@ -156,7 +135,7 @@ public class ImportHelper { public boolean handleGpxImport(final Uri contentUri, final boolean useImportDir, boolean showInDetailsActivity) { String name = getNameFromContentUri(app, contentUri); - boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(contentUri.getPath())); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(GPX_INDEX_DIR), new File(contentUri.getPath())); if (!isOsmandSubdir && name != null) { String nameLC = name.toLowerCase(); if (nameLC.endsWith(GPX_FILE_EXT)) { @@ -180,7 +159,7 @@ public class ImportHelper { String scheme = uri.getScheme(); boolean isFileIntent = "file".equals(scheme); boolean isContentIntent = "content".equals(scheme); - boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(uri.getPath())); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(GPX_INDEX_DIR), new File(uri.getPath())); final boolean saveFile = !isFileIntent || !isOsmandSubdir; String fileName = ""; if (isFileIntent) { @@ -193,7 +172,7 @@ public class ImportHelper { public void handleFileImport(Uri intentUri, String fileName, Bundle extras, boolean useImportDir) { boolean isFileIntent = "file".equals(intentUri.getScheme()); - boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(GPX_INDEX_DIR), new File(intentUri.getPath())); boolean saveFile = !isFileIntent || !isOsmandSubdir; if (fileName == null) { @@ -202,7 +181,7 @@ public class ImportHelper { handleKmlImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(KMZ_SUFFIX)) { handleKmzImport(intentUri, fileName, saveFile, useImportDir); - } else if (fileName.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { + } else if (fileName.endsWith(BINARY_MAP_INDEX_EXT)) { handleObfImport(intentUri, fileName); } else if (fileName.endsWith(SQLITE_EXT)) { handleSqliteTileImport(intentUri, fileName); @@ -221,9 +200,8 @@ public class ImportHelper { public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) { try { - final String name; - final Cursor returnCursor = app.getContentResolver().query(contentUri, - new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); + String name; + Cursor returnCursor = app.getContentResolver().query(contentUri, new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); if (returnCursor != null && returnCursor.moveToFirst()) { int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (columnIndex != -1) { @@ -244,251 +222,52 @@ public class ImportHelper { } } - @SuppressLint("StaticFieldLeak") - private void handleGpxImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir, - final boolean showInDetailsActivity) { - AsyncTask gpxImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - InputStream is = null; - try { - is = app.getContentResolver().openInputStream(gpxFile); - if (is != null) { - return GPXUtilities.loadGPXFile(is); - } - } catch (FileNotFoundException e) { - // - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - } - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); - } - }; - executeImportTask(gpxImportTask); + private void handleGpxImport(Uri gpxFile, String fileName, boolean save, boolean useImportDir, boolean showInDetailsActivity) { + executeImportTask(new GpxImportTask(this, activity, gpxFile, fileName, save, useImportDir, showInDetailsActivity)); } - @SuppressLint("StaticFieldLeak") - private void handleGpxOrFavouritesImport(final Uri fileUri, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { - AsyncTask gpxOrFavouritesImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - InputStream is = null; - ZipInputStream zis = null; - try { - is = app.getContentResolver().openInputStream(fileUri); - if (is != null) { - if (fileName != null && fileName.endsWith(KML_SUFFIX)) { - final String result = Kml2Gpx.toGpx(is); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } else if (fileName != null && fileName.endsWith(KMZ_SUFFIX)) { - try { - zis = new ZipInputStream(is); - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { - if (entry.getName().endsWith(KML_SUFFIX)) { - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } - } - } catch (Exception e) { - return null; - } - } else { - return GPXUtilities.loadGPXFile(is); - } - } - } catch (FileNotFoundException e) { - // - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - Algorithms.closeStream(zis); - } - return null; - } - - @Override - protected void onPostExecute(final GPXFile result) { - hideProgress(); - importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); - } - }; - executeImportTask(gpxOrFavouritesImportTask); + private void handleGpxOrFavouritesImport(Uri fileUri, String fileName, boolean save, boolean useImportDir, + boolean forceImportFavourites, boolean forceImportGpx) { + executeImportTask(new GpxOrFavouritesImportTask(this, activity, fileUri, fileName, save, useImportDir, forceImportFavourites, forceImportGpx)); } - @SuppressLint("StaticFieldLeak") - private void importFavoritesImpl(final GPXFile gpxFile, final String fileName, final boolean forceImportFavourites) { - AsyncTask favoritesImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - final List favourites = asFavourites(gpxFile.getPoints(), - fileName, forceImportFavourites); - final FavouritesDbHelper favoritesHelper = app.getFavorites(); - for (final FavouritePoint favourite : favourites) { - favoritesHelper.deleteFavourite(favourite, false); - favoritesHelper.addFavourite(favourite, false); - } - favoritesHelper.sortAll(); - favoritesHelper.saveCurrentPointsIntoFile(); - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG).show(); - final Intent newIntent = new Intent(activity, - app.getAppCustomization().getFavoritesActivity()); - newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - newIntent.putExtra(TAB_ID, FAV_TAB); - activity.startActivity(newIntent); - } - }; - executeImportTask(favoritesImportTask); + private void importFavoritesImpl(GPXFile gpxFile, String fileName, boolean forceImportFavourites) { + executeImportTask(new FavoritesImportTask(activity, gpxFile, fileName, forceImportFavourites)); } - @SuppressLint("StaticFieldLeak") - private void handleKmzImport(final Uri kmzFile, final String name, final boolean save, final boolean useImportDir) { - AsyncTask kmzImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... voids) { - InputStream is = null; - ZipInputStream zis = null; - try { - is = app.getContentResolver().openInputStream(kmzFile); - if (is != null) { - zis = new ZipInputStream(is); - - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { - if (entry.getName().endsWith(KML_SUFFIX)) { - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } - } - } - } catch (Exception e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - Algorithms.closeStream(zis); - } - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - handleResult(result, name, save, useImportDir, false); - } - - }; - executeImportTask(kmzImportTask); + private void handleKmzImport(Uri kmzFile, String name, boolean save, boolean useImportDir) { + executeImportTask(new KmzImportTask(this, activity, kmzFile, name, save, useImportDir)); } - @SuppressLint("StaticFieldLeak") - private void handleKmlImport(final Uri kmlFile, final String name, final boolean save, final boolean useImportDir) { - AsyncTask kmlImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - InputStream is = null; - try { - is = app.getContentResolver().openInputStream(kmlFile); - if (is != null) { - final String result = Kml2Gpx.toGpx(is); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } - } catch (FileNotFoundException e) { - // - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - } - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - handleResult(result, name, save, useImportDir, false); - } - }; - executeImportTask(kmlImportTask); + private void handleKmlImport(Uri kmlFile, String name, boolean save, boolean useImportDir) { + executeImportTask(new KmlImportTask(this, activity, kmlFile, name, save, useImportDir)); } - @SuppressLint("StaticFieldLeak") - private void handleObfImport(final Uri obfFile, final String name) { - AsyncTask obfImportTask = new BaseImportAsyncTask() { - - @Override - protected String doInBackground(Void... voids) { - String error = copyFile(app, getObfDestFile(name), obfFile, false); - if (error == null) { - app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList()); - app.getDownloadThread().updateLoadedFiles(); - return app.getString(R.string.map_imported_successfully); - } - return app.getString(R.string.map_import_error) + ": " + error; - } - - @Override - protected void onPostExecute(String message) { - hideProgress(); - app.showShortToastMessage(message); - } - }; - executeImportTask(obfImportTask); + private void handleObfImport(Uri obfFile, String name) { + executeImportTask(new ObfImportTask(activity, obfFile, name)); } - @NonNull - private File getObfDestFile(@NonNull String name) { - if (name.endsWith(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT)) { - return app.getAppPath(IndexConstants.ROADS_INDEX_DIR + name); - } else if (name.endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) { - return app.getAppPath(IndexConstants.WIKI_INDEX_DIR + name); + private void handleSqliteTileImport(Uri uri, String name) { + executeImportTask(new SqliteTileImportTask(activity, uri, name)); + } + + private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject> callback) { + if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { + int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); + String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); + handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback); + } else { + handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback); } - return app.getAppPath(name); + } + + private void handleOsmAndSettingsImport(Uri uri, String name, String latestChanges, int version, + CallbackWithObject> callback) { + executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); + } + + private void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { + executeImportTask(new XmlImportTask(activity, intentUri, fileName, routingCallback)); } @Nullable @@ -538,36 +317,6 @@ public class ImportHelper { return error; } - @SuppressLint("StaticFieldLeak") - private void handleSqliteTileImport(final Uri uri, final String name) { - AsyncTask sqliteTileImportTask = new BaseImportAsyncTask() { - - @Override - protected String doInBackground(Void... voids) { - return copyFile(app, app.getAppPath(IndexConstants.TILES_INDEX_DIR + name), uri, false); - } - - @Override - protected void onPostExecute(String error) { - hideProgress(); - if (error == null) { - OsmandRasterMapsPlugin plugin = OsmandPlugin.getPlugin(OsmandRasterMapsPlugin.class); - if (plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { - OsmandPlugin.enablePlugin(getMapActivity(), app, plugin, true); - } - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - mapActivity.getMapLayers().selectMapLayer(mapActivity.getMapView(), null, null); - } - Toast.makeText(app, app.getString(R.string.map_imported_successfully), Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(app, app.getString(R.string.map_import_error) + ": " + error, Toast.LENGTH_SHORT).show(); - } - } - }; - executeImportTask(sqliteTileImportTask); - } - public void chooseFileToImport(final ImportType importType, final CallbackWithObject callback) { final MapActivity mapActivity = getMapActivity(); if (mapActivity == null) { @@ -627,255 +376,13 @@ public class ImportHelper { return intent; } - private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject> callback) { - if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { - int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); - String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); - handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback); - } else { - handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback); - } - } - - @SuppressLint("StaticFieldLeak") - private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, - final CallbackWithObject> callback) { - AsyncTask settingsImportTask = new BaseImportAsyncTask() { - - @Override - protected String doInBackground(Void... voids) { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } - File dest = new File(tempDir, name); - return copyFile(app, dest, uri, true); - } - - @Override - protected void onPostExecute(String error) { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - final File file = new File(tempDir, name); - if (error == null && file.exists()) { - app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { - @Override - public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { - hideProgress(); - if (succeed) { - List pluginIndependentItems = new ArrayList<>(); - List pluginSettingsItems = new ArrayList<>(); - for (SettingsItem item : items) { - if (item instanceof PluginSettingsItem) { - pluginSettingsItems.add((PluginSettingsItem) item); - } else if (Algorithms.isEmpty(item.getPluginId())) { - pluginIndependentItems.add(item); - } - } - for (PluginSettingsItem pluginItem : pluginSettingsItems) { - handlePluginImport(pluginItem, file); - } - if (!pluginIndependentItems.isEmpty()) { - FragmentManager fragmentManager = activity.getSupportFragmentManager(); - ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file); - } - } else if (empty) { - app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error))); - } - } - }); - } else { - hideProgress(); - app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); - } - } - }; - executeImportTask(settingsImportTask); - } - - private void handlePluginImport(final PluginSettingsItem pluginItem, final File file) { - final ProgressDialog progress = new ProgressDialog(activity); - progress.setTitle(app.getString(R.string.loading_smth, "")); - progress.setMessage(app.getString(R.string.importing_from, pluginItem.getPublicName(app))); - progress.setIndeterminate(true); - progress.setCancelable(false); - - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.show(); - } - - final SettingsImportListener importListener = new SettingsImportListener() { - @Override - public void onSettingsImportFinished(boolean succeed, @NonNull List items) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - CustomOsmandPlugin plugin = pluginItem.getPlugin(); - plugin.loadResources(); - - for (SettingsItem item : items) { - if (item instanceof ProfileSettingsItem) { - ((ProfileSettingsItem) item).applyAdditionalPrefs(); - } - } - if (!Algorithms.isEmpty(plugin.getDownloadMaps())) { - app.getDownloadThread().runReloadIndexFilesSilent(); - } - if (!Algorithms.isEmpty(plugin.getRendererNames())) { - app.getRendererRegistry().updateExternalRenderers(); - } - if (!Algorithms.isEmpty(plugin.getRouterNames())) { - loadRoutingFiles(app, null); - } - if (activity != null) { - plugin.onInstall(app, activity); - } - String pluginId = pluginItem.getPluginId(); - File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId); - app.getSettingsHelper().exportSettings(pluginDir, "items", null, items, false); - } - }; - List pluginItems = new ArrayList<>(pluginItem.getPluginDependentItems()); - pluginItems.add(0, pluginItem); - app.getSettingsHelper().checkDuplicates(file, pluginItems, pluginItems, new CheckDuplicatesListener() { - @Override - public void onDuplicatesChecked(@NonNull List duplicates, List items) { - for (SettingsItem item : items) { - item.setShouldReplace(true); - } - app.getSettingsHelper().importSettings(file, items, "", 1, importListener); - } - }); - } - - @SuppressLint("StaticFieldLeak") - private void handleXmlFileImport(final Uri intentUri, final String fileName, - final CallbackWithObject routingCallback) { - AsyncTask renderingImportTask = new BaseImportAsyncTask() { - - private String destFileName; - private ImportType importType; - - @Override - protected void onPreExecute() { - showProgress(); - destFileName = fileName; - } - - @Override - protected String doInBackground(Void... voids) { - checkImportType(); - if (importType != null) { - File dest = getDestinationFile(); - if (dest != null) { - return copyFile(app, dest, intentUri, true); - } - } - return app.getString(R.string.file_import_error, destFileName, app.getString(R.string.unsupported_type_error)); - } - - @Override - protected void onPostExecute(String error) { - File destDir = getDestinationDir(); - File file = new File(destDir, destFileName); - if (error == null && file.exists()) { - if (importType == ImportType.RENDERING) { - app.getRendererRegistry().updateExternalRenderers(); - app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); - hideProgress(); - } else if (importType == ImportType.ROUTING) { - loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { - @Override - public void onRoutingFilesLoaded() { - hideProgress(); - RoutingConfiguration.Builder builder = app.getCustomRoutingConfig(destFileName); - if (builder != null) { - if (routingCallback != null) { - routingCallback.processResult(builder); - } - app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); - } else { - app.showToastMessage(app.getString(R.string.file_does_not_contain_routing_rules, destFileName)); - } - } - }); - } - } else { - hideProgress(); - app.showShortToastMessage(app.getString(R.string.file_import_error, destFileName, error)); - } - } - - private File getDestinationDir() { - if (importType == ImportType.ROUTING) { - return app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); - } else if (importType == ImportType.RENDERING) { - return app.getAppPath(IndexConstants.RENDERERS_DIR); - } - return null; - } - - private File getDestinationFile() { - File destDir = getDestinationDir(); - if (destDir != null) { - if (!destDir.exists()) { - destDir.mkdirs(); - } - if (importType == ImportType.RENDERING && !destFileName.endsWith(RENDERER_INDEX_EXT)) { - String fileName = Algorithms.getFileNameWithoutExtension(destFileName); - destFileName = fileName + RENDERER_INDEX_EXT; - } - File destFile = new File(destDir, destFileName); - while (destFile.exists()) { - destFileName = AndroidUtils.createNewFileName(destFileName); - destFile = new File(destDir, destFileName); - } - return destFile; - } - return null; - } - - private void checkImportType() { - InputStream is = null; - try { - is = app.getContentResolver().openInputStream(intentUri); - if (is != null) { - XmlPullParser parser = PlatformUtil.newXMLPullParser(); - parser.setInput(is, "UTF-8"); - int tok; - while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { - if (tok == XmlPullParser.START_TAG) { - String name = parser.getName(); - if ("osmand_routing_config".equals(name)) { - importType = ImportType.ROUTING; - } else if ("renderingStyle".equals(name)) { - importType = ImportType.RENDERING; - } - break; - } - } - Algorithms.closeStream(is); - } - } catch (FileNotFoundException | XmlPullParserException e) { - log.error(e); - } catch (IOException e) { - log.error(e); - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - } - } - }; - executeImportTask(renderingImportTask); - } - - private void handleResult(GPXFile result, String name, boolean save, - boolean useImportDir, boolean forceImportFavourites) { + protected void handleResult(GPXFile result, String name, boolean save, + boolean useImportDir, boolean forceImportFavourites) { handleResult(result, name, save, useImportDir, forceImportFavourites, true); } - private void handleResult(final GPXFile result, final String name, final boolean save, - final boolean useImportDir, boolean forceImportFavourites, boolean showInDetailsActivity) { + protected void handleResult(final GPXFile result, final String name, final boolean save, + final boolean useImportDir, boolean forceImportFavourites, boolean showInDetailsActivity) { if (result != null) { if (result.error != null) { Toast.makeText(activity, result.error.getMessage(), Toast.LENGTH_LONG).show(); @@ -937,7 +444,7 @@ public class ImportHelper { if (useImportDir) { importDir = app.getAppPath(IndexConstants.GPX_IMPORT_DIR); } else { - importDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); + importDir = app.getAppPath(GPX_INDEX_DIR); } //noinspection ResultOfMethodCallIgnored importDir.mkdirs(); @@ -1058,9 +565,9 @@ public class ImportHelper { } } - private void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { + protected void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save, + final boolean useImportDir, final boolean forceImportFavourites, + final boolean forceImportGpx) { if (gpxFile == null || gpxFile.isPointsEmpty()) { if (forceImportFavourites) { final DialogInterface.OnClickListener importAsTrackListener = new DialogInterface.OnClickListener() { @@ -1083,11 +590,10 @@ public class ImportHelper { .setPositiveButton(R.string.shared_string_import, importAsTrackListener) .setNegativeButton(R.string.shared_string_cancel, importAsTrackListener) .show(); - return; } else { handleResult(gpxFile, fileName, save, useImportDir, false); - return; } + return; } if (forceImportFavourites) { @@ -1110,7 +616,7 @@ public class ImportHelper { } } - private List asFavourites(final List wptPts, String fileName, boolean forceImportFavourites) { + protected static List asFavourites(OsmandApplication app, List wptPts, String fileName, boolean forceImportFavourites) { final List favourites = new ArrayList<>(); for (WptPt p : wptPts) { if (p.name != null) { @@ -1155,27 +661,4 @@ public class ImportHelper { importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); } } - - protected abstract class BaseImportAsyncTask extends AsyncTask { - - protected ProgressDialog progress; - - @Override - protected void onPreExecute() { - showProgress(); - } - - protected void showProgress() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - String title = app.getString(R.string.loading_smth, ""); - progress = ProgressDialog.show(activity, title, app.getString(R.string.loading_data)); - } - } - - protected void hideProgress() { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - } - } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java new file mode 100644 index 0000000000..38c557e8c7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java @@ -0,0 +1,71 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.plus.helpers.Kml2Gpx; +import net.osmand.util.Algorithms; + +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +class KmlImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private String name; + private boolean save; + private boolean useImportDir; + + public KmlImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, String name, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.name = name; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + InputStream is = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + return loadGpxFromKml(is); + } + } catch (FileNotFoundException e) { + // + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + } + return null; + } + + @Override + protected void onPostExecute(GPXFile result) { + hideProgress(); + importHelper.handleResult(result, name, save, useImportDir, false); + } + + protected static GPXFile loadGpxFromKml(@NonNull InputStream is) { + String result = Kml2Gpx.toGpx(is); + if (result != null) { + try { + return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + return null; + } + } + return null; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java new file mode 100644 index 0000000000..420f4feff4 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java @@ -0,0 +1,67 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.util.Algorithms; + +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; +import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; + +class KmzImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private String name; + private boolean save; + private boolean useImportDir; + + public KmzImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, @NonNull String name, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.name = name; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected GPXFile doInBackground(Void... voids) { + InputStream is = null; + ZipInputStream zis = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + zis = new ZipInputStream(is); + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(KML_SUFFIX)) { + return loadGpxFromKml(is); + } + } + } + } catch (Exception e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(zis); + } + return null; + } + + @Override + protected void onPostExecute(GPXUtilities.GPXFile result) { + hideProgress(); + importHelper.handleResult(result, name, save, useImportDir, false); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java new file mode 100644 index 0000000000..e4a82faff9 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java @@ -0,0 +1,52 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.IProgress; +import net.osmand.IndexConstants; +import net.osmand.plus.R; + +import java.io.File; +import java.util.ArrayList; + +class ObfImportTask extends BaseImportAsyncTask { + + private Uri uri; + private String name; + + public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, String name) { + super(activity); + this.uri = uri; + this.name = name; + } + + @Override + protected String doInBackground(Void... voids) { + String error = ImportHelper.copyFile(app, getObfDestFile(name), uri, false); + if (error == null) { + app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList()); + app.getDownloadThread().updateLoadedFiles(); + return app.getString(R.string.map_imported_successfully); + } + return app.getString(R.string.map_import_error) + ": " + error; + } + + @Override + protected void onPostExecute(String message) { + hideProgress(); + app.showShortToastMessage(message); + } + + @NonNull + private File getObfDestFile(@NonNull String name) { + if (name.endsWith(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT)) { + return app.getAppPath(IndexConstants.ROADS_INDEX_DIR + name); + } else if (name.endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) { + return app.getAppPath(IndexConstants.WIKI_INDEX_DIR + name); + } + return app.getAppPath(name); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java new file mode 100644 index 0000000000..7800714610 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java @@ -0,0 +1,158 @@ +package net.osmand.plus.importfiles; + +import android.app.ProgressDialog; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +import net.osmand.AndroidUtils; +import net.osmand.CallbackWithObject; +import net.osmand.IndexConstants; +import net.osmand.plus.CustomOsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener; +import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem; +import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsImportListener; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; +import net.osmand.plus.settings.fragments.ImportSettingsFragment; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.IndexConstants.TEMP_DIR; +import static net.osmand.plus.AppInitializer.loadRoutingFiles; + +class SettingsImportTask extends BaseImportAsyncTask { + + private Uri uri; + private String name; + private String latestChanges; + private int version; + private CallbackWithObject> callback; + + public SettingsImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, + @NonNull String name, String latestChanges, int version, + CallbackWithObject> callback) { + super(activity); + this.uri = uri; + this.name = name; + this.latestChanges = latestChanges; + this.version = version; + this.callback = callback; + } + + @Override + protected String doInBackground(Void... voids) { + File tempDir = app.getAppPath(TEMP_DIR); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + File dest = new File(tempDir, name); + return ImportHelper.copyFile(app, dest, uri, true); + } + + @Override + protected void onPostExecute(String error) { + File tempDir = app.getAppPath(TEMP_DIR); + final File file = new File(tempDir, name); + if (error == null && file.exists()) { + app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { + @Override + public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { + hideProgress(); + if (succeed) { + List pluginIndependentItems = new ArrayList<>(); + List pluginSettingsItems = new ArrayList<>(); + for (SettingsItem item : items) { + if (item instanceof PluginSettingsItem) { + pluginSettingsItems.add((PluginSettingsItem) item); + } else if (Algorithms.isEmpty(item.getPluginId())) { + pluginIndependentItems.add(item); + } + } + for (PluginSettingsItem pluginItem : pluginSettingsItems) { + handlePluginImport(pluginItem, file); + } + if (!pluginIndependentItems.isEmpty()) { + FragmentActivity activity = activityRef.get(); + if (activity != null) { + FragmentManager fragmentManager = activity.getSupportFragmentManager(); + ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file); + } + } + } else if (empty) { + app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error))); + } + } + }); + } else { + hideProgress(); + app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); + } + } + + private void handlePluginImport(final PluginSettingsItem pluginItem, final File file) { + FragmentActivity activity = activityRef.get(); + final ProgressDialog progress; + if (AndroidUtils.isActivityNotDestroyed(activity)) { + progress = new ProgressDialog(activity); + progress.setTitle(app.getString(R.string.loading_smth, "")); + progress.setMessage(app.getString(R.string.importing_from, pluginItem.getPublicName(app))); + progress.setIndeterminate(true); + progress.setCancelable(false); + progress.show(); + } else { + progress = null; + } + + final SettingsImportListener importListener = new SettingsImportListener() { + @Override + public void onSettingsImportFinished(boolean succeed, @NonNull List items) { + FragmentActivity activity = activityRef.get(); + if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { + progress.dismiss(); + } + CustomOsmandPlugin plugin = pluginItem.getPlugin(); + plugin.loadResources(); + + for (SettingsItem item : items) { + if (item instanceof ProfileSettingsItem) { + ((ProfileSettingsItem) item).applyAdditionalPrefs(); + } + } + if (!Algorithms.isEmpty(plugin.getDownloadMaps())) { + app.getDownloadThread().runReloadIndexFilesSilent(); + } + if (!Algorithms.isEmpty(plugin.getRendererNames())) { + app.getRendererRegistry().updateExternalRenderers(); + } + if (!Algorithms.isEmpty(plugin.getRouterNames())) { + loadRoutingFiles(app, null); + } + if (activity != null) { + plugin.onInstall(app, activity); + } + String pluginId = pluginItem.getPluginId(); + File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId); + app.getSettingsHelper().exportSettings(pluginDir, "items", null, items, false); + } + }; + List pluginItems = new ArrayList<>(pluginItem.getPluginDependentItems()); + pluginItems.add(0, pluginItem); + app.getSettingsHelper().checkDuplicates(file, pluginItems, pluginItems, new CheckDuplicatesListener() { + @Override + public void onDuplicatesChecked(@NonNull List duplicates, List items) { + for (SettingsItem item : items) { + item.setShouldReplace(true); + } + app.getSettingsHelper().importSettings(file, items, "", 1, importListener); + } + }); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java new file mode 100644 index 0000000000..d9a177a016 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java @@ -0,0 +1,50 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; + +import static net.osmand.IndexConstants.TILES_INDEX_DIR; + +class SqliteTileImportTask extends BaseImportAsyncTask { + + private Uri uri; + private String name; + + public SqliteTileImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, @NonNull String name) { + super(activity); + this.uri = uri; + this.name = name; + } + + @Override + protected String doInBackground(Void... voids) { + return ImportHelper.copyFile(app, app.getAppPath(TILES_INDEX_DIR + name), uri, false); + } + + @Override + protected void onPostExecute(String error) { + hideProgress(); + if (error == null) { + FragmentActivity activity = activityRef.get(); + OsmandRasterMapsPlugin plugin = OsmandPlugin.getPlugin(OsmandRasterMapsPlugin.class); + if (plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { + OsmandPlugin.enablePlugin(activity, app, plugin, true); + } + if (activity instanceof MapActivity) { + MapActivity mapActivity = (MapActivity) activity; + mapActivity.getMapLayers().selectMapLayer(mapActivity.getMapView(), null, null); + } + Toast.makeText(app, app.getString(R.string.map_imported_successfully), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(app, app.getString(R.string.map_import_error) + ": " + error, Toast.LENGTH_SHORT).show(); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java new file mode 100644 index 0000000000..bc66d77a76 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java @@ -0,0 +1,149 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.CallbackWithObject; +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; +import net.osmand.plus.AppInitializer.LoadRoutingFilesCallback; +import net.osmand.plus.R; +import net.osmand.plus.importfiles.ImportHelper.ImportType; +import net.osmand.router.RoutingConfiguration.Builder; +import net.osmand.util.Algorithms; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; +import static net.osmand.plus.AppInitializer.loadRoutingFiles; + +class XmlImportTask extends BaseImportAsyncTask { + + private Uri intentUri; + private String destFileName; + private ImportType importType; + private CallbackWithObject routingCallback; + + public XmlImportTask(@NonNull FragmentActivity activity, @NonNull Uri intentUri, + @NonNull String fileName, @Nullable CallbackWithObject routingCallback) { + super(activity); + this.intentUri = intentUri; + this.destFileName = fileName; + this.routingCallback = routingCallback; + } + + @Override + protected String doInBackground(Void... voids) { + checkImportType(); + if (importType != null) { + File dest = getDestinationFile(); + if (dest != null) { + return ImportHelper.copyFile(app, dest, intentUri, true); + } + } + return app.getString(R.string.file_import_error, destFileName, app.getString(R.string.unsupported_type_error)); + } + + @Override + protected void onPostExecute(String error) { + File destDir = getDestinationDir(); + File file = new File(destDir, destFileName); + if (error == null && file.exists()) { + if (importType == ImportType.RENDERING) { + app.getRendererRegistry().updateExternalRenderers(); + app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); + hideProgress(); + } else if (importType == ImportType.ROUTING) { + loadRoutingFiles(app, new LoadRoutingFilesCallback() { + @Override + public void onRoutingFilesLoaded() { + hideProgress(); + Builder builder = app.getCustomRoutingConfig(destFileName); + if (builder != null) { + if (routingCallback != null) { + routingCallback.processResult(builder); + } + app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); + } else { + app.showToastMessage(app.getString(R.string.file_does_not_contain_routing_rules, destFileName)); + } + } + }); + } + } else { + hideProgress(); + app.showShortToastMessage(app.getString(R.string.file_import_error, destFileName, error)); + } + } + + private File getDestinationDir() { + if (importType == ImportType.ROUTING) { + return app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); + } else if (importType == ImportType.RENDERING) { + return app.getAppPath(IndexConstants.RENDERERS_DIR); + } + return null; + } + + private File getDestinationFile() { + File destDir = getDestinationDir(); + if (destDir != null) { + if (!destDir.exists()) { + destDir.mkdirs(); + } + if (importType == ImportType.RENDERING && !destFileName.endsWith(RENDERER_INDEX_EXT)) { + String fileName = Algorithms.getFileNameWithoutExtension(destFileName); + destFileName = fileName + RENDERER_INDEX_EXT; + } + File destFile = new File(destDir, destFileName); + while (destFile.exists()) { + destFileName = AndroidUtils.createNewFileName(destFileName); + destFile = new File(destDir, destFileName); + } + return destFile; + } + return null; + } + + private void checkImportType() { + InputStream is = null; + try { + is = app.getContentResolver().openInputStream(intentUri); + if (is != null) { + XmlPullParser parser = PlatformUtil.newXMLPullParser(); + parser.setInput(is, "UTF-8"); + int tok; + while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (tok == XmlPullParser.START_TAG) { + String name = parser.getName(); + if ("osmand_routing_config".equals(name)) { + importType = ImportType.ROUTING; + } else if ("renderingStyle".equals(name)) { + importType = ImportType.RENDERING; + } + break; + } + } + Algorithms.closeStream(is); + } + } catch (FileNotFoundException | XmlPullParserException e) { + ImportHelper.log.error(e); + } catch (IOException e) { + ImportHelper.log.error(e); + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java index b81b015f32..fe02db28b8 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java @@ -28,8 +28,8 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.helpers.ImportHelper.OnGpxImportCompleteListener; +import net.osmand.plus.importfiles.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import org.apache.commons.logging.Log; diff --git a/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java b/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java index f310802c44..c77cfbfc0d 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java @@ -30,8 +30,8 @@ import net.osmand.plus.R; import net.osmand.plus.activities.FavoritesTreeFragment; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TabActivity; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.helpers.ImportHelper.OnGpxImportCompleteListener; +import net.osmand.plus.importfiles.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.controls.PagerSlidingTabStrip; diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java index c7d7ec843c..743c9897ad 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java @@ -40,7 +40,7 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; -import static net.osmand.plus.helpers.ImportHelper.ImportType.ROUTING; +import static net.osmand.plus.importfiles.ImportHelper.ImportType.ROUTING; public class SelectProfileBottomSheetDialogFragment extends BasePreferenceBottomSheet { diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index ee2bf6b38e..48eba555cb 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -40,8 +40,8 @@ import net.osmand.plus.base.ContextMenuScrollFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.helpers.ImportHelper.OnGpxImportCompleteListener; +import net.osmand.plus.importfiles.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import net.osmand.plus.measurementtool.GpxData; import net.osmand.plus.measurementtool.GpxData.ActionType; import net.osmand.plus.measurementtool.MeasurementEditingContext; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java index b23edbbea1..c8025bc2d5 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java @@ -31,7 +31,7 @@ import net.osmand.plus.activities.PluginsActivity; import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.download.DownloadActivity; -import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.routing.RouteCalculationResult; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java index 6aac50bc9c..2428290517 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java @@ -31,7 +31,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import static net.osmand.plus.helpers.ImportHelper.ImportType.SETTINGS; +import static net.osmand.plus.importfiles.ImportHelper.ImportType.SETTINGS; import static net.osmand.plus.profiles.SelectProfileBottomSheetDialogFragment.DIALOG_TYPE; import static net.osmand.plus.profiles.SelectProfileBottomSheetDialogFragment.IS_PROFILE_IMPORTED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheetDialogFragment.PROFILE_KEY_ARG; From ad4562383bebb19f857d7bd1d0a1099b00b544bc Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Tue, 6 Oct 2020 10:47:15 +0000 Subject: [PATCH 0512/1366] Translated using Weblate (French) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 73e8c40be0..41007cc7eb 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3412,7 +3412,7 @@ OSM Icône affiché pendant la navigation ou en déplacement. Icône affiché à l\'arrêt. - Consultez et partagez les journaux de l\'application (pour debug) + Vérifier et partager les logs détaillés de l\'application Vous n\'êtes pas autorisés à utiliser cette option. Intervalle de suivi Adresse web From 05977020bcbda3cbde8d46b849d3859c6500230a Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Tue, 6 Oct 2020 17:04:49 +0000 Subject: [PATCH 0513/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-ru/strings.xml | 80 ++++++++++++++++---------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 26dae657c6..dffc2313b4 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -60,7 +60,7 @@ Выбрать цвет Задать имя Для больших расстояний: добавьте промежуточные пункты, если маршрут не построен в течение 10 минут. - Разрешить частный доступ + Разрешить частные зоны Разрешить доступ на частную территорию. Обзор Выберите улицу @@ -105,7 +105,7 @@ Добавление нового пункта назначения в центре экрана. Ранее выбранный пункт назначения станет последним промежуточным пунктом. Кнопка для установки центра экрана пунктом отправления. Затем нужно будет выбрать пункт назначения или запустить расчёт маршрута. Кнопка для установки центра экрана пунктом назначения с заменой предыдущего (если был задан). - Установка центра экрана первой промежуточной точкой маршрута. + Установка центра экрана местом первой остановки на маршруте. Нет покрытия Нет подложки Гористый @@ -715,10 +715,10 @@ Фильтр Звук Без звука - Выберите язык голосовых инструкции для навигации. + Выберите голосовое сопровождение для навигации. Голосовые данные Инициализируются голосовые данные… - Голосовые данные не поддерживаются текущей версией приложения + Неподдерживаемая версия голосовых данных Выбранные голосовые данные не правильного формата Выбранный пакет голосовых подсказок не доступен SD-карта недоступна. @@ -726,14 +726,14 @@ Карта памяти доступна только для чтения. \nТеперь можно только просматривать предварительно загруженную карту, а не загружать новые области. Файл распаковывается… - Направо - Резко направо - Плавно направо - Налево - Резко налево - Плавно налево - Выполните разворот - Двигайтесь прямо + Направо ⇒ + Резко направо ⇘ + Плавно направо ⇗ + Налево ⇐ + Резко налево ⇙ + Плавно налево ⇖ + Выполните разворот ⇓ + Двигайтесь прямо ⇑ Продолжить Загрузить детальные карты регионов Поиск сигнала… @@ -1024,8 +1024,8 @@ Показывать больше деталей на карте. Больше деталей Круговое движение, %1$d съезд - Держитесь левее - Держитесь правее + Держитесь левее ⇖ + Держитесь правее ⇗ Скорее Общедоступный Идентифицируемый @@ -1177,11 +1177,11 @@ Рестораны Достопримечательности Последний промежуточный пункт - Первый промежуточный пункт - Добавить последним промежуточным пунктом + Сделать начальной остановкой + Сделать последней остановкой Первый промежуточный пункт Заменить пункт назначения - Вы уже задали пункт назначения + Пункт назначения уже задан Пункт %1$s Точки маршрута Промежуточный пункт %1$s @@ -1386,7 +1386,7 @@ Задать пункт назначения Предпочтения маршрута Информация про маршрут - Добавить новым пунктом назначения + Добавить пункт назначения Использовать показанный путь для навигации? Рассчитать сегмент маршрута OsmAnd без интернета Рассчитать маршрут OsmAnd для первого и последнего сегмента маршрута @@ -1581,7 +1581,7 @@ Снизьте скорость Камера скорости Дорожные предупреждения - Выберите допустимое значение превышения скорости выше которого вы получите голосовое предупреждение. + Выберите значение скорости, при превышении которого вы получите голосовое предупреждение. Допустимое превышение скорости Избранная точка переименована на «%1$s», чтобы сохранить строку, содержащую эмотикон в файл. Печать маршрута @@ -1815,7 +1815,7 @@ Переместить файлы данных Osmand в новое место назначения\? Напечатайте для поиска Номера домов - Избегать перехода границы + Избегать пересечения границ Предельная высота Укажите высоту транспортного средства для учёта при построении маршрута. Умный пересчёт маршрута @@ -2030,7 +2030,7 @@ Изменить путевую точку GPX Без лестниц Избегать ступеней и лестниц - Без пересечений границ + Без перехода границы Обновлять Загружать только по Wi-Fi Обновить сейчас @@ -2110,7 +2110,7 @@ Запись удалена элементы удалены Автообновления - Выберите или скачайте голосовые подсказки для вашего языка. + Выберите или скачайте голосовое сопровождение для вашего языка. Полный отчёт Пересчёт маршрута Имя пользователя и пароль OSM @@ -2235,7 +2235,7 @@ Получить Получайте неограниченное количество загрузок карт, вдобавок к еженедельным, ежедневным и даже почасовым обновлениям. Неограниченный доступ к картам, обновлениям и плагину «Википедия». - Голосовое сопровождение + Голосовые инструкции Абонентская плата взимается за выбранный период. Отменить подписку можно в Google Play в любой момент. Пожертвование для сообщества OSM Часть вашего пожертвования будет отправлена участникам OSM. Стоимость подписки при этом остаётся прежней. @@ -2281,9 +2281,9 @@ Изменить положение кнопки Название действия Сербский (латиница) - Голос вкл/выкл - Включить голос - Выключить голос + Голосовая навигация + Включить подсказки + Выключить подсказки Не удалось переместить файл. Благодарим вас за покупку контуров морских глубин Добавить фото @@ -2440,7 +2440,7 @@ Кнопка для добавления фотозаметки в центре экрана. Добавление в центре экрана OSM-заметки. Добавление POI в центре экрана. - Переключатель, чтобы включить или выключить голосовые подсказки во время навигации. + Включение/отключение голосового сопровождения при навигации. Добавление в центре экрана места парковки. Показывать промежуточный диалог Фотографии Mapillary доступны только онлайн. @@ -2668,9 +2668,9 @@ Копировать местоположение/название POI Место без названия Текущий - Добавляет промежуточную остановку - Добавляет начальную остановку - Добавляет новый пункт назначения, делая выбранный ранее промежуточной точкой + Добавить последним промежуточным пунктом + Добавить первым промежуточным пунктом + Ранее выбранный пункт назначения станет последним промежуточным пунктом Показать закрытые заметки Показать/скрыть заметки OSM на карте. GPX — подходит для экспорта в JOSM и другие OSM редакторы. @@ -2908,7 +2908,7 @@ пешком Показывать вдоль маршрута Покрытие - Тип дороги + Класс дороги Крутизна Добавить дом Добавить работу @@ -3107,14 +3107,14 @@ Режим пользователя, полученный из: %s Повторяющееся имя BRouter (локально) - Альпийские/горные лыжи + Горнолыжные спуски Склоны для катания и спуска на горных лыжах и доступ к подъёмникам. Лыжные туры Сани Склоны для катания на санях. Более сложные маршруты с крутыми участками дороги. В целом, препятствия, которых следует избегать. Сложные маршруты, с опасными препятствиями и крутыми участками. - Предпочитаемая сложность + Предпочтительная сложность Служба скачивания OsmAnd Пурпурный Оценить @@ -3187,8 +3187,8 @@ \nРасчёт: %.1f с, %d дорог, %d тайлов) Добавьте хотя бы один элемент в список «Быстрые действия» в настройках Маршруты для горнолыжного туризма. - Офпист - Фрирайды и офписты являются неофициальными неадаптированными трассами. Обычно неухоженные, неразмеченные и неосвещённые вечером. Вход на свой страх и риск. + Вне трассы + Фрирайды и внетрассовые маршруты — это неофициальные неподготовленные трассы. Обычно неухоженные, неразмеченные и неосвещённые вечером. Вход на свой страх и риск. Открыть трек Соединить разрывы (исключить пробелы) Кемпер @@ -3233,7 +3233,7 @@ Карта во время навигации Скорость движения, размеры, масса транспортного средства Параметры транспортного средства - Голосовые инструкции работают только во время навигации. + Голосовые инструкции работают только при навигации. Навигационные инструкции и объявления Голосовые подсказки Экранные оповещения @@ -3365,8 +3365,8 @@ Разрешить только маршруты для катания на коньках Маршруты, подготовленные для фристайла или катания только на коньках без классических треков. Разрешить только классические маршруты - Маршруты, подготовленные только для классического стиля без конькобежных трасс. Сюда входят маршруты, подготовленные небольшим снегоходом с более свободной лыжнёй и трассами, подготовленные вручную лыжниками. - Предпочтительный уровень сложности маршрутов. Более сложные или лёгкие трассы могут использоваться, если они короче. + Маршруты только для классического стиля, без конькобежных трасс. Сюда входят маршруты, подготовленные небольшим снегоходом с более свободной лыжнёй и трассами, подготовленные вручную лыжниками. + Предпочитаемый уровень сложности маршрутов. Более сложные или лёгкие трассы могут использоваться, если они короче. Включать на повороте Класс 1 Класс 2 @@ -3581,7 +3581,7 @@ Разделение записи Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. "Будут записываться только точки, отвечающие -\n в минимальной точностью (в метрах/футах —д зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." +\n в минимальной точностью (в метрах/футах —зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться. Для визуализации крутизны рельефа используются цвета. Подробнее об уклонах можно прочитать в %1$s. @@ -3790,7 +3790,7 @@ Изменение масштаба карты кнопками громкости. Масштабирование кнопками громкости Укажите длину автомобиля, для длинных транспортных средств могут применяться ограничения на маршруте. - Удалить следующий пункт + Удалить следующую Задайте название точки Следующая точка маршрута будет удалена. Если это конечный пункт, навигация завершится. Информация о достопримечательностях из Википедии. Ваш карманный офлайн-путеводитель — просто включите плагин Википедии и читайте об объектах вокруг вас. From 6786edbd2f8dca76dcda836abe226250919121b7 Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Tue, 6 Oct 2020 13:57:23 +0000 Subject: [PATCH 0514/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-ru/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index dffc2313b4..0df61cb806 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3903,4 +3903,5 @@ Имя: Я - А Имя: А - Я Значки старта и финиша + Спасибо за покупку \'Контурных линий\' \ No newline at end of file From 836cbde26159c7c452f0580a5577e4e6905a83ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 6 Oct 2020 16:49:29 +0000 Subject: [PATCH 0515/1366] Translated using Weblate (Turkish) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-tr/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 5c1607f332..50a41c8562 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -892,7 +892,7 @@ Güzergahı göster Yönlendirmeyi başlatın Lütfen önce hedefi ayarlayın - Açılış saatleri + Çalışma saatleri Yetkilendirme başarısız Sokaklar/binalar yükleniyor… Sokaklar yükleniyor… @@ -1374,7 +1374,7 @@ Açılış Kapanış İletişim Bilgileri - Açılış saatleri ekle + Çalışma saatleri ekle POI Türü Dash %1$s satır sayısı POI türü belirtiniz. From 096e34c6c63816e33e67bc20b8fe92a25b50fb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Tue, 6 Oct 2020 07:16:01 +0000 Subject: [PATCH 0516/1366] Translated using Weblate (Hungarian) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-hu/strings.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index 97f76c0623..b903ccb8da 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -3277,7 +3277,7 @@ Térképnézet Alapértelmezés visszaállítása Másolás egy másik profilból - Logcat-puffer + Logcat-puffer (hibanapló) Alapértelmezés szerint Hópark Lovas szán @@ -3424,8 +3424,8 @@ OSM-szerkesztés Az összes még fel nem töltött szerkesztés vagy OSM-hiba megtalálható a %1$s helyen. A már feltöltött pontok nem láthatók az OsmAndban. OSM - Az ikon navigáció vagy haladás közben jelenik meg. - Az ikon álló helyzetben jelenik meg. + Navigáció vagy haladás közben megjelenő ikon. + Álló helyzetben megjelenő ikon. Az alkalmazás részletes naplóinak ellenőrzése és megosztása A beállítás használatához engedélyre van szükség. Kategóriák átrendezése @@ -3896,4 +3896,6 @@ Utolsó módosítás Név: Z–A Név: A–Z + Kiindulás/érkezés ikonjai + Köszönjük, hogy megvásárolta a szintvonalbővítményt (Contour lines) \ No newline at end of file From 72ba5a9451273c70c9a501ca789269c220e10e4c Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Tue, 6 Oct 2020 12:59:26 +0000 Subject: [PATCH 0517/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-uk/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 6d73e13701..fda15847c5 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -428,7 +428,7 @@ Відсутні точки Закладок для збереження Імпортувати Не вдалося завантажити GPX. - Відправити звіт + Надіслати звіт Не знайдено завантаженої мапи на карті пам\'яті. Почніть вводити текст для пошуку POI Всі @@ -3431,7 +3431,7 @@ OSM Значок відображається під час навігації чи переміщення. Значок показано в спокої. - Перевіряти та обмінюватися докладними журналами застосунку + Переглянути та надіслати докладний журнал застосунку Не вдалося розібрати метод \'%s\'. Для використання цього параметра потрібен дозвіл. Це низькошвидкісний відсічний фільтр, щоб не записувати точки нижче певної швидкості. Це може призвести до плавнішого вигляду записаних треків при перегляді на мапі. From cbfae5608a6a36b45f75d84a41d771d3b2388b06 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 6 Oct 2020 05:12:36 +0000 Subject: [PATCH 0518/1366] Translated using Weblate (Hebrew) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-iw/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 31795c6dc2..42a840fa87 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -2103,7 +2103,7 @@ ביטול הבחירה למחוק הכול שיתוף - יצוא + ייצוא עוד… שמירת הבחירה שגיאה בלתי צפויה @@ -3248,7 +3248,7 @@ התצורה הנבחרת תחול בכל רחבי היישומון. הגדרה זו נבחרת כבררת מחדל על הפרופילים: %s החלפת הגדרה - זיכרון זמני של Logcat + מכלא Logcat כבררת מחדל הגדרות תוסף הורדת המפה המפורטת %s, כדי לצפות באזור זה. @@ -3428,7 +3428,7 @@ סמל שמופיע רק בעת ניווט או תזוזה. סמל שמופיע במנוחה. דירוג - לבדוק ולשתף תיעוד מפורט של יומני היישומון + בדיקה ושיתוף יומני תיעוד מפורטים של היישומים נדרשת הרשאה כדי להשתמש באפשרות הזו. סידור הקטגוריות מחדש ניתן להחליף את סדר הרשימה ולהסתיר קטגוריות בלתי נחוצות. אפשר לייבא או לייצא את כל השינויים עם פרופילים. From 431f1b10d0b12c4f688994744144b7165bc42693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Tue, 6 Oct 2020 07:18:38 +0000 Subject: [PATCH 0519/1366] Translated using Weblate (Hungarian) Currently translated at 99.9% (3822 of 3825 strings) --- OsmAnd/res/values-hu/phrases.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml index 4e0cce87d3..0234cd76a2 100644 --- a/OsmAnd/res/values-hu/phrases.xml +++ b/OsmAnd/res/values-hu/phrases.xml @@ -294,7 +294,7 @@ Forgalomlassító útszűkület Gázolaj Biodízel - Cseppfolyós gáz (LPG) + LPG (cseppfolyósított PB-gáz) 80-as oktánszámú 91-es oktánszámú 92-es oktánszámú @@ -3835,4 +3835,5 @@ Ivóvíz-utántöltés Mag- és aszaltgyümölcsbolt Méhkaptár + LNG (cseppfolyósított földgáz) \ No newline at end of file From 5fd389970d0c6244adac2e1d2d0a5de9079b6fbc Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Tue, 6 Oct 2020 13:33:49 +0000 Subject: [PATCH 0520/1366] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 3807266c57..1358007216 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -3427,7 +3427,7 @@ OSM Ícone mostrado ao navegar ou mover. Ícone mostrado em repouso. - Verifique e compartilhe logs detalhados do aplicativo + Verifique e compartilhe registros detalhados do aplicativo Não foi possível analisar a intenção geográfica \'%s\'. É necessária permissão para usar esta opção. Este é um filtro de corte de baixa velocidade para não registrar pontos abaixo de uma determinada velocidade. Isso pode fazer com que as faixas gravadas pareçam mais suaves quando visualizadas no mapa. @@ -3900,4 +3900,5 @@ Nome: Z – A Nome: A – Z Ícones de início/término + Obrigado por adquirir \'curvas de nível\' \ No newline at end of file From fc1b97f51d019e19071fc2d1bea64a51b5298f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 6 Oct 2020 05:38:12 +0000 Subject: [PATCH 0521/1366] Translated using Weblate (Estonian) Currently translated at 99.3% (3468 of 3489 strings) --- OsmAnd/res/values-et/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index c2b36454b5..8e58fdad52 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -40,7 +40,7 @@ Start Stop Import - Eksport + Ekspordi Veel… Veel tegevusi Ära enam näita @@ -910,7 +910,7 @@ Seadista teekonna parameetrid Teekonna parameetrid Rakenduse profiiliks muudetud \"%s\" - Logcat puhver + Logcati puhver Laienduse seaded Vaikimisi Selle ala vaatlemiseks lae alla üksikasjalik %s kaart. @@ -3364,7 +3364,7 @@ OSM Ikooni kuvatakse vaid navigeerimise või liikumise ajal. Peatumisel näidatav ikoon. - Kontrolli ja jaga rakenduse detailseid logisid + Vaata ja jaga rakenduse detailseid logisid Geokavatsuse väärtusest \'%s\' ei saanud aru. Selle valiku kasutamine vajab luba. See on madala kiirusega väljalülitusfilter, et mitte salvestada punkte, mis jäävad alla teatud kiiruse. See võib muuta salvestatud rajad kaardil vaadates sujuvamaks. From b88f48ad35bbec3899422982a38f1edbc6a5ab4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 6 Oct 2020 17:08:56 +0000 Subject: [PATCH 0522/1366] Translated using Weblate (Turkish) Currently translated at 75.0% (2871 of 3825 strings) --- OsmAnd/res/values-tr/phrases.xml | 68 ++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index 3fd2637960..05e1fb7d24 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -326,7 +326,7 @@ Düşük enerji Ampüller Floresan tüpler Metal - Elektrik öğeleri + Elektrik ögeleri Beyaz eşya Yemeklik yağ Motor yağı @@ -2201,8 +2201,8 @@ Karavan: hayır Hazırlıksız: evet Hazırlıksız: hayır - Tuvalet atığı istasyonu: evet - Tuvalet atığı istasyonu: hayır + Sıhhi atık boşaltma istasyonu: evet + Sıhhi atık boşaltma istasyonu: hayır Evet Güç kaynağı: hayır Güç kaynağı (soket): CEE 17 mavi @@ -2605,7 +2605,7 @@ Açık Görünürlük: sokak Görünürlük: ev - Konu: duvar + Konum: duvar Konum: yerüstü Konum: sualtı Konum: yeraltı @@ -2617,7 +2617,7 @@ Bakanlık Arşiv - + Yatak Yön: her Yön: çıkış Yön: giriş @@ -2653,7 +2653,7 @@ Şarap: evet Evet Çilingir - Elektronik mağazası + Elektrik mağazası Tibet Bulgar Yahudi @@ -2697,7 +2697,7 @@ Hırvat Peru Balkan - Arjantina + Arjantin Karayip Afrika Endonez @@ -2742,7 +2742,7 @@ Makarna Biftek Kahvaltı - Barbekü + Mangal Suşi Dondurma Tavuk @@ -2762,7 +2762,7 @@ Konsolosluk Yalnızca Evet - Su kültür: midye + Su kültürü: midye Su kültürü: balık Su kültürü: karides Su kültürü @@ -2772,8 +2772,8 @@ Barometre Teleskop Özel - Ordu/kamusal - Ordu + Askeri/kamusal + Askeri Kamusal Bölgesel Uluslararası @@ -2836,4 +2836,50 @@ Korunan nesne: tarihi Koruma alanı Yapım aşamasında + Fast food + Pankek + Pasta + Izgara + Sosis + Sosisli sandviç + Köri + Krep + Erişte (ramen) + Çörek (donut) + Erişte (noodle) + Deniz ürünleri + Balık ve patates kızartması + Noel: web sitesi + Noel: konum + Noel: çalışma saatleri + Noel: not + Noel: etkinlik dönemi + Ağaç dükkanı + Noel dükkanı + Noel piramidi + Noel marketi + Noel etkinliği + Yolcu bilgilendirme ekranı: hayır + Yolcu bilgilendirme ekranı: evet + Higrometre: hayır + Higrometre + Kullanım: casusluk + Kullanım: araştırma + Kullanım: casusluk + Kullanım: eğitim + Ev ziyareti: hayır + Yunani + Sidda + Kampo + Ayurveda + Sıhhi atık boşaltma istasyonu + Yalnızca adil ticaret ürünleri + Adil ticaret: hayır + Adil ticaret: evet + Basınçlı hava: hayır + Bitki fidanlığı + Motorlu tekneler: hayır + Motorlu tekneler: evet + Tekne kiralama + Konum: giriş \ No newline at end of file From a0f1b21b96fde98efc9ccee46af2bccafd604e4e Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 6 Oct 2020 06:11:27 +0000 Subject: [PATCH 0523/1366] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 47137ac203..cf0cc3fd99 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3425,7 +3425,7 @@ OSM 在導航或移動時顯示的圖示。 靜止時顯示的圖示。 - 檢視及分享應用程式的紀錄檔 + 檢查及分享應用程式的詳細紀錄 無法解析地理含義「%s」。 您已紀錄的軌跡位於 %1$s,或是 OsmAnd 資料夾。 您的 OSM 註記位於 %1$s。 @@ -3900,4 +3900,5 @@ 名稱:Z – A 名稱:A – Z 開始/結束圖示 + 感謝您購買 \'Contour lines\' \ No newline at end of file From 3e6b69591367a4dda315a13f5e0b4d475de952fb Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Tue, 6 Oct 2020 13:56:29 +0000 Subject: [PATCH 0524/1366] Translated using Weblate (Russian) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/ru/ --- OsmAnd-telegram/res/values-ru/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-ru/strings.xml b/OsmAnd-telegram/res/values-ru/strings.xml index a494bf809b..e12c0245b5 100644 --- a/OsmAnd-telegram/res/values-ru/strings.xml +++ b/OsmAnd-telegram/res/values-ru/strings.xml @@ -267,4 +267,8 @@ Последнее обновление от Telegram: %1$s назад Последний ответ: %1$s Последнее обновление от Telegram: %1$s + Экспорт + Буфер Logcat + Проверьте и поделитесь подробными журналами приложения + Отправить отчёт \ No newline at end of file From d5c046b00ba73685cea4f2638413ecd99bff9647 Mon Sep 17 00:00:00 2001 From: ihor_ck Date: Tue, 6 Oct 2020 13:00:52 +0000 Subject: [PATCH 0525/1366] Translated using Weblate (Ukrainian) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/uk/ --- OsmAnd-telegram/res/values-uk/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-uk/strings.xml b/OsmAnd-telegram/res/values-uk/strings.xml index 9a2d31a4e7..e370c05360 100644 --- a/OsmAnd-telegram/res/values-uk/strings.xml +++ b/OsmAnd-telegram/res/values-uk/strings.xml @@ -267,4 +267,8 @@ Остання відповідь: %1$s тому %1$s тому ПМЛК + Експорт + Буфер logcat + Переглянути та надіслати докладний журнал застосунку + Надіслати звіт \ No newline at end of file From 81f6414368bc16280115dcf2f26f5bed3aed2b2a Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 6 Oct 2020 05:12:36 +0000 Subject: [PATCH 0526/1366] Translated using Weblate (Hebrew) Currently translated at 99.6% (270 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/he/ --- OsmAnd-telegram/res/values-he/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-he/strings.xml b/OsmAnd-telegram/res/values-he/strings.xml index 99c18d4cb2..65da2f52a1 100644 --- a/OsmAnd-telegram/res/values-he/strings.xml +++ b/OsmAnd-telegram/res/values-he/strings.xml @@ -268,4 +268,8 @@ תגובה אחרונה: לפני %1$s לפני %1$s שגיאה + ייצוא + מכלא Logcat + בדיקה ושיתוף יומני תיעוד מפורטים של היישומים + שליחת דיווח \ No newline at end of file From 03ba69ae2963174757cd43720c09285a8085f633 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 6 Oct 2020 06:11:51 +0000 Subject: [PATCH 0527/1366] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/zh_Hant/ --- OsmAnd-telegram/res/values-zh-rTW/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-zh-rTW/strings.xml b/OsmAnd-telegram/res/values-zh-rTW/strings.xml index f1f06a0daa..7739c65184 100644 --- a/OsmAnd-telegram/res/values-zh-rTW/strings.xml +++ b/OsmAnd-telegram/res/values-zh-rTW/strings.xml @@ -270,4 +270,8 @@ 最後回應:%1$s 前 %1$s 前 ERR + 傳送報告 + 匯出 + Logcat 緩衝 + 檢查及分享應用程式的詳細紀錄 \ No newline at end of file From 4c469d5833483a1002ffb2c41c61e4604ae0d40e Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Tue, 6 Oct 2020 13:34:10 +0000 Subject: [PATCH 0528/1366] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/pt_BR/ --- OsmAnd-telegram/res/values-pt-rBR/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-pt-rBR/strings.xml b/OsmAnd-telegram/res/values-pt-rBR/strings.xml index c1aa3b8e55..d792f9748f 100644 --- a/OsmAnd-telegram/res/values-pt-rBR/strings.xml +++ b/OsmAnd-telegram/res/values-pt-rBR/strings.xml @@ -267,4 +267,8 @@ Última resposta: %1$s atrás %1$s atrás ERR + Exportar + Buffer de Logcat + Verifique e compartilhe registros detalhados do aplicativo + Enviar o relatório \ No newline at end of file From ee0e3910e1ccd8c841a0c7b0c076093ed8b8e342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Tue, 6 Oct 2020 07:12:29 +0000 Subject: [PATCH 0529/1366] Translated using Weblate (Hungarian) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/hu/ --- OsmAnd-telegram/res/values-hu/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-hu/strings.xml b/OsmAnd-telegram/res/values-hu/strings.xml index 8c257bb040..95d655b5cb 100644 --- a/OsmAnd-telegram/res/values-hu/strings.xml +++ b/OsmAnd-telegram/res/values-hu/strings.xml @@ -268,4 +268,8 @@ Utolsó válasz: %1$s Ennyivel ezelőtt: %1$s HIBA + Exportálás + Logcat-puffer (hibanapló) + Az alkalmazás részletes naplóinak ellenőrzése és megosztása + Jelentés küldése \ No newline at end of file From f0497cb59634a563718ed618701e830cc1b9dec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 6 Oct 2020 04:59:54 +0000 Subject: [PATCH 0530/1366] Translated using Weblate (Turkish) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/tr/ --- OsmAnd-telegram/res/values-tr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-tr/strings.xml b/OsmAnd-telegram/res/values-tr/strings.xml index 086306b609..87ba56717d 100644 --- a/OsmAnd-telegram/res/values-tr/strings.xml +++ b/OsmAnd-telegram/res/values-tr/strings.xml @@ -267,4 +267,8 @@ Son cevap: %1$s önce %1$s önce HATA + Dışa aktar + Logcat tamponu + Uygulamanın ayrıntılı günlük kayıtlarına göz atın ve paylaşın + Rapor gönder \ No newline at end of file From 1b10bce1a3072335137cde7af6c9afea7dd6d884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 6 Oct 2020 05:38:13 +0000 Subject: [PATCH 0531/1366] Translated using Weblate (Estonian) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/et/ --- OsmAnd-telegram/res/values-et/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-et/strings.xml b/OsmAnd-telegram/res/values-et/strings.xml index 126490e593..0ddb7950a7 100644 --- a/OsmAnd-telegram/res/values-et/strings.xml +++ b/OsmAnd-telegram/res/values-et/strings.xml @@ -267,4 +267,8 @@ Viimane vastus: %1$s tagasi %1$s tagasi ERR + Ekspordi + Logcati puhver + Vaata ja jaga rakenduse detailseid logisid + Saada ettekanne \ No newline at end of file From a64636c9ffc90c17cf45f721a45251c89a30637e Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Tue, 6 Oct 2020 10:47:22 +0000 Subject: [PATCH 0532/1366] Translated using Weblate (French) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/fr/ --- OsmAnd-telegram/res/values-fr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-fr/strings.xml b/OsmAnd-telegram/res/values-fr/strings.xml index 4397948508..4b9d45edfb 100644 --- a/OsmAnd-telegram/res/values-fr/strings.xml +++ b/OsmAnd-telegram/res/values-fr/strings.xml @@ -267,4 +267,8 @@ Définissez l\'heure à laquelle les contacts et groupes sélectionnés verront votre position en temps réel. OsmAnd connect depuis + Buffer Logcat + Vérifier et partager les logs détaillés de l\'application + Exporter + Envoyer le rapport \ No newline at end of file From 27b235cb39399c855e61f258f608335dff455232 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 7 Oct 2020 03:17:16 +0300 Subject: [PATCH 0533/1366] Add import with file signature check --- .../main/java/net/osmand/IndexConstants.java | 5 +- .../main/java/net/osmand/util/Algorithms.java | 9 +- .../plus/importfiles/FavoritesImportTask.java | 3 +- .../plus/importfiles/GpxImportTask.java | 2 +- .../GpxOrFavouritesImportTask.java | 2 +- .../osmand/plus/importfiles/ImportHelper.java | 16 ++- .../plus/importfiles/KmlImportTask.java | 2 +- .../plus/importfiles/KmzImportTask.java | 5 +- .../plus/importfiles/ObfImportTask.java | 2 +- .../plus/importfiles/UriImportTask.java | 129 ++++++++++++++++++ 10 files changed, 156 insertions(+), 19 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java index 93569dfddd..c8ffd2d96b 100644 --- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java +++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java @@ -14,7 +14,8 @@ public class IndexConstants { public static final String TEMP_SOURCE_TO_LOAD = "temp"; public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$ - + + public static final String ZIP_EXT = ".zip"; //$NON-NLS-1$ public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$ public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$ @@ -71,7 +72,7 @@ public class IndexConstants { public static final String FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$ public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$ public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$ - public static final String ROUTING_XML_FILE= "routing.xml"; + public static final String ROUTING_XML_FILE = "routing.xml"; public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$ public static final String TEMP_DIR = "temp/"; public static final String ROUTING_PROFILES_DIR = "routing/"; diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index ea2869aaa3..d890d5edea 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -49,6 +49,11 @@ public class Algorithms { private static char[] CHARS_TO_NORMALIZE_KEY = new char['’']; private static char[] CHARS_TO_NORMALIZE_VALUE = new char['\'']; + public static final int ZIP_FILE_SIGNATURE = 0x504b0304; + public static final int XML_FILE_SIGNATURE = 0x3c3f786d; + public static final int OBF_FILE_SIGNATURE = 0x08029001; + public static final int SQLITE_FILE_SIGNATURE = 0x53514C69; + public static String normalizeSearchText(String s) { boolean norm = false; for (int i = 0; i < s.length() && !norm; i++) { @@ -293,7 +298,7 @@ public class Algorithms { FileInputStream in = new FileInputStream(file); int test = readInt(in); in.close(); - return test == 0x504b0304; + return test == ZIP_FILE_SIGNATURE; } /** @@ -322,7 +327,7 @@ public class Algorithms { return false; } - private static int readInt(InputStream in) throws IOException { + public static int readInt(InputStream in) throws IOException { int ch1 = in.read(); int ch2 = in.read(); int ch3 = in.read(); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java index 2793e1e0ab..9047baeb59 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java @@ -5,7 +5,6 @@ import android.content.Intent; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; -import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.data.FavouritePoint; import net.osmand.plus.FavouritesDbHelper; @@ -45,7 +44,7 @@ class FavoritesImportTask extends BaseImportAsyncTask { } @Override - protected void onPostExecute(GPXUtilities.GPXFile result) { + protected void onPostExecute(GPXFile result) { hideProgress(); FragmentActivity activity = activityRef.get(); if (activity != null) { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java index 1e76f15a26..4a410172a7 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java @@ -52,7 +52,7 @@ class GpxImportTask extends BaseImportAsyncTask { } @Override - protected void onPostExecute(GPXUtilities.GPXFile result) { + protected void onPostExecute(GPXFile result) { hideProgress(); importHelper.handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java index 48eadfb5b1..ed1a16c3b1 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java @@ -76,7 +76,7 @@ class GpxOrFavouritesImportTask extends BaseImportAsyncTask } @Override - protected void onPostExecute(final GPXUtilities.GPXFile result) { + protected void onPostExecute(GPXFile result) { hideProgress(); importHelper.importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index f5b47604ac..d8bca201b4 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -20,7 +20,6 @@ import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; -import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint.BackgroundType; @@ -55,6 +54,7 @@ import java.util.Locale; import static android.app.Activity.RESULT_OK; import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT; +import static net.osmand.IndexConstants.GPX_IMPORT_DIR; import static net.osmand.IndexConstants.GPX_INDEX_DIR; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; @@ -176,7 +176,7 @@ public class ImportHelper { boolean saveFile = !isFileIntent || !isOsmandSubdir; if (fileName == null) { - handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false); + handleUriImport(intentUri, saveFile, useImportDir); } else if (fileName.endsWith(KML_SUFFIX)) { handleKmlImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(KMZ_SUFFIX)) { @@ -243,11 +243,11 @@ public class ImportHelper { executeImportTask(new KmlImportTask(this, activity, kmlFile, name, save, useImportDir)); } - private void handleObfImport(Uri obfFile, String name) { + protected void handleObfImport(Uri obfFile, String name) { executeImportTask(new ObfImportTask(activity, obfFile, name)); } - private void handleSqliteTileImport(Uri uri, String name) { + protected void handleSqliteTileImport(Uri uri, String name) { executeImportTask(new SqliteTileImportTask(activity, uri, name)); } @@ -266,10 +266,14 @@ public class ImportHelper { executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); } - private void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { + protected void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { executeImportTask(new XmlImportTask(activity, intentUri, fileName, routingCallback)); } + private void handleUriImport(Uri uri, boolean save, boolean useImportDir) { + executeImportTask(new UriImportTask(this, activity, uri, save, useImportDir)); + } + @Nullable public static String copyFile(OsmandApplication app, @NonNull File dest, @NonNull Uri uri, boolean overwrite) { if (dest.exists() && !overwrite) { @@ -442,7 +446,7 @@ public class ImportHelper { } else { final File importDir; if (useImportDir) { - importDir = app.getAppPath(IndexConstants.GPX_IMPORT_DIR); + importDir = app.getAppPath(GPX_IMPORT_DIR); } else { importDir = app.getAppPath(GPX_INDEX_DIR); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java index 38c557e8c7..8d48485b33 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java @@ -15,7 +15,7 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.io.UnsupportedEncodingException; -class KmlImportTask extends BaseImportAsyncTask { +class KmlImportTask extends BaseImportAsyncTask { private ImportHelper importHelper; private Uri uri; diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java index 420f4feff4..41d01be264 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java @@ -5,7 +5,6 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; -import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.util.Algorithms; @@ -16,7 +15,7 @@ import java.util.zip.ZipInputStream; import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; -class KmzImportTask extends BaseImportAsyncTask { +class KmzImportTask extends BaseImportAsyncTask { private ImportHelper importHelper; private Uri uri; @@ -60,7 +59,7 @@ class KmzImportTask extends BaseImportAsyncTask { private Uri uri; private String name; - public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, String name) { + public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, @NonNull String name) { super(activity); this.uri = uri; this.name = name; diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java new file mode 100644 index 0000000000..0bc9909643 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -0,0 +1,129 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.plus.R; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import static net.osmand.FileUtils.createUniqueFileName; +import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; +import static net.osmand.IndexConstants.MAPS_PATH; +import static net.osmand.IndexConstants.ROUTING_FILE_EXT; +import static net.osmand.IndexConstants.SQLITE_EXT; +import static net.osmand.IndexConstants.TEMP_DIR; +import static net.osmand.IndexConstants.TILES_INDEX_DIR; +import static net.osmand.IndexConstants.ZIP_EXT; +import static net.osmand.util.Algorithms.OBF_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.SQLITE_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.XML_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.ZIP_FILE_SIGNATURE; + +class UriImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private String tempFileName; + + private int fileSignature; + + private boolean save; + private boolean useImportDir; + + public UriImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected String doInBackground(Void... nothing) { + String error = null; + InputStream is = null; + OutputStream out = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + fileSignature = Algorithms.readInt(is); + if (isSupportedFileSignature()) { + File tempDir = app.getAppPath(TEMP_DIR); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + tempFileName = getTempFileName(); + File dest = new File(tempDir, tempFileName); + + out = new FileOutputStream(dest); + Algorithms.writeInt(out, Integer.reverseBytes(fileSignature)); + Algorithms.streamCopy(is, out); + } + } + } catch (FileNotFoundException e) { + ImportHelper.log.error(e); + error = e.getMessage(); + } catch (SecurityException e) { + ImportHelper.log.error(e); + error = e.getMessage(); + } catch (IOException e) { + ImportHelper.log.error(e); + error = e.getMessage(); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(out); + } + return error; + } + + private boolean isSupportedFileSignature() { + return fileSignature == XML_FILE_SIGNATURE || fileSignature == OBF_FILE_SIGNATURE + || fileSignature == ZIP_FILE_SIGNATURE || fileSignature == SQLITE_FILE_SIGNATURE; + } + + @Override + protected void onPostExecute(String error) { + hideProgress(); + File file = app.getAppPath(TEMP_DIR + tempFileName); + if (error == null && file.exists()) { + Uri tempUri = AndroidUtils.getUriForFile(app, file); + if (XML_FILE_SIGNATURE == fileSignature) { + importHelper.handleXmlFileImport(tempUri, null, null); + } else if (OBF_FILE_SIGNATURE == fileSignature) { + String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT); + importHelper.handleObfImport(tempUri, name); + } else if (ZIP_FILE_SIGNATURE == fileSignature) { +// importHelper.handleKmzImport(tempUri, null, save, useImportDir); + } else if (SQLITE_FILE_SIGNATURE == fileSignature) { + String name = createUniqueFileName(app, "online_map", TILES_INDEX_DIR, SQLITE_EXT); + importHelper.handleSqliteTileImport(tempUri, name); + } + } else { + app.showShortToastMessage(app.getString(R.string.file_import_error, tempFileName, error)); + } + } + + private String getTempFileName() { + if (XML_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT); + } else if (OBF_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT); + } else if (ZIP_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT); + } else if (SQLITE_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT); + } + return ""; + } +} \ No newline at end of file From fea6b424ca3b4ede41e432fe45848c13d3659699 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 7 Oct 2020 04:06:52 +0300 Subject: [PATCH 0534/1366] Add xml files import after check for file signature --- .../osmand/plus/importfiles/ImportHelper.java | 8 ++++--- .../plus/importfiles/UriImportTask.java | 10 +++++++- .../plus/importfiles/XmlImportTask.java | 23 ++++++++++++------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index d8bca201b4..62e0f1dbd0 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -87,7 +87,9 @@ public class ImportHelper { public enum ImportType { SETTINGS(OSMAND_SETTINGS_FILE_EXT), ROUTING(ROUTING_FILE_EXT), - RENDERING(RENDERER_INDEX_EXT); + RENDERING(RENDERER_INDEX_EXT), + GPX(GPX_FILE_EXT), + KML(KML_SUFFIX); ImportType(String extension) { this.extension = extension; @@ -226,8 +228,8 @@ public class ImportHelper { executeImportTask(new GpxImportTask(this, activity, gpxFile, fileName, save, useImportDir, showInDetailsActivity)); } - private void handleGpxOrFavouritesImport(Uri fileUri, String fileName, boolean save, boolean useImportDir, - boolean forceImportFavourites, boolean forceImportGpx) { + protected void handleGpxOrFavouritesImport(Uri fileUri, String fileName, boolean save, boolean useImportDir, + boolean forceImportFavourites, boolean forceImportGpx) { executeImportTask(new GpxOrFavouritesImportTask(this, activity, fileUri, fileName, save, useImportDir, forceImportFavourites, forceImportGpx)); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java index 0bc9909643..27b4a0fa73 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -7,6 +7,7 @@ import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.plus.R; +import net.osmand.plus.importfiles.ImportHelper.ImportType; import net.osmand.util.Algorithms; import java.io.File; @@ -19,6 +20,7 @@ import java.io.OutputStream; import static net.osmand.FileUtils.createUniqueFileName; import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.MAPS_PATH; +import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_EXT; import static net.osmand.IndexConstants.TEMP_DIR; @@ -99,7 +101,13 @@ class UriImportTask extends BaseImportAsyncTask { if (error == null && file.exists()) { Uri tempUri = AndroidUtils.getUriForFile(app, file); if (XML_FILE_SIGNATURE == fileSignature) { - importHelper.handleXmlFileImport(tempUri, null, null); + ImportType importType = XmlImportTask.checkImportType(app, tempUri); + if (importType == ImportType.RENDERING || importType == ImportType.ROUTING) { + String name = importType == ImportType.RENDERING ? "renderer" + RENDERER_INDEX_EXT : "router" + ROUTING_FILE_EXT; + importHelper.handleXmlFileImport(tempUri, name, null); + } else if (importType == ImportType.GPX || importType == ImportType.KML) { + importHelper.handleGpxOrFavouritesImport(tempUri, tempFileName, save, useImportDir, false, false); + } } else if (OBF_FILE_SIGNATURE == fileSignature) { String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT); importHelper.handleObfImport(tempUri, name); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java index bc66d77a76..6d45466bab 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java @@ -11,6 +11,7 @@ import net.osmand.CallbackWithObject; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.AppInitializer.LoadRoutingFilesCallback; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.importfiles.ImportHelper.ImportType; import net.osmand.router.RoutingConfiguration.Builder; @@ -29,26 +30,26 @@ import static net.osmand.plus.AppInitializer.loadRoutingFiles; class XmlImportTask extends BaseImportAsyncTask { - private Uri intentUri; + private Uri uri; private String destFileName; private ImportType importType; private CallbackWithObject routingCallback; - public XmlImportTask(@NonNull FragmentActivity activity, @NonNull Uri intentUri, - @NonNull String fileName, @Nullable CallbackWithObject routingCallback) { + public XmlImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, + @NonNull String fileName, @Nullable CallbackWithObject routingCallback) { super(activity); - this.intentUri = intentUri; + this.uri = uri; this.destFileName = fileName; this.routingCallback = routingCallback; } @Override protected String doInBackground(Void... voids) { - checkImportType(); + importType = checkImportType(app, uri); if (importType != null) { File dest = getDestinationFile(); if (dest != null) { - return ImportHelper.copyFile(app, dest, intentUri, true); + return ImportHelper.copyFile(app, dest, uri, true); } } return app.getString(R.string.file_import_error, destFileName, app.getString(R.string.unsupported_type_error)); @@ -115,10 +116,11 @@ class XmlImportTask extends BaseImportAsyncTask { return null; } - private void checkImportType() { + protected static ImportType checkImportType(OsmandApplication app, Uri uri) { + ImportType importType = null; InputStream is = null; try { - is = app.getContentResolver().openInputStream(intentUri); + is = app.getContentResolver().openInputStream(uri); if (is != null) { XmlPullParser parser = PlatformUtil.newXMLPullParser(); parser.setInput(is, "UTF-8"); @@ -130,6 +132,10 @@ class XmlImportTask extends BaseImportAsyncTask { importType = ImportType.ROUTING; } else if ("renderingStyle".equals(name)) { importType = ImportType.RENDERING; + } else if ("gpx".equals(name)) { + importType = ImportType.GPX; + } else if ("kml".equals(name)) { + importType = ImportType.KML; } break; } @@ -145,5 +151,6 @@ class XmlImportTask extends BaseImportAsyncTask { } finally { Algorithms.closeStream(is); } + return importType; } } \ No newline at end of file From 62c119731978546079d97595b3de7ddf78ebcbd5 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 7 Oct 2020 05:23:02 +0300 Subject: [PATCH 0535/1366] Add zip files import with check for file signature --- .../osmand/plus/importfiles/ImportHelper.java | 13 ++- .../plus/importfiles/UriImportTask.java | 14 +-- .../plus/importfiles/ZipImportTask.java | 90 +++++++++++++++++++ 3 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index 62e0f1dbd0..c67ae8834e 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -89,7 +89,8 @@ public class ImportHelper { ROUTING(ROUTING_FILE_EXT), RENDERING(RENDERER_INDEX_EXT), GPX(GPX_FILE_EXT), - KML(KML_SUFFIX); + KML(KML_SUFFIX), + KMZ(KMZ_SUFFIX); ImportType(String extension) { this.extension = extension; @@ -237,7 +238,7 @@ public class ImportHelper { executeImportTask(new FavoritesImportTask(activity, gpxFile, fileName, forceImportFavourites)); } - private void handleKmzImport(Uri kmzFile, String name, boolean save, boolean useImportDir) { + protected void handleKmzImport(Uri kmzFile, String name, boolean save, boolean useImportDir) { executeImportTask(new KmzImportTask(this, activity, kmzFile, name, save, useImportDir)); } @@ -263,8 +264,8 @@ public class ImportHelper { } } - private void handleOsmAndSettingsImport(Uri uri, String name, String latestChanges, int version, - CallbackWithObject> callback) { + protected void handleOsmAndSettingsImport(Uri uri, String name, String latestChanges, int version, + CallbackWithObject> callback) { executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); } @@ -276,6 +277,10 @@ public class ImportHelper { executeImportTask(new UriImportTask(this, activity, uri, save, useImportDir)); } + protected void handleZipImport(Uri uri, boolean save, boolean useImportDir) { + executeImportTask(new ZipImportTask(this, activity, uri, save, useImportDir)); + } + @Nullable public static String copyFile(OsmandApplication app, @NonNull File dest, @NonNull Uri uri, boolean overwrite) { if (dest.exists() && !overwrite) { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java index 27b4a0fa73..c2de2d072f 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -110,12 +110,12 @@ class UriImportTask extends BaseImportAsyncTask { } } else if (OBF_FILE_SIGNATURE == fileSignature) { String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT); - importHelper.handleObfImport(tempUri, name); + importHelper.handleObfImport(tempUri, name + BINARY_MAP_INDEX_EXT); } else if (ZIP_FILE_SIGNATURE == fileSignature) { -// importHelper.handleKmzImport(tempUri, null, save, useImportDir); + importHelper.handleZipImport(tempUri, save, useImportDir); } else if (SQLITE_FILE_SIGNATURE == fileSignature) { String name = createUniqueFileName(app, "online_map", TILES_INDEX_DIR, SQLITE_EXT); - importHelper.handleSqliteTileImport(tempUri, name); + importHelper.handleSqliteTileImport(tempUri, name + SQLITE_EXT); } } else { app.showShortToastMessage(app.getString(R.string.file_import_error, tempFileName, error)); @@ -124,13 +124,13 @@ class UriImportTask extends BaseImportAsyncTask { private String getTempFileName() { if (XML_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT); + return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT) + ROUTING_FILE_EXT; } else if (OBF_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT); + return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT) + BINARY_MAP_INDEX_EXT; } else if (ZIP_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT); + return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT) + ZIP_EXT; } else if (SQLITE_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT); + return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT) + SQLITE_EXT; } return ""; } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java new file mode 100644 index 0000000000..3704f2192b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java @@ -0,0 +1,90 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.plus.importfiles.ImportHelper.ImportType; +import net.osmand.util.Algorithms; + +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static net.osmand.FileUtils.createUniqueFileName; +import static net.osmand.IndexConstants.GPX_FILE_EXT; +import static net.osmand.IndexConstants.GPX_IMPORT_DIR; +import static net.osmand.IndexConstants.GPX_INDEX_DIR; +import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; +import static net.osmand.IndexConstants.TEMP_DIR; +import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; + +public class ZipImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private boolean save; + private boolean useImportDir; + + public ZipImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected ImportType doInBackground(Void... voids) { + ImportType importType = null; + InputStream is = null; + ZipInputStream zis = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + zis = new ZipInputStream(is); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + String fileName = checkEntryName(entry.getName()); + if (fileName.endsWith(KML_SUFFIX)) { + importType = ImportType.KMZ; + break; + } else if (fileName.equals("items.json")) { + importType = ImportType.SETTINGS; + break; + } + } + } + } catch (Exception e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(zis); + } + return importType; + } + + private String checkEntryName(String entryName) { + String fileExt = OSMAND_SETTINGS_FILE_EXT + "/"; + int index = entryName.indexOf(fileExt); + if (index != -1) { + entryName = entryName.substring(index + fileExt.length()); + } + return entryName; + } + + @Override + protected void onPostExecute(ImportType importType) { + hideProgress(); + if (importType == ImportType.KMZ) { + String dir = useImportDir ? GPX_IMPORT_DIR : GPX_INDEX_DIR; + String name = createUniqueFileName(app, "track", dir, GPX_FILE_EXT); + importHelper.handleKmzImport(uri, name + GPX_FILE_EXT, save, useImportDir); + } else if (importType == ImportType.SETTINGS) { + String name = createUniqueFileName(app, "settings", TEMP_DIR, OSMAND_SETTINGS_FILE_EXT); + importHelper.handleOsmAndSettingsImport(uri, name + OSMAND_SETTINGS_FILE_EXT, null, -1, null); + } + } +} \ No newline at end of file From 410144553dc5c1e7d66f6d4c6b1c3047746b14ef Mon Sep 17 00:00:00 2001 From: max-klaus Date: Wed, 7 Oct 2020 11:07:31 +0300 Subject: [PATCH 0536/1366] Fix inapp texts --- OsmAnd/res/values/strings.xml | 2 ++ .../net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java | 3 +++ .../src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java | 3 +++ 3 files changed, 8 insertions(+) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index b58b6d0a1f..619ee52e91 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,8 @@ Thx - Hardy --> + Payment will be charged to your AppGallery account at the confirmation of purchase.\n\nSubscription automatically renews unless it is canceled before the renewal date. Your account will be charged for renewal period(month/three month/year) only on the renewal date.\n\nYou can manage and cancel your subscriptions by going to your AppGallery settings. + Subscription charged per selected period. Cancel it on AppGallery at any time. Thank you for purchasing \'Contour lines\' Start/finish icons Name: A – Z diff --git a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java index c909d50845..9a7215867f 100644 --- a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java @@ -215,6 +215,9 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment if (!TextUtils.isEmpty(getInfoDescription())) { infoDescription.setText(getInfoDescription()); } + TextViewEx planInfoDescription = (TextViewEx) view.findViewById(R.id.plan_info_description); + planInfoDescription.setText(Version.isHuawei(app) + ? R.string.osm_live_payment_subscription_management_hw : R.string.osm_live_payment_subscription_management); ViewGroup osmLiveCard = buildOsmLiveCard(ctx, cardsContainer); if (osmLiveCard != null) { cardsContainer.addView(osmLiveCard); diff --git a/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java b/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java index 788b605eec..43d95c266c 100644 --- a/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java +++ b/OsmAnd/src/net/osmand/plus/chooseplan/OsmLiveCancelledDialog.java @@ -23,6 +23,7 @@ import androidx.fragment.app.FragmentManager; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.Version; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.R; @@ -110,6 +111,8 @@ public class OsmLiveCancelledDialog extends BaseOsmAndDialogFragment implements descr.append("\n").append("— ").append(feature.toHumanString(ctx)); } infoDescr.setText(descr); + TextViewEx inappDescr = (TextViewEx) view.findViewById(R.id.inapp_descr); + inappDescr.setText(Version.isHuawei(app) ? R.string.osm_live_payment_desc_hw : R.string.osm_live_payment_desc); osmLiveButton = view.findViewById(R.id.card_button); From 02dbacf4fe09d48d719c56ed42a0fd524d0044ff Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 7 Oct 2020 12:10:59 +0300 Subject: [PATCH 0537/1366] amenity id --- .../builders/cards/ImageCard.java | 137 ++++++++++++------ .../plus/views/layers/ContextMenuLayer.java | 6 +- .../osmand/plus/views/layers/POIMapLayer.java | 2 +- 3 files changed, 95 insertions(+), 50 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java index c7cf92df0f..84a63cb72a 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java @@ -2,6 +2,7 @@ package net.osmand.plus.mapcontextmenu.builders.cards; import android.content.res.ColorStateList; import android.graphics.Bitmap; +import android.graphics.PointF; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.view.View; @@ -16,9 +17,13 @@ import androidx.appcompat.widget.AppCompatButton; import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities; import net.osmand.Location; import net.osmand.data.Amenity; +import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; +import net.osmand.data.RotatedTileBox; +import net.osmand.osm.PoiType; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -26,6 +31,8 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapillary.MapillaryContributeCard; import net.osmand.plus.mapillary.MapillaryImageCard; +import net.osmand.plus.osmedit.OsmBugsLayer; +import net.osmand.plus.views.layers.ContextMenuLayer; import net.osmand.plus.wikimedia.WikiImageHelper; import net.osmand.util.Algorithms; @@ -43,6 +50,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE; + public abstract class ImageCard extends AbstractCard { public static String TYPE_MAPILLARY_PHOTO = "mapillary-photo"; @@ -411,7 +420,7 @@ public abstract class ImageCard extends AbstractCard { } public GetImageCardsTask(@NonNull MapActivity mapActivity, LatLon latLon, - @Nullable Map params, GetImageCardsListener listener) { + @Nullable Map params, GetImageCardsListener listener) { this.mapActivity = mapActivity; this.app = mapActivity.getMyApplication(); this.latLon = latLon; @@ -422,64 +431,100 @@ public abstract class ImageCard extends AbstractCard { @Override protected List doInBackground(Void... params) { List result = new ArrayList<>(); - try { + RotatedTileBox rtb = mapActivity.getMapView().getCurrentRotatedTileBox(); + Object o = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject(); + if (this.params != null) { + String wikidataId = this.params.get(Amenity.WIKIDATA); + if (wikidataId != null) { + this.params.remove(Amenity.WIKIDATA); + WikiImageHelper.addWikidataImageCards(mapActivity, wikidataId, result); + } + String wikimediaContent = this.params.get(Amenity.WIKIMEDIA_COMMONS); + if (wikimediaContent != null) { + this.params.remove(Amenity.WIKIMEDIA_COMMONS); + WikiImageHelper.addWikimediaImageCards(mapActivity, wikimediaContent, result); + } + } + if (o instanceof Amenity) { + Amenity am = (Amenity) o; + System.out.println("POINT OSM ID: " + am.getId() + " " + am.getType().ordinal()); final Map pms = new LinkedHashMap<>(); - pms.put("lat", "" + (float) latLon.getLatitude()); - pms.put("lon", "" + (float) latLon.getLongitude()); - Location myLocation = app.getLocationProvider().getLastKnownLocation(); - if (myLocation != null) { - pms.put("mloc", "" + (float) myLocation.getLatitude() + "," + (float) myLocation.getLongitude()); - } - pms.put("app", Version.isPaidVersion(app) ? "paid" : "free"); - String preferredLang = app.getSettings().MAP_PREFERRED_LOCALE.get(); - if (Algorithms.isEmpty(preferredLang)) { - preferredLang = app.getLanguage(); - } - if (!Algorithms.isEmpty(preferredLang)) { - pms.put("lang", preferredLang); - } - if (this.params != null) { - String wikidataId = this.params.get(Amenity.WIKIDATA); - if (wikidataId != null) { - this.params.remove(Amenity.WIKIDATA); - WikiImageHelper.addWikidataImageCards(mapActivity, wikidataId, result); - } - String wikimediaContent = this.params.get(Amenity.WIKIMEDIA_COMMONS); - if (wikimediaContent != null) { - this.params.remove(Amenity.WIKIMEDIA_COMMONS); - WikiImageHelper.addWikimediaImageCards(mapActivity, wikimediaContent, result); - } - pms.putAll(this.params); - } + pms.put("osmid", "" + am.getId()); String response = AndroidNetworkUtils.sendRequest(app, "https://osmand.net/api/cm_place", pms, "Requesting location images...", false, false); if (!Algorithms.isEmpty(response)) { - JSONObject obj = new JSONObject(response); - JSONArray images = obj.getJSONArray("features"); - if (images.length() > 0) { - for (int i = 0; i < images.length(); i++) { - try { - JSONObject imageObject = (JSONObject) images.get(i); - if (imageObject != JSONObject.NULL) { - ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); - if (imageCard != null) { - result.add(imageCard); + JSONObject obj = null; + try { + obj = new JSONObject(response); + JSONArray images = null; + images = obj.getJSONArray("features"); + if (images.length() > 0) { + for (int i = 0; i < images.length(); i++) { + try { + JSONObject imageObject = (JSONObject) images.get(i); + if (imageObject != JSONObject.NULL) { + ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); + if (imageCard != null) { + result.add(imageCard); + } } + } catch (JSONException e) { + e.printStackTrace(); } - } catch (JSONException e) { - e.printStackTrace(); } } + } catch (JSONException e) { + e.printStackTrace(); } } - } catch (Exception e) { - e.printStackTrace(); - } - if (listener != null) { - listener.onPostProcess(result); } return result; +// try { +// final Map pms = new LinkedHashMap<>(); +// pms.put("lat", "" + (float) latLon.getLatitude()); +// pms.put("lon", "" + (float) latLon.getLongitude()); +// Location myLocation = app.getLocationProvider().getLastKnownLocation(); +// if (myLocation != null) { +// pms.put("mloc", "" + (float) myLocation.getLatitude() + "," + (float) myLocation.getLongitude()); +// } +// pms.put("app", Version.isPaidVersion(app) ? "paid" : "free"); +// String preferredLang = app.getSettings().MAP_PREFERRED_LOCALE.get(); +// if (Algorithms.isEmpty(preferredLang)) { +// preferredLang = app.getLanguage(); +// } +// if (!Algorithms.isEmpty(preferredLang)) { +// pms.put("lang", preferredLang); +// } +// String response = AndroidNetworkUtils.sendRequest(app, "https://osmand.net/api/cm_place", pms, +// "Requesting location images...", false, false); +// +// if (!Algorithms.isEmpty(response)) { +// JSONObject obj = new JSONObject(response); +// JSONArray images = obj.getJSONArray("features"); +// if (images.length() > 0) { +// for (int i = 0; i < images.length(); i++) { +// try { +// JSONObject imageObject = (JSONObject) images.get(i); +// if (imageObject != JSONObject.NULL) { +// ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); +// if (imageCard != null) { +// result.add(imageCard); +// } +// } +// } catch (JSONException e) { +// e.printStackTrace(); +// } +// } +// } +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// if (listener != null) { +// listener.onPostProcess(result); +// } +// return result; } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java index 7a8690fe2d..2902794ee8 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java @@ -907,9 +907,9 @@ public class ContextMenuLayer extends OsmandMapLayer { } @NonNull - private Map selectObjectsForContextMenu(RotatedTileBox tileBox, - PointF point, boolean acquireObjLatLon, - boolean unknownLocation) { + public Map selectObjectsForContextMenu(RotatedTileBox tileBox, + PointF point, boolean acquireObjLatLon, + boolean unknownLocation) { Map pressedLatLonFull = new HashMap<>(); Map pressedLatLonSmall = new HashMap<>(); Map selectedObjects = new HashMap<>(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java index ed0f2cc45d..d01ec310a9 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java @@ -66,7 +66,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon /// cache for displayed POI // Work with cache (for map copied from AmenityIndexRepositoryOdb) - private MapLayerData> data; + public MapLayerData> data; private OsmandApplication app; From 5cdc7da1fa84ae2d64c8e68e5b04615868a3e2b6 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 7 Oct 2020 12:20:16 +0300 Subject: [PATCH 0538/1366] Fix #9927 Prefer route parameter --- .../plus/settings/fragments/RouteParametersFragment.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java index 198e6e13eb..cfd6874d89 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java @@ -216,8 +216,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP } if (preferParameters.size() > 0) { String title = getString(R.string.prefer_in_routing_title); - String descr = getString(R.string.prefer_in_routing_descr); - MultiSelectBooleanPreference preferRouting = createRoutingBooleanMultiSelectPref(PREFER_ROUTING_PARAMETER_PREFIX, title, descr, preferParameters); + MultiSelectBooleanPreference preferRouting = createRoutingBooleanMultiSelectPref(PREFER_ROUTING_PARAMETER_PREFIX, title, "", preferParameters); screen.addPreference(preferRouting); } if (reliefFactorParameters.size() > 0) { From 8a51ac185b775967f1e448a951b6af3f32a338e3 Mon Sep 17 00:00:00 2001 From: sergosm Date: Wed, 7 Oct 2020 13:27:19 +0300 Subject: [PATCH 0539/1366] Fix #9498 Details, Configure Map, Route Parameters: add support for multiline text --- OsmAnd/res/layout/bottom_sheet_item_with_switch.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml b/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml index 955c2937b2..c7544da1dd 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml @@ -28,7 +28,7 @@ android:layout_marginRight="@dimen/content_padding" android:layout_weight="1" android:ellipsize="end" - android:maxLines="1" + android:maxLines="2" android:textAppearance="@style/TextAppearance.ListItemTitle" tools:text="Some Title"/> From b201f147aca39dccdfdbaa9561f5afdd3c23fa16 Mon Sep 17 00:00:00 2001 From: Alexander Sytnyk Date: Wed, 7 Oct 2020 14:23:34 +0300 Subject: [PATCH 0540/1366] #9621 Add validation for the online tracking link --- .../main/java/net/osmand/util/Algorithms.java | 16 ++++++++++++++ .../plus/monitoring/LiveMonitoringHelper.java | 16 +++++++++----- .../SettingsMonitoringActivity.java | 21 ++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index ea2869aaa3..a1e721ac21 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -942,4 +942,20 @@ public class Algorithms { } return res; } + + public static boolean isValidMessageFormat(CharSequence sequence) { + if (!isEmpty(sequence)) { + int counter = 0; + for (int i = 0; i < sequence.length(); i++) { + char ch = sequence.charAt(i); + if (ch == '{') { + counter++; + } else if (ch == '}') { + counter--; + } + } + return counter == 0; + } + return false; + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/monitoring/LiveMonitoringHelper.java b/OsmAnd/src/net/osmand/plus/monitoring/LiveMonitoringHelper.java index 169507b35a..9ec8a3081c 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/LiveMonitoringHelper.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/LiveMonitoringHelper.java @@ -131,7 +131,14 @@ public class LiveMonitoringHelper { } public void sendData(LiveMonitoringData data) { - String urlStr = getLiveUrl(data); + String baseUrl = app.getSettings().LIVE_MONITORING_URL.get(); + String urlStr; + try { + urlStr = getLiveUrl(baseUrl, data); + } catch (IllegalArgumentException e) { + log.error("Could not construct live url from base url: " + baseUrl, e); + return; + } try { // Parse the URL and let the URI constructor handle proper encoding of special characters such as spaces URL url = new URL(urlStr); @@ -172,12 +179,11 @@ public class LiveMonitoringHelper { } } - private String getLiveUrl(LiveMonitoringData data) { - String st = app.getSettings().LIVE_MONITORING_URL.get(); + private String getLiveUrl(String baseUrl, LiveMonitoringData data) { List prm = new ArrayList(); int maxLen = 0; for (int i = 0; i < 7; i++) { - boolean b = st.contains("{"+i+"}"); + boolean b = baseUrl.contains("{"+i+"}"); if(b) { maxLen = i; } @@ -210,6 +216,6 @@ public class LiveMonitoringHelper { break; } } - return MessageFormat.format(st, prm.toArray()); + return MessageFormat.format(baseUrl, prm.toArray()); } } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java b/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java index d048bbedd5..7ace6377ad 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/SettingsMonitoringActivity.java @@ -8,6 +8,7 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; @@ -23,11 +24,11 @@ import android.view.Window; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndTaskManager.OsmAndTaskRunnable; import net.osmand.plus.OsmandApplication; @@ -35,6 +36,8 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SettingsBaseActivity; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.util.Algorithms; import java.util.Map; @@ -172,8 +175,20 @@ public class SettingsMonitoringActivity extends SettingsBaseActivity { cat.setTitle(R.string.live_monitoring_m); grp.addPreference(cat); - cat.addPreference(createEditTextPreference(settings.LIVE_MONITORING_URL, R.string.live_monitoring_url, - R.string.live_monitoring_url_descr)); + EditTextPreference urlPreference = createEditTextPreference(settings.LIVE_MONITORING_URL, R.string.live_monitoring_url, + R.string.live_monitoring_url_descr); + urlPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (Algorithms.isValidMessageFormat((String) newValue)) { + return SettingsMonitoringActivity.super.onPreferenceChange(preference, newValue); + } else { + Toast.makeText(SettingsMonitoringActivity.this, R.string.wrong_format, Toast.LENGTH_SHORT).show(); + return false; + } + } + }); + cat.addPreference(urlPreference); final CheckBoxPreference liveMonitoring = createCheckBoxPreference(settings.LIVE_MONITORING, R.string.live_monitoring_m, R.string.live_monitoring_m_descr); cat.addPreference(liveMonitoring); From 1876a1d12f01be695f40c575fe78520c1c2e5b69 Mon Sep 17 00:00:00 2001 From: sergosm Date: Wed, 7 Oct 2020 14:27:13 +0300 Subject: [PATCH 0541/1366] 4 lines restriction --- OsmAnd/res/layout/bottom_sheet_item_with_switch.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml b/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml index c7544da1dd..53b21954ee 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_switch.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="@dimen/bottom_sheet_list_item_height" + android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" android:gravity="center_vertical" android:minHeight="@dimen/bottom_sheet_list_item_height" @@ -28,7 +28,7 @@ android:layout_marginRight="@dimen/content_padding" android:layout_weight="1" android:ellipsize="end" - android:maxLines="2" + android:maxLines="4" android:textAppearance="@style/TextAppearance.ListItemTitle" tools:text="Some Title"/> From 9472f6306d7342976f30746fd194ff758491a3c2 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 7 Oct 2020 15:25:14 +0300 Subject: [PATCH 0542/1366] refactor fix build --- OsmAnd/res/xml/configure_profile.xml | 4 +- OsmAnd/res/xml/general_profile_settings.xml | 2 +- OsmAnd/res/xml/global_settings.xml | 4 +- OsmAnd/res/xml/navigation_settings_new.xml | 6 +- OsmAnd/res/xml/settings_main_screen.xml | 6 +- .../osmand/plus/AppVersionUpgradeOnInit.java | 100 +++++++----------- .../BooleanAccessibilityPreference.java | 13 +-- .../settings/backend/BooleanPreference.java | 6 +- .../settings/backend/CommonPreference.java | 17 ++- .../backend/ContextMenuItemsPreference.java | 10 +- .../backend/ContextMenuItemsSettings.java | 9 +- .../backend/EnumStringPreference.java | 16 +-- .../settings/backend/FloatPreference.java | 12 +-- .../backend/ImpassableRoadsStorage.java | 11 +- .../plus/settings/backend/IntPreference.java | 12 +-- .../backend/IntermediatePointsStorage.java | 6 +- .../backend/ListStringPreference.java | 16 ++- .../plus/settings/backend/LongPreference.java | 12 +-- .../backend/OsmAndPreferencesDataStore.java | 20 ++-- .../plus/settings/backend/OsmandSettings.java | 86 +++++++++++---- .../plus/settings/backend/SettingsHelper.java | 14 +-- .../backend/SettingsMapPointsStorage.java | 23 ++-- .../settings/backend/StringPreference.java | 11 +- 23 files changed, 216 insertions(+), 200 deletions(-) diff --git a/OsmAnd/res/xml/configure_profile.xml b/OsmAnd/res/xml/configure_profile.xml index d86a80620f..9fb131486e 100644 --- a/OsmAnd/res/xml/configure_profile.xml +++ b/OsmAnd/res/xml/configure_profile.xml @@ -16,7 +16,7 @@ android:persistent="false" android:summary="@string/general_settings_profile_descr" android:title="@string/general_settings_2" - app:fragment="net.osmand.plus.settings.GeneralProfileSettingsFragment" + app:fragment="net.osmand.plus.settings.fragments.GeneralProfileSettingsFragment" tools:icon="@drawable/ic_action_settings" /> + app:fragment="net.osmand.plus.settings.fragments.CoordinatesFormatFragment" /> + app:fragment="net.osmand.plus.settings.fragments.MapDuringNavigationFragment" /> globalPrefsMap = globalSharedPreferences.getAll(); for (String key : globalPrefsMap.keySet()) { - OsmandPreference pref = getPreference(key); + OsmandPreference pref = settings.getPreference(key); if (pref instanceof CommonPreference) { - CommonPreference commonPreference = (CommonPreference) pref; - if (!commonPreference.global) { + CommonPreference commonPreference = (CommonPreference) pref; + if (!commonPreference.isGlobal()) { for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { if (!commonPreference.isSetForMode(mode) && !commonPreference.hasDefaultValueForMode(mode)) { - setPreference(key, globalPrefsMap.get(key), mode); + settings.setPreference(key, globalPrefsMap.get(key), mode); } } } } } - SharedPreferences defaultProfilePreferences = (SharedPreferences) getProfilePreferences(ApplicationMode.DEFAULT); + SharedPreferences defaultProfilePreferences = (SharedPreferences) settings.getProfilePreferences(ApplicationMode.DEFAULT); Map defaultPrefsMap = defaultProfilePreferences.getAll(); for (String key : defaultPrefsMap.keySet()) { - OsmandPreference pref = getPreference(key); + OsmandPreference pref = settings.getPreference(key); if (pref instanceof CommonPreference) { - CommonPreference commonPreference = (CommonPreference) pref; - if (commonPreference.global && !commonPreference.isSet()) { - setPreference(key, defaultPrefsMap.get(key)); + CommonPreference commonPreference = (CommonPreference) pref; + if (commonPreference.isGlobal() && !commonPreference.isSet()) { + settings.setPreference(key, defaultPrefsMap.get(key)); } } } - for (OsmandPreference pref : generalPrefs) { + for (OsmandPreference pref : settings.getGeneralPrefs()) { if (pref instanceof CommonPreference) { - CommonPreference commonPref = (CommonPreference) pref; + CommonPreference commonPref = (CommonPreference) pref; Object defaultVal = commonPref.getModeValue(ApplicationMode.DEFAULT); for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { if (!commonPref.isSetForMode(mode) && !commonPref.hasDefaultValueForMode(mode)) { - setPreference(commonPref.getId(), defaultVal, mode); + settings.setPreference(commonPref.getId(), defaultVal, mode); } } } } - String json = settingsAPI.getString(globalPreferences, "custom_app_profiles", ""); + String json = settings.getSettingsAPI().getString(settings.getGlobalPreferences(), "custom_app_profiles", ""); if (!Algorithms.isEmpty(json)) { Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); Type t = new TypeToken>() { @@ -252,22 +226,22 @@ class AppVersionUpgradeOnInit { List customProfiles = gson.fromJson(json, t); if (!Algorithms.isEmpty(customProfiles)) { for (ApplicationMode.ApplicationModeBean modeBean : customProfiles) { - ApplicationMode.ApplicationModeBuilder builder = ApplicationMode.fromModeBean(ctx, modeBean); - ApplicationMode.saveProfile(builder, ctx); + ApplicationMode.ApplicationModeBuilder builder = ApplicationMode.fromModeBean(app, modeBean); + ApplicationMode.saveProfile(builder, app); } } } } public void migrateEnumPreferences() { - for (OsmandPreference pref : registeredPreferences.values()) { + for (OsmandPreference pref : settings.getRegisteredPreferences().values()) { if (pref instanceof EnumStringPreference) { EnumStringPreference enumPref = (EnumStringPreference) pref; if (enumPref.isGlobal()) { - migrateEnumPref(enumPref, (SharedPreferences) globalPreferences); + migrateEnumPref(enumPref, (SharedPreferences) settings.getGlobalPreferences()); } else { for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { - migrateEnumPref(enumPref, (SharedPreferences) getProfilePreferences(mode)); + migrateEnumPref(enumPref, (SharedPreferences) settings.getProfilePreferences(mode)); } } } @@ -278,15 +252,17 @@ class AppVersionUpgradeOnInit { Object value = sharedPreferences.getAll().get(enumPref.getId()); if (value instanceof Integer) { int enumIndex = (int) value; - if (enumIndex >= 0 && enumIndex < enumPref.values.length) { - Enum savedValue = enumPref.values[enumIndex]; + if (enumIndex >= 0 && enumIndex < enumPref.getValues().length) { + Enum savedValue = enumPref.getValues()[enumIndex]; enumPref.setValue(sharedPreferences, savedValue); } } } public void migrateHomeWorkParkingToFavorites() { - FavouritesDbHelper favorites = ctx.getFavorites(); + FavouritesDbHelper favorites = app.getFavorites(); + SettingsAPI settingsAPI = settings.getSettingsAPI(); + Object globalPreferences= settings.getGlobalPreferences(); LatLon homePoint = null; float lat = settingsAPI.getFloat(globalPreferences, "home_point_lat", 0); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java index 7a796b6a6a..c376b6a99a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java @@ -4,30 +4,27 @@ import net.osmand.plus.ApplicationMode; class BooleanAccessibilityPreference extends BooleanPreference { - private OsmandSettings osmandSettings; - BooleanAccessibilityPreference(OsmandSettings osmandSettings, String id, boolean defaultValue) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); } @Override public Boolean get() { - return osmandSettings.ctx.accessibilityEnabled() ? super.get() : getDefaultValue(); + return getContext().accessibilityEnabled() ? super.get() : getDefaultValue(); } @Override public Boolean getModeValue(ApplicationMode mode) { - return osmandSettings.ctx.accessibilityEnabledForMode(mode) ? super.getModeValue(mode) : getDefaultValue(); + return getContext().accessibilityEnabledForMode(mode) ? super.getModeValue(mode) : getDefaultValue(); } @Override public boolean set(Boolean obj) { - return osmandSettings.ctx.accessibilityEnabled() && super.set(obj); + return getContext().accessibilityEnabled() && super.set(obj); } @Override public boolean setModeValue(ApplicationMode mode, Boolean obj) { - return osmandSettings.ctx.accessibilityEnabledForMode(mode) && super.setModeValue(mode, obj); + return getContext().accessibilityEnabledForMode(mode) && super.setModeValue(mode, obj); } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java index 3a1c0cd363..9a0c2a2391 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java @@ -7,13 +7,13 @@ public class BooleanPreference extends CommonPreference { } @Override - protected Boolean getValue(Object prefs, Boolean defaultValue) { - return osmandSettings.settingsAPI.getBoolean(prefs, getId(), defaultValue); + public Boolean getValue(Object prefs, Boolean defaultValue) { + return getSettingsAPI().getBoolean(prefs, getId(), defaultValue); } @Override protected boolean setValue(Object prefs, Boolean val) { - return osmandSettings.settingsAPI.edit(prefs).putBoolean(getId(), val).commit(); + return getSettingsAPI().edit(prefs).putBoolean(getId(), val).commit(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java index 4e1e69f1b4..0a53139dc1 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java @@ -1,6 +1,8 @@ package net.osmand.plus.settings.backend; import net.osmand.plus.ApplicationMode; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.api.SettingsAPI; import org.json.JSONException; import org.json.JSONObject; @@ -27,16 +29,27 @@ public abstract class CommonPreference extends PreferenceWithListener { } // Methods to possibly override - protected abstract T getValue(Object prefs, T defaultValue); + public abstract T getValue(Object prefs, T defaultValue); protected abstract boolean setValue(Object prefs, T val); public abstract T parseString(String s); protected String toString(T o) { - return o == null ? null : o.toString(); + return o == null ? null : o.toString(); } + protected SettingsAPI getSettingsAPI() { + return osmandSettings.getSettingsAPI(); + } + + protected ApplicationMode getApplicationMode() { + return osmandSettings.getApplicationMode(); + } + + protected OsmandApplication getContext() { + return osmandSettings.getContext(); + } // common methods diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java index a671d6141b..4e562f1aca 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java @@ -3,25 +3,23 @@ package net.osmand.plus.settings.backend; import androidx.annotation.NonNull; public class ContextMenuItemsPreference extends CommonPreference { - private OsmandSettings osmandSettings; @NonNull private String idScheme; ContextMenuItemsPreference(OsmandSettings osmandSettings, String id, @NonNull String idScheme, @NonNull ContextMenuItemsSettings defValue) { - super(id, defValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defValue); this.idScheme = idScheme; } @Override - protected ContextMenuItemsSettings getValue(Object prefs, ContextMenuItemsSettings defaultValue) { - String s = osmandSettings.settingsAPI.getString(prefs, getId(), ""); + public ContextMenuItemsSettings getValue(Object prefs, ContextMenuItemsSettings defaultValue) { + String s = getSettingsAPI().getString(prefs, getId(), ""); return readValue(s); } @Override protected boolean setValue(Object prefs, ContextMenuItemsSettings val) { - return osmandSettings.settingsAPI.edit(prefs).putString(getId(), val.writeToJsonString(idScheme)).commit(); + return getSettingsAPI().edit(prefs).putString(getId(), val.writeToJsonString(idScheme)).commit(); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java index 85046ba00a..822840a60e 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsSettings.java @@ -1,7 +1,9 @@ package net.osmand.plus.settings.backend; +import net.osmand.PlatformUtil; import net.osmand.util.Algorithms; +import org.apache.commons.logging.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -14,6 +16,9 @@ import java.util.List; import androidx.annotation.NonNull; public class ContextMenuItemsSettings implements Serializable { + + private static final Log LOG = PlatformUtil.getLog(ContextMenuItemsSettings.class.getName()); + private static final String HIDDEN = "hidden"; private static final String ORDER = "order"; private List hiddenIds = new ArrayList<>(); @@ -40,7 +45,7 @@ public class ContextMenuItemsSettings implements Serializable { JSONObject json = new JSONObject(jsonString); readFromJson(json, idScheme); } catch (JSONException e) { - OsmandSettings.LOG.error("Error converting to json string: " + e); + LOG.error("Error converting to json string: " + e); } } @@ -66,7 +71,7 @@ public class ContextMenuItemsSettings implements Serializable { writeToJson(json, idScheme); return json.toString(); } catch (JSONException e) { - OsmandSettings.LOG.error("Error converting to json string: " + e); + LOG.error("Error converting to json string: " + e); } return ""; } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java index d8d01e4091..5d03d3e556 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java @@ -2,19 +2,17 @@ package net.osmand.plus.settings.backend; public class EnumStringPreference> extends CommonPreference { - private OsmandSettings osmandSettings; private final E[] values; EnumStringPreference(OsmandSettings osmandSettings, String id, E defaultValue, E[] values) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); this.values = values; } @Override - protected E getValue(Object prefs, E defaultValue) { + public E getValue(Object prefs, E defaultValue) { try { - String name = osmandSettings.settingsAPI.getString(prefs, getId(), defaultValue.name()); + String name = getSettingsAPI().getString(prefs, getId(), defaultValue.name()); E value = parseString(name); return value != null ? value : defaultValue; } catch (ClassCastException ex) { @@ -24,8 +22,8 @@ public class EnumStringPreference> extends CommonPreference } @Override - protected boolean setValue(Object prefs, E val) { - return osmandSettings.settingsAPI.edit(prefs).putString(getId(), val.name()).commit(); + public boolean setValue(Object prefs, E val) { + return getSettingsAPI().edit(prefs).putString(getId(), val.name()).commit(); } @Override @@ -42,4 +40,8 @@ public class EnumStringPreference> extends CommonPreference } return null; } + + public E[] getValues() { + return values; + } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java index 9c10a314f9..47ee4a24bd 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/FloatPreference.java @@ -2,22 +2,18 @@ package net.osmand.plus.settings.backend; public class FloatPreference extends CommonPreference { - - private OsmandSettings osmandSettings; - FloatPreference(OsmandSettings osmandSettings, String id, float defaultValue) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); } @Override - protected Float getValue(Object prefs, Float defaultValue) { - return osmandSettings.settingsAPI.getFloat(prefs, getId(), defaultValue); + public Float getValue(Object prefs, Float defaultValue) { + return getSettingsAPI().getFloat(prefs, getId(), defaultValue); } @Override protected boolean setValue(Object prefs, Float val) { - return osmandSettings.settingsAPI.edit(prefs).putFloat(getId(), val).commit(); + return getSettingsAPI().edit(prefs).putFloat(getId(), val).commit(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java index dacadbf149..1f890766c2 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java @@ -11,12 +11,11 @@ import java.util.StringTokenizer; class ImpassableRoadsStorage extends SettingsMapPointsStorage { - private OsmandSettings osmandSettings; protected String roadsIdsKey; protected String appModeKey; public ImpassableRoadsStorage(OsmandSettings osmandSettings) { - this.osmandSettings = osmandSettings; + super(osmandSettings); pointsKey = OsmandSettings.IMPASSABLE_ROAD_POINTS; descriptionsKey = OsmandSettings.IMPASSABLE_ROADS_DESCRIPTIONS; roadsIdsKey = OsmandSettings.IMPASSABLE_ROADS_IDS; @@ -25,7 +24,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public List getRoadIds(int size) { List list = new ArrayList<>(); - String roadIds = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, roadsIdsKey, ""); + String roadIds = getSettingsAPI().getString(getOsmandSettings().globalPreferences, roadsIdsKey, ""); if (roadIds.trim().length() > 0) { StringTokenizer tok = new StringTokenizer(roadIds, ","); while (tok.hasMoreTokens() && list.size() <= size) { @@ -40,7 +39,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public List getAppModeKeys(int size) { List list = new ArrayList<>(); - String roadIds = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, appModeKey, ""); + String roadIds = getSettingsAPI().getString(getOsmandSettings().globalPreferences, appModeKey, ""); if (roadIds.trim().length() > 0) { StringTokenizer tok = new StringTokenizer(roadIds, ","); while (tok.hasMoreTokens() && list.size() <= size) { @@ -173,7 +172,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { stringBuilder.append(","); } } - return osmandSettings.settingsAPI.edit(osmandSettings.globalPreferences) + return getSettingsAPI().edit(getOsmandSettings().globalPreferences) .putString(roadsIdsKey, stringBuilder.toString()) .commit(); } @@ -187,7 +186,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { stringBuilder.append(","); } } - return osmandSettings.settingsAPI.edit(osmandSettings.globalPreferences) + return getSettingsAPI().edit(getOsmandSettings().globalPreferences) .putString(appModeKey, stringBuilder.toString()) .commit(); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java index 3c040821b9..92e0b9071c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/IntPreference.java @@ -2,22 +2,18 @@ package net.osmand.plus.settings.backend; class IntPreference extends CommonPreference { - - private OsmandSettings osmandSettings; - IntPreference(OsmandSettings osmandSettings, String id, int defaultValue) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); } @Override - protected Integer getValue(Object prefs, Integer defaultValue) { - return osmandSettings.settingsAPI.getInt(prefs, getId(), defaultValue); + public Integer getValue(Object prefs, Integer defaultValue) { + return getSettingsAPI().getInt(prefs, getId(), defaultValue); } @Override protected boolean setValue(Object prefs, Integer val) { - return osmandSettings.settingsAPI.edit(prefs).putInt(getId(), val).commit(); + return getSettingsAPI().edit(prefs).putInt(getId(), val).commit(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java index aaf90f0efd..c420036da0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/IntermediatePointsStorage.java @@ -6,10 +6,8 @@ import java.util.List; class IntermediatePointsStorage extends SettingsMapPointsStorage { - private OsmandSettings osmandSettings; - public IntermediatePointsStorage(OsmandSettings osmandSettings) { - this.osmandSettings = osmandSettings; + super(osmandSettings); pointsKey = OsmandSettings.INTERMEDIATE_POINTS; descriptionsKey = OsmandSettings.INTERMEDIATE_POINTS_DESCRIPTION; } @@ -17,7 +15,7 @@ class IntermediatePointsStorage extends SettingsMapPointsStorage { @Override public boolean savePoints(List ps, List ds) { boolean res = super.savePoints(ps, ds); - osmandSettings.backupTargetPoints(); + getOsmandSettings().backupTargetPoints(); return res; } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java index 81b7a01f60..ff611593cc 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java @@ -8,17 +8,15 @@ import java.util.List; public class ListStringPreference extends StringPreference { - private OsmandSettings osmandSettings; private String delimiter; ListStringPreference(OsmandSettings osmandSettings, String id, String defaultValue, String delimiter) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); this.delimiter = delimiter; } public boolean addValue(String res) { - return addModeValue(osmandSettings.getApplicationMode(), res); + return addModeValue(getApplicationMode(), res); } public boolean addModeValue(ApplicationMode appMode, String res) { @@ -33,7 +31,7 @@ public class ListStringPreference extends StringPreference { } public void clearAll() { - clearAllForProfile(osmandSettings.getApplicationMode()); + clearAllForProfile(getApplicationMode()); } public void clearAllForProfile(ApplicationMode appMode) { @@ -41,7 +39,7 @@ public class ListStringPreference extends StringPreference { } public boolean containsValue(String res) { - return containsValue(osmandSettings.getApplicationMode(), res); + return containsValue(getApplicationMode(), res); } public boolean containsValue(ApplicationMode appMode, String res) { @@ -51,7 +49,7 @@ public class ListStringPreference extends StringPreference { } public boolean removeValue(String res) { - return removeValueForProfile(osmandSettings.getApplicationMode(), res); + return removeValueForProfile(getApplicationMode(), res); } public boolean removeValueForProfile(ApplicationMode appMode, String res) { @@ -75,7 +73,7 @@ public class ListStringPreference extends StringPreference { } public List getStringsList() { - return getStringsListForProfile(osmandSettings.getApplicationMode()); + return getStringsListForProfile(getApplicationMode()); } public List getStringsListForProfile(ApplicationMode appMode) { @@ -93,7 +91,7 @@ public class ListStringPreference extends StringPreference { } public void setStringsList(List values) { - setStringsListForProfile(osmandSettings.getApplicationMode(), values); + setStringsListForProfile(getApplicationMode(), values); } public void setStringsListForProfile(ApplicationMode appMode, List values) { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java index 8993919e23..f36d8368a3 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/LongPreference.java @@ -2,22 +2,18 @@ package net.osmand.plus.settings.backend; class LongPreference extends CommonPreference { - - private OsmandSettings osmandSettings; - LongPreference(OsmandSettings osmandSettings, String id, long defaultValue) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); } @Override - protected Long getValue(Object prefs, Long defaultValue) { - return osmandSettings.settingsAPI.getLong(prefs, getId(), defaultValue); + public Long getValue(Object prefs, Long defaultValue) { + return getSettingsAPI().getLong(prefs, getId(), defaultValue); } @Override protected boolean setValue(Object prefs, Long val) { - return osmandSettings.settingsAPI.edit(prefs).putLong(getId(), val).commit(); + return getSettingsAPI().edit(prefs).putLong(getId(), val).commit(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java index 0a6f464b77..d4eaf070f2 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java @@ -55,7 +55,7 @@ public class OsmAndPreferencesDataStore extends PreferenceDataStore { @Nullable @Override public String getString(String key, @Nullable String defValue) { - OsmandPreference preference = osmandSettings.getPreference(key); + OsmandPreference preference = osmandSettings.getPreference(key); if (preference instanceof StringPreference) { return ((StringPreference) preference).getModeValue(appMode); } else { @@ -75,25 +75,25 @@ public class OsmAndPreferencesDataStore extends PreferenceDataStore { @Override public int getInt(String key, int defValue) { - OsmandPreference preference = osmandSettings.getPreference(key); - if (preference instanceof OsmandSettings.IntPreference) { - return ((OsmandSettings.IntPreference) preference).getModeValue(appMode); + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof IntPreference) { + return ((IntPreference) preference).getModeValue(appMode); } return defValue; } @Override public long getLong(String key, long defValue) { - OsmandPreference preference = osmandSettings.getPreference(key); - if (preference instanceof OsmandSettings.LongPreference) { - return ((OsmandSettings.LongPreference) preference).getModeValue(appMode); + OsmandPreference preference = osmandSettings.getPreference(key); + if (preference instanceof LongPreference) { + return ((LongPreference) preference).getModeValue(appMode); } return defValue; } @Override public float getFloat(String key, float defValue) { - OsmandPreference preference = osmandSettings.getPreference(key); + OsmandPreference preference = osmandSettings.getPreference(key); if (preference instanceof FloatPreference) { return ((FloatPreference) preference).getModeValue(appMode); } @@ -102,7 +102,7 @@ public class OsmAndPreferencesDataStore extends PreferenceDataStore { @Override public boolean getBoolean(String key, boolean defValue) { - OsmandPreference preference = osmandSettings.getPreference(key); + OsmandPreference preference = osmandSettings.getPreference(key); if (preference instanceof BooleanPreference) { return ((BooleanPreference) preference).getModeValue(appMode); } @@ -111,7 +111,7 @@ public class OsmAndPreferencesDataStore extends PreferenceDataStore { @Nullable public Object getValue(String key, Object defValue) { - OsmandPreference preference = osmandSettings.getPreference(key); + OsmandPreference preference = osmandSettings.getPreference(key); if (preference != null) { return preference.getModeValue(appMode); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 523caf7866..3a9cd36219 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -113,14 +113,13 @@ public class OsmandSettings { private boolean editObjectToShow; private String searchRequestToShow; - - protected OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI) { + public OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI) { ctx = clientContext; this.settingsAPI = settinsAPI; initPrefs(); } - protected OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI, String sharedPreferencesName) { + public OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI, String sharedPreferencesName) { ctx = clientContext; this.settingsAPI = settinsAPI; CUSTOM_SHARED_PREFERENCES_NAME = CUSTOM_SHARED_PREFERENCES_PREFIX + sharedPreferencesName; @@ -196,7 +195,7 @@ public class OsmandSettings { return settingsAPI.getPreferenceObject(getSharedPreferencesNameForKey(modeKey)); } - public OsmandPreference getPreference(String key) { + public OsmandPreference getPreference(String key) { return registeredPreferences.get(key); } @@ -301,7 +300,7 @@ public class OsmandSettings { } else if (preference instanceof EnumStringPreference) { EnumStringPreference enumPref = (EnumStringPreference) preference; if (value instanceof String) { - Enum enumValue = enumPref.parseString((String) value); + Enum enumValue = enumPref.parseString((String) value); if (enumValue != null) { return enumPref.setModeValue(mode, enumValue); } @@ -310,8 +309,8 @@ public class OsmandSettings { return enumPref.setModeValue(mode, value); } else if (value instanceof Integer) { int newVal = (Integer) value; - if (enumPref.values.length > newVal) { - Enum enumValue = enumPref.values[newVal]; + if (enumPref.getValues().length > newVal) { + Enum enumValue = enumPref.getValues()[newVal]; return enumPref.setModeValue(mode, enumValue); } return false; @@ -358,7 +357,7 @@ public class OsmandSettings { } private boolean prefCanBeCopiedOrReset(OsmandPreference pref) { - return pref instanceof CommonPreference && !((CommonPreference) pref).global + return pref instanceof CommonPreference && !((CommonPreference) pref).isGlobal() && !APP_MODE_ORDER.getId().equals(pref.getId()); } @@ -412,7 +411,7 @@ public class OsmandSettings { OsmandAidlApi aidlApi = ctx.getAidlApi(); if (aidlApi != null) { - ctx.poiFilters.loadSelectedPoiFilters(); + ctx.getPoiFilters().loadSelectedPoiFilters(); } fireEvent(oldMode); @@ -728,13 +727,13 @@ public class OsmandSettings { public final OsmandPreference DEFAULT_APPLICATION_MODE = new CommonPreference(this, "default_application_mode_string", ApplicationMode.DEFAULT) { @Override - protected ApplicationMode getValue(Object prefs, ApplicationMode defaultValue) { + public ApplicationMode getValue(Object prefs, ApplicationMode defaultValue) { String key = settingsAPI.getString(prefs, getId(), defaultValue.getStringKey()); return ApplicationMode.valueOfStringKey(key, defaultValue); } @Override - protected boolean setValue(Object prefs, ApplicationMode val) { + public boolean setValue(Object prefs, ApplicationMode val) { boolean valueSaved = settingsAPI.edit(prefs).putString(getId(), val.getStringKey()).commit(); if (valueSaved) { APPLICATION_MODE.set(val); @@ -774,13 +773,13 @@ public class OsmandSettings { public final OsmandPreference LAST_ROUTE_APPLICATION_MODE = new CommonPreference(this, "last_route_application_mode_backup_string", ApplicationMode.DEFAULT) { @Override - protected ApplicationMode getValue(Object prefs, ApplicationMode defaultValue) { + public ApplicationMode getValue(Object prefs, ApplicationMode defaultValue) { String key = settingsAPI.getString(prefs, getId(), defaultValue.getStringKey()); return ApplicationMode.valueOfStringKey(key, defaultValue); } @Override - protected boolean setValue(Object prefs, ApplicationMode val) { + public boolean setValue(Object prefs, ApplicationMode val) { return settingsAPI.edit(prefs).putString(getId(), val.getStringKey()).commit(); } @@ -818,7 +817,7 @@ public class OsmandSettings { public final CommonPreference DRIVING_REGION_AUTOMATIC = new BooleanPreference(this, "driving_region_automatic", true).makeProfile().cache(); public final OsmandPreference DRIVING_REGION = new EnumStringPreference(this, "default_driving_region", DrivingRegion.EUROPE_ASIA, DrivingRegion.values()) { - protected boolean setValue(Object prefs, DrivingRegion val) { + public boolean setValue(Object prefs, DrivingRegion val) { if (val != null) { METRIC_SYSTEM.set(val.defMetrics); } @@ -2067,10 +2066,10 @@ public class OsmandSettings { public final static String MY_LOC_POINT_LON = "my_loc_point_lon"; public final static String MY_LOC_POINT_DESCRIPTION = "my_loc_point_description"; - private static final String IMPASSABLE_ROAD_POINTS = "impassable_road_points"; - private static final String IMPASSABLE_ROADS_DESCRIPTIONS = "impassable_roads_descriptions"; - private static final String IMPASSABLE_ROADS_IDS = "impassable_roads_ids"; - private static final String IMPASSABLE_ROADS_APP_MODE_KEYS = "impassable_roads_app_mode_keys"; + public static final String IMPASSABLE_ROAD_POINTS = "impassable_road_points"; + public static final String IMPASSABLE_ROADS_DESCRIPTIONS = "impassable_roads_descriptions"; + public static final String IMPASSABLE_ROADS_IDS = "impassable_roads_ids"; + public static final String IMPASSABLE_ROADS_APP_MODE_KEYS = "impassable_roads_app_mode_keys"; public void backupPointToStart() { settingsAPI.edit(globalPreferences) @@ -2509,7 +2508,7 @@ public class OsmandSettings { @Nullable public ContextMenuItemsPreference getContextMenuItemsPreference(@NonNull String id) { for (ContextMenuItemsPreference preference : CONTEXT_MENU_ITEMS_PREFERENCES) { - if (id.startsWith(preference.idScheme)) { + if (id.startsWith(preference.getIdScheme())) { return preference; } } @@ -2745,6 +2744,55 @@ public class OsmandSettings { return res; } + public String[] getAppModeBeanPrefsIds() { + return new String[]{ + ICON_COLOR.getId(), + ICON_RES_NAME.getId(), + PARENT_APP_MODE.getId(), + ROUTING_PROFILE.getId(), + ROUTE_SERVICE.getId(), + USER_PROFILE_NAME.getId(), + LOCATION_ICON.getId(), + NAVIGATION_ICON.getId(), + APP_MODE_ORDER.getId() + }; + } + + public OsmandPreference[] getGeneralPrefs() { + return new OsmandPreference[]{ + EXTERNAL_INPUT_DEVICE, + CENTER_POSITION_ON_MAP, + ROTATE_MAP, + MAP_SCREEN_ORIENTATION, + LIVE_MONITORING_URL, + LIVE_MONITORING_MAX_INTERVAL_TO_SEND, + LIVE_MONITORING_INTERVAL, + LIVE_MONITORING, + SHOW_TRIP_REC_NOTIFICATION, + AUTO_SPLIT_RECORDING, + SAVE_TRACK_MIN_SPEED, + SAVE_TRACK_PRECISION, + SAVE_TRACK_MIN_DISTANCE, + SAVE_TRACK_INTERVAL, + TRACK_STORAGE_DIRECTORY, + SAVE_HEADING_TO_GPX, + DISABLE_RECORDING_ONCE_APP_KILLED, + SAVE_TRACK_TO_GPX, + SAVE_GLOBAL_TRACK_REMEMBER, + SAVE_GLOBAL_TRACK_INTERVAL, + MAP_EMPTY_STATE_ALLOWED, + DO_NOT_USE_ANIMATIONS, + USE_KALMAN_FILTER_FOR_COMPASS, + USE_MAGNETIC_FIELD_SENSOR_COMPASS, + USE_TRACKBALL_FOR_MOVEMENTS, + SPEED_SYSTEM, + ANGULAR_UNITS, + METRIC_SYSTEM, + DRIVING_REGION, + DRIVING_REGION_AUTOMATIC + }; + } + public enum DayNightMode { AUTO(R.string.daynight_mode_auto, R.drawable.ic_action_map_sunset), DAY(R.string.daynight_mode_day, R.drawable.ic_action_map_day), diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java index 50ee1c028e..1c6c003021 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java @@ -906,18 +906,6 @@ public class SettingsHelper { } } - String[] - appModeBeanPrefsIds = new String[] { - ICON_COLOR.getId(), - ICON_RES_NAME.getId(), - PARENT_APP_MODE.getId(), - ROUTING_PROFILE.getId(), - ROUTE_SERVICE.getId(), - USER_PROFILE_NAME.getId(), - LOCATION_ICON.getId(), - NAVIGATION_ICON.getId(), - APP_MODE_ORDER.getId() - }; public static class ProfileSettingsItem extends OsmandSettingsItem { @@ -947,7 +935,7 @@ public class SettingsHelper { @Override protected void init() { super.init(); - appModeBeanPrefsIds = new HashSet<>(Arrays.asList(app.getSettings().appModeBeanPrefsIds)); + appModeBeanPrefsIds = new HashSet<>(Arrays.asList(app.getSettings().getAppModeBeanPrefsIds())); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java index cdb923ed23..46c5bc1f3d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsMapPointsStorage.java @@ -2,6 +2,7 @@ package net.osmand.plus.settings.backend; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.plus.api.SettingsAPI; import net.osmand.plus.helpers.SearchHistoryHelper; import java.util.ArrayList; @@ -19,9 +20,17 @@ abstract class SettingsMapPointsStorage { this.osmandSettings = osmandSettings; } + protected SettingsAPI getSettingsAPI() { + return osmandSettings.getSettingsAPI(); + } + + protected OsmandSettings getOsmandSettings() { + return osmandSettings; + } + public List getPointDescriptions(int sz) { List list = new ArrayList<>(); - String ip = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, descriptionsKey, ""); + String ip = getSettingsAPI().getString(osmandSettings.globalPreferences, descriptionsKey, ""); if (ip.trim().length() > 0) { list.addAll(Arrays.asList(ip.split("--"))); } @@ -36,7 +45,7 @@ abstract class SettingsMapPointsStorage { public List getPoints() { List list = new ArrayList<>(); - String ip = osmandSettings.settingsAPI.getString(osmandSettings.globalPreferences, pointsKey, ""); + String ip = getSettingsAPI().getString(osmandSettings.globalPreferences, pointsKey, ""); if (ip.trim().length() > 0) { StringTokenizer tok = new StringTokenizer(ip, ","); while (tok.hasMoreTokens()) { @@ -56,8 +65,8 @@ abstract class SettingsMapPointsStorage { List ds = getPointDescriptions(ps.size()); ps.add(index, new LatLon(latitude, longitude)); ds.add(index, PointDescription.serializeToString(historyDescription)); - if (historyDescription != null && !historyDescription.isSearchingAddress(osmandSettings.ctx)) { - SearchHistoryHelper.getInstance(osmandSettings.ctx).addNewItemToHistory(latitude, longitude, historyDescription); + if (historyDescription != null && !historyDescription.isSearchingAddress(osmandSettings.getContext())) { + SearchHistoryHelper.getInstance(osmandSettings.getContext()).addNewItemToHistory(latitude, longitude, historyDescription); } return savePoints(ps, ds); } @@ -68,8 +77,8 @@ abstract class SettingsMapPointsStorage { int i = ps.indexOf(new LatLon(latitude, longitude)); if (i != -1) { ds.set(i, PointDescription.serializeToString(historyDescription)); - if (historyDescription != null && !historyDescription.isSearchingAddress(osmandSettings.ctx)) { - SearchHistoryHelper.getInstance(osmandSettings.ctx).addNewItemToHistory(latitude, longitude, historyDescription); + if (historyDescription != null && !historyDescription.isSearchingAddress(osmandSettings.getContext())) { + SearchHistoryHelper.getInstance(osmandSettings.getContext()).addNewItemToHistory(latitude, longitude, historyDescription); } return savePoints(ps, ds); } else { @@ -121,7 +130,7 @@ abstract class SettingsMapPointsStorage { tb.append(ds.get(i)); } } - return osmandSettings.settingsAPI.edit(osmandSettings.globalPreferences) + return getSettingsAPI().edit(osmandSettings.globalPreferences) .putString(pointsKey, sb.toString()) .putString(descriptionsKey, tb.toString()) .commit(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java index 3ee07b43bd..e0c98404be 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/StringPreference.java @@ -2,21 +2,18 @@ package net.osmand.plus.settings.backend; public class StringPreference extends CommonPreference { - private OsmandSettings osmandSettings; - StringPreference(OsmandSettings osmandSettings, String id, String defaultValue) { - super(id, defaultValue); - this.osmandSettings = osmandSettings; + super(osmandSettings, id, defaultValue); } @Override - protected String getValue(Object prefs, String defaultValue) { - return osmandSettings.settingsAPI.getString(prefs, getId(), defaultValue); + public String getValue(Object prefs, String defaultValue) { + return getSettingsAPI().getString(prefs, getId(), defaultValue); } @Override protected boolean setValue(Object prefs, String val) { - return osmandSettings.settingsAPI.edit(prefs).putString(getId(), (val != null) ? val.trim() : val).commit(); + return getSettingsAPI().edit(prefs).putString(getId(), (val != null) ? val.trim() : val).commit(); } @Override From 878129ce93c17b688fc516530ef3806d10d59cb9 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 7 Oct 2020 17:01:51 +0300 Subject: [PATCH 0543/1366] photos added --- .../builders/cards/IPFSImageCard.java | 47 +++++ .../builders/cards/ImageCard.java | 183 +++++++++--------- 2 files changed, 143 insertions(+), 87 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java new file mode 100644 index 0000000000..b029c7cdfc --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java @@ -0,0 +1,47 @@ +package net.osmand.plus.mapcontextmenu.builders.cards; + +import android.view.View; +import net.osmand.plus.activities.MapActivity; +import net.osmand.util.Algorithms; +import org.json.JSONException; +import org.json.JSONObject; + +public class IPFSImageCard extends ImageCard { + private static final String BASE_URL = "https://test.openplacereviews.org/api/ipfs/image-ipfs?cid="; + + public IPFSImageCard(MapActivity mapActivity, JSONObject imageObject) { + super(mapActivity, imageObject); + try { + this.url = BASE_URL + imageObject.get("cid"); + this.imageHiresUrl = BASE_URL + imageObject.get("cid"); + this.imageUrl = BASE_URL + imageObject.get("cid"); + } catch (JSONException e) { + e.printStackTrace(); + } + if (!Algorithms.isEmpty(getSuitableUrl())) { + View.OnClickListener onClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + openUrl(getMapActivity(), getMyApplication(), getTitle(), getSuitableUrl(), + isExternalLink() || Algorithms.isEmpty(getImageHiresUrl()), + !Algorithms.isEmpty(getImageHiresUrl())); + } + }; + if (!Algorithms.isEmpty(buttonText)) { + this.onButtonClickListener = onClickListener; + } else { + this.onClickListener = onClickListener; + } + } + } + + private String getSuitableUrl() { + final String url; + if (Algorithms.isEmpty(getImageHiresUrl())) { + url = getUrl(); + } else { + url = getImageHiresUrl(); + } + return url; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java index 84a63cb72a..667b234956 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java @@ -4,6 +4,7 @@ import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.PointF; import android.graphics.drawable.Drawable; +import android.net.TrafficStats; import android.os.AsyncTask; import android.view.View; import android.view.View.OnClickListener; @@ -15,10 +16,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatButton; -import net.osmand.AndroidNetworkUtils; -import net.osmand.AndroidUtils; -import net.osmand.GPXUtilities; -import net.osmand.Location; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import net.osmand.*; import net.osmand.data.Amenity; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; @@ -28,6 +28,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapillary.MapillaryContributeCard; import net.osmand.plus.mapillary.MapillaryImageCard; @@ -36,6 +37,7 @@ import net.osmand.plus.views.layers.ContextMenuLayer; import net.osmand.plus.wikimedia.WikiImageHelper; import net.osmand.util.Algorithms; +import org.apache.commons.logging.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -43,12 +45,7 @@ import org.json.JSONObject; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE; @@ -57,6 +54,7 @@ public abstract class ImageCard extends AbstractCard { public static String TYPE_MAPILLARY_PHOTO = "mapillary-photo"; public static String TYPE_MAPILLARY_CONTRIBUTE = "mapillary-contribute"; + private static final Log LOG = PlatformUtil.getLog(ImageCard.class); protected String type; // Image location protected LatLon location; @@ -200,6 +198,14 @@ public abstract class ImageCard extends AbstractCard { return imageCard; } + private static ImageCard createCardOpr(MapActivity mapActivity, JSONObject imageObject) { + ImageCard imageCard = null; + if (imageObject.has("cid")) { + imageCard = new IPFSImageCard(mapActivity, imageObject); + } + return imageCard; + } + public double getCa() { return ca; } @@ -430,101 +436,104 @@ public abstract class ImageCard extends AbstractCard { @Override protected List doInBackground(Void... params) { + final int THREAD_ID = 10104; + TrafficStats.setThreadStatsTag(THREAD_ID); List result = new ArrayList<>(); RotatedTileBox rtb = mapActivity.getMapView().getCurrentRotatedTileBox(); Object o = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject(); - if (this.params != null) { - String wikidataId = this.params.get(Amenity.WIKIDATA); - if (wikidataId != null) { - this.params.remove(Amenity.WIKIDATA); - WikiImageHelper.addWikidataImageCards(mapActivity, wikidataId, result); - } - String wikimediaContent = this.params.get(Amenity.WIKIMEDIA_COMMONS); - if (wikimediaContent != null) { - this.params.remove(Amenity.WIKIMEDIA_COMMONS); - WikiImageHelper.addWikimediaImageCards(mapActivity, wikimediaContent, result); - } - } if (o instanceof Amenity) { Amenity am = (Amenity) o; - System.out.println("POINT OSM ID: " + am.getId() + " " + am.getType().ordinal()); + long amenityId = (am.getId() >> 1); + getPicturesForPlace(result, amenityId); + } + try { final Map pms = new LinkedHashMap<>(); - pms.put("osmid", "" + am.getId()); + pms.put("lat", "" + (float) latLon.getLatitude()); + pms.put("lon", "" + (float) latLon.getLongitude()); + Location myLocation = app.getLocationProvider().getLastKnownLocation(); + if (myLocation != null) { + pms.put("mloc", "" + (float) myLocation.getLatitude() + "," + (float) myLocation.getLongitude()); + } + pms.put("app", Version.isPaidVersion(app) ? "paid" : "free"); + String preferredLang = app.getSettings().MAP_PREFERRED_LOCALE.get(); + if (Algorithms.isEmpty(preferredLang)) { + preferredLang = app.getLanguage(); + } + if (!Algorithms.isEmpty(preferredLang)) { + pms.put("lang", preferredLang); + } + if (this.params != null) { + String wikidataId = this.params.get(Amenity.WIKIDATA); + if (wikidataId != null) { + this.params.remove(Amenity.WIKIDATA); + WikiImageHelper.addWikidataImageCards(mapActivity, wikidataId, result); + } + String wikimediaContent = this.params.get(Amenity.WIKIMEDIA_COMMONS); + if (wikimediaContent != null) { + this.params.remove(Amenity.WIKIMEDIA_COMMONS); + WikiImageHelper.addWikimediaImageCards(mapActivity, wikimediaContent, result); + } + pms.putAll(this.params); + } String response = AndroidNetworkUtils.sendRequest(app, "https://osmand.net/api/cm_place", pms, "Requesting location images...", false, false); if (!Algorithms.isEmpty(response)) { - JSONObject obj = null; - try { - obj = new JSONObject(response); - JSONArray images = null; - images = obj.getJSONArray("features"); - if (images.length() > 0) { - for (int i = 0; i < images.length(); i++) { - try { - JSONObject imageObject = (JSONObject) images.get(i); - if (imageObject != JSONObject.NULL) { - ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); - if (imageCard != null) { - result.add(imageCard); - } + JSONObject obj = new JSONObject(response); + JSONArray images = obj.getJSONArray("features"); + if (images.length() > 0) { + for (int i = 0; i < images.length(); i++) { + try { + JSONObject imageObject = (JSONObject) images.get(i); + if (imageObject != JSONObject.NULL) { + ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); + if (imageCard != null) { + result.add(imageCard); } - } catch (JSONException e) { - e.printStackTrace(); } + } catch (JSONException e) { + e.printStackTrace(); } } - } catch (JSONException e) { - e.printStackTrace(); } } + } catch (Exception e) { + e.printStackTrace(); + } + if (listener != null) { + listener.onPostProcess(result); } return result; -// try { -// final Map pms = new LinkedHashMap<>(); -// pms.put("lat", "" + (float) latLon.getLatitude()); -// pms.put("lon", "" + (float) latLon.getLongitude()); -// Location myLocation = app.getLocationProvider().getLastKnownLocation(); -// if (myLocation != null) { -// pms.put("mloc", "" + (float) myLocation.getLatitude() + "," + (float) myLocation.getLongitude()); -// } -// pms.put("app", Version.isPaidVersion(app) ? "paid" : "free"); -// String preferredLang = app.getSettings().MAP_PREFERRED_LOCALE.get(); -// if (Algorithms.isEmpty(preferredLang)) { -// preferredLang = app.getLanguage(); -// } -// if (!Algorithms.isEmpty(preferredLang)) { -// pms.put("lang", preferredLang); -// } -// String response = AndroidNetworkUtils.sendRequest(app, "https://osmand.net/api/cm_place", pms, -// "Requesting location images...", false, false); -// -// if (!Algorithms.isEmpty(response)) { -// JSONObject obj = new JSONObject(response); -// JSONArray images = obj.getJSONArray("features"); -// if (images.length() > 0) { -// for (int i = 0; i < images.length(); i++) { -// try { -// JSONObject imageObject = (JSONObject) images.get(i); -// if (imageObject != JSONObject.NULL) { -// ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); -// if (imageCard != null) { -// result.add(imageCard); -// } -// } -// } catch (JSONException e) { -// e.printStackTrace(); -// } -// } -// } -// } -// } catch (Exception e) { -// e.printStackTrace(); -// } -// if (listener != null) { -// listener.onPostProcess(result); -// } -// return result; + } + + private void getPicturesForPlace(List result, long l) { + String url = "https://test.openplacereviews.org/api/objects-by-index?type=opr.place&index=osmid&limit=1&key=" + l; + String response = AndroidNetworkUtils.sendRequest(app, url, Collections.emptyMap(), + "Requesting location images...", false, false); + + try { + if (!Algorithms.isEmpty(response)) { + JSONArray obj = new JSONObject(response).getJSONArray("objects"); + JSONArray images = ((JSONObject) ((JSONObject) obj.get(0)).get("images")).getJSONArray("outdoor"); + if (images.length() > 0) { + for (int i = 0; i < images.length(); i++) { + try { + JSONObject imageObject = (JSONObject) images.get(i); + if (imageObject != JSONObject.NULL) { + ImageCard imageCard = ImageCard.createCardOpr(mapActivity, imageObject); + if (imageCard != null) { + result.add(imageCard); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + } + } catch (Exception e) { + LOG.error(e); + } } @Override From 243d7013c0985346207c646771650d5b6e493854 Mon Sep 17 00:00:00 2001 From: xmd5a Date: Wed, 7 Oct 2020 18:44:34 +0300 Subject: [PATCH 0544/1366] Add strings --- OsmAnd/res/values/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 619ee52e91..449dc145f2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,8 @@ Thx - Hardy --> + Avoid footways + Avoid footways Payment will be charged to your AppGallery account at the confirmation of purchase.\n\nSubscription automatically renews unless it is canceled before the renewal date. Your account will be charged for renewal period(month/three month/year) only on the renewal date.\n\nYou can manage and cancel your subscriptions by going to your AppGallery settings. Subscription charged per selected period. Cancel it on AppGallery at any time. Thank you for purchasing \'Contour lines\' From 2867736814b406309807724440bd6af34654ad37 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 7 Oct 2020 23:08:57 +0300 Subject: [PATCH 0545/1366] refactor OsmandSettings remove Enum --- .../plus/inapp/InAppPurchaseHelperImpl.java | 3 +- .../plus/inapp/InAppPurchaseHelperImpl.java | 2 +- OsmAnd/src/net/osmand/FileUtils.java | 13 + OsmAnd/src/net/osmand/aidl/ConnectedApp.java | 1 - .../src/net/osmand/plus/AppInitializer.java | 2 +- .../osmand/plus/AppVersionUpgradeOnInit.java | 19 +- .../net/osmand/plus/ContextMenuAdapter.java | 3 - .../net/osmand/plus/GpxSelectionHelper.java | 2 +- .../src/net/osmand/plus/OsmAndFormatter.java | 6 +- .../net/osmand/plus/OsmandApplication.java | 19 +- .../osmand/plus/activities/MapActivity.java | 2 +- .../plus/activities/SettingsBaseActivity.java | 3 - .../activities/SettingsGeneralActivity.java | 6 +- .../SettingsNavigationActivity.java | 11 +- .../osmand/plus/audionotes/NotesFragment.java | 1 - .../plus/audionotes/NotesSortByMode.java | 14 + .../SortByMenuBottomSheetDialogFragment.java | 1 - .../dashboard/DashChooseAppDirFragment.java | 5 +- .../plus/development/TestVoiceActivity.java | 2 +- .../osmand/plus/dialogs/ConfigureMapMenu.java | 12 +- .../plus/dialogs/DetailsBottomSheet.java | 2 +- .../osmand/plus/dialogs/RasterMapMenu.java | 6 +- .../ui/DataStoragePlaceDialogFragment.java | 5 +- .../DayNightHelper.java | 4 +- .../net/osmand/plus/helpers/GpxUiHelper.java | 43 +- .../osmand/plus/helpers/WaypointHelper.java | 13 +- .../plus/helpers/enums/AngularConstants.java | 28 + .../plus/helpers/enums/AutoZoomMap.java | 19 + .../plus/helpers/enums/DayNightMode.java | 62 ++ .../plus/helpers/enums/DrivingRegion.java | 62 ++ .../plus/helpers/enums/MetricsConstants.java | 30 + .../plus/helpers/enums/SpeedConstants.java | 33 + .../plus/helpers/enums/TracksSortByMode.java | 38 ++ .../plus/liveupdates/LiveUpdatesFragment.java | 2 +- .../MapContextMenuFragment.java | 3 +- .../builders/AmenityMenuBuilder.java | 9 +- .../DirectionIndicationDialogFragment.java | 1 - .../plus/mapmarkers/MapMarkersMode.java | 37 ++ .../OptionsBottomSheetDialogFragment.java | 3 +- .../SelectFileBottomSheet.java | 2 +- .../plus/myplaces/AvailableGPXFragment.java | 2 +- .../TrackActivityFragmentAdapter.java | 2 - .../parkingpoint/ParkingPositionPlugin.java | 6 - .../actions/DayNightModeAction.java | 7 +- .../LayerTransparencySeekbarMode.java | 22 + .../plus/rastermaps/MapOverlayAction.java | 3 +- .../plus/rastermaps/MapUnderlayAction.java | 1 - .../rastermaps/OsmandRasterMapsPlugin.java | 10 +- .../MapRouteInfoMenu.java | 3 - .../osmand/plus/routing/RouteProvider.java | 3 - .../osmand/plus/routing/RoutingHelper.java | 5 +- .../BooleanAccessibilityPreference.java | 2 - .../backend/BooleanStringPreference.java | 25 + .../settings/backend/CommonPreference.java | 1 - .../backend/ListStringPreference.java | 2 - .../backend/OsmAndPreferencesDataStore.java | 2 - .../settings/backend/OsmandPreference.java | 1 - .../plus/settings/backend/OsmandSettings.java | 583 ++++-------------- .../ChangeDataStorageBottomSheet.java | 4 +- ...ecalculateRouteInDeviationBottomSheet.java | 5 +- .../fragments/DataStorageFragment.java | 3 +- .../GeneralProfileSettingsFragment.java | 31 +- .../MapDuringNavigationFragment.java | 8 +- .../fragments/RouteParametersFragment.java | 1 - .../fragments/VehicleParametersFragment.java | 4 +- .../fragments/VoiceAnnouncesFragment.java | 3 +- .../preferences/ListPreferenceEx.java | 1 - .../osmand/plus/srtmplugin/SRTMPlugin.java | 1 - .../plus/srtmplugin/TerrainFragment.java | 5 +- .../osmand/plus/srtmplugin/TerrainLayer.java | 3 +- .../osmand/plus/srtmplugin/TerrainMode.java | 6 + .../plus/track/ShowStartFinishCard.java | 3 +- .../plus/track/TrackAppearanceFragment.java | 4 +- .../osmand/plus/views/layers/GPXLayer.java | 2 +- .../plus/views/layers/MapControlsLayer.java | 5 +- .../plus/views/layers/RulerControlLayer.java | 9 +- .../osmand/plus/views/layers/RulerMode.java | 7 + .../mapwidgets/MapInfoWidgetsFactory.java | 5 +- .../mapwidgets/RouteInfoWidgetsFactory.java | 2 - .../views/mapwidgets/widgets/AlarmWidget.java | 7 +- .../views/mapwidgets/widgets/RulerWidget.java | 2 +- .../widgetstates/BearingWidgetState.java | 4 +- .../widgetstates/CompassRulerWidgetState.java | 2 +- .../widgetstates/TimeWidgetState.java | 2 +- .../voice/AbstractPrologCommandPlayer.java | 2 +- .../WikiArticleBaseDialogFragment.java | 3 +- .../plus/wikipedia/WikiArticleShowImages.java | 15 + ...pediaOptionsBottomSheetDialogFragment.java | 1 - .../WikivoyageShowPicturesDialogFragment.java | 2 +- .../WikivoyageArticleDialogFragment.java | 2 +- ...oyageOptionsBottomSheetDialogFragment.java | 2 +- 91 files changed, 703 insertions(+), 662 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/audionotes/NotesSortByMode.java rename OsmAnd/src/net/osmand/plus/{activities => helpers}/DayNightHelper.java (98%) create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/enums/TracksSortByMode.java create mode 100644 OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java create mode 100644 OsmAnd/src/net/osmand/plus/rastermaps/LayerTransparencySeekbarMode.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java create mode 100644 OsmAnd/src/net/osmand/plus/srtmplugin/TerrainMode.java create mode 100644 OsmAnd/src/net/osmand/plus/views/layers/RulerMode.java create mode 100644 OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleShowImages.java diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index c6925a5e63..5bd9f2cb23 100644 --- a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -23,6 +23,7 @@ import net.osmand.plus.inapp.InAppPurchases.InAppPurchase; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.inapp.util.BillingManager; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.srtmplugin.SRTMPlugin; import net.osmand.util.Algorithms; @@ -407,7 +408,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper { } } } - OsmandSettings.OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; + OsmandPreference subscriptionCancelledTime = ctx.getSettings().LIVE_UPDATES_PURCHASE_CANCELLED_TIME; if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) { if (subscriptionCancelledTime.get() == 0) { subscriptionCancelledTime.set(System.currentTimeMillis()); diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java index c3d6fc193c..0f3536e5d0 100644 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchaseHelperImpl.java @@ -31,7 +31,7 @@ import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo; import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java index 65ea676356..1f9a755be5 100644 --- a/OsmAnd/src/net/osmand/FileUtils.java +++ b/OsmAnd/src/net/osmand/FileUtils.java @@ -223,6 +223,19 @@ public class FileUtils { return tempDir; } + public static boolean isWritable(File dirToTest) { + boolean isWriteable; + try { + dirToTest.mkdirs(); + File writeTestFile = File.createTempFile("osmand_", ".tmp", dirToTest); + isWriteable = writeTestFile.exists(); + writeTestFile.delete(); + } catch (IOException e) { + isWriteable = false; + } + return isWriteable; + } + public interface RenameCallback { void renamedTo(File file); } diff --git a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java index 0d4c9bc36b..be25ab931d 100644 --- a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java +++ b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java @@ -22,7 +22,6 @@ import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.layers.AidlMapLayer; import net.osmand.plus.views.layers.MapInfoLayer; diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 0ae24b7c5f..78364460a7 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -28,7 +28,7 @@ import net.osmand.map.OsmandRegions.RegionTranslation; import net.osmand.map.WorldRegion; import net.osmand.osm.AbstractPoiType; import net.osmand.osm.MapPoiTypes; -import net.osmand.plus.activities.DayNightHelper; +import net.osmand.plus.helpers.DayNightHelper; import net.osmand.plus.activities.LocalIndexHelper; import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.activities.SavingTrackHelper; diff --git a/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java b/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java index 0ab61f725a..49e354ea8b 100644 --- a/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java +++ b/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java @@ -10,6 +10,7 @@ import com.google.gson.reflect.TypeToken; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.plus.api.SettingsAPI; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.EnumStringPreference; import net.osmand.plus.settings.backend.OsmandPreference; @@ -18,6 +19,7 @@ import net.osmand.util.Algorithms; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -133,7 +135,7 @@ class AppVersionUpgradeOnInit { startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, VERSION_3_7_01).commit(); } if (prevAppVersion < VERSION_3_8_00) { - app.getSettings().migrateQuickActionStates(); + migrateQuickActionStates(); startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, VERSION_3_8_00).commit(); } startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, lastVersion).commit(); @@ -253,6 +255,21 @@ class AppVersionUpgradeOnInit { } } + public void migrateQuickActionStates() { + String quickActionsJson = settings.getSettingsAPI().getString(settings.getGlobalPreferences(), "quick_action_new", ""); + if (!Algorithms.isEmpty(quickActionsJson)) { + Gson gson = new GsonBuilder().create(); + Type type = new TypeToken>() { + }.getType(); + HashMap quickActions = gson.fromJson(quickActionsJson, type); + if (!Algorithms.isEmpty(quickActions)) { + for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { + settings.setQuickActions(quickActions, mode); + } + } + } + } + private void migrateEnumPref(EnumStringPreference enumPref, SharedPreferences sharedPreferences) { Object value = sharedPreferences.getAll().get(enumPref.getId()); if (value instanceof Integer) { diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index c076f75ee2..c6226d6615 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -38,9 +38,6 @@ import net.osmand.plus.dialogs.HelpArticleDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmAndAppCustomization; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.ContextMenuItemsPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.settings.backend.ContextMenuItemsPreference; import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.util.Algorithms; diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index 7217e8af5f..923bbe646a 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -29,7 +29,7 @@ import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; import net.osmand.plus.routing.RouteProvider; -import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.track.GpxSplitType; import net.osmand.plus.track.GradientScaleType; import net.osmand.util.Algorithms; diff --git a/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java b/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java index 2ac142d06a..b58b3eba5e 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java @@ -15,9 +15,9 @@ import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.AngularConstants; -import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; -import net.osmand.plus.settings.backend.OsmandSettings.SpeedConstants; +import net.osmand.plus.helpers.enums.AngularConstants; +import net.osmand.plus.helpers.enums.MetricsConstants; +import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.util.Algorithms; import java.text.DateFormatSymbols; diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 43c3a17f09..1a48650a4d 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -30,6 +30,7 @@ import androidx.multidex.MultiDex; import androidx.multidex.MultiDexApplication; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.access.AccessibilityPlugin; @@ -42,7 +43,7 @@ import net.osmand.osm.MapPoiTypes; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.AppInitializer.AppInitializeListener; import net.osmand.plus.access.AccessibilityMode; -import net.osmand.plus.activities.DayNightHelper; +import net.osmand.plus.helpers.DayNightHelper; import net.osmand.plus.activities.ExitActivity; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SavingTrackHelper; @@ -56,7 +57,9 @@ import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadService; import net.osmand.plus.download.IndexItem; import net.osmand.plus.helpers.AvoidSpecificRoads; +import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.helpers.LockHelper; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper; @@ -189,7 +192,7 @@ public class OsmandApplication extends MultiDexApplication { osmandSettings.initExternalStorageDirectory(); } externalStorageDirectory = osmandSettings.getExternalStorageDirectory(); - if (!OsmandSettings.isWritable(externalStorageDirectory)) { + if (!FileUtils.isWritable(externalStorageDirectory)) { externalStorageDirectoryReadOnly = true; externalStorageDirectory = osmandSettings.getInternalAppPath(); } @@ -983,15 +986,15 @@ public class OsmandApplication extends MultiDexApplication { } public void setupDrivingRegion(WorldRegion reg) { - OsmandSettings.DrivingRegion drg = null; + DrivingRegion drg = null; WorldRegion.RegionParams params = reg.getParams(); // boolean americanSigns = "american".equals(params.getRegionRoadSigns()); boolean leftHand = "yes".equals(params.getRegionLeftHandDriving()); - OsmandSettings.MetricsConstants mc1 = "miles".equals(params.getRegionMetric()) ? - OsmandSettings.MetricsConstants.MILES_AND_FEET : OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS; - OsmandSettings.MetricsConstants mc2 = "miles".equals(params.getRegionMetric()) ? - OsmandSettings.MetricsConstants.MILES_AND_METERS : OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS; - for (OsmandSettings.DrivingRegion r : OsmandSettings.DrivingRegion.values()) { + MetricsConstants mc1 = "miles".equals(params.getRegionMetric()) ? + MetricsConstants.MILES_AND_FEET : MetricsConstants.KILOMETERS_AND_METERS; + MetricsConstants mc2 = "miles".equals(params.getRegionMetric()) ? + MetricsConstants.MILES_AND_METERS : MetricsConstants.KILOMETERS_AND_METERS; + for (DrivingRegion r : DrivingRegion.values()) { if (r.leftHandDriving == leftHand && (r.defMetrics == mc1 || r.defMetrics == mc2)) { drg = r; break; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 8533c9c463..083c95d279 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -74,6 +74,7 @@ import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.helpers.DayNightHelper; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; @@ -132,7 +133,6 @@ import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab; import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType; import net.osmand.plus.settings.fragments.ConfigureProfileFragment; diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java index 58f0b57029..316de777b0 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsBaseActivity.java @@ -32,9 +32,6 @@ import net.osmand.plus.R; import net.osmand.plus.profiles.AppProfileArrayAdapter; import net.osmand.plus.profiles.ProfileDataObject; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import org.apache.commons.logging.Log; diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java index aaf206ca06..225384349c 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java @@ -42,9 +42,9 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.AngularConstants; -import net.osmand.plus.settings.backend.OsmandSettings.DrivingRegion; -import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; +import net.osmand.plus.helpers.enums.AngularConstants; +import net.osmand.plus.helpers.enums.DrivingRegion; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.base.MapViewTrackingUtilities; diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java index 89c0806d0a..a0a5c74992 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java @@ -34,11 +34,12 @@ import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.AutoZoomMap; +import net.osmand.plus.helpers.enums.AutoZoomMap; import net.osmand.plus.settings.backend.OsmandPreference; -import net.osmand.plus.settings.backend.OsmandSettings.SpeedConstants; +import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.Version; @@ -49,10 +50,6 @@ import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper; import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.AutoZoomMap; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; -import net.osmand.plus.settings.backend.OsmandSettings.SpeedConstants; import net.osmand.plus.voice.CommandPlayer; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.GeneralRouterProfile; @@ -176,7 +173,7 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { //array size must be equal! Float[] speedLimitsKmhPos = new Float[]{0f, 5f, 7f, 10f, 15f, 20f}; Float[] speedLimitsMphPos = new Float[]{0f, 3f, 5f, 7f, 10f, 15f}; - if (settings.METRIC_SYSTEM.get() == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) { + if (settings.METRIC_SYSTEM.get() == MetricsConstants.KILOMETERS_AND_METERS) { String[] speedNames = new String[speedLimitsKmh.length]; String[] speedNamesPos = new String[speedLimitsKmhPos.length]; for (int i = 0; i < speedLimitsKmh.length; i++) { diff --git a/OsmAnd/src/net/osmand/plus/audionotes/NotesFragment.java b/OsmAnd/src/net/osmand/plus/audionotes/NotesFragment.java index 09acdca8d8..8e911b04fc 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/NotesFragment.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/NotesFragment.java @@ -38,7 +38,6 @@ import net.osmand.PlatformUtil; import net.osmand.data.PointDescription; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.settings.backend.OsmandSettings.NotesSortByMode; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.activities.ActionBarProgressActivity; diff --git a/OsmAnd/src/net/osmand/plus/audionotes/NotesSortByMode.java b/OsmAnd/src/net/osmand/plus/audionotes/NotesSortByMode.java new file mode 100644 index 0000000000..cf791dbf26 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/audionotes/NotesSortByMode.java @@ -0,0 +1,14 @@ +package net.osmand.plus.audionotes; + +public enum NotesSortByMode { + BY_TYPE, + BY_DATE; + + public boolean isByType() { + return this == BY_TYPE; + } + + public boolean isByDate() { + return this == BY_DATE; + } +} diff --git a/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java index 2e228874b0..06fa83f6ca 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/SortByMenuBottomSheetDialogFragment.java @@ -4,7 +4,6 @@ import android.os.Bundle; import android.view.View; import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.NotesSortByMode; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashChooseAppDirFragment.java b/OsmAnd/src/net/osmand/plus/dashboard/DashChooseAppDirFragment.java index 9f37cd1b41..883010ea46 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashChooseAppDirFragment.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashChooseAppDirFragment.java @@ -30,6 +30,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.ValueHolder; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; @@ -113,7 +114,7 @@ public class DashChooseAppDirFragment { boolean copyFiles = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath()) && !mapsCopied; warningReadonly.setVisibility(copyFiles ? View.VISIBLE : View.GONE); if (copyFiles) { - if (!OsmandSettings.isWritable(currentAppFile)) { + if (!FileUtils.isWritable(currentAppFile)) { warningReadonly.setText(activity.getString(R.string.android_19_location_disabled, currentAppFile.getAbsolutePath())); } else { @@ -385,7 +386,7 @@ public class DashChooseAppDirFragment { @Override public void onClick(View v) { - boolean wr = OsmandSettings.isWritable(selectedFile); + boolean wr = FileUtils.isWritable(selectedFile); if (wr) { boolean changed = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath()); getMyApplication().setExternalStorageDirectory(type, selectedFile.getAbsolutePath()); diff --git a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java index 2e4dfc3dfb..a9a0ba563e 100644 --- a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java @@ -151,7 +151,7 @@ public class TestVoiceActivity extends OsmandActionBarActivity { v += "\n \u25CF BT SCO: The current app profile is not set to use 'Phone call audio'."; } - //OsmandSettings.OsmandPreference pref = ((OsmandApplication) getApplication()).getSettings().VOICE_PROMPT_DELAY[stream]; + //OsmandPreference pref = ((OsmandApplication) getApplication()).getSettings().VOICE_PROMPT_DELAY[stream]; //if(pref != null) { // v += "\n \u25CF Voice prompt delay for selected output: " + pref.get() + "\u00A0ms"; //} diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 97534b5bdf..1c01808be8 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -33,6 +33,7 @@ import net.osmand.plus.ContextMenuItem; import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.helpers.enums.DayNightMode; import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; @@ -44,9 +45,6 @@ import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.render.RendererRegistry; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.ListStringPreference; import net.osmand.plus.srtmplugin.SRTMPlugin; import net.osmand.plus.transport.TransportLinesMenu; import net.osmand.plus.views.OsmandMapTileView; @@ -311,7 +309,7 @@ public class ConfigureMapMenu { DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); String sunriseTime = dateFormat.format(sunriseSunset.getSunrise()); String sunsetTime = dateFormat.format(sunriseSunset.getSunset()); - OsmandSettings.DayNightMode dayNightMode = activity.getMyApplication().getSettings().DAYNIGHT_MODE.get(); + DayNightMode dayNightMode = activity.getMyApplication().getSettings().DAYNIGHT_MODE.get(); if (dayNightMode.isDay() || dayNightMode.isNight()) { if (sunriseSunset.isDaytime()) { description = String.format(app.getString(R.string.sunset_at), sunsetTime); @@ -338,9 +336,9 @@ public class ConfigureMapMenu { final OsmandMapTileView view = activity.getMapView(); AlertDialog.Builder bld = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes)); bld.setTitle(R.string.daynight); - final String[] items = new String[OsmandSettings.DayNightMode.values().length]; + final String[] items = new String[DayNightMode.values().length]; for (int i = 0; i < items.length; i++) { - items[i] = OsmandSettings.DayNightMode.values()[i].toHumanString(app); + items[i] = DayNightMode.values()[i].toHumanString(app); } int i = view.getSettings().DAYNIGHT_MODE.get().ordinal(); bld.setNegativeButton(R.string.shared_string_dismiss, null); @@ -349,7 +347,7 @@ public class ConfigureMapMenu { @Override public void onClick(View v) { int which = (int) v.getTag(); - view.getSettings().DAYNIGHT_MODE.set(OsmandSettings.DayNightMode.values()[which]); + view.getSettings().DAYNIGHT_MODE.set(DayNightMode.values()[which]); refreshMapComplete(activity); activity.getDashboard().refreshContent(true); // adapter.getItem(pos).setDescription(s, getDayNightDescr(activity)); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java index 4e8febb56e..ecb8f04b86 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java @@ -27,7 +27,7 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemTwoChoicesButton.OnBo import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRuleStorageProperties; diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java index e5414bd0b4..8219cc5a23 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java @@ -12,7 +12,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; +import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivityLayers; @@ -182,8 +182,8 @@ public class RasterMapMenu { @NonNull public static Boolean isSeekbarVisible(OsmandApplication app, RasterMapType type) { - final OsmandSettings.LayerTransparencySeekbarMode currentMapTypeSeekbarMode = - type == RasterMapType.OVERLAY ? OsmandSettings.LayerTransparencySeekbarMode.OVERLAY : OsmandSettings.LayerTransparencySeekbarMode.UNDERLAY; + final LayerTransparencySeekbarMode currentMapTypeSeekbarMode = + type == RasterMapType.OVERLAY ? LayerTransparencySeekbarMode.OVERLAY : LayerTransparencySeekbarMode.UNDERLAY; LayerTransparencySeekbarMode seekbarMode = app.getSettings().LAYER_TRANSPARENCY_SEEKBAR_MODE.get(); return seekbarMode == LayerTransparencySeekbarMode.UNDEFINED || seekbarMode == currentMapTypeSeekbarMode; } diff --git a/OsmAnd/src/net/osmand/plus/download/ui/DataStoragePlaceDialogFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/DataStoragePlaceDialogFragment.java index dceeac1862..f97784cb36 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/DataStoragePlaceDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/DataStoragePlaceDialogFragment.java @@ -21,6 +21,7 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.IProgress; import net.osmand.plus.OnDismissDialogFragmentListener; import net.osmand.plus.OsmandApplication; @@ -71,7 +72,7 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment { File internalStorage = getInternalStorageDirectory(activity); File external1Storage = getExternal1StorageDirectory(activity); - if (external1Storage != null && external1Storage.exists() && OsmandSettings.isWritable(external1Storage)) { + if (external1Storage != null && external1Storage.exists() && FileUtils.isWritable(external1Storage)) { deviceStorage = external1Storage; deviceStorageType = OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE; deviceStorageName = getString(R.string.storage_directory_external); @@ -246,7 +247,7 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment { }; public boolean saveFilesLocation(int type, File selectedFile, Activity context) { - boolean wr = OsmandSettings.isWritable(selectedFile); + boolean wr = FileUtils.isWritable(selectedFile); if (wr) { ((OsmandApplication) context.getApplication()) .setExternalStorageDirectory(type, selectedFile.getAbsolutePath()); diff --git a/OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java b/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java similarity index 98% rename from OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java rename to OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java index f9ca2afca4..ea4f6a1ae7 100644 --- a/OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java @@ -1,4 +1,4 @@ -package net.osmand.plus.activities; +package net.osmand.plus.helpers; import java.util.Date; @@ -8,9 +8,9 @@ import java.util.TimeZone; import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.StateChangedListener; +import net.osmand.plus.helpers.enums.DayNightMode; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings.DayNightMode; import net.osmand.util.SunriseSunset; import org.apache.commons.logging.Log; diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index 2305d1beec..47650dc2ec 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -80,6 +80,8 @@ import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.helpers.enums.MetricsConstants; +import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; @@ -95,7 +97,6 @@ import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.routing.RouteCalculationResult; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRulesStorage; import net.osmand.router.RouteStatisticsHelper; @@ -1041,7 +1042,7 @@ public class GpxUiHelper { private static float setupAxisDistance(OsmandApplication ctx, AxisBase axisBase, float meters) { OsmandSettings settings = ctx.getSettings(); - OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get(); + MetricsConstants mc = settings.METRIC_SYSTEM.get(); float divX; String format1 = "{0,number,0.#} "; @@ -1050,10 +1051,10 @@ public class GpxUiHelper { float granularity = 1f; int mainUnitStr; float mainUnitInMeters; - if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) { + if (mc == MetricsConstants.KILOMETERS_AND_METERS) { mainUnitStr = R.string.km; mainUnitInMeters = METERS_IN_KILOMETER; - } else if (mc == OsmandSettings.MetricsConstants.NAUTICAL_MILES) { + } else if (mc == MetricsConstants.NAUTICAL_MILES) { mainUnitStr = R.string.nm; mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE; } else { @@ -1067,10 +1068,10 @@ public class GpxUiHelper { if (meters >= 100 * mainUnitInMeters || meters > 9.99f * mainUnitInMeters || meters > 0.999f * mainUnitInMeters || - mc == OsmandSettings.MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters || - mc == OsmandSettings.MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters || - mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters || - mc == OsmandSettings.MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) { + mc == MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters || + mc == MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters || + mc == MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters || + mc == MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) { divX = mainUnitInMeters; if (fmt == null) { @@ -1080,13 +1081,13 @@ public class GpxUiHelper { } else { fmt = null; granularity = 1f; - if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS || mc == OsmandSettings.MetricsConstants.MILES_AND_METERS) { + if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) { divX = 1f; mainUnitStr = R.string.m; - } else if (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) { + } else if (mc == MetricsConstants.MILES_AND_FEET) { divX = 1f / FEET_IN_ONE_METER; mainUnitStr = R.string.foot; - } else if (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS) { + } else if (mc == MetricsConstants.MILES_AND_YARDS) { divX = 1f / YARDS_IN_ONE_METER; mainUnitStr = R.string.yard; } else { @@ -1308,8 +1309,8 @@ public class GpxUiHelper { boolean drawFilled, boolean calcWithoutGaps) { OsmandSettings settings = ctx.getSettings(); - OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get(); - boolean useFeet = (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) || (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS); + MetricsConstants mc = settings.METRIC_SYSTEM.get(); + boolean useFeet = (mc == MetricsConstants.MILES_AND_FEET) || (mc == MetricsConstants.MILES_AND_YARDS); boolean light = settings.isLightContent(); final float convEle = useFeet ? 3.28084f : 1.0f; @@ -1410,19 +1411,19 @@ public class GpxUiHelper { divX = setupAxisDistance(ctx, xAxis, calcWithoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance); } - OsmandSettings.SpeedConstants sps = settings.SPEED_SYSTEM.get(); + SpeedConstants sps = settings.SPEED_SYSTEM.get(); float mulSpeed = Float.NaN; float divSpeed = Float.NaN; final String mainUnitY = sps.toShortString(ctx); - if (sps == OsmandSettings.SpeedConstants.KILOMETERS_PER_HOUR) { + if (sps == SpeedConstants.KILOMETERS_PER_HOUR) { mulSpeed = 3.6f; - } else if (sps == OsmandSettings.SpeedConstants.MILES_PER_HOUR) { + } else if (sps == SpeedConstants.MILES_PER_HOUR) { mulSpeed = 3.6f * METERS_IN_KILOMETER / METERS_IN_ONE_MILE; - } else if (sps == OsmandSettings.SpeedConstants.NAUTICALMILES_PER_HOUR) { + } else if (sps == SpeedConstants.NAUTICALMILES_PER_HOUR) { mulSpeed = 3.6f * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE; - } else if (sps == OsmandSettings.SpeedConstants.MINUTES_PER_KILOMETER) { + } else if (sps == SpeedConstants.MINUTES_PER_KILOMETER) { divSpeed = METERS_IN_KILOMETER / 60; - } else if (sps == OsmandSettings.SpeedConstants.MINUTES_PER_MILE) { + } else if (sps == SpeedConstants.MINUTES_PER_MILE) { divSpeed = METERS_IN_ONE_MILE / 60; } else { mulSpeed = 1f; @@ -1573,8 +1574,8 @@ public class GpxUiHelper { } OsmandSettings settings = ctx.getSettings(); boolean light = settings.isLightContent(); - OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get(); - boolean useFeet = (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) || (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS); + MetricsConstants mc = settings.METRIC_SYSTEM.get(); + boolean useFeet = (mc == MetricsConstants.MILES_AND_FEET) || (mc == MetricsConstants.MILES_AND_YARDS); final float convEle = useFeet ? 3.28084f : 1.0f; final float totalDistance = calcWithoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; diff --git a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java index b143653754..7f20de3e60 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java @@ -24,6 +24,9 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.IntermediatePointsDialog; import net.osmand.plus.base.PointImageDrawable; +import net.osmand.plus.helpers.enums.DrivingRegion; +import net.osmand.plus.helpers.enums.MetricsConstants; +import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.routing.AlarmInfo; @@ -31,8 +34,6 @@ import net.osmand.plus.routing.AlarmInfo.AlarmInfoType; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.VoiceRouter; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; import net.osmand.util.MapUtils; import java.util.ArrayList; @@ -193,7 +194,7 @@ public class WaypointHelper { return found; } - public AlarmInfo getMostImportantAlarm(OsmandSettings.SpeedConstants sc, boolean showCameras) { + public AlarmInfo getMostImportantAlarm(SpeedConstants sc, boolean showCameras) { Location lastProjection = app.getRoutingHelper().getLastProjection(); float mxspeed = route.getCurrentMaxSpeed(); float delta = app.getSettings().SPEED_LIMIT_EXCEED_KMH.get() / 3.6f; @@ -291,7 +292,7 @@ public class WaypointHelper { } public AlarmInfo calculateMostImportantAlarm(RouteDataObject ro, Location loc, MetricsConstants mc, - OsmandSettings.SpeedConstants sc, boolean showCameras) { + SpeedConstants sc, boolean showCameras) { float mxspeed = ro.getMaximumSpeed(ro.bearingVsRouteDirection(loc)); float delta = app.getSettings().SPEED_LIMIT_EXCEED_KMH.get() / 3.6f; AlarmInfo speedAlarm = createSpeedAlarm(sc, mxspeed, loc, delta); @@ -331,7 +332,7 @@ public class WaypointHelper { return null; } - private static AlarmInfo createSpeedAlarm(OsmandSettings.SpeedConstants sc, float mxspeed, Location loc, float delta) { + private static AlarmInfo createSpeedAlarm(SpeedConstants sc, float mxspeed, Location loc, float delta) { AlarmInfo speedAlarm = null; if (mxspeed != 0 && loc != null && loc.hasSpeed() && mxspeed != RouteDataObject.NONE_MAX_SPEED) { if (loc.getSpeed() > mxspeed + delta) { @@ -790,7 +791,7 @@ public class WaypointHelper { } else if (type == ALARMS) { //assign alarm list icons manually for now String typeString = ((AlarmInfo) point).getType().toString(); - OsmandSettings.DrivingRegion region = app.getSettings().DRIVING_REGION.get(); + DrivingRegion region = app.getSettings().DRIVING_REGION.get(); if (typeString.equals("SPEED_CAMERA")) { return AppCompatResources.getDrawable(uiCtx, R.drawable.mx_highway_speed_camera); } else if (typeString.equals("BORDER_CONTROL")) { diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java b/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java new file mode 100644 index 0000000000..9962144fa4 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java @@ -0,0 +1,28 @@ +package net.osmand.plus.helpers.enums; + +import android.content.Context; + +import net.osmand.plus.R; + +public enum AngularConstants { + DEGREES(R.string.shared_string_degrees, "°"), + DEGREES360(R.string.shared_string_degrees, "°"), + MILLIRADS(R.string.shared_string_milliradians, "mil"); + + private final int key; + private final String unit; + + AngularConstants(int key, String unit) { + this.key = key; + this.unit = unit; + } + + public String toHumanString(Context ctx) { + return ctx.getString(key); + } + + public String getUnitSymbol() { + return unit; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java b/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java new file mode 100644 index 0000000000..f092c19be7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java @@ -0,0 +1,19 @@ +package net.osmand.plus.helpers.enums; + +import net.osmand.plus.R; + +public enum AutoZoomMap { + FARTHEST(R.string.auto_zoom_farthest, 1f, 15.5f), + FAR(R.string.auto_zoom_far, 1.4f, 17f), + CLOSE(R.string.auto_zoom_close, 2f, 19f); + public final float coefficient; + public final int name; + public final float maxZoom; + + AutoZoomMap(int name, float coefficient, float maxZoom) { + this.name = name; + this.coefficient = coefficient; + this.maxZoom = maxZoom; + + } +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java b/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java new file mode 100644 index 0000000000..9c8865e877 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java @@ -0,0 +1,62 @@ +package net.osmand.plus.helpers.enums; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorManager; + +import androidx.annotation.DrawableRes; +import androidx.annotation.StringRes; + +import net.osmand.plus.R; + +public enum DayNightMode { + AUTO(R.string.daynight_mode_auto, R.drawable.ic_action_map_sunset), + DAY(R.string.daynight_mode_day, R.drawable.ic_action_map_day), + NIGHT(R.string.daynight_mode_night, R.drawable.ic_action_map_night), + SENSOR(R.string.daynight_mode_sensor, R.drawable.ic_action_map_light_sensor); + + private final int key; + @DrawableRes + private final int drawableRes; + + DayNightMode(@StringRes int key, @DrawableRes int drawableRes) { + this.key = key; + this.drawableRes = drawableRes; + } + + public String toHumanString(Context ctx) { + return ctx.getString(key); + } + + @DrawableRes + public int getIconRes() { + return drawableRes; + } + + public boolean isSensor() { + return this == SENSOR; + } + + public boolean isAuto() { + return this == AUTO; + } + + public boolean isDay() { + return this == DAY; + } + + public boolean isNight() { + return this == NIGHT; + } + + public static DayNightMode[] possibleValues(Context context) { + SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); + boolean isLightSensorEnabled = mLight != null; + if (isLightSensorEnabled) { + return DayNightMode.values(); + } else { + return new DayNightMode[]{AUTO, DAY, NIGHT}; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java b/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java new file mode 100644 index 0000000000..70c825926e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java @@ -0,0 +1,62 @@ +package net.osmand.plus.helpers.enums; + +import android.content.Context; + +import net.osmand.plus.R; + +import java.util.Locale; + +/** + * Class represents specific for driving region + * Signs, leftHandDriving + */ +public enum DrivingRegion { + + EUROPE_ASIA(R.string.driving_region_europe_asia, MetricsConstants.KILOMETERS_AND_METERS, false), + US(R.string.driving_region_us, MetricsConstants.MILES_AND_FEET, false), + CANADA(R.string.driving_region_canada, MetricsConstants.KILOMETERS_AND_METERS, false), + UK_AND_OTHERS(R.string.driving_region_uk, MetricsConstants.MILES_AND_METERS, true), + JAPAN(R.string.driving_region_japan, MetricsConstants.KILOMETERS_AND_METERS, true), + AUSTRALIA(R.string.driving_region_australia, MetricsConstants.KILOMETERS_AND_METERS, true); + + public final boolean leftHandDriving; + public final MetricsConstants defMetrics; + public final int name; + + DrivingRegion(int name, MetricsConstants def, boolean leftHandDriving) { + this.name = name; + defMetrics = def; + this.leftHandDriving = leftHandDriving; + } + + public boolean isAmericanTypeSigns() { + return this == DrivingRegion.AUSTRALIA || + this == DrivingRegion.US || + this == DrivingRegion.CANADA; + } + + public String getDescription(Context ctx) { + return ctx.getString(leftHandDriving ? R.string.left_side_navigation : R.string.right_side_navigation) + + ", " + + defMetrics.toHumanString(ctx).toLowerCase(); + } + + public static DrivingRegion getDrivingRegionByLocale() { + Locale df = Locale.getDefault(); + if (df == null) { + return DrivingRegion.EUROPE_ASIA; + } + if (df.getCountry().equalsIgnoreCase(Locale.US.getCountry())) { + return DrivingRegion.US; + } else if (df.getCountry().equalsIgnoreCase(Locale.CANADA.getCountry())) { + return DrivingRegion.CANADA; + } else if (df.getCountry().equalsIgnoreCase(Locale.JAPAN.getCountry())) { + return DrivingRegion.JAPAN; + } else if (df.getCountry().equalsIgnoreCase("au")) { + return DrivingRegion.AUSTRALIA; + } else if(df.getCountry().equalsIgnoreCase(Locale.UK.getCountry())) { + return DrivingRegion.UK_AND_OTHERS; + } + return DrivingRegion.EUROPE_ASIA; + } +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java b/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java new file mode 100644 index 0000000000..23034b5277 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java @@ -0,0 +1,30 @@ +package net.osmand.plus.helpers.enums; + +import android.content.Context; + +import net.osmand.plus.R; + +public enum MetricsConstants { + KILOMETERS_AND_METERS(R.string.si_km_m, "km-m"), + MILES_AND_FEET(R.string.si_mi_feet, "mi-f"), + MILES_AND_METERS(R.string.si_mi_meters, "mi-m"), + MILES_AND_YARDS(R.string.si_mi_yard, "mi-y"), + NAUTICAL_MILES(R.string.si_nm, "nm"); + + private final int key; + private final String ttsString; + + MetricsConstants(int key, String ttsString) { + this.key = key; + this.ttsString = ttsString; + } + + public String toHumanString(Context ctx) { + return ctx.getString(key); + } + + public String toTTSString() { + return ttsString; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java b/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java new file mode 100644 index 0000000000..15a54513eb --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java @@ -0,0 +1,33 @@ +package net.osmand.plus.helpers.enums; + +import android.content.Context; + +import net.osmand.plus.R; + +public enum SpeedConstants { + KILOMETERS_PER_HOUR(R.string.km_h, R.string.si_kmh, false), + MILES_PER_HOUR(R.string.mile_per_hour, R.string.si_mph, true), + METERS_PER_SECOND(R.string.m_s, R.string.si_m_s, false), + MINUTES_PER_MILE(R.string.min_mile, R.string.si_min_m, true), + MINUTES_PER_KILOMETER(R.string.min_km, R.string.si_min_km, false), + NAUTICALMILES_PER_HOUR(R.string.nm_h, R.string.si_nm_h, true); + + public final int key; + public final int descr; + public final boolean imperial; + + SpeedConstants(int key, int descr, boolean imperial) { + this.key = key; + this.descr = descr; + this.imperial = imperial; + } + + public String toHumanString(Context ctx) { + return ctx.getString(descr); + } + + public String toShortString(Context ctx) { + return ctx.getString(key); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/TracksSortByMode.java b/OsmAnd/src/net/osmand/plus/helpers/enums/TracksSortByMode.java new file mode 100644 index 0000000000..6b4177c701 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/TracksSortByMode.java @@ -0,0 +1,38 @@ +package net.osmand.plus.helpers.enums; + +import androidx.annotation.DrawableRes; +import androidx.annotation.StringRes; + +import net.osmand.plus.R; + +public enum TracksSortByMode { + BY_DATE(R.string.sort_last_modified, R.drawable.ic_action_time_start), + BY_NAME_ASCENDING(R.string.sort_name_ascending, R.drawable.ic_action_sort_by_name_ascending), + BY_NAME_DESCENDING(R.string.sort_name_descending, R.drawable.ic_action_sort_by_name_descending); + + private final int iconId; + private final int nameId; + + TracksSortByMode(int nameId, int iconId) { + this.nameId = nameId; + this.iconId = iconId; + } + + public boolean isByName() { + return this == BY_NAME_ASCENDING || this == BY_NAME_DESCENDING; + } + + public boolean isByDate() { + return this == BY_DATE; + } + + @StringRes + public int getNameId() { + return nameId; + } + + @DrawableRes + public int getIconId() { + return iconId; + } +} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index f7c5f8bc59..c503162910 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -314,7 +314,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc public void add(LocalIndexInfo info) { CommonPreference preference = preferenceLiveUpdatesOn( - info.getFileName(), getSettings()); + info.getFileName(), app.getSettings()); if (preference.get()) { dataShouldUpdate.add(info); } else { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java index 27dd2c89c3..7977a9ddc6 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenuFragment.java @@ -76,7 +76,6 @@ import net.osmand.plus.mapcontextmenu.MenuController.TitleProgressController; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; import net.osmand.plus.routepreparationmenu.ChooseRouteFragment; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.OsmandMapTileView; @@ -644,7 +643,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo // Action buttons ContextMenuAdapter adapter = menu.getActionsContextMenuAdapter(false); List items = adapter.getVisibleItems(); - List mainIds = ((OsmandSettings.MainContextMenuItemsSettings) mapActivity.getMyApplication() + List mainIds = ((MainContextMenuItemsSettings) mapActivity.getMyApplication() .getSettings().CONTEXT_MENU_ACTIONS_ITEMS.get()).getMainIds(); ContextMenuAdapter mainAdapter = new ContextMenuAdapter(requireMyApplication()); ContextMenuAdapter additionalAdapter = new ContextMenuAdapter(requireMyApplication()); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 5a4618ca4f..f0d33b68dd 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -36,8 +36,7 @@ import net.osmand.plus.mapcontextmenu.CollapsableView; import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.poi.PoiUIFilter; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.views.layers.POIMapLayer; import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.tools.ClickableSpanTouchListener; @@ -70,7 +69,7 @@ public class AmenityMenuBuilder extends MenuBuilder { private static final String WIKI_LINK = ".wikipedia.org/w"; public final static Log LOG = PlatformUtil.getLog(AmenityMenuBuilder.class); private final static DecimalFormat DF = new DecimalFormat("#.##"); - private OsmandSettings.MetricsConstants metricSystem; + private MetricsConstants metricSystem; private final Amenity amenity; @@ -714,10 +713,10 @@ public class AmenityMenuBuilder extends MenuBuilder { case "seamark_height": if (Algorithms.isFloat(value)) { double valueAsDouble = Double.valueOf(value); - if (metricSystem == OsmandSettings.MetricsConstants.MILES_AND_FEET) { + if (metricSystem == MetricsConstants.MILES_AND_FEET) { formattedValue = String.valueOf(DF.format(valueAsDouble * OsmAndFormatter.FEET_IN_ONE_METER)) + " " + mapActivity.getResources().getString(R.string.foot); - } else if (metricSystem == OsmandSettings.MetricsConstants.MILES_AND_YARDS) { + } else if (metricSystem == MetricsConstants.MILES_AND_YARDS) { formattedValue = String.valueOf(DF.format(valueAsDouble * OsmAndFormatter.YARDS_IN_ONE_METER)) + " " + mapActivity.getResources().getString(R.string.yard); } else { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java index c82230a464..d624ec7947 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/DirectionIndicationDialogFragment.java @@ -32,7 +32,6 @@ import com.github.ksoichiro.android.observablescrollview.ScrollState; import net.osmand.AndroidUtils; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.MapMarkersMode; import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java new file mode 100644 index 0000000000..840da1ad92 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java @@ -0,0 +1,37 @@ +package net.osmand.plus.mapmarkers; + +import android.content.Context; + +import net.osmand.plus.R; + +public enum MapMarkersMode { + TOOLBAR(R.string.shared_string_topbar), + WIDGETS(R.string.shared_string_widgets), + NONE(R.string.shared_string_none); + + private final int key; + + MapMarkersMode(int key) { + this.key = key; + } + + public String toHumanString(Context ctx) { + return ctx.getString(key); + } + + public boolean isToolbar() { + return this == TOOLBAR; + } + + public boolean isWidgets() { + return this == WIDGETS; + } + + public boolean isNone() { + return this == NONE; + } + + public static MapMarkersMode[] possibleValues(Context context) { + return new MapMarkersMode[]{TOOLBAR, WIDGETS, NONE}; + } +} diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/OptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/OptionsBottomSheetDialogFragment.java index 487ee2073c..4627ed764b 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/OptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/OptionsBottomSheetDialogFragment.java @@ -14,7 +14,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import net.osmand.AndroidUtils; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; @@ -63,7 +62,7 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment } ((ImageView) mainView.findViewById(R.id.sort_by_icon)).setImageDrawable(getContentIcon(R.drawable.ic_sort_waypoint_dark)); - OsmandSettings.MapMarkersMode mode = getMyApplication().getSettings().MAP_MARKERS_MODE.get(); + MapMarkersMode mode = getMyApplication().getSettings().MAP_MARKERS_MODE.get(); int displayedCount = getMyApplication().getSettings().DISPLAYED_MARKERS_WIDGETS_COUNT.get(); ImageView showDirectionIcon = (ImageView) mainView.findViewById(R.id.show_direction_icon); int imageResId = 0; diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index 24d3ec8282..c155ec493c 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -25,6 +25,7 @@ import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.GpxTrackAdapter.OnItemClickListener; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.plus.helpers.enums.TracksSortByMode; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; @@ -38,7 +39,6 @@ import java.util.Map; import static net.osmand.plus.SimplePopUpMenuItemAdapter.*; import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo; -import static net.osmand.plus.settings.backend.OsmandSettings.*; import static net.osmand.util.Algorithms.collectDirs; public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index fae190ea01..31cb5375fe 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -84,7 +84,7 @@ import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.TracksSortByMode; +import net.osmand.plus.helpers.enums.TracksSortByMode; import java.io.File; import java.text.DateFormat; diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java index f99046de4d..4451354fc8 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java @@ -58,8 +58,6 @@ import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.measurementtool.GpxData; import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; import net.osmand.plus.track.GpxSplitType; import net.osmand.plus.track.SplitTrackAsyncTask; import net.osmand.plus.track.SplitTrackAsyncTask.SplitTrackListener; diff --git a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java index bc0ff794c5..d131721376 100644 --- a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java +++ b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java @@ -7,7 +7,6 @@ import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.format.DateFormat; -import android.text.format.Time; import android.view.View; import android.widget.ArrayAdapter; import android.widget.CheckBox; @@ -36,20 +35,15 @@ import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.quickaction.QuickActionType; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.layers.MapInfoLayer; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.Date; import java.util.List; -import java.util.Locale; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MARK_AS_PARKING_LOC; diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java index 0be5c0f715..8314341371 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/DayNightModeAction.java @@ -6,8 +6,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.DayNightMode; +import net.osmand.plus.helpers.enums.DayNightMode; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.quickaction.QuickAction; @@ -27,9 +26,9 @@ public class DayNightModeAction extends QuickAction { @Override public void execute(MapActivity activity) { if (activity.getMyApplication().getDaynightHelper().isNightMode()) { - activity.getMyApplication().getSettings().DAYNIGHT_MODE.set(OsmandSettings.DayNightMode.DAY); + activity.getMyApplication().getSettings().DAYNIGHT_MODE.set(DayNightMode.DAY); } else { - activity.getMyApplication().getSettings().DAYNIGHT_MODE.set(OsmandSettings.DayNightMode.NIGHT); + activity.getMyApplication().getSettings().DAYNIGHT_MODE.set(DayNightMode.NIGHT); } } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/LayerTransparencySeekbarMode.java b/OsmAnd/src/net/osmand/plus/rastermaps/LayerTransparencySeekbarMode.java new file mode 100644 index 0000000000..1fd8b2f91d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/rastermaps/LayerTransparencySeekbarMode.java @@ -0,0 +1,22 @@ +package net.osmand.plus.rastermaps; + +import android.content.Context; + +import net.osmand.plus.R; + +public enum LayerTransparencySeekbarMode { + OVERLAY(R.string.overlay_transparency), + UNDERLAY(R.string.map_transparency), + OFF(R.string.shared_string_off), + UNDEFINED(R.string.shared_string_none); + + private final int key; + + LayerTransparencySeekbarMode(int key) { + this.key = key; + } + + public String toHumanString(Context ctx) { + return ctx.getString(key); + } +} diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java index 575196f8a2..7972b264aa 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java @@ -16,7 +16,6 @@ import com.google.gson.reflect.TypeToken; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -137,7 +136,7 @@ public class MapOverlayAction extends SwitchableAction> { if (settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.get() == LayerTransparencySeekbarMode.UNDEFINED) { settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.set(LayerTransparencySeekbarMode.OVERLAY); } - if (settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.get() == OsmandSettings.LayerTransparencySeekbarMode.OVERLAY) { + if (settings.LAYER_TRANSPARENCY_SEEKBAR_MODE.get() == LayerTransparencySeekbarMode.OVERLAY) { activity.getMapLayers().getMapControlsLayer().showTransparencyBar(settings.MAP_OVERLAY_TRANSPARENCY, true); } } else { diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java index d938174c1f..ca79cb4895 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java @@ -17,7 +17,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java index 5d79637b1a..942a34cbf1 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java @@ -31,7 +31,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.activities.DownloadTilesDialog; @@ -41,9 +40,6 @@ import net.osmand.plus.activities.MapActivityLayers; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.dialogs.RasterMapMenu; import net.osmand.plus.quickaction.QuickActionType; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.views.MapTileLayer; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.util.Algorithms; @@ -562,10 +558,10 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { } MapActivityLayers mapLayers = mapActivity.getMapLayers(); ITileSource map = layer.getMap(); - final OsmandSettings.LayerTransparencySeekbarMode currentMapTypeSeekbarMode = type == + final LayerTransparencySeekbarMode currentMapTypeSeekbarMode = type == OsmandRasterMapsPlugin.RasterMapType.OVERLAY - ? OsmandSettings.LayerTransparencySeekbarMode.OVERLAY - : OsmandSettings.LayerTransparencySeekbarMode.UNDERLAY; + ? LayerTransparencySeekbarMode.OVERLAY + : LayerTransparencySeekbarMode.UNDERLAY; if (map != null) { mapTypePreference.set(null); if (callback != null) { diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java index 7c8238e7a1..927a085c8c 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java @@ -105,9 +105,6 @@ import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.TransportRoutingHelper; import net.osmand.plus.search.QuickSearchHelper; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.widgets.TextViewExProgress; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 6a5599fa1a..a21b8898e6 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -30,13 +30,10 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.Version; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.GeneralRouter.RoutingParameterType; import net.osmand.router.PrecalculatedRouteDirection; -import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteExporter; import net.osmand.router.RouteImporter; import net.osmand.router.RoutePlannerFrontEnd; diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 4fd5b1dd65..e92c8c0504 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -21,6 +21,7 @@ import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.notifications.OsmandNotification.NotificationType; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; @@ -408,8 +409,8 @@ public class RoutingHelper { } else if (mode.getRouteService() == RouteService.DIRECT_TO) { return -1.0f; } else if (mode.getRouteService() == RouteService.STRAIGHT) { - OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.getModeValue(mode); - if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS || mc == OsmandSettings.MetricsConstants.MILES_AND_METERS) { + MetricsConstants mc = settings.METRIC_SYSTEM.getModeValue(mode); + if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) { return 500.f; } else { // 1/4 mile diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java index c376b6a99a..145a566b77 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanAccessibilityPreference.java @@ -1,7 +1,5 @@ package net.osmand.plus.settings.backend; -import net.osmand.plus.ApplicationMode; - class BooleanAccessibilityPreference extends BooleanPreference { BooleanAccessibilityPreference(OsmandSettings osmandSettings, String id, boolean defaultValue) { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java new file mode 100644 index 0000000000..8ca99f8521 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java @@ -0,0 +1,25 @@ +package net.osmand.plus.settings.backend; + +public class BooleanStringPreference extends BooleanPreference { + + public BooleanStringPreference(OsmandSettings osmandSettings, String id, boolean defaultValue) { + super(osmandSettings, id, defaultValue); + } + + @Override + public Boolean getValue(Object prefs, Boolean defaultValue) { + Boolean value; + try { + value = parseString(getSettingsAPI().getString(prefs, getId(), defaultValue.toString())); + } catch (ClassCastException e) { + value = getSettingsAPI().getBoolean(prefs, getId(), defaultValue); + setValue(prefs, value); + } + return value; + } + + @Override + protected boolean setValue(Object prefs, Boolean val) { + return getSettingsAPI().edit(prefs).putString(getId(), val != null ? val.toString() : null).commit(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java index 0a53139dc1..ea1c251375 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java @@ -1,6 +1,5 @@ package net.osmand.plus.settings.backend; -import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.api.SettingsAPI; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java index ff611593cc..661a42341a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ListStringPreference.java @@ -1,7 +1,5 @@ package net.osmand.plus.settings.backend; -import net.osmand.plus.ApplicationMode; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java index d4eaf070f2..135055c234 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndPreferencesDataStore.java @@ -1,7 +1,5 @@ package net.osmand.plus.settings.backend; -import net.osmand.plus.ApplicationMode; - import java.util.Set; import androidx.annotation.NonNull; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java index ae9a3f5e3a..897f9c22b0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandPreference.java @@ -1,7 +1,6 @@ package net.osmand.plus.settings.backend; import net.osmand.StateChangedListener; -import net.osmand.plus.ApplicationMode; import org.json.JSONException; import org.json.JSONObject; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 6a00a9f5a3..f66f81de57 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -6,29 +6,19 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; -import android.hardware.Sensor; -import android.hardware.SensorManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Build; import android.os.Environment; -import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.StringRes; import androidx.core.util.Pair; -import androidx.preference.PreferenceDataStore; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; +import net.osmand.FileUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.ValueHolder; -import net.osmand.data.FavouritePoint; -import net.osmand.aidl.OsmandAidlApi; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.map.ITileSource; @@ -36,8 +26,6 @@ import net.osmand.map.TileSourceManager; import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.osm.MapPoiTypes; import net.osmand.osm.io.NetworkUtils; -import net.osmand.plus.ApplicationMode; -import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; @@ -46,19 +34,30 @@ import net.osmand.plus.access.RelativeDirectionStyle; import net.osmand.plus.api.SettingsAPI; import net.osmand.plus.api.SettingsAPI.SettingsEditor; import net.osmand.plus.api.SettingsAPIImpl; +import net.osmand.plus.audionotes.NotesSortByMode; import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment.RateUsState; +import net.osmand.plus.helpers.enums.AngularConstants; +import net.osmand.plus.helpers.enums.AutoZoomMap; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; +import net.osmand.plus.helpers.enums.DayNightMode; +import net.osmand.plus.helpers.enums.DrivingRegion; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.helpers.SearchHistoryHelper; +import net.osmand.plus.helpers.enums.SpeedConstants; +import net.osmand.plus.helpers.enums.TracksSortByMode; import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format; +import net.osmand.plus.mapmarkers.MapMarkersMode; import net.osmand.plus.profiles.LocationIcon; import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.ProfileIconColors; +import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode; import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.routing.RouteProvider.RouteService; -import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; -import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBuilder; +import net.osmand.plus.srtmplugin.TerrainMode; +import net.osmand.plus.views.layers.RulerMode; import net.osmand.plus.voice.CommandPlayer; +import net.osmand.plus.wikipedia.WikiArticleShowImages; import net.osmand.render.RenderingRulesStorage; import net.osmand.util.Algorithms; @@ -78,7 +77,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; @@ -213,7 +211,7 @@ public class OsmandSettings { } // TODO doesn't look correct package visibility - public Object getProfilePreferences(String modeKey) { + Object getProfilePreferences(String modeKey) { return settingsAPI.getPreferenceObject(getSharedPreferencesNameForKey(modeKey)); } @@ -693,51 +691,47 @@ public class OsmandSettings { return false; } - public final CommonPreference RULER_MODE = new EnumStringPreference<>("ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal(); + public final CommonPreference RULER_MODE = new EnumStringPreference<>(this, "ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal(); - public final OsmandPreference SHOW_COMPASS_CONTROL_RULER = new BooleanPreference("show_compass_ruler", true).makeGlobal(); + public final OsmandPreference SHOW_COMPASS_CONTROL_RULER = new BooleanPreference(this, "show_compass_ruler", true).makeGlobal(); - public final CommonPreference SHOW_LINES_TO_FIRST_MARKERS = new BooleanPreference("show_lines_to_first_markers", false).makeProfile(); - public final CommonPreference SHOW_ARROWS_TO_FIRST_MARKERS = new BooleanPreference("show_arrows_to_first_markers", false).makeProfile(); + public final CommonPreference SHOW_LINES_TO_FIRST_MARKERS = new BooleanPreference(this, "show_lines_to_first_markers", false).makeProfile(); + public final CommonPreference SHOW_ARROWS_TO_FIRST_MARKERS = new BooleanPreference(this, "show_arrows_to_first_markers", false).makeProfile(); - public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES_ASKED = new BooleanPreference("wikivoyage_show_images_asked", false).makeGlobal(); - public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES = new EnumStringPreference<>("wikivoyage_show_imgs", WikiArticleShowImages.OFF, WikiArticleShowImages.values()).makeGlobal(); - public final CommonPreference GLOBAL_WIKIPEDIA_POI_ENABLED = new BooleanPreference("global_wikipedia_poi_enabled", false).makeProfile(); - public final ListStringPreference WIKIPEDIA_POI_ENABLED_LANGUAGES = (ListStringPreference) new ListStringPreference("wikipedia_poi_enabled_languages", null, ",").makeProfile().cache(); + public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES_ASKED = new BooleanPreference(this, "wikivoyage_show_images_asked", false).makeGlobal(); + public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES = new EnumStringPreference<>(this, "wikivoyage_show_imgs", WikiArticleShowImages.OFF, WikiArticleShowImages.values()).makeGlobal(); + public final CommonPreference GLOBAL_WIKIPEDIA_POI_ENABLED = new BooleanPreference(this, "global_wikipedia_poi_enabled", false).makeProfile(); + public final ListStringPreference WIKIPEDIA_POI_ENABLED_LANGUAGES = (ListStringPreference) new ListStringPreference(this, "wikipedia_poi_enabled_languages", null, ",").makeProfile().cache(); - public final CommonPreference SELECT_MARKER_ON_SINGLE_TAP = new BooleanPreference("select_marker_on_single_tap", false).makeProfile(); - public final CommonPreference KEEP_PASSED_MARKERS_ON_MAP = new BooleanPreference("keep_passed_markers_on_map", true).makeProfile(); + public final CommonPreference SELECT_MARKER_ON_SINGLE_TAP = new BooleanPreference(this, "select_marker_on_single_tap", false).makeProfile(); + public final CommonPreference KEEP_PASSED_MARKERS_ON_MAP = new BooleanPreference(this, "keep_passed_markers_on_map", true).makeProfile(); - public final CommonPreference COORDS_INPUT_USE_RIGHT_SIDE = new BooleanPreference("coords_input_use_right_side", true).makeGlobal(); - public final OsmandPreference COORDS_INPUT_FORMAT = new EnumStringPreference<>("coords_input_format", Format.DD_MM_MMM, Format.values()).makeGlobal(); - public final CommonPreference COORDS_INPUT_USE_OSMAND_KEYBOARD = new BooleanPreference("coords_input_use_osmand_keyboard", Build.VERSION.SDK_INT >= 16).makeGlobal(); - public final CommonPreference COORDS_INPUT_TWO_DIGITS_LONGTITUDE = new BooleanPreference("coords_input_two_digits_longitude", false).makeGlobal(); + public final CommonPreference COORDS_INPUT_USE_RIGHT_SIDE = new BooleanPreference(this, "coords_input_use_right_side", true).makeGlobal(); + public final OsmandPreference COORDS_INPUT_FORMAT = new EnumStringPreference<>(this, "coords_input_format", Format.DD_MM_MMM, Format.values()).makeGlobal(); + public final CommonPreference COORDS_INPUT_USE_OSMAND_KEYBOARD = new BooleanPreference(this, "coords_input_use_osmand_keyboard", Build.VERSION.SDK_INT >= 16).makeGlobal(); + public final CommonPreference COORDS_INPUT_TWO_DIGITS_LONGTITUDE = new BooleanPreference(this, "coords_input_two_digits_longitude", false).makeGlobal(); - public final CommonPreference USE_MAPILLARY_FILTER = new BooleanPreference("use_mapillary_filters", false).makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_USER_KEY = new StringPreference("mapillary_filter_user_key", "").makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_USERNAME = new StringPreference("mapillary_filter_username", "").makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_FROM_DATE = new LongPreference("mapillary_filter_from_date", 0).makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_TO_DATE = new LongPreference("mapillary_filter_to_date", 0).makeGlobal(); - public final CommonPreference MAPILLARY_FILTER_PANO = new BooleanPreference("mapillary_filter_pano", false).makeGlobal(); + public final CommonPreference USE_MAPILLARY_FILTER = new BooleanPreference(this, "use_mapillary_filters", false).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_USER_KEY = new StringPreference(this, "mapillary_filter_user_key", "").makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_USERNAME = new StringPreference(this, "mapillary_filter_username", "").makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_FROM_DATE = new LongPreference(this, "mapillary_filter_from_date", 0).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_TO_DATE = new LongPreference(this, "mapillary_filter_to_date", 0).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_PANO = new BooleanPreference(this, "mapillary_filter_pano", false).makeGlobal(); - public final CommonPreference USE_FAST_RECALCULATION = new BooleanPreference("use_fast_recalculation", true).makeGlobal().cache(); - public final CommonPreference FORCE_PRIVATE_ACCESS_ROUTING_ASKED = new BooleanPreference("force_private_access_routing", false).makeProfile().cache(); + public final CommonPreference USE_FAST_RECALCULATION = new BooleanPreference(this, "use_fast_recalculation", true).makeGlobal().cache(); + public final CommonPreference FORCE_PRIVATE_ACCESS_ROUTING_ASKED = new BooleanPreference(this, "force_private_access_routing", false).makeProfile().cache(); - public final CommonPreference SHOW_CARD_TO_CHOOSE_DRAWER = new BooleanPreference("show_card_to_choose_drawer", false).makeGlobal(); - public final CommonPreference SHOW_DASHBOARD_ON_START = new BooleanPreference("should_show_dashboard_on_start", false).makeGlobal(); - public final CommonPreference SHOW_DASHBOARD_ON_MAP_SCREEN = new BooleanPreference("show_dashboard_on_map_screen", false).makeGlobal(); - public final CommonPreference SHOW_OSMAND_WELCOME_SCREEN = new BooleanPreference("show_osmand_welcome_screen", true).makeGlobal(); + public final CommonPreference SHOW_CARD_TO_CHOOSE_DRAWER = new BooleanPreference(this, "show_card_to_choose_drawer", false).makeGlobal(); + public final CommonPreference SHOW_DASHBOARD_ON_START = new BooleanPreference(this, "should_show_dashboard_on_start", false).makeGlobal(); + public final CommonPreference SHOW_DASHBOARD_ON_MAP_SCREEN = new BooleanPreference(this, "show_dashboard_on_map_screen", false).makeGlobal(); + public final CommonPreference SHOW_OSMAND_WELCOME_SCREEN = new BooleanPreference(this, "show_osmand_welcome_screen", true).makeGlobal(); - public final CommonPreference API_NAV_DRAWER_ITEMS_JSON = new StringPreference("api_nav_drawer_items_json", "{}").makeGlobal(); - public final CommonPreference API_CONNECTED_APPS_JSON = new StringPreference("api_connected_apps_json", "[]").makeGlobal(); - public final CommonPreference NAV_DRAWER_LOGO = new StringPreference("drawer_logo", "").makeProfile(); - public final CommonPreference NAV_DRAWER_URL = new StringPreference("drawer_url", "").makeProfile(); + public final CommonPreference API_NAV_DRAWER_ITEMS_JSON = new StringPreference(this, "api_nav_drawer_items_json", "{}").makeGlobal(); + public final CommonPreference API_CONNECTED_APPS_JSON = new StringPreference(this, "api_connected_apps_json", "[]").makeGlobal(); + public final CommonPreference NAV_DRAWER_LOGO = new StringPreference(this, "drawer_logo", "").makeProfile(); + public final CommonPreference NAV_DRAWER_URL = new StringPreference(this, "drawer_url", "").makeProfile(); - public final CommonPreference NUMBER_OF_STARTS_FIRST_XMAS_SHOWN = new IntPreference("number_of_starts_first_xmas_shown", 0).makeGlobal(); - - public final OsmandPreference AVAILABLE_APP_MODES = new StringPreference("available_application_modes", "car,bicycle,pedestrian,public_transport,").makeGlobal().cache(); - - public final OsmandPreference LAST_FAV_CATEGORY_ENTERED = new StringPreference("last_fav_category", "").makeGlobal(); + public final CommonPreference NUMBER_OF_STARTS_FIRST_XMAS_SHOWN = new IntPreference(this, "number_of_starts_first_xmas_shown", 0).makeGlobal(); public final OsmandPreference AVAILABLE_APP_MODES = new StringPreference(this, "available_application_modes", "car,bicycle,pedestrian,public_transport,").makeGlobal().cache(); @@ -844,22 +838,7 @@ public class OsmandSettings { } protected DrivingRegion getDefaultValue() { - Locale df = Locale.getDefault(); - if (df == null) { - return DrivingRegion.EUROPE_ASIA; - } - if (df.getCountry().equalsIgnoreCase(Locale.US.getCountry())) { - return DrivingRegion.US; - } else if (df.getCountry().equalsIgnoreCase(Locale.CANADA.getCountry())) { - return DrivingRegion.CANADA; - } else if (df.getCountry().equalsIgnoreCase(Locale.JAPAN.getCountry())) { - return DrivingRegion.JAPAN; - } else if (df.getCountry().equalsIgnoreCase("au")) { - return DrivingRegion.AUSTRALIA; - } else if(df.getCountry().equalsIgnoreCase(Locale.UK.getCountry())) { - return DrivingRegion.UK_AND_OTHERS; - } - return DrivingRegion.EUROPE_ASIA; + return DrivingRegion.getDrivingRegionByLocale(); } }.makeProfile().cache(); @@ -1040,31 +1019,31 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference ACCESSIBILITY_SMART_AUTOANNOUNCE = new BooleanAccessibilityPreference(this, "accessibility_smart_autoannounce", true).makeProfile(); - + // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often public final OsmandPreference ACCESSIBILITY_AUTOANNOUNCE_PERIOD = new IntPreference(this, "accessibility_autoannounce_period", 10000).makeProfile().cache(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DISABLE_OFFROUTE_RECALC = - new BooleanPreference(this,"disable_offroute_recalc", false).makeProfile(); + new BooleanPreference(this, "disable_offroute_recalc", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DISABLE_WRONG_DIRECTION_RECALC = - new BooleanPreference("disable_wrong_direction_recalc", false).makeProfile(); - + new BooleanPreference(this, "disable_wrong_direction_recalc", false).makeProfile(); + // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DIRECTION_AUDIO_FEEDBACK = - new BooleanAccessibilityPreference(this, "direction_audio_feedback", false).makeProfile(); - + new BooleanAccessibilityPreference(this, "direction_audio_feedback", false).makeProfile(); + // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DIRECTION_HAPTIC_FEEDBACK = - new BooleanAccessibilityPreference(this, "direction_haptic_feedback", false).makeProfile(); + new BooleanAccessibilityPreference(this, "direction_haptic_feedback", false).makeProfile(); // magnetic field doesn'torkmost of the time on some phones - public final OsmandPreference USE_MAGNETIC_FIELD_SENSOR_COMPASS = new BooleanPreference("use_magnetic_field_sensor_compass", false).makeProfile().cache(); - public final OsmandPreference USE_KALMAN_FILTER_FOR_COMPASS = new BooleanPreference("use_kalman_filter_compass", true).makeProfile().cache(); - public final OsmandPreference USE_VOLUME_BUTTONS_AS_ZOOM = new BooleanPreference("use_volume_buttons_as_zoom", false).makeProfile().cache(); + public final OsmandPreference USE_MAGNETIC_FIELD_SENSOR_COMPASS = new BooleanPreference(this, "use_magnetic_field_sensor_compass", false).makeProfile().cache(); + public final OsmandPreference USE_KALMAN_FILTER_FOR_COMPASS = new BooleanPreference(this, "use_kalman_filter_compass", true).makeProfile().cache(); + public final OsmandPreference USE_VOLUME_BUTTONS_AS_ZOOM = new BooleanPreference(this, "use_volume_buttons_as_zoom", false).makeProfile().cache(); public final OsmandPreference DO_NOT_SHOW_STARTUP_MESSAGES = new BooleanPreference(this, "do_not_show_startup_messages", false).makeGlobal().cache(); public final OsmandPreference SHOW_DOWNLOAD_MAP_DIALOG = new BooleanPreference(this, "show_download_map_dialog", true).makeGlobal().cache(); @@ -1117,23 +1096,23 @@ public class OsmandSettings { public final OsmandPreference INAPPS_READ = new BooleanPreference(this, "inapps_read", false).makeGlobal(); - public final OsmandPreference BILLING_USER_ID = new StringPreference("billing_user_id", "").makeGlobal(); - public final OsmandPreference BILLING_USER_TOKEN = new StringPreference("billing_user_token", "").makeGlobal(); - public final OsmandPreference BILLING_USER_NAME = new StringPreference("billing_user_name", "").makeGlobal(); - public final OsmandPreference BILLING_USER_EMAIL = new StringPreference("billing_user_email", "").makeGlobal(); - public final OsmandPreference BILLING_USER_COUNTRY = new StringPreference("billing_user_country", "").makeGlobal(); - public final OsmandPreference BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", BILLING_USER_DONATION_NONE_PARAMETER).makeGlobal(); - public final OsmandPreference BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal(); - public final OsmandPreference BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal(); - public final OsmandPreference BILLING_PURCHASE_TOKENS_SENT = new StringPreference("billing_purchase_tokens_sent", "").makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASED = new BooleanPreference("billing_live_updates_purchased", false).makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_TIME = new LongPreference("live_updates_purchase_cancelled_time", 0).makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN = new BooleanPreference("live_updates_purchase_cancelled_first_dlg_shown", false).makeGlobal(); - public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN = new BooleanPreference("live_updates_purchase_cancelled_second_dlg_shown", false).makeGlobal(); - public final OsmandPreference FULL_VERSION_PURCHASED = new BooleanPreference("billing_full_version_purchased", false).makeGlobal(); - public final OsmandPreference DEPTH_CONTOURS_PURCHASED = new BooleanPreference("billing_sea_depth_purchased", false).makeGlobal(); - public final OsmandPreference CONTOUR_LINES_PURCHASED = new BooleanPreference("billing_srtm_purchased", false).makeGlobal(); - public final OsmandPreference EMAIL_SUBSCRIBED = new BooleanPreference("email_subscribed", false).makeGlobal(); + public final OsmandPreference BILLING_USER_ID = new StringPreference(this, "billing_user_id", "").makeGlobal(); + public final OsmandPreference BILLING_USER_TOKEN = new StringPreference(this, "billing_user_token", "").makeGlobal(); + public final OsmandPreference BILLING_USER_NAME = new StringPreference(this, "billing_user_name", "").makeGlobal(); + public final OsmandPreference BILLING_USER_EMAIL = new StringPreference(this, "billing_user_email", "").makeGlobal(); + public final OsmandPreference BILLING_USER_COUNTRY = new StringPreference(this, "billing_user_country", "").makeGlobal(); + public final OsmandPreference BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference(this, "billing_user_country_download_name", BILLING_USER_DONATION_NONE_PARAMETER).makeGlobal(); + public final OsmandPreference BILLING_HIDE_USER_NAME = new BooleanPreference(this, "billing_hide_user_name", false).makeGlobal(); + public final OsmandPreference BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference(this, "billing_purchase_token_sent", false).makeGlobal(); + public final OsmandPreference BILLING_PURCHASE_TOKENS_SENT = new StringPreference(this, "billing_purchase_tokens_sent", "").makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASED = new BooleanPreference(this, "billing_live_updates_purchased", false).makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_TIME = new LongPreference(this, "live_updates_purchase_cancelled_time", 0).makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_FIRST_DLG_SHOWN = new BooleanPreference(this, "live_updates_purchase_cancelled_first_dlg_shown", false).makeGlobal(); + public final OsmandPreference LIVE_UPDATES_PURCHASE_CANCELLED_SECOND_DLG_SHOWN = new BooleanPreference(this, "live_updates_purchase_cancelled_second_dlg_shown", false).makeGlobal(); + public final OsmandPreference FULL_VERSION_PURCHASED = new BooleanPreference(this, "billing_full_version_purchased", false).makeGlobal(); + public final OsmandPreference DEPTH_CONTOURS_PURCHASED = new BooleanPreference(this, "billing_sea_depth_purchased", false).makeGlobal(); + public final OsmandPreference CONTOUR_LINES_PURCHASED = new BooleanPreference(this, "billing_srtm_purchased", false).makeGlobal(); + public final OsmandPreference EMAIL_SUBSCRIBED = new BooleanPreference(this, "email_subscribed", false).makeGlobal(); public final OsmandPreference DISCOUNT_ID = new IntPreference(this, "discount_id", 0).makeGlobal(); public final OsmandPreference DISCOUNT_SHOW_NUMBER_OF_STARTS = new IntPreference(this, "number_of_starts_on_discount_show", 0).makeGlobal(); @@ -1284,17 +1263,19 @@ public class OsmandSettings { { SPEAK_TRAFFIC_WARNINGS.setModeDefaultValue(ApplicationMode.CAR, true); } + public final CommonPreference SPEAK_PEDESTRIAN = new BooleanPreference(this, "speak_pedestrian", false).makeProfile().cache(); + { SPEAK_PEDESTRIAN.setModeDefaultValue(ApplicationMode.CAR, true); } + public final OsmandPreference SPEAK_SPEED_LIMIT = new BooleanPreference(this, "speak_speed_limit", false).makeProfile().cache(); public final OsmandPreference SPEAK_SPEED_CAMERA = new BooleanPreference(this, "speak_cameras", false).makeProfile().cache(); public final OsmandPreference SPEAK_TUNNELS = new BooleanPreference(this, "speak_tunnels", false).makeProfile().cache(); - public final OsmandPreference ANNOUNCE_WPT = new BooleanPreference(this, "announce_wpt", true) { - public final OsmandPreference SPEED_CAMERAS_UNINSTALLED = new BooleanPreference("speed_cameras_uninstalled", false).makeGlobal(); - public final OsmandPreference SPEED_CAMERAS_ALERT_SHOWED = new BooleanPreference("speed_cameras_alert_showed", false).makeGlobal(); + public final OsmandPreference SPEED_CAMERAS_UNINSTALLED = new BooleanPreference(this, "speed_cameras_uninstalled", false).makeGlobal(); + public final OsmandPreference SPEED_CAMERAS_ALERT_SHOWED = new BooleanPreference(this, "speed_cameras_alert_showed", false).makeGlobal(); public Set getForbiddenTypes() { Set typeNames = new HashSet<>(); @@ -1304,7 +1285,7 @@ public class OsmandSettings { return typeNames; } - public final OsmandPreference ANNOUNCE_WPT = new BooleanPreference("announce_wpt", true) { + public final OsmandPreference ANNOUNCE_WPT = new BooleanPreference(this, "announce_wpt", true) { @Override protected boolean setValue(Object prefs, Boolean val) { boolean valueSaved = super.setValue(prefs, val); @@ -1343,11 +1324,7 @@ public class OsmandSettings { public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference(this, "gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference(this, "gpx_routing_calculate_rtept", true).makeGlobal().cache(); public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference(this, "calc_gpx_route", false).makeGlobal().cache(); - public final OsmandPreference SHOW_START_FINISH_ICONS = new BooleanPreference("show_start_finish_icons", true).makeGlobal().cache(); - - public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); -// public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache(); - public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); + public final OsmandPreference SHOW_START_FINISH_ICONS = new BooleanPreference(this, "show_start_finish_icons", true).makeGlobal().cache(); public final OsmandPreference AVOID_TOLL_ROADS = new BooleanPreference(this, "avoid_toll_roads", false).makeProfile().cache(); public final OsmandPreference AVOID_MOTORWAY = new BooleanPreference(this, "avoid_motorway", false).makeProfile().cache(); @@ -1358,11 +1335,11 @@ public class OsmandSettings { public final OsmandPreference LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal(); - public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference("current_track_color", 0).makeGlobal().cache(); - public final CommonPreference CURRENT_TRACK_WIDTH = new StringPreference("current_track_width", "").makeGlobal().cache(); - public final CommonPreference CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference("current_track_show_arrows", false).makeGlobal().cache(); - public final CommonPreference CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference("current_track_show_start_finish", true).makeGlobal().cache(); - public final ListStringPreference CUSTOM_TRACK_COLORS = (ListStringPreference) new ListStringPreference("custom_track_colors", null, ",").makeGlobal(); + public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().cache(); + public final CommonPreference CURRENT_TRACK_WIDTH = new StringPreference(this, "current_track_width", "").makeGlobal().cache(); + public final CommonPreference CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference(this, "current_track_show_arrows", false).makeGlobal().cache(); + public final CommonPreference CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference(this, "current_track_show_start_finish", true).makeGlobal().cache(); + public final ListStringPreference CUSTOM_TRACK_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_track_colors", null, ",").makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public final CommonPreference SAVE_TRACK_INTERVAL = new IntPreference(this, "save_track_interval", 5000).makeProfile(); @@ -1372,7 +1349,7 @@ public class OsmandSettings { SAVE_TRACK_INTERVAL.setModeDefaultValue(ApplicationMode.BICYCLE, 5000); SAVE_TRACK_INTERVAL.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 10000); } - + // Please note that SAVE_TRACK_MIN_DISTANCE, SAVE_TRACK_PRECISION, SAVE_TRACK_MIN_SPEED should all be "0" for the default profile, as we have no interface to change them public final CommonPreference SAVE_TRACK_MIN_DISTANCE = new FloatPreference(this, "save_track_min_distance", 0).makeProfile(); //{ @@ -1420,6 +1397,7 @@ public class OsmandSettings { public final CommonPreference SHOW_OSM_BUGS_MIN_ZOOM = new IntPreference(this, "show_osm_bugs_min_zoom", 8).makeProfile().cache(); public final CommonPreference MAP_INFO_CONTROLS = new StringPreference(this, "map_info_controls", "").makeProfile(); + { for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { MAP_INFO_CONTROLS.setModeDefaultValue(mode, ""); @@ -1474,7 +1452,7 @@ public class OsmandSettings { KEEP_INFORMING.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 0); } - public final CommonPreference USE_SYSTEM_SCREEN_TIMEOUT = new BooleanPreference("use_system_screen_timeout", false).makeProfile(); + public final CommonPreference USE_SYSTEM_SCREEN_TIMEOUT = new BooleanPreference(this, "use_system_screen_timeout", false).makeProfile(); public final CommonPreference TURN_SCREEN_ON_TIME_INT = new IntPreference(this, "turn_screen_on_time_int", 0).makeProfile(); @@ -1485,16 +1463,16 @@ public class OsmandSettings { } public final CommonPreference TURN_SCREEN_ON_SENSOR = new BooleanPreference(this, "turn_screen_on_sensor", false).makeProfile(); - + { TURN_SCREEN_ON_SENSOR.setModeDefaultValue(ApplicationMode.CAR, false); TURN_SCREEN_ON_SENSOR.setModeDefaultValue(ApplicationMode.BICYCLE, false); TURN_SCREEN_ON_SENSOR.setModeDefaultValue(ApplicationMode.PEDESTRIAN, false); } - public final CommonPreference TURN_SCREEN_ON_NAVIGATION_INSTRUCTIONS = new BooleanPreference("turn_screen_on_navigation_instructions", false).makeProfile(); + public final CommonPreference TURN_SCREEN_ON_NAVIGATION_INSTRUCTIONS = new BooleanPreference(this, "turn_screen_on_navigation_instructions", false).makeProfile(); - public final CommonPreference TURN_SCREEN_ON_POWER_BUTTON = new BooleanPreference("turn_screen_on_power_button", false).makeProfile(); + public final CommonPreference TURN_SCREEN_ON_POWER_BUTTON = new BooleanPreference(this, "turn_screen_on_power_button", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name // try without AUTO_FOLLOW_ROUTE_NAV (see forum discussion 'Simplify our navigation preference menu') @@ -1567,7 +1545,8 @@ public class OsmandSettings { VOICE_PROMPT_DELAY[3] = new IntPreference(this, "voice_prompt_delay_3", 0).makeGlobal().cache(); /*AudioManager.STREAM_MUSIC*/ VOICE_PROMPT_DELAY[5] = new IntPreference(this, "voice_prompt_delay_5", 0).makeGlobal().cache(); /*AudioManager.STREAM_NOTIFICATION*/ } - public final OsmandPreference DISPLAY_TTS_UTTERANCE = new BooleanPreference("display_tts_utterance", false).makeGlobal(); + + public final OsmandPreference DISPLAY_TTS_UTTERANCE = new BooleanPreference(this, "display_tts_utterance", false).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name public final CommonPreference MAP_ONLINE_DATA = new BooleanPreference(this, "map_online_data", false).makeProfile(); @@ -1636,8 +1615,8 @@ public class OsmandSettings { public final OsmandPreference SHOW_COORDINATES_WIDGET = new BooleanPreference(this, "show_coordinates_widget", false).makeProfile().cache(); - public final CommonPreference NOTES_SORT_BY_MODE = new EnumStringPreference<>("notes_sort_by_mode", NotesSortByMode.BY_DATE, NotesSortByMode.values()); - public final CommonPreference TRACKS_SORT_BY_MODE = new EnumStringPreference<>("tracks_sort_by_mode", TracksSortByMode.BY_DATE, TracksSortByMode.values()); + public final CommonPreference NOTES_SORT_BY_MODE = new EnumStringPreference<>(this, "notes_sort_by_mode", NotesSortByMode.BY_DATE, NotesSortByMode.values()); + public final CommonPreference TRACKS_SORT_BY_MODE = new EnumStringPreference<>(this, "tracks_sort_by_mode", TracksSortByMode.BY_DATE, TracksSortByMode.values()); public final OsmandPreference ANIMATE_MY_LOCATION = new BooleanPreference(this, "animate_my_location", true).makeProfile().cache(); @@ -1791,7 +1770,7 @@ public class OsmandSettings { setExternalStorageDirectoryPre19(getInternalAppPath().getAbsolutePath()); } else { File externalStorage = getExternal1AppPath(); - if (externalStorage != null && OsmandSettings.isWritable(externalStorage)) { + if (externalStorage != null && FileUtils.isWritable(externalStorage)) { setExternalStorageDirectoryV19(EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE, getExternal1AppPath().getAbsolutePath()); } else { @@ -1843,7 +1822,7 @@ public class OsmandSettings { int type = settingsAPI.getInt(globalPreferences, EXTERNAL_STORAGE_DIR_TYPE_V19, -1); File location = getDefaultLocationV19(); if (type == -1) { - if (isWritable(location)) { + if (FileUtils.isWritable(location)) { if (tp != null) { tp.value = settingsAPI.contains(globalPreferences, EXTERNAL_STORAGE_DIR_V19) ? EXTERNAL_STORAGE_TYPE_SPECIFIED : @@ -1881,20 +1860,6 @@ public class OsmandSettings { return new File(location); } - - public static boolean isWritable(File dirToTest) { - boolean isWriteable = false; - try { - dirToTest.mkdirs(); - File writeTestFile = File.createTempFile("osmand_", ".tmp", dirToTest); - isWriteable = writeTestFile.exists(); - writeTestFile.delete(); - } catch (IOException e) { - isWriteable = false; - } - return isWriteable; - } - public boolean isExternalStorageDirectoryTypeSpecifiedV19() { return settingsAPI.contains(globalPreferences, EXTERNAL_STORAGE_DIR_TYPE_V19); } @@ -2008,10 +1973,6 @@ public class OsmandSettings { } } - private Object objectToShow; - private boolean editObjectToShow; - private String searchRequestToShow; - public void setSearchRequestToShow(String request) { this.searchRequestToShow = request; } @@ -2039,7 +2000,7 @@ public class OsmandSettings { } public void setMapLocationToShow(double latitude, double longitude, int zoom, PointDescription pointDescription, - boolean addToHistory, Object toShow) { + boolean addToHistory, Object toShow) { SettingsEditor edit = settingsAPI.edit(globalPreferences); edit.putFloat(MAP_LAT_TO_SHOW, (float) latitude); edit.putFloat(MAP_LON_TO_SHOW, (float) longitude); @@ -2103,7 +2064,6 @@ public class OsmandSettings { public final static String INTERMEDIATE_POINTS = "intermediate_points"; //$NON-NLS-1$ public final static String INTERMEDIATE_POINTS_DESCRIPTION = "intermediate_points_description"; //$NON-NLS-1$ - private IntermediatePointsStorage intermediatePointsStorage = new IntermediatePointsStorage(); public final static String POINT_NAVIGATE_LAT_BACKUP = "point_navigate_lat_backup"; //$NON-NLS-1$ public final static String POINT_NAVIGATE_LON_BACKUP = "point_navigate_lon_backup"; //$NON-NLS-1$ @@ -2363,7 +2323,7 @@ public class OsmandSettings { public static final String QUICK_FAB_MARGIN_X_LANDSCAPE_MARGIN = "quick_fab_margin_x_landscape_margin"; public static final String QUICK_FAB_MARGIN_Y_LANDSCAPE_MARGIN = "quick_fab_margin_y_landscape_margin"; - public final CommonPreference QUICK_ACTION = new BooleanPreference("quick_action_state", false).makeProfile(); + public final CommonPreference QUICK_ACTION = new BooleanPreference(this, "quick_action_state", false).makeProfile(); public final CommonPreference QUICK_ACTION_LIST = new StringPreference(this, "quick_action_list", "").makeGlobal(); @@ -2538,7 +2498,7 @@ public class OsmandSettings { public final ListStringPreference POI_FILTERS_ORDER = (ListStringPreference) new ListStringPreference(this, "poi_filters_order", null, ",,").makeProfile().cache(); - + public final ListStringPreference INACTIVE_POI_FILTERS = (ListStringPreference) new ListStringPreference(this, "inactive_poi_filters", null, ",,").makeProfile().cache(); @@ -2609,11 +2569,9 @@ public class OsmandSettings { RENDERER.setModeDefaultValue(ApplicationMode.SKI, RendererRegistry.WINTER_SKI_RENDER); } - Map> customRendersProps = new LinkedHashMap>(); - public CommonPreference getCustomRenderProperty(String attrName) { if (!customRendersProps.containsKey(attrName)) { - customRendersProps.put(attrName, new StringPreference(RENDERER_PREFERENCE_PREFIX + attrName, "").makeProfile()); + customRendersProps.put(attrName, new StringPreference(this, RENDERER_PREFERENCE_PREFIX + attrName, "").makeProfile()); } return customRendersProps.get(attrName); } @@ -2623,29 +2581,24 @@ public class OsmandSettings { getCustomRenderProperty("defAppMode"); } - Map> customBooleanRendersProps = new LinkedHashMap>(); - public CommonPreference getCustomRenderBooleanProperty(String attrName) { if (!customBooleanRendersProps.containsKey(attrName)) { - customBooleanRendersProps.put(attrName, new BooleanPreference(RENDERER_PREFERENCE_PREFIX + attrName, false).makeProfile()); + customBooleanRendersProps.put(attrName, new BooleanPreference(this, RENDERER_PREFERENCE_PREFIX + attrName, false).makeProfile()); } return customBooleanRendersProps.get(attrName); } - Map> customRoutingProps = new LinkedHashMap<>(); - public CommonPreference getCustomRoutingProperty(String attrName, String defValue) { if (!customRoutingProps.containsKey(attrName)) { - customRoutingProps.put(attrName, new StringPreference(ROUTING_PREFERENCE_PREFIX + attrName, defValue).makeProfile()); + customRoutingProps.put(attrName, new StringPreference(this, ROUTING_PREFERENCE_PREFIX + attrName, defValue).makeProfile()); } return customRoutingProps.get(attrName); } - Map> customBooleanRoutingProps = new LinkedHashMap<>(); public CommonPreference getCustomRoutingBooleanProperty(String attrName, boolean defaulfValue) { if (!customBooleanRoutingProps.containsKey(attrName)) { - customBooleanRoutingProps.put(attrName, new BooleanStringPreference(ROUTING_PREFERENCE_PREFIX + attrName, defaulfValue).makeProfile()); + customBooleanRoutingProps.put(attrName, new BooleanStringPreference(this, ROUTING_PREFERENCE_PREFIX + attrName, defaulfValue).makeProfile()); } return customBooleanRoutingProps.get(attrName); } @@ -2663,9 +2616,9 @@ public class OsmandSettings { public final OsmandPreference MAP_ACTIVITY_ENABLED = new BooleanPreference(this, "map_activity_enabled", false).makeGlobal(); // this value string is synchronized with settings_pref.xml preference name - public final OsmandPreference SAFE_MODE = new BooleanPreference("safe_mode", false).makeGlobal(); - public final OsmandPreference PT_SAFE_MODE = new BooleanPreference("pt_safe_mode", false).makeGlobal(); - public final OsmandPreference NATIVE_RENDERING_FAILED = new BooleanPreference("native_rendering_failed_init", false).makeGlobal(); + public final OsmandPreference SAFE_MODE = new BooleanPreference(this, "safe_mode", false).makeGlobal(); + public final OsmandPreference PT_SAFE_MODE = new BooleanPreference(this, "pt_safe_mode", false).makeGlobal(); + public final OsmandPreference NATIVE_RENDERING_FAILED = new BooleanPreference(this, "native_rendering_failed_init", false).makeGlobal(); public final OsmandPreference USE_OPENGL_RENDER = new BooleanPreference(this, "use_opengl_render", false /*Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH*/ @@ -2681,12 +2634,12 @@ public class OsmandSettings { public final OsmandPreference FOLLOW_THE_ROUTE = new BooleanPreference(this, "follow_to_route", false).makeGlobal(); public final OsmandPreference FOLLOW_THE_GPX_ROUTE = new StringPreference(this, "follow_gpx", null).makeGlobal(); - + public final OsmandPreference SELECTED_TRAVEL_BOOK = new StringPreference(this, "selected_travel_book", "").makeGlobal(); public final ListStringPreference DISPLAYED_TRANSPORT_SETTINGS = (ListStringPreference) new ListStringPreference(this, "displayed_transport_settings", null, ",").makeProfile(); - + public final OsmandPreference SHOW_ARRIVAL_TIME_OTHERWISE_EXPECTED_TIME = new BooleanPreference(this, "show_arrival_time", true).makeProfile(); @@ -2741,7 +2694,7 @@ public class OsmandSettings { new IntPreference(this, "FAVORITES_TAB", 0).makeGlobal().cache(); public final CommonPreference OSMAND_THEME = - new IntPreference("osmand_theme", OSMAND_LIGHT_THEME) { + new IntPreference(this, "osmand_theme", OSMAND_LIGHT_THEME) { @Override public void readFromJson(JSONObject json, ApplicationMode appMode) throws JSONException { Integer theme = parseString(json.getString(getId())); @@ -2792,7 +2745,6 @@ public class OsmandSettings { new BooleanPreference(this, "fluorescent_overlays", false).makeGlobal().cache(); - // public final OsmandPreference NUMBER_OF_FREE_DOWNLOADS_V2 = new IntPreference("free_downloads_v2", 0).makeGlobal(); public final OsmandPreference NUMBER_OF_FREE_DOWNLOADS = new IntPreference(this, NUMBER_OF_FREE_DOWNLOADS_ID, 0).makeGlobal(); @@ -2811,7 +2763,7 @@ public class OsmandSettings { new EnumStringPreference<>(this, "rate_us_state", RateUsState.INITIAL_STATE, RateUsState.values()).makeGlobal(); public final CommonPreference CUSTOM_APP_MODES_KEYS = - new StringPreference(this, "custom_app_modes_keys", "").makeGlobal().cache(); + new StringPreference(this, "custom_app_modes_keys", "").makeGlobal().cache(); public Set getCustomAppModesKeys() { String appModesKeys = CUSTOM_APP_MODES_KEYS.get(); @@ -2823,6 +2775,16 @@ public class OsmandSettings { return res; } + public void setQuickActions(HashMap quickActions, ApplicationMode mode) { + if (!QUICK_ACTION.isSetForMode(mode)) { + Boolean actionState = quickActions.get(mode.getStringKey()); + if (actionState == null) { + actionState = QUICK_ACTION.getDefaultValue(); + } + setPreference(QUICK_ACTION.getId(), actionState, mode); + } + } + public String[] getAppModeBeanPrefsIds() { return new String[]{ ICON_COLOR.getId(), @@ -2871,305 +2833,4 @@ public class OsmandSettings { DRIVING_REGION_AUTOMATIC }; } - - public enum DayNightMode { - AUTO(R.string.daynight_mode_auto, R.drawable.ic_action_map_sunset), - DAY(R.string.daynight_mode_day, R.drawable.ic_action_map_day), - NIGHT(R.string.daynight_mode_night, R.drawable.ic_action_map_night), - SENSOR(R.string.daynight_mode_sensor, R.drawable.ic_action_map_light_sensor); - - private final int key; - @DrawableRes - private final int drawableRes; - - DayNightMode(@StringRes int key, @DrawableRes int drawableRes) { - this.key = key; - this.drawableRes = drawableRes; - } - - public String toHumanString(Context ctx) { - return ctx.getString(key); - } - - @DrawableRes - public int getIconRes() { - return drawableRes; - } - - public boolean isSensor() { - return this == SENSOR; - } - - public boolean isAuto() { - return this == AUTO; - } - - public boolean isDay() { - return this == DAY; - } - - public boolean isNight() { - return this == NIGHT; - } - - public static DayNightMode[] possibleValues(Context context) { - SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); - Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); - boolean isLightSensorEnabled = mLight != null; - if (isLightSensorEnabled) { - return DayNightMode.values(); - } else { - return new DayNightMode[]{AUTO, DAY, NIGHT}; - } - } - } - - - public enum LayerTransparencySeekbarMode { - OVERLAY(R.string.overlay_transparency), - UNDERLAY(R.string.map_transparency), - OFF(R.string.shared_string_off), - UNDEFINED(R.string.shared_string_none); - - private final int key; - - LayerTransparencySeekbarMode(int key) { - this.key = key; - } - - public String toHumanString(Context ctx) { - return ctx.getString(key); - } - } - - public enum NotesSortByMode { - BY_TYPE, - BY_DATE; - - public boolean isByType() { - return this == BY_TYPE; - } - - public boolean isByDate() { - return this == BY_DATE; - } - } - - public enum TracksSortByMode { - BY_DATE(R.string.sort_last_modified, R.drawable.ic_action_time_start), - BY_NAME_ASCENDING(R.string.sort_name_ascending, R.drawable.ic_action_sort_by_name_ascending), - BY_NAME_DESCENDING(R.string.sort_name_descending, R.drawable.ic_action_sort_by_name_descending); - - private final int iconId; - private final int nameId; - - TracksSortByMode(int nameId, int iconId) { - this.nameId = nameId; - this.iconId = iconId; - } - - public boolean isByName() { - return this == BY_NAME_ASCENDING || this == BY_NAME_DESCENDING; - } - - public boolean isByDate() { - return this == BY_DATE; - } - - @StringRes - public int getNameId() { - return nameId; - } - - @DrawableRes - public int getIconId() { - return iconId; - } - } - - public enum MapMarkersMode { - TOOLBAR(R.string.shared_string_topbar), - WIDGETS(R.string.shared_string_widgets), - NONE(R.string.shared_string_none); - - private final int key; - - MapMarkersMode(int key) { - this.key = key; - } - - public String toHumanString(Context ctx) { - return ctx.getString(key); - } - - public boolean isToolbar() { - return this == TOOLBAR; - } - - public boolean isWidgets() { - return this == WIDGETS; - } - - public boolean isNone() { - return this == NONE; - } - - public static MapMarkersMode[] possibleValues(Context context) { - return new MapMarkersMode[]{TOOLBAR, WIDGETS, NONE}; - } - } - - public enum SpeedConstants { - KILOMETERS_PER_HOUR(R.string.km_h, R.string.si_kmh, false), - MILES_PER_HOUR(R.string.mile_per_hour, R.string.si_mph, true), - METERS_PER_SECOND(R.string.m_s, R.string.si_m_s, false), - MINUTES_PER_MILE(R.string.min_mile, R.string.si_min_m, true), - MINUTES_PER_KILOMETER(R.string.min_km, R.string.si_min_km, false), - NAUTICALMILES_PER_HOUR(R.string.nm_h, R.string.si_nm_h, true); - - public final int key; - public final int descr; - public final boolean imperial; - - SpeedConstants(int key, int descr, boolean imperial) { - this.key = key; - this.descr = descr; - this.imperial = imperial; - } - - - - public String toHumanString(Context ctx) { - return ctx.getString(descr); - } - - public String toShortString(Context ctx) { - return ctx.getString(key); - } - - - } - - public enum MetricsConstants { - KILOMETERS_AND_METERS(R.string.si_km_m, "km-m"), - MILES_AND_FEET(R.string.si_mi_feet, "mi-f"), - MILES_AND_METERS(R.string.si_mi_meters, "mi-m"), - MILES_AND_YARDS(R.string.si_mi_yard, "mi-y"), - NAUTICAL_MILES(R.string.si_nm, "nm"); - - private final int key; - private final String ttsString; - - MetricsConstants(int key, String ttsString) { - this.key = key; - this.ttsString = ttsString; - } - - public String toHumanString(Context ctx) { - return ctx.getString(key); - } - - public String toTTSString() { - return ttsString; - } - - } - - public enum AngularConstants { - DEGREES(R.string.shared_string_degrees, "°"), - DEGREES360(R.string.shared_string_degrees, "°"), - MILLIRADS(R.string.shared_string_milliradians, "mil"); - - private final int key; - private final String unit; - - AngularConstants(int key, String unit) { - this.key = key; - this.unit = unit; - } - - public String toHumanString(Context ctx) { - return ctx.getString(key); - } - public String getUnitSymbol() { - return unit; - } - - } - - public enum AutoZoomMap { - FARTHEST(R.string.auto_zoom_farthest, 1f, 15.5f), - FAR(R.string.auto_zoom_far, 1.4f, 17f), - CLOSE(R.string.auto_zoom_close, 2f, 19f); - public final float coefficient; - public final int name; - public final float maxZoom; - - AutoZoomMap(int name, float coefficient, float maxZoom) { - this.name = name; - this.coefficient = coefficient; - this.maxZoom = maxZoom; - - } - } - - /** - * Class represents specific for driving region - * Signs, leftHandDriving - */ - public enum DrivingRegion { - - EUROPE_ASIA(R.string.driving_region_europe_asia, MetricsConstants.KILOMETERS_AND_METERS, false), - US(R.string.driving_region_us, MetricsConstants.MILES_AND_FEET, false), - CANADA(R.string.driving_region_canada, MetricsConstants.KILOMETERS_AND_METERS, false), - UK_AND_OTHERS(R.string.driving_region_uk, MetricsConstants.MILES_AND_METERS, true), - JAPAN(R.string.driving_region_japan, MetricsConstants.KILOMETERS_AND_METERS, true), - AUSTRALIA(R.string.driving_region_australia, MetricsConstants.KILOMETERS_AND_METERS, true); - - public final boolean leftHandDriving; - public final MetricsConstants defMetrics; - public final int name; - - DrivingRegion(int name, MetricsConstants def, boolean leftHandDriving) { - this.name = name; - defMetrics = def; - this.leftHandDriving = leftHandDriving; - } - - public boolean isAmericanTypeSigns() { - return this == OsmandSettings.DrivingRegion.AUSTRALIA || - this == OsmandSettings.DrivingRegion.US || - this == OsmandSettings.DrivingRegion.CANADA; - } - - public String getDescription(Context ctx) { - return ctx.getString(leftHandDriving ? R.string.left_side_navigation : R.string.right_side_navigation) + - ", " + - defMetrics.toHumanString(ctx).toLowerCase(); - } - } - - public enum RulerMode { - FIRST, - SECOND, - EMPTY - } - - public enum WikiArticleShowImages { - ON(R.string.shared_string_on), - OFF(R.string.shared_string_off), - WIFI(R.string.shared_string_wifi_only); - - public final int name; - - WikiArticleShowImages(int name) { - this.name = name; - } - } - - public enum TerrainMode { - HILLSHADE, - SLOPE - } - } diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ChangeDataStorageBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ChangeDataStorageBottomSheet.java index 334cc42aa8..e61faafe16 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ChangeDataStorageBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ChangeDataStorageBottomSheet.java @@ -11,8 +11,8 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import net.osmand.FileUtils; import net.osmand.PlatformUtil; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; @@ -63,7 +63,7 @@ public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet { CharSequence desc = null; File currentStorageFile = new File(currentDirectory.getDirectory()); - if ((!OsmandSettings.isWritable(currentStorageFile))) { + if ((!FileUtils.isWritable(currentStorageFile))) { desc = String.format(getString(R.string.android_19_location_disabled), currentStorageFile.getAbsoluteFile()); } else { String from = currentDirectory.getKey().equals(MANUALLY_SPECIFIED) ? currentDirectory.getDirectory() : currentDirectory.getTitle(); diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java index 5d37d40b3b..d2679564a8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java @@ -14,6 +14,7 @@ import androidx.fragment.app.FragmentManager; import com.google.android.material.slider.Slider; import net.osmand.AndroidUtils; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -76,8 +77,8 @@ public class RecalculateRouteInDeviationBottomSheet extends BooleanPreferenceBot int contentPaddingSmall = app.getResources().getDimensionPixelSize(R.dimen.content_padding_small); int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); - OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get(); - if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) { + MetricsConstants mc = settings.METRIC_SYSTEM.get(); + if (mc == MetricsConstants.KILOMETERS_AND_METERS) { entryValues = new Float[]{10.f, 20.0f, 30.0f, 50.0f, 100.0f, 200.0f, 500.0f, 1000.0f, 1500.0f}; } else { entryValues = new Float[]{9.1f, 18.3f, 30.5f, 45.7f, 91.5f, 183.0f, 482.0f, 965.0f, 1609.0f}; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageFragment.java index 93719a83ab..842b53e2fa 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageFragment.java @@ -23,6 +23,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.ProgressImplementation; @@ -408,7 +409,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto String newDirectory = newStorageDirectory.getDirectory(); int type = newStorageDirectory.getType(); File newDirectoryFile = new File(newDirectory); - boolean wr = OsmandSettings.isWritable(newDirectoryFile); + boolean wr = FileUtils.isWritable(newDirectoryFile); if (wr) { app.setExternalStorageDirectory(type, newDirectory); reloadData(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java index 0cd1e628bb..3a81548285 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/GeneralProfileSettingsFragment.java @@ -22,9 +22,12 @@ import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreferenceCompat; import net.osmand.data.PointDescription; +import net.osmand.plus.helpers.enums.AngularConstants; +import net.osmand.plus.helpers.enums.MetricsConstants; +import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.DrivingRegion; +import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.Version; @@ -186,7 +189,7 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment impleme } private void setupUnitsOfLengthPref() { - OsmandSettings.MetricsConstants[] metricsConstants = OsmandSettings.MetricsConstants.values(); + MetricsConstants[] metricsConstants = MetricsConstants.values(); String[] entries = new String[metricsConstants.length]; Integer[] entryValues = new Integer[metricsConstants.length]; @@ -208,20 +211,20 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment impleme } private void setupAngularUnitsPref() { - OsmandSettings.AngularConstants[] ac = OsmandSettings.AngularConstants.values(); + AngularConstants[] ac = AngularConstants.values(); String[] entries = new String[ac.length]; Integer[] entryValues = new Integer[ac.length]; for (int i = 0; i < entries.length; i++) { - if (ac[i] == OsmandSettings.AngularConstants.DEGREES) { - entries[i] = OsmandSettings.AngularConstants.DEGREES.toHumanString(app) + " 180"; - entryValues[i] = OsmandSettings.AngularConstants.DEGREES.ordinal(); - } else if (ac[i] == OsmandSettings.AngularConstants.DEGREES360) { - entries[i] = OsmandSettings.AngularConstants.DEGREES.toHumanString(app) + " 360"; - entryValues[i] = OsmandSettings.AngularConstants.DEGREES360.ordinal(); + if (ac[i] == AngularConstants.DEGREES) { + entries[i] = AngularConstants.DEGREES.toHumanString(app) + " 180"; + entryValues[i] = AngularConstants.DEGREES.ordinal(); + } else if (ac[i] == AngularConstants.DEGREES360) { + entries[i] = AngularConstants.DEGREES.toHumanString(app) + " 360"; + entryValues[i] = AngularConstants.DEGREES360.ordinal(); } else { entries[i] = ac[i].toHumanString(app); - entryValues[i] = OsmandSettings.AngularConstants.MILLIRADS.ordinal(); + entryValues[i] = AngularConstants.MILLIRADS.ordinal(); } } @@ -232,7 +235,7 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment impleme } private void setupSpeedSystemPref() { - OsmandSettings.SpeedConstants[] speedConstants = OsmandSettings.SpeedConstants.values(); + SpeedConstants[] speedConstants = SpeedConstants.values(); String[] entries = new String[speedConstants.length]; Integer[] entryValues = new Integer[speedConstants.length]; @@ -377,14 +380,14 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment impleme if (mapViewTrackingUtilities != null) { mapViewTrackingUtilities.resetDrivingRegionUpdate(); } - } else if (newValue instanceof OsmandSettings.DrivingRegion) { + } else if (newValue instanceof DrivingRegion) { applyPreference(settings.DRIVING_REGION_AUTOMATIC.getId(), applyToAllProfiles, false); if (applyToAllProfiles) { for (ApplicationMode appMode : ApplicationMode.allPossibleValues()) { - settings.DRIVING_REGION.setModeValue(appMode, (OsmandSettings.DrivingRegion) newValue); + settings.DRIVING_REGION.setModeValue(appMode, (DrivingRegion) newValue); } } else { - settings.DRIVING_REGION.setModeValue(selectedMode, (OsmandSettings.DrivingRegion) newValue); + settings.DRIVING_REGION.setModeValue(selectedMode, (DrivingRegion) newValue); } } updateAllSettings(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MapDuringNavigationFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MapDuringNavigationFragment.java index 06aa0c4c08..0fe5a6d6a3 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MapDuringNavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MapDuringNavigationFragment.java @@ -2,8 +2,8 @@ package net.osmand.plus.settings.fragments; import androidx.preference.Preference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.AutoZoomMap; +import net.osmand.plus.helpers.enums.MetricsConstants; +import net.osmand.plus.helpers.enums.AutoZoomMap; import net.osmand.plus.R; import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.plus.settings.preferences.SwitchPreferenceEx; @@ -78,7 +78,7 @@ public class MapDuringNavigationFragment extends BaseSettingsFragment { Float[] valuesKmh = new Float[]{0f, 5f, 7f, 10f, 15f, 20f}; Float[] valuesMph = new Float[]{0f, 3f, 5f, 7f, 10f, 15f}; String[] names; - if (settings.METRIC_SYSTEM.getModeValue(getSelectedAppMode()) == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) { + if (settings.METRIC_SYSTEM.getModeValue(getSelectedAppMode()) == MetricsConstants.KILOMETERS_AND_METERS) { names = new String[valuesKmh.length]; for (int i = 0; i < names.length; i++) { names[i] = valuesKmh[i].intValue() + " " + getString(R.string.km_h); @@ -113,7 +113,7 @@ public class MapDuringNavigationFragment extends BaseSettingsFragment { } else { applyPreference(settings.AUTO_ZOOM_MAP.getId(), applyToAllProfiles, true); applyPreference(settings.AUTO_ZOOM_MAP_SCALE.getId(), - applyToAllProfiles, OsmandSettings.AutoZoomMap.values()[position - 1]); + applyToAllProfiles, AutoZoomMap.values()[position - 1]); } } } else { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java index 00ec37480a..12e1fba73c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java @@ -37,7 +37,6 @@ import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.activities.SettingsNavigationActivity; import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RoutingHelper; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.settings.bottomsheets.RecalculateRouteInDeviationBottomSheet; import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java index df1af1a693..dfed2c5930 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java @@ -14,7 +14,7 @@ import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.StringPreference; import net.osmand.plus.settings.bottomsheets.VehicleParametersBottomSheet; import net.osmand.plus.settings.bottomsheets.VehicleSizeAssets; import net.osmand.plus.settings.preferences.ListPreferenceEx; @@ -72,7 +72,7 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O parameter.getDescription()); String defValue = parameter.getType() == RoutingParameterType.NUMERIC ? ROUTING_PARAMETER_NUMERIC_DEFAULT : ROUTING_PARAMETER_SYMBOLIC_DEFAULT; - OsmandSettings.StringPreference pref = (OsmandSettings.StringPreference) app.getSettings() + StringPreference pref = (StringPreference) app.getSettings() .getCustomRoutingProperty(parameterId, defValue); VehicleSizeAssets assets = VehicleSizeAssets.getAssets(parameterId, routerProfile); Object[] values = parameter.getPossibleValues(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java index 4ff8f3262d..8013baeb63 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java @@ -18,6 +18,7 @@ import androidx.preference.SwitchPreferenceCompat; import net.osmand.AndroidUtils; import net.osmand.plus.dialogs.SpeedCamerasBottomSheet; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; @@ -107,7 +108,7 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr Float[] valuesKmh = new Float[]{-10f, -7f, -5f, 0f, 5f, 7f, 10f, 15f, 20f}; Float[] valuesMph = new Float[]{-7f, -5f, -3f, 0f, 3f, 5f, 7f, 10f, 15f}; String[] names; - if (settings.METRIC_SYSTEM.getModeValue(getSelectedAppMode()) == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) { + if (settings.METRIC_SYSTEM.getModeValue(getSelectedAppMode()) == MetricsConstants.KILOMETERS_AND_METERS) { names = new String[valuesKmh.length]; for (int i = 0; i < names.length; i++) { names[i] = valuesKmh[i].intValue() + " " + getString(R.string.km_h); diff --git a/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java b/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java index b1ea56806d..07e5d088b9 100644 --- a/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java +++ b/OsmAnd/src/net/osmand/plus/settings/preferences/ListPreferenceEx.java @@ -8,7 +8,6 @@ import androidx.preference.DialogPreference; import androidx.preference.PreferenceDataStore; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings.PreferencesDataStore; import net.osmand.plus.settings.backend.OsmAndPreferencesDataStore; public class ListPreferenceEx extends DialogPreference { diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index 7b477176a4..5a186e75d0 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -21,7 +21,6 @@ import net.osmand.plus.DialogListItemAdapter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.TerrainMode; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java index b613d2ba13..3635aafe89 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java @@ -43,7 +43,6 @@ import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.IndexItem; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.TerrainMode; import net.osmand.plus.widgets.style.CustomTypefaceSpan; import org.apache.commons.logging.Log; @@ -55,8 +54,8 @@ import java.util.List; import static net.osmand.plus.UiUtilities.CustomRadioButtonType.*; import static net.osmand.plus.download.DownloadActivityType.HILLSHADE_FILE; import static net.osmand.plus.download.DownloadActivityType.SLOPE_FILE; -import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.HILLSHADE; -import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.SLOPE; +import static net.osmand.plus.srtmplugin.TerrainMode.HILLSHADE; +import static net.osmand.plus.srtmplugin.TerrainMode.SLOPE; import static net.osmand.plus.srtmplugin.SRTMPlugin.TERRAIN_MAX_ZOOM; import static net.osmand.plus.srtmplugin.SRTMPlugin.TERRAIN_MIN_ZOOM; diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java index 8f75c68259..79e47de648 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java @@ -18,7 +18,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; -import net.osmand.plus.settings.backend.OsmandSettings.TerrainMode; import net.osmand.plus.views.MapTileLayer; import net.osmand.util.Algorithms; @@ -31,7 +30,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.HILLSHADE; +import static net.osmand.plus.srtmplugin.TerrainMode.HILLSHADE; public class TerrainLayer extends MapTileLayer { diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainMode.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainMode.java new file mode 100644 index 0000000000..e9f3d20d9f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainMode.java @@ -0,0 +1,6 @@ +package net.osmand.plus.srtmplugin; + +public enum TerrainMode { + HILLSHADE, + SLOPE +} diff --git a/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java b/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java index 3941bdbb15..eaf145379c 100644 --- a/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java +++ b/OsmAnd/src/net/osmand/plus/track/ShowStartFinishCard.java @@ -10,8 +10,7 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.routepreparationmenu.cards.BaseCard; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; class ShowStartFinishCard extends BaseCard { diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 81a43da20f..2276d57cd2 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -41,7 +41,7 @@ import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; import net.osmand.plus.track.SplitTrackAsyncTask.SplitTrackListener; import net.osmand.render.RenderingRulesStorage; @@ -185,7 +185,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } if (color == 0) { RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer(); - OsmandSettings.CommonPreference prefColor = app.getSettings().getCustomRenderProperty(CURRENT_TRACK_COLOR_ATTR); + CommonPreference prefColor = app.getSettings().getCustomRenderProperty(CURRENT_TRACK_COLOR_ATTR); color = GpxAppearanceAdapter.parseTrackColor(renderer, prefColor.get()); } trackDrawInfo.setColor(color); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 641944ce21..46d51bca33 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -50,7 +50,7 @@ import net.osmand.plus.mapcontextmenu.other.TrackChartPoints; import net.osmand.plus.render.OsmandRenderer; import net.osmand.plus.render.OsmandRenderer.RenderingContext; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; +import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.TrackDrawInfo; import net.osmand.plus.views.OsmandMapLayer; diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index 2d813e0bd9..6a4cf344c7 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -47,7 +47,7 @@ import net.osmand.plus.OsmandPlugin; import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; +import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; @@ -67,9 +67,6 @@ import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmAndAppCustomization; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.LayerTransparencySeekbarMode; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.corenative.NativeCoreContext; diff --git a/OsmAnd/src/net/osmand/plus/views/layers/RulerControlLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/RulerControlLayer.java index 7847b6e7c3..e6f864af3d 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/RulerControlLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/RulerControlLayer.java @@ -29,10 +29,9 @@ import net.osmand.data.QuadPoint; import net.osmand.data.RotatedTileBox; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.settings.backend.OsmandPreference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.AngularConstants; -import net.osmand.plus.settings.backend.OsmandSettings.RulerMode; +import net.osmand.plus.helpers.enums.AngularConstants; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.views.OsmandMapLayer; @@ -72,7 +71,7 @@ public class RulerControlLayer extends OsmandMapLayer { private QuadPoint cacheCenter; private float cacheMapDensity; private OsmandPreference mapDensity; - private OsmandSettings.MetricsConstants cacheMetricSystem; + private MetricsConstants cacheMetricSystem; private int cacheIntZoom; private LatLon cacheCenterLatLon; private long cacheMultiTouchEndTime; @@ -452,7 +451,7 @@ public class RulerControlLayer extends OsmandMapLayer { updateCenter(tb, center); } - OsmandSettings.MetricsConstants currentMetricSystem = app.getSettings().METRIC_SYSTEM.get(); + MetricsConstants currentMetricSystem = app.getSettings().METRIC_SYSTEM.get(); boolean updateCache = tb.getZoom() != cacheIntZoom || !tb.getCenterLatLon().equals(cacheCenterLatLon) || mapDensity.get() != cacheMapDensity || cacheMetricSystem != currentMetricSystem; diff --git a/OsmAnd/src/net/osmand/plus/views/layers/RulerMode.java b/OsmAnd/src/net/osmand/plus/views/layers/RulerMode.java new file mode 100644 index 0000000000..db5d6d8e61 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/views/layers/RulerMode.java @@ -0,0 +1,7 @@ +package net.osmand.plus.views.layers; + +public enum RulerMode { + FIRST, + SECOND, + EMPTY +} diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index bf75a64bac..4aafc1b2af 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -48,9 +48,8 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndLocationProvider.GPSInfo; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.RulerMode; +import net.osmand.plus.views.layers.RulerMode; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; @@ -66,8 +65,6 @@ import net.osmand.plus.routepreparationmenu.ShowAlongTheRouteBottomSheet; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.RulerMode; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.layers.RulerControlLayer; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java index 782dc4c04f..f77bc27f36 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java @@ -25,8 +25,6 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RoutingHelper; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.mapwidgets.widgets.AlarmWidget; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java index a75422967d..2dc092139e 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java @@ -16,6 +16,7 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.routing.AlarmInfo; import net.osmand.plus.routing.RoutingHelper; @@ -40,7 +41,7 @@ public class AlarmWidget { private int imgId; private String cachedText; private String cachedBottomText; - private OsmandSettings.DrivingRegion cachedRegion; + private DrivingRegion cachedRegion; public AlarmWidget(final OsmandApplication app, MapActivity ma) { layout = ma.findViewById(R.id.map_alarm_warning); @@ -81,9 +82,9 @@ public class AlarmWidget { int locimgId = R.drawable.warnings_limit; String text = ""; String bottomText = ""; - OsmandSettings.DrivingRegion region = settings.DRIVING_REGION.get(); + DrivingRegion region = settings.DRIVING_REGION.get(); boolean americanType = region.isAmericanTypeSigns(); - boolean isCanadianRegion = region == OsmandSettings.DrivingRegion.CANADA; + boolean isCanadianRegion = region == DrivingRegion.CANADA; if (alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT) { if (isCanadianRegion) { locimgId = R.drawable.warnings_speed_limit_ca; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/RulerWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/RulerWidget.java index 8d576c72cf..636ef0af5a 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/RulerWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/RulerWidget.java @@ -10,7 +10,7 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/BearingWidgetState.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/BearingWidgetState.java index ce4761eab1..d3fc793ee1 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/BearingWidgetState.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/BearingWidgetState.java @@ -2,14 +2,14 @@ package net.osmand.plus.views.mapwidgets.widgetstates; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.OsmandPreference; public class BearingWidgetState extends WidgetState { public static final int BEARING_WIDGET_STATE_RELATIVE_BEARING = R.id.bearing_widget_state_relative_bearing; public static final int BEARING_WIDGET_STATE_MAGNETIC_BEARING = R.id.bearing_widget_state_magnetic_bearing; - private final OsmandSettings.OsmandPreference showRelativeBearing; + private final OsmandPreference showRelativeBearing; public BearingWidgetState(OsmandApplication ctx) { super(ctx); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/CompassRulerWidgetState.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/CompassRulerWidgetState.java index eb77043746..39de1d653c 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/CompassRulerWidgetState.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/CompassRulerWidgetState.java @@ -2,7 +2,7 @@ package net.osmand.plus.views.mapwidgets.widgetstates; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; public class CompassRulerWidgetState extends WidgetState { diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/TimeWidgetState.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/TimeWidgetState.java index 3274245a0c..b42d5a970d 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/TimeWidgetState.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgetstates/TimeWidgetState.java @@ -2,7 +2,7 @@ package net.osmand.plus.views.mapwidgets.widgetstates; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference; +import net.osmand.plus.settings.backend.OsmandPreference; public class TimeWidgetState extends WidgetState { diff --git a/OsmAnd/src/net/osmand/plus/voice/AbstractPrologCommandPlayer.java b/OsmAnd/src/net/osmand/plus/voice/AbstractPrologCommandPlayer.java index 74c0de1508..44f301945f 100644 --- a/OsmAnd/src/net/osmand/plus/voice/AbstractPrologCommandPlayer.java +++ b/OsmAnd/src/net/osmand/plus/voice/AbstractPrologCommandPlayer.java @@ -12,7 +12,7 @@ import net.osmand.StateChangedListener; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; +import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.R; import net.osmand.plus.api.AudioFocusHelper; diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java index 302140ba03..0e15c2b4a9 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java @@ -13,7 +13,6 @@ import androidx.annotation.NonNull; import net.osmand.AndroidUtils; import net.osmand.IndexConstants; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.wikivoyage.WikiBaseDialogFragment; @@ -94,7 +93,7 @@ public abstract class WikiArticleBaseDialogFragment extends WikiBaseDialogFragme protected void updateWebSettings() { - OsmandSettings.WikiArticleShowImages showImages = getSettings().WIKI_ARTICLE_SHOW_IMAGES.get(); + WikiArticleShowImages showImages = getSettings().WIKI_ARTICLE_SHOW_IMAGES.get(); WebSettings webSettings = contentWebView.getSettings(); switch (showImages) { case ON: diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleShowImages.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleShowImages.java new file mode 100644 index 0000000000..ea3d8a925b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleShowImages.java @@ -0,0 +1,15 @@ +package net.osmand.plus.wikipedia; + +import net.osmand.plus.R; + +public enum WikiArticleShowImages { + ON(R.string.shared_string_on), + OFF(R.string.shared_string_off), + WIFI(R.string.shared_string_wifi_only); + + public final int name; + + WikiArticleShowImages(int name) { + this.name = name; + } +} diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java index f05bb9273f..7c2b23867e 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaOptionsBottomSheetDialogFragment.java @@ -10,7 +10,6 @@ import androidx.fragment.app.Fragment; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.WikiArticleShowImages; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageShowPicturesDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageShowPicturesDialogFragment.java index 07c748cd28..824a2e9e49 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageShowPicturesDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageShowPicturesDialogFragment.java @@ -18,7 +18,7 @@ import androidx.fragment.app.Fragment; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings.WikiArticleShowImages; +import net.osmand.plus.wikipedia.WikiArticleShowImages; import net.osmand.plus.R; import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index be9d3f2e58..fa704688a0 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -50,7 +50,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import static net.osmand.plus.settings.backend.OsmandSettings.WikiArticleShowImages.OFF; +import static net.osmand.plus.wikipedia.WikiArticleShowImages.OFF; public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragment { diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java index ea09a79314..988598c359 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java @@ -16,7 +16,7 @@ import net.osmand.PicassoUtils; import net.osmand.plus.OnDialogFragmentResultListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings.WikiArticleShowImages; +import net.osmand.plus.wikipedia.WikiArticleShowImages; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; From 4e3526e742fb0f02e1e8bf426f6608c808928821 Mon Sep 17 00:00:00 2001 From: sergosm Date: Wed, 7 Oct 2020 23:15:45 +0300 Subject: [PATCH 0546/1366] We have a few issues with text and icon colors. --- .../plus/wikivoyage/search/SearchRecyclerViewAdapter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java index 902b883e3d..e4c310c866 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java @@ -135,6 +135,7 @@ public class SearchRecyclerViewAdapter extends RecyclerView.Adapter Date: Wed, 7 Oct 2020 09:04:39 +0000 Subject: [PATCH 0547/1366] Translated using Weblate (Japanese) Currently translated at 98.6% (3443 of 3489 strings) --- OsmAnd/res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 565e5ae9d6..35f9146fc7 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -1625,7 +1625,7 @@ POIの更新は利用できません 所属ネットワークに応じたカラー変更 OSMCのハイキングシンボルカラー 被災域 - 太線 + 輪郭強調 更新はありません ライブ更新 ユーザーからの意見やフィードバックを大切にしています。 @@ -2496,7 +2496,7 @@ POIの更新は利用できません 今年 全て履歴に移動 距離表示 - 並び順の変更 + 並び順: マップ上に表示し続ける 保存せずに終了しますか? From 98c103a775a50a9c6ef1e6c47921406470b57e1f Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Wed, 7 Oct 2020 20:02:04 +0000 Subject: [PATCH 0548/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-ru/strings.xml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 0df61cb806..b6dd46c4e9 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -202,7 +202,7 @@ Продолжить Пауза Поездка - Записано + Записано в трек Запись Нет данных Минимальная скорость для записи @@ -726,14 +726,14 @@ Карта памяти доступна только для чтения. \nТеперь можно только просматривать предварительно загруженную карту, а не загружать новые области. Файл распаковывается… - Направо ⇒ - Резко направо ⇘ - Плавно направо ⇗ - Налево ⇐ - Резко налево ⇙ - Плавно налево ⇖ - Выполните разворот ⇓ - Двигайтесь прямо ⇑ + Направо + Резко направо + Плавно направо + Налево + Резко налево + Плавно налево + Выполните разворот + Двигайтесь прямо Продолжить Загрузить детальные карты регионов Поиск сигнала… @@ -1024,8 +1024,8 @@ Показывать больше деталей на карте. Больше деталей Круговое движение, %1$d съезд - Держитесь левее ⇖ - Держитесь правее ⇗ + Держитесь левее + Держитесь правее Скорее Общедоступный Идентифицируемый @@ -1179,7 +1179,7 @@ Последний промежуточный пункт Сделать начальной остановкой Сделать последней остановкой - Первый промежуточный пункт + Сделать начальной остановкой Заменить пункт назначения Пункт назначения уже задан Пункт %1$s @@ -1539,7 +1539,7 @@ Линии метро Продолжить навигацию Приостановить навигацию - Визуализация маршрута по шкале SAC. + Отрисовка дорог cогласно шкале SAC. Отрисовка дорог согласно трассам OSMC. Раннее По умолчанию @@ -3790,7 +3790,7 @@ Изменение масштаба карты кнопками громкости. Масштабирование кнопками громкости Укажите длину автомобиля, для длинных транспортных средств могут применяться ограничения на маршруте. - Удалить следующую + Удалить ближайший пункт Задайте название точки Следующая точка маршрута будет удалена. Если это конечный пункт, навигация завершится. Информация о достопримечательностях из Википедии. Ваш карманный офлайн-путеводитель — просто включите плагин Википедии и читайте об объектах вокруг вас. From ade8cf103158e57e0e1dde3b3dbfd382f141d6a9 Mon Sep 17 00:00:00 2001 From: ace shadow Date: Tue, 6 Oct 2020 22:01:53 +0000 Subject: [PATCH 0549/1366] Translated using Weblate (Slovak) Currently translated at 100.0% (3489 of 3489 strings) --- OsmAnd/res/values-sk/strings.xml | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 9c2a49a143..6ce4134d80 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -224,7 +224,7 @@ Aktualizovať OsmAnd+ Stiahnite novú verziu aplikácie, aby ste mohli použiť nové mapové súbory. Online filter Nominatim - Hľadám umiestnenie… + Hľadám polohu… Moja poloha (nájdená) Adresa… Obľúbené miesta… @@ -325,11 +325,11 @@ ft mph mi - Zdieľať umiestnenie cez + Zdieľať polohu cez Pozícia: %1$s\n%2$s Na zobrazenie umiestnenia nasledujte webový odkaz %1$s alebo odkaz androidovského obsahu (intent link) %2$s - Poslať umiestnenie - Zdieľať umiestnenie + Poslať polohu + Zdieľať polohu GPX bod (waypoint) \"{0}\" pridaný Pridať waypoint do nahranej GPX stopy Administratíva @@ -419,7 +419,7 @@ sem zadajte čo chcete nájsť Mapa s vysokým rozlíšením Nerozťahovať (a nerozmazať) mapové dlaždice na obrazovkách s vysokou hustotou bodov. - Umiestnenie zatiaľ nenájdené. + Poloha zatiaľ nezistená. Hľadať hromadnú dopravu Hľadá sa preprava (bez cieľa): Hľadá sa preprava ({0} ako cieľ): @@ -743,7 +743,7 @@ Pridať pripomienku do aplikácie Kalendár Časovo obmedzené parkovanie Časovo neobmedzené parkovanie - Umiestnenie vášho zaparkovaného vozidla. %1$s + Poloha vášho zaparkovaného vozidla. %1$s Vyzdvihnúť vozidlo o: popoludní dopoludnia @@ -754,7 +754,7 @@ Označiť ako parkovacie miesto Odstrániť parkovaciu značku Východzí bod je príliš ďaleko od najbližšej cesty. - Zdieľané umiestnenie + Zdieľaná poloha Pridelená pamäť %1$s MB (Android limit %2$s MB, Dalvik %3$s MB). Pridelená pamäť Celková natívna pamäť pridelená aplikácii %1$s MB (Dalvik %2$s MB, iné %3$s MB). @@ -886,7 +886,7 @@ \n \nGlobálne údaje (medzi 70° severne a 70° južne) sú založené na meraní SRTM (Shuttle Radar Topography Mission) a ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer), zobrazovacieho nástroja na palube Terra, vlajkového satelitu NASA Earth Observing System. ASTER je kooperatívne úsilie medzi NASA, Japonským ministerstvom hospodárstva, obchodu a priemyslu (METI) a Japonských vesmírnych systémov (J-spacesystems). Meranie vzdialenosti - Stlačte \"Použiť umiestnenie…\" pre pridanie poznámky k polohe. + Stlačte \"Použiť polohu…\" pre pridanie poznámky k polohe. Zvukové poznámky Vytvárajte obrazové/zvukové/video poznámky počas výletu, buď tlačidlom na mape alebo v kontextovom menu polohy na mape. Audio/video poznámky @@ -1393,7 +1393,9 @@ \n \nTento pohľad môže byť vypnutý jeho deaktivovaním tu alebo zmenou hodnoty v \"Štýl vykresľovania\" v \"Nastaviť mapu\". Cestovný mapový pohľad - Umiestnenie:\n Šírka %1$s\n Dĺžka %2$s + Poloha: +\n Šírka %1$s +\n Dĺžka %2$s Zobraziť dní pozadu Premenovanie zlyhalo. @@ -2632,7 +2634,7 @@ Cestovný pohľad Námorný Kopírovať názov bodu/umiestnenia - Nepomenované umiestnenie + Nepomenované miesto Zobraziť uzavreté poznámky Zobraziť/skryť OSM poznámky na mape. GPX - vhodné na export do JOSM a iných editorov OSM. @@ -3890,17 +3892,18 @@ \n \n • Zlepšená viditeľnosť bodov pre bicykle. \n -\n • Stopy je teraz možné aktivovať, pre kontextové menu sú základnými údajmi. +\n • Stopy je teraz možné aktivovať a majú kontextové menu so základnými údajmi. \n \n • Zlepšený algoritmus vyhľadávania \n \n • Zlepšené možnosti nasledovania stopy v navigácii \n -\n • Opravené problému s importom a exportom nastavení profilov +\n • Opravené problémy s importom a exportom nastavení profilov \n \n Naposledy zmenené Názov: Z – A Názov: A – Z Ikony štartu/cieľa + Ďakujeme za zakúpenie modulu \'Vrstevnice\' \ No newline at end of file From e548bc48a5479d101506963029292e4b2bb934b7 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Tue, 6 Oct 2020 22:59:11 +0000 Subject: [PATCH 0550/1366] Translated using Weblate (Sardinian) Currently translated at 99.7% (3481 of 3489 strings) --- OsmAnd/res/values-sc/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index cf47d42af8..57221ff561 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3904,4 +3904,5 @@ Nùmene: Z – A Nùmene: A – Z Iconas de incumintzu/fine + Gràtzias pro àere comporadu \'Curvas de livellu\' \ No newline at end of file From 493190de098e663429e5e64fafa9066124ef72e9 Mon Sep 17 00:00:00 2001 From: Mehmet Akif Dokuzoglu Date: Tue, 6 Oct 2020 20:14:01 +0000 Subject: [PATCH 0551/1366] Translated using Weblate (Turkish) Currently translated at 75.9% (2904 of 3825 strings) --- OsmAnd/res/values-tr/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index 05e1fb7d24..4d71056b28 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -2882,4 +2882,6 @@ Motorlu tekneler: evet Tekne kiralama Konum: giriş + Yön tabelası: orman tahsisi + Yön tabelası: orman bölmesi \ No newline at end of file From 25fc59800583d358f422f305adfeeccaa65fd72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 6 Oct 2020 17:36:20 +0000 Subject: [PATCH 0552/1366] Translated using Weblate (Turkish) Currently translated at 75.9% (2904 of 3825 strings) --- OsmAnd/res/values-tr/phrases.xml | 41 ++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index 4d71056b28..16005d8a23 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -1740,8 +1740,8 @@ Açıklık genişliği 0.5$ madeni para Satıcı - Onarım - Onarım yok + Tamir + Tamir yok Elektrikli araçların tamiri Motosiklet tamiri Evet @@ -2043,8 +2043,8 @@ Bisiklet kiralama: hayır Pompa Bisiklet pompası: hayır - Kendin-Yap onarım için araçlar - Kendin-Yap onarım için bisiklet araçları: hayır + Kendin-Yap tamir için araçlar + Kendin-Yap tamir için bisiklet araçları: hayır Temizleme Bisiklet temizleme: hayır Zincir aleti @@ -2477,7 +2477,7 @@ Taşıma: evet Uzunluk Havai fişek mağazası - Elektronik onarımı + Elektronik tamiri Hackerspace Fitness istasyonu Bina türü: piramit @@ -2884,4 +2884,35 @@ Konum: giriş Yön tabelası: orman tahsisi Yön tabelası: orman bölmesi + Motosiklet giysileri: hayır + Motosiklet giysileri + Lastik: hayır + Lastik + Yedek parça: hayır + Yedek parça + Tamir: hayır + Tamir + Kiralama: hayır + Kiralama + Müzik okulu + Şarap: servis + Parti malzemeleri + Cajun + Tex-mex + Baget + Waffle + Krep + Falafel + Taco + Kantin + Tuzlu krep + Kızarmış tavuk + Kuskus + Fırın + Bistro + Kızarmış yiyecekler + Dondurulmuş yoğurt + Şarküteri + Turta + Çay dükkanı \ No newline at end of file From 83c20aaa794a3a5a98571d2a50cf85302c7174bf Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 7 Oct 2020 13:48:14 +0000 Subject: [PATCH 0553/1366] Translated using Weblate (German) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/de/ --- OsmAnd-telegram/res/values-de/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-de/strings.xml b/OsmAnd-telegram/res/values-de/strings.xml index 8c12570da5..0767c598d8 100644 --- a/OsmAnd-telegram/res/values-de/strings.xml +++ b/OsmAnd-telegram/res/values-de/strings.xml @@ -267,4 +267,8 @@ Letzte Antwort: vor %1$s vor %1$s ERR + Export + Logcat-Puffer + Protokolle der Anwendung einsehen und freigeben + Bericht senden \ No newline at end of file From 3cae2e14b176779288593b8a787dd9f8cdd9a2c8 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Tue, 6 Oct 2020 22:57:47 +0000 Subject: [PATCH 0554/1366] Translated using Weblate (Sardinian) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/sc/ --- OsmAnd-telegram/res/values-sc/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-sc/strings.xml b/OsmAnd-telegram/res/values-sc/strings.xml index 9846061b82..82a4e8aade 100644 --- a/OsmAnd-telegram/res/values-sc/strings.xml +++ b/OsmAnd-telegram/res/values-sc/strings.xml @@ -268,4 +268,8 @@ Ùrtima risposta: %1$s a como %1$s a como ERR + Esporta + Buffer de Logcat + Verìfica e cumpartzi sos registros de s\'aplicatzione fatos a sa minuda + Imbia resumu \ No newline at end of file From 242839a7873d86247246c65350d32a773ca4f391 Mon Sep 17 00:00:00 2001 From: Nazar-Kutz Date: Thu, 8 Oct 2020 09:19:18 +0300 Subject: [PATCH 0555/1366] Increase waiting telegram library time for fixing widget fake error state --- OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index 042fb03d11..d9ec335a0e 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -110,7 +110,7 @@ private const val PROXY_ENABLED = "proxy_enabled" private const val PROXY_PREFERENCES_KEY = "proxy_preferences" private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes -private const val WAITING_TDLIB_TIME = 3 // 3 seconds +private const val WAITING_TDLIB_TIME = 7 // 7 seconds private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes From 0fdc58960a989544cb03f09fe35fb75fbddb7a78 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 8 Oct 2020 09:58:44 +0300 Subject: [PATCH 0556/1366] cleanup --- .../builders/cards/IPFSImageCard.java | 30 ++++++++----------- .../builders/cards/ImageCard.java | 8 ++--- .../osmand/plus/views/layers/POIMapLayer.java | 2 +- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java index b029c7cdfc..682cfe8abd 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java @@ -1,28 +1,34 @@ package net.osmand.plus.mapcontextmenu.builders.cards; import android.view.View; +import net.osmand.AndroidNetworkUtils; +import net.osmand.PlatformUtil; import net.osmand.plus.activities.MapActivity; import net.osmand.util.Algorithms; +import org.apache.commons.logging.Log; import org.json.JSONException; import org.json.JSONObject; public class IPFSImageCard extends ImageCard { private static final String BASE_URL = "https://test.openplacereviews.org/api/ipfs/image-ipfs?cid="; + private static final Log LOG = PlatformUtil.getLog(IPFSImageCard.class); public IPFSImageCard(MapActivity mapActivity, JSONObject imageObject) { super(mapActivity, imageObject); + String cid = ""; try { - this.url = BASE_URL + imageObject.get("cid"); - this.imageHiresUrl = BASE_URL + imageObject.get("cid"); - this.imageUrl = BASE_URL + imageObject.get("cid"); + cid = (String) imageObject.get("cid"); } catch (JSONException e) { - e.printStackTrace(); + LOG.error(e); } - if (!Algorithms.isEmpty(getSuitableUrl())) { + this.url = BASE_URL + cid; + this.imageHiresUrl = BASE_URL + cid; + this.imageUrl = BASE_URL + cid; + if (!Algorithms.isEmpty(getUrl())) { View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - openUrl(getMapActivity(), getMyApplication(), getTitle(), getSuitableUrl(), + openUrl(getMapActivity(), getMyApplication(), getTitle(), getUrl(), isExternalLink() || Algorithms.isEmpty(getImageHiresUrl()), !Algorithms.isEmpty(getImageHiresUrl())); } @@ -34,14 +40,4 @@ public class IPFSImageCard extends ImageCard { } } } - - private String getSuitableUrl() { - final String url; - if (Algorithms.isEmpty(getImageHiresUrl())) { - url = getUrl(); - } else { - url = getImageHiresUrl(); - } - return url; - } -} \ No newline at end of file +} diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java index 667b234956..9a4486b8a5 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java @@ -418,6 +418,7 @@ public abstract class ImageCard extends AbstractCard { private Map params; private GetImageCardsListener listener; private List result; + private static final int GET_IMAGE_CARD_THREAD_ID = 10104; public interface GetImageCardsListener { void onPostProcess(List cardList); @@ -436,10 +437,8 @@ public abstract class ImageCard extends AbstractCard { @Override protected List doInBackground(Void... params) { - final int THREAD_ID = 10104; - TrafficStats.setThreadStatsTag(THREAD_ID); + TrafficStats.setThreadStatsTag(GET_IMAGE_CARD_THREAD_ID); List result = new ArrayList<>(); - RotatedTileBox rtb = mapActivity.getMapView().getCurrentRotatedTileBox(); Object o = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject(); if (o instanceof Amenity) { Amenity am = (Amenity) o; @@ -510,7 +509,6 @@ public abstract class ImageCard extends AbstractCard { String url = "https://test.openplacereviews.org/api/objects-by-index?type=opr.place&index=osmid&limit=1&key=" + l; String response = AndroidNetworkUtils.sendRequest(app, url, Collections.emptyMap(), "Requesting location images...", false, false); - try { if (!Algorithms.isEmpty(response)) { JSONArray obj = new JSONObject(response).getJSONArray("objects"); @@ -526,7 +524,7 @@ public abstract class ImageCard extends AbstractCard { } } } catch (JSONException e) { - e.printStackTrace(); + LOG.error(e); } } } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java index d01ec310a9..ed0f2cc45d 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java @@ -66,7 +66,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon /// cache for displayed POI // Work with cache (for map copied from AmenityIndexRepositoryOdb) - public MapLayerData> data; + private MapLayerData> data; private OsmandApplication app; From 4eae0ee60a2494693e9523f49085ac9a3e241b3c Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 8 Oct 2020 10:03:58 +0300 Subject: [PATCH 0557/1366] cleanup --- .../plus/mapcontextmenu/builders/cards/IPFSImageCard.java | 8 ++++---- .../plus/mapcontextmenu/builders/cards/ImageCard.java | 2 +- .../net/osmand/plus/views/layers/ContextMenuLayer.java | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java index 682cfe8abd..45495ca8d0 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/IPFSImageCard.java @@ -21,9 +21,9 @@ public class IPFSImageCard extends ImageCard { } catch (JSONException e) { LOG.error(e); } - this.url = BASE_URL + cid; - this.imageHiresUrl = BASE_URL + cid; - this.imageUrl = BASE_URL + cid; + url = BASE_URL + cid; + imageHiresUrl = BASE_URL + cid; + imageUrl = BASE_URL + cid; if (!Algorithms.isEmpty(getUrl())) { View.OnClickListener onClickListener = new View.OnClickListener() { @Override @@ -34,7 +34,7 @@ public class IPFSImageCard extends ImageCard { } }; if (!Algorithms.isEmpty(buttonText)) { - this.onButtonClickListener = onClickListener; + onButtonClickListener = onClickListener; } else { this.onClickListener = onClickListener; } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java index 9a4486b8a5..1afb883231 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java @@ -442,7 +442,7 @@ public abstract class ImageCard extends AbstractCard { Object o = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject(); if (o instanceof Amenity) { Amenity am = (Amenity) o; - long amenityId = (am.getId() >> 1); + long amenityId = am.getId() >> 1; getPicturesForPlace(result, amenityId); } try { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java index 2902794ee8..7a8690fe2d 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java @@ -907,9 +907,9 @@ public class ContextMenuLayer extends OsmandMapLayer { } @NonNull - public Map selectObjectsForContextMenu(RotatedTileBox tileBox, - PointF point, boolean acquireObjLatLon, - boolean unknownLocation) { + private Map selectObjectsForContextMenu(RotatedTileBox tileBox, + PointF point, boolean acquireObjLatLon, + boolean unknownLocation) { Map pressedLatLonFull = new HashMap<>(); Map pressedLatLonSmall = new HashMap<>(); Map selectedObjects = new HashMap<>(); From 0cd8cd049f67f80853d3bc05d6837a0c2b673316 Mon Sep 17 00:00:00 2001 From: sergosm Date: Thu, 8 Oct 2020 11:53:45 +0300 Subject: [PATCH 0558/1366] update --- .../plus/wikivoyage/search/SearchRecyclerViewAdapter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java index e4c310c866..de9793d267 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java @@ -135,7 +135,7 @@ public class SearchRecyclerViewAdapter extends RecyclerView.Adapter Date: Thu, 8 Oct 2020 12:08:31 +0300 Subject: [PATCH 0559/1366] #9621 Add validation for the online tracking link to the new settings screen --- .../fragments/LiveMonitoringFragment.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/LiveMonitoringFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/LiveMonitoringFragment.java index e664953662..6a426e654c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/LiveMonitoringFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/LiveMonitoringFragment.java @@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; +import android.widget.Toast; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; @@ -12,11 +13,12 @@ import androidx.preference.Preference; import net.osmand.AndroidUtils; import net.osmand.plus.OsmAndFormatter; -import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.preferences.EditTextPreferenceEx; import net.osmand.plus.settings.preferences.ListPreferenceEx; +import net.osmand.util.Algorithms; import static net.osmand.plus.UiUtilities.CompoundButtonType.TOOLBAR; import static net.osmand.plus.monitoring.OsmandMonitoringPlugin.MAX_INTERVAL_TO_SEND_MINUTES; @@ -60,6 +62,19 @@ public class LiveMonitoringFragment extends BaseSettingsFragment { updateToolbarSwitch(); } + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference.getKey().equals(settings.LIVE_MONITORING_URL.getId())) { + if (Algorithms.isValidMessageFormat((String) newValue)) { + return super.onPreferenceChange(preference, newValue); + } else { + Toast.makeText(app, R.string.wrong_format, Toast.LENGTH_SHORT).show(); + return false; + } + } + return super.onPreferenceChange(preference, newValue); + } + private void updateToolbarSwitch() { View view = getView(); if (view == null) { From e083c3958df2762f0f3601dd0d24298983533cd3 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 8 Oct 2020 12:50:33 +0300 Subject: [PATCH 0560/1366] Fix wrong place of configure profile --- OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java | 12 ++++++++++++ .../fragments/ConfigureMenuItemsFragment.java | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 7263f119bd..26e173d568 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -53,6 +53,9 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_PROFILE_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SWITCH_PROFILE_ID; + public class ContextMenuAdapter { private static final Log LOG = PlatformUtil.getLog(ContextMenuAdapter.class); @@ -134,6 +137,15 @@ public class ContextMenuAdapter { Collections.sort(items, new Comparator() { @Override public int compare(ContextMenuItem item1, ContextMenuItem item2) { + if (DRAWER_SWITCH_PROFILE_ID.equals(item1.getId())) { + return -1; + } + if (DRAWER_CONFIGURE_PROFILE_ID.equals(item1.getId()) && DRAWER_SWITCH_PROFILE_ID.equals(item2.getId())) { + return 1; + } + if (DRAWER_CONFIGURE_PROFILE_ID.equals(item1.getId())) { + return -1; + } int order1 = item1.getOrder(); int order2 = item2.getOrder(); if (order1 < order2) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java index 44fb4bf7f6..4d2309af82 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ConfigureMenuItemsFragment.java @@ -51,6 +51,8 @@ import java.util.HashMap; import java.util.List; import static net.osmand.aidlapi.OsmAndCustomizationConstants.APP_PROFILES_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_PROFILE_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SWITCH_PROFILE_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MORE_ID; import static net.osmand.plus.settings.fragments.RearrangeMenuItemsAdapter.AdapterItemType.BUTTON; import static net.osmand.plus.settings.fragments.RearrangeMenuItemsAdapter.AdapterItemType.DESCRIPTION; @@ -183,7 +185,9 @@ public class ConfigureMenuItemsFragment extends BaseOsmAndFragment public static List getCustomizableDefaultItems(List defItems) { List items = new ArrayList<>(); for (ContextMenuItem item : defItems) { - if (!APP_PROFILES_ID.equals(item.getId())) { + if (!APP_PROFILES_ID.equals(item.getId()) + && !DRAWER_CONFIGURE_PROFILE_ID.equals(item.getId()) + && !DRAWER_SWITCH_PROFILE_ID.equals(item.getId())) { items.add(item); } } From bde5ae822b5a8172761a329bcf43ed04816d70bb Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 8 Oct 2020 15:43:57 +0300 Subject: [PATCH 0561/1366] stream improvements --- .../java/net/osmand/osm/io/NetworkUtils.java | 71 ++--- .../osm/oauth/IInputStreamHttpClient.java | 7 + .../osmand/osm/oauth/OsmAndJDKHttpClient.java | 260 ++++++++++++++++++ .../oauth/OsmOAuthAuthorizationClient.java | 3 + 4 files changed, 297 insertions(+), 44 deletions(-) create mode 100644 OsmAnd-java/src/main/java/net/osmand/osm/oauth/IInputStreamHttpClient.java create mode 100644 OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmAndJDKHttpClient.java diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java index 8880184f96..d684b148a4 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java @@ -4,6 +4,7 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; import net.osmand.PlatformUtil; +import net.osmand.osm.oauth.IInputStreamHttpClient; import net.osmand.osm.oauth.OsmOAuthAuthorizationClient; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -72,12 +73,13 @@ public class NetworkUtils { HttpURLConnection conn; if (client != null && client.isValidToken()){ OAuthRequest req = new OAuthRequest(Verb.POST, urlText); - req.setPayload(prepareStream(formName,fileToUpload,gzip)); client.getService().signRequest(client.getAccessToken(), req); req.addHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); try { + IInputStreamHttpClient service = (IInputStreamHttpClient) client.getService(); + service.execute(service.getUserAgent(), req.getHeaders(), req.getVerb(), req.getCompleteUrl(), fileToUpload); Response r = client.getService().execute(req); - if(r.getCode() != 200){ + if (r.getCode() != 200) { return r.getBody(); } return null; @@ -100,7 +102,29 @@ public class NetworkUtils { conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$ conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$ OutputStream ous = conn.getOutputStream(); - ous.write(prepareStream(formName,fileToUpload,gzip)); + ous.write(("--" + BOUNDARY + "\r\n").getBytes()); + String filename = fileToUpload.getName(); + if (gzip) { + filename += ".gz"; + } + ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ + ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$ + InputStream fis = new FileInputStream(fileToUpload); + BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024); + ous.flush(); + if (gzip) { + GZIPOutputStream gous = new GZIPOutputStream(ous, 1024); + Algorithms.streamCopy(bis, gous); + gous.flush(); + gous.finish(); + } else { + Algorithms.streamCopy(bis, ous); + } + ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ + ous.flush(); + Algorithms.closeStream(bis); + Algorithms.closeStream(ous); + log.info("Finish uploading file " + fileToUpload.getName()); log.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage()); if(conn.getResponseCode() != 200){ @@ -131,46 +155,6 @@ public class NetworkUtils { } } - private static byte[] prepareStream(String formName, File fileToUpload, boolean gzip) { - try { - ByteArrayOutputStream ous = new ByteArrayOutputStream(); -// for (String key : additionalMapData.keySet()) { -// ous.write(("--" + BOUNDARY + "\r\n").getBytes()); -// ous.write(("content-disposition: form-data; name=\"" + key + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ -// ous.write((additionalMapData.get(key) + "\r\n").getBytes()); -// } - ous.write(("--" + BOUNDARY + "\r\n").getBytes()); - - String filename = fileToUpload.getName(); - if (gzip) { - filename += ".gz"; - } - ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ - ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$ - InputStream fis = new FileInputStream(fileToUpload); - BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024); - ous.flush(); - if (gzip) { - GZIPOutputStream gous = new GZIPOutputStream(ous, 1024); - Algorithms.streamCopy(bis, gous); - gous.flush(); - gous.finish(); - gous.close(); - } else { - Algorithms.streamCopy(bis, ous); - } - - ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ - ous.flush(); - Algorithms.closeStream(bis); - Algorithms.closeStream(ous); - return ous.toByteArray(); - } catch (IOException e) { - log.error(e); - } - return new byte[0]; - } - public static void setProxy(String host, int port) { if(host != null && port > 0) { InetSocketAddress isa = new InetSocketAddress(host, port); @@ -179,7 +163,6 @@ public class NetworkUtils { proxy = null; } } - public static Proxy getProxy() { return proxy; } diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/IInputStreamHttpClient.java b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/IInputStreamHttpClient.java new file mode 100644 index 0000000000..c42182fdd7 --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/IInputStreamHttpClient.java @@ -0,0 +1,7 @@ +package net.osmand.osm.oauth; + +import com.github.scribejava.core.httpclient.HttpClient; + +public interface IInputStreamHttpClient extends HttpClient { + String getUserAgent(); +} diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmAndJDKHttpClient.java b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmAndJDKHttpClient.java new file mode 100644 index 0000000000..c7d8f88446 --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmAndJDKHttpClient.java @@ -0,0 +1,260 @@ +package net.osmand.osm.oauth; + +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig; +import com.github.scribejava.core.httpclient.jdk.JDKHttpFuture; +import com.github.scribejava.core.httpclient.multipart.MultipartPayload; +import com.github.scribejava.core.httpclient.multipart.MultipartUtils; +import com.github.scribejava.core.model.*; +import net.osmand.util.Algorithms; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class OsmAndJDKHttpClient implements IInputStreamHttpClient { + private static final String BOUNDARY = "CowMooCowMooCowCowCow"; + private final JDKHttpClientConfig config; + + public OsmAndJDKHttpClient() { + this(JDKHttpClientConfig.defaultConfig()); + } + + public OsmAndJDKHttpClient(JDKHttpClientConfig clientConfig) { + config = clientConfig; + } + + @Override + public void close() { + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + MultipartPayload bodyContents, OAuthAsyncRequestCallback callback, + OAuthRequest.ResponseConverter converter) { + + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.MULTIPART, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STREAM, bodyContents, callback, + converter); + } + + private Future doExecuteAsync(String userAgent, Map headers, Verb httpVerb, + String completeUrl, BodyType bodyType, Object bodyContents, OAuthAsyncRequestCallback callback, + OAuthRequest.ResponseConverter converter) { + try { + final Response response = doExecute(userAgent, headers, httpVerb, completeUrl, bodyType, bodyContents); + @SuppressWarnings("unchecked") + final T t = converter == null ? (T) response : converter.convert(response); + if (callback != null) { + callback.onCompleted(t); + } + return new JDKHttpFuture<>(t); + } catch (IOException | RuntimeException e) { + if (callback != null) { + callback.onThrowable(e); + } + return new JDKHttpFuture<>(e); + } + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + MultipartPayload multipartPayloads) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.MULTIPART, multipartPayloads); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STREAM, bodyContents); + } + + private Response doExecute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + BodyType bodyType, Object bodyContents) throws IOException { + final URL url = new URL(completeUrl); + final HttpURLConnection connection; + if (config.getProxy() == null) { + connection = (HttpURLConnection) url.openConnection(); + } else { + connection = (HttpURLConnection) url.openConnection(config.getProxy()); + } + connection.setInstanceFollowRedirects(config.isFollowRedirects()); + connection.setRequestMethod(httpVerb.name()); + if (config.getConnectTimeout() != null) { + connection.setConnectTimeout(config.getConnectTimeout()); + } + if (config.getReadTimeout() != null) { + connection.setReadTimeout(config.getReadTimeout()); + } + addHeaders(connection, headers, userAgent); + if (httpVerb.isPermitBody()) { + bodyType.setBody(connection, bodyContents, httpVerb.isRequiresBody()); + } + + try { + connection.connect(); + final int responseCode = connection.getResponseCode(); + return new Response(responseCode, connection.getResponseMessage(), parseHeaders(connection), + responseCode >= 200 && responseCode < 400 ? connection.getInputStream() + : connection.getErrorStream()); + } catch (UnknownHostException e) { + throw new OAuthException("The IP address of a host could not be determined.", e); + } + } + + @Override + public String getUserAgent() { + return "OsmandUserAgent"; + } + + private enum BodyType { + BYTE_ARRAY { + @Override + void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException { + addBody(connection, (byte[]) bodyContents, requiresBody); + } + }, + STREAM { + @Override + void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException { + addBody(connection, (File) bodyContents, requiresBody); + } + }, + MULTIPART { + @Override + void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException { + addBody(connection, (MultipartPayload) bodyContents, requiresBody); + } + }, + STRING { + @Override + void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException { + addBody(connection, ((String) bodyContents).getBytes(), requiresBody); + } + }; + abstract void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) + throws IOException; + } + + private static Map parseHeaders(HttpURLConnection conn) { + final Map headers = new HashMap<>(); + + for (Map.Entry> headerField : conn.getHeaderFields().entrySet()) { + final String key = headerField.getKey(); + final String value = headerField.getValue().get(0); + if ("Content-Encoding".equalsIgnoreCase(key)) { + headers.put("Content-Encoding", value); + } else { + headers.put(key, value); + } + } + return headers; + } + + private static void addHeaders(HttpURLConnection connection, Map headers, String userAgent) { + for (Map.Entry header : headers.entrySet()) { + connection.setRequestProperty(header.getKey(), header.getValue()); + } + + if (userAgent != null) { + connection.setRequestProperty(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); + } + } + + private static void addBody(HttpURLConnection connection, File file, boolean requiresBody) throws IOException { + if (requiresBody) { + String filename = file.getName(); + String formName = "file"; + final OutputStream ous = prepareConnectionForBodyAndGetOutputStream(connection, 20 * 1024); + ous.write(("--" + BOUNDARY+"\r\n").getBytes()); + InputStream stream = new FileInputStream(file); + ous.write(("content-disposition: form-data; name=\""+formName+"\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ + ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$ + BufferedInputStream bis = new BufferedInputStream(stream, 20 * 1024); + ous.flush(); + Algorithms.streamCopy(bis, ous); + ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$ + ous.flush(); + Algorithms.closeStream(bis); + Algorithms.closeStream(ous); + } + } + + private static void addBody(HttpURLConnection connection, byte[] content, boolean requiresBody) throws IOException { + final int contentLength = content.length; + if (requiresBody || contentLength > 0) { + final OutputStream outputStream = prepareConnectionForBodyAndGetOutputStream(connection, contentLength); + if (contentLength > 0) { + outputStream.write(content); + } + } + } + + private static void addBody(HttpURLConnection connection, MultipartPayload multipartPayload, boolean requiresBody) + throws IOException { + + for (Map.Entry header : multipartPayload.getHeaders().entrySet()) { + connection.setRequestProperty(header.getKey(), header.getValue()); + } + + if (requiresBody) { + final ByteArrayOutputStream os = MultipartUtils.getPayload(multipartPayload); + final int contentLength = os.size(); + final OutputStream outputStream = prepareConnectionForBodyAndGetOutputStream(connection, contentLength); + if (contentLength > 0) { + os.writeTo(outputStream); + } + } + } + + private static OutputStream prepareConnectionForBodyAndGetOutputStream(HttpURLConnection connection, + int contentLength) throws IOException { + connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(contentLength)); + if (connection.getRequestProperty(CONTENT_TYPE) == null) { + connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + connection.setDoOutput(true); + return connection.getOutputStream(); + } +} \ No newline at end of file diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java index 5726855f72..709dbaa275 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/oauth/OsmOAuthAuthorizationClient.java @@ -4,6 +4,8 @@ package net.osmand.osm.oauth; import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.builder.api.DefaultApi10a; import com.github.scribejava.core.builder.api.OAuth1SignatureType; +import com.github.scribejava.core.httpclient.jdk.JDKHttpClient; +import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig; import com.github.scribejava.core.model.*; import com.github.scribejava.core.oauth.OAuth10aService; import net.osmand.PlatformUtil; @@ -26,6 +28,7 @@ public class OsmOAuthAuthorizationClient { public OsmOAuthAuthorizationClient(String key, String secret) { service = new ServiceBuilder(key) .apiSecret(secret) + .httpClient(new OsmAndJDKHttpClient(JDKHttpClientConfig.defaultConfig())) .callback("osmand-oauth://example.com/oauth") .build(new OsmApi()); } From dd220b193213ee6a8f1833611b1cf2ae4525884c Mon Sep 17 00:00:00 2001 From: Alexander Sytnyk Date: Thu, 8 Oct 2020 16:10:31 +0300 Subject: [PATCH 0562/1366] #9984 Fix overlapping text --- ...bottom_sheet_item_slider_with_two_text.xml | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml b/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml index b5cb11cf49..f386e8c59f 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml @@ -6,33 +6,37 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + osmand:typeface="@string/font_roboto_regular" + tools:text="Some very long title to check overlapped texts" /> + + + osmand:typeface="@string/font_roboto_medium" + tools:text="summary" /> - + Date: Thu, 8 Oct 2020 16:12:07 +0300 Subject: [PATCH 0563/1366] update OpenGL Check Invert Disable Setting --- OsmAnd/src/net/osmand/plus/Version.java | 27 ++++++++++++++++--- .../SettingsDevelopmentActivity.java | 13 +++------ .../fragments/RouteParametersFragment.java | 12 ++++----- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/Version.java b/OsmAnd/src/net/osmand/plus/Version.java index 14ed68b100..4a13b98783 100644 --- a/OsmAnd/src/net/osmand/plus/Version.java +++ b/OsmAnd/src/net/osmand/plus/Version.java @@ -1,13 +1,15 @@ package net.osmand.plus; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; +import android.content.pm.PackageManager; import net.osmand.plus.inapp.InAppPurchaseHelper; +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + public class Version { private final String appVersion; @@ -149,4 +151,21 @@ public class Version { return v; } -} + public static boolean isOpenGlAvailable(OsmandApplication app) { + if ("qnx".equals(System.getProperty("os.name"))) { + return false; + } + File nativeLibraryDir = new File(app.getApplicationInfo().nativeLibraryDir); + if (nativeLibraryDir.exists() && nativeLibraryDir.canRead()) { + File[] files = nativeLibraryDir.listFiles(); + if (files != null) { + for (File file : files) { + if ("libOsmAndCoreWithJNI.so".equals(file.getName())) { + return true; + } + } + } + } + return false; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java b/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java index 3f95829762..f7e1fa064f 100644 --- a/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java @@ -14,12 +14,11 @@ import android.preference.PreferenceScreen; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.render.NativeOsmandLibrary; -import net.osmand.plus.views.corenative.NativeCoreContext; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.SunriseSunset; import java.text.SimpleDateFormat; @@ -38,9 +37,9 @@ public class SettingsDevelopmentActivity extends SettingsBaseActivity { PreferenceScreen category = getPreferenceScreen(); Preference pref; - if (app.getSettings().USE_OPENGL_RENDER.get() && NativeCoreContext.isInit()) { - CheckBoxPreference useOpenglRender = createCheckBoxPreference(settings.USE_OPENGL_RENDER, R.string.use_opengl_render, R.string.use_opengl_render_descr); - category.addPreference(useOpenglRender); + if (Version.isOpenGlAvailable(app)) { + category.addPreference(createCheckBoxPreference(settings.USE_OPENGL_RENDER, + R.string.use_opengl_render, R.string.use_opengl_render_descr)); } if (!Version.isBlackberry(app)) { @@ -113,10 +112,6 @@ public class SettingsDevelopmentActivity extends SettingsBaseActivity { R.string.show_free_version_banner, R.string.show_free_version_banner_description)); - - - - pref = new Preference(this); pref.setTitle(R.string.test_voice_prompts); pref.setSummary(R.string.play_commands_of_currently_selected_voice); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java index 70dc81c23e..ae82028971 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java @@ -168,16 +168,14 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP } private void setupNativePublicTransport() { - SwitchPreferenceEx setupNativePublicTransport = createSwitchPreferenceEx(settings.PT_SAFE_MODE.getId(), - R.string.use_native_pt, R.layout.preference_with_descr_dialog_and_switch); if (!Version.isBlackberry(app)) { + SwitchPreferenceEx setupNativePublicTransport = createSwitchPreferenceEx(settings.PT_SAFE_MODE.getId(), + R.string.use_native_pt, R.layout.preference_with_descr_dialog_and_switch); setupNativePublicTransport.setDescription(getString(R.string.use_native_pt_desc)); setupNativePublicTransport.setSummaryOn(R.string.shared_string_enabled); setupNativePublicTransport.setSummaryOff(R.string.shared_string_disabled); setupNativePublicTransport.setIconSpaceReserved(true); getPreferenceScreen().addPreference(setupNativePublicTransport); - } else { - setupNativePublicTransport.setVisible(false); } } @@ -192,12 +190,14 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP } private void setupDisableComplexRoutingPref() { + boolean enabled = !settings.DISABLE_COMPLEX_ROUTING.get(); // pref ui was inverted SwitchPreferenceEx disableComplexRouting = createSwitchPreferenceEx(settings.DISABLE_COMPLEX_ROUTING.getId(), R.string.use_complex_routing, R.layout.preference_with_descr_dialog_and_switch); disableComplexRouting.setDescription(getString(R.string.disable_complex_routing_descr)); disableComplexRouting.setSummaryOn(R.string.shared_string_enabled); disableComplexRouting.setSummaryOff(R.string.shared_string_disabled); disableComplexRouting.setIconSpaceReserved(true); + disableComplexRouting.setChecked(enabled); getPreferenceScreen().addPreference(disableComplexRouting); } @@ -330,7 +330,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP setupSelectRouteRecalcDistance(screen); setupReverseDirectionRecalculation(screen); addDivider(screen); - setupDevelopmentcategoryHeader(screen); + setupDevelopmentCategoryHeader(screen); if (am.isDerivedRoutingFrom(ApplicationMode.PUBLIC_TRANSPORT)) { setupOsmLiveForPublicTransportPref(); setupNativePublicTransport(); @@ -367,7 +367,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP screen.addPreference(routingCategory); } - private void setupDevelopmentcategoryHeader (PreferenceScreen screen) { + private void setupDevelopmentCategoryHeader (PreferenceScreen screen) { PreferenceCategory developmentCategory = new PreferenceCategory(requireContext()); developmentCategory.setLayoutResource(R.layout.preference_category_with_descr); developmentCategory.setTitle(R.string.development); From faf565b205f3c279309e4a90a7c3c60184ee3a1b Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 8 Oct 2020 16:41:46 +0300 Subject: [PATCH 0564/1366] Added logo for OpenPlaceReview --- .../res/drawable/ic_logo_openplacereview.xml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 OsmAnd/res/drawable/ic_logo_openplacereview.xml diff --git a/OsmAnd/res/drawable/ic_logo_openplacereview.xml b/OsmAnd/res/drawable/ic_logo_openplacereview.xml new file mode 100644 index 0000000000..fc5b26cbf3 --- /dev/null +++ b/OsmAnd/res/drawable/ic_logo_openplacereview.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + From 8d271c08ed58dcdac4b56638a4e452b3fe1bc656 Mon Sep 17 00:00:00 2001 From: Artem Date: Thu, 8 Oct 2020 13:28:35 +0000 Subject: [PATCH 0565/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-ru/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index b6dd46c4e9..2088db1fe7 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3904,4 +3904,6 @@ Имя: А - Я Значки старта и финиша Спасибо за покупку \'Контурных линий\' + Избегать пешеходных дорожек + Избегать пешеходных дорожек \ No newline at end of file From 76eeec305aa47c93999f9793946cb883820d7f1b Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Thu, 8 Oct 2020 12:37:33 +0000 Subject: [PATCH 0566/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-ru/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 2088db1fe7..90e1c50349 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3906,4 +3906,10 @@ Спасибо за покупку \'Контурных линий\' Избегать пешеходных дорожек Избегать пешеходных дорожек + Подписка взимается за выбранный период. Отмените её в AppGallery в любое время. + Оплата будет снята с вашей учетной записи AppGallery при подтверждении покупки. +\n +\nПодписка продлевается автоматически, если она не будет отменена до даты продления. С вашего счета будет взиматься плата за период продления (месяц/три месяца/год) только в дату продления. +\n +\nВы можете управлять своими подписками и отменять их, перейдя в настройки AppGallery. \ No newline at end of file From dda863700c78832a7cae93d014e427c23253ede3 Mon Sep 17 00:00:00 2001 From: Deelite <556xxy@gmail.com> Date: Thu, 8 Oct 2020 00:50:47 +0000 Subject: [PATCH 0567/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-ru/strings.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 90e1c50349..17452f3328 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -73,7 +73,7 @@ Поиск почтового индекса Запись аудио⁣ Записать видео - Фотозаметка + Сделать фото OSM-заметка Функции парковки Благодарим вас за покупку платной версии OsmAnd. @@ -1813,7 +1813,7 @@ Хранилище карт Копировать Переместить файлы данных Osmand в новое место назначения\? - Напечатайте для поиска + Любой текст для поиска Номера домов Избегать пересечения границ Предельная высота @@ -3580,8 +3580,7 @@ Примечание: проверка скорости > 0: большинство модулей GPS сообщают значение скорости только в том случае, если алгоритм определяет, что вы движетесь, и ничего, если вы не перемещаетесь. Следовательно, использование параметра > 0 в этом фильтре в некотором смысле приводит к обнаружению факта перемещения модуля GPS. Но даже если мы не производим данную фильтрацию во время записи, то всё равно эта функция используется при анализе GPX для определения скорректированного расстояния, то есть значение, отображаемое в этом поле, является расстоянием, записанным во время движения. Разделение записи Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. - "Будут записываться только точки, отвечающие -\n в минимальной точностью (в метрах/футах —зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." + "Будут записываться только точки, отвечающие по показателю минимальной точности (в метрах или футах — зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений." Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться. Для визуализации крутизны рельефа используются цвета. Подробнее об уклонах можно прочитать в %1$s. From 81f114afe92da53e3dd66bd1902d2d3caa310da2 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Wed, 7 Oct 2020 21:22:40 +0000 Subject: [PATCH 0568/1366] Translated using Weblate (French) Currently translated at 99.9% (3492 of 3493 strings) --- OsmAnd/res/values-fr/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 41007cc7eb..401664b66e 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3885,4 +3885,7 @@ Nom : A – Z Icônes de départ / arrivée Merci pour votre achat de \'Courbes de niveaux\' + Abonnement facturé pour chaque période sélectionnée. Annulation possible à tout moment sur AppGallery. + Éviter les trottoirs + Éviter les trottoirs \ No newline at end of file From ad9b88354e6bb76e61a4a9cfdb234b149fc2b93d Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Spieth Date: Thu, 8 Oct 2020 05:17:50 +0000 Subject: [PATCH 0569/1366] Translated using Weblate (German) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 1fcf32f445..281ac9f4d2 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3826,7 +3826,7 @@ Wählen Sie eine Trackdatei zum Öffnen aus. Fertig Track überschreiben - Schwellenwert-Distanz + Maximaler Abstand Als neuen Track speichern Route umkehren Der gesamte Track wird mit dem ausgewählten Profil neu berechnet. From d42bb5d72ea96b8cf129553f0f03a0cc6bf93b8c Mon Sep 17 00:00:00 2001 From: nautilusx Date: Thu, 8 Oct 2020 05:15:04 +0000 Subject: [PATCH 0570/1366] Translated using Weblate (German) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-de/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 281ac9f4d2..fcfcca7c77 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3910,4 +3910,12 @@ Name: A – Z Start-/Ziel-Symbole Vielen Dank für den Kauf von \'Höhenlinien\' + Das Abonnement wird pro ausgewähltem Zeitraum berechnet. Sie können das Abonnement jederzeit über die AppGallery kündigen. + Die Bezahlung wird Ihrem AppGallery-Konto bei der Bestätigung des Kaufs belastet. +\n +\n Das Abonnement verlängert sich automatisch, sofern es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird für den Verlängerungszeitraum (Monat / drei Monate / Jahr) nur am Verlängerungsdatum belastet. +\n +\n Sie können Ihre Abonnements verwalten und kündigen, indem Sie zu Ihren AppGallery-Einstellungen gehen. + Vermeidet Fußwege + Keine Fußwege \ No newline at end of file From 968931a4bed9f8094f23188305083120b6dd0e4f Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Thu, 8 Oct 2020 13:49:03 +0000 Subject: [PATCH 0571/1366] Translated using Weblate (Russian) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 17452f3328..1f3bd7185a 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -1813,7 +1813,7 @@ Хранилище карт Копировать Переместить файлы данных Osmand в новое место назначения\? - Любой текст для поиска + Напечатайте для поиска Номера домов Избегать пересечения границ Предельная высота From 62f0d4b74029e84f609120dbd67b18eeda02e4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Wed, 7 Oct 2020 22:02:49 +0000 Subject: [PATCH 0572/1366] Translated using Weblate (Turkish) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-tr/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 50a41c8562..071ecab230 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3861,4 +3861,12 @@ İsim: A – Z Başlangıç/bitiş simgeleri \'Eş yükselti eğrileri\'ni satın aldığınız için teşekkürler + Abonelik seçilen dönem başına ücretlendirilir. İstediğiniz zaman AppGallery\'den iptal edin. + Ödeme, satın alma onaylandığında AppGallery hesabınızdan alınacaktır. +\n +\nYenileme tarihinden önce iptal edilmedikçe abonelik otomatik olarak yenilenir. Hesabınızdan yenileme süresi (ay/üç ay/yıl) için yalnızca yenileme tarihinde ücret alınacaktır. +\n +\n AppGallery ayarlarınıza giderek aboneliklerinizi yönetebilir ve iptal edebilirsiniz. + Yaya yollarından kaçın + Yaya yollarından kaçın \ No newline at end of file From d3fa589a0f07279a2b73b5cba8d4c54c60470b9b Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 8 Oct 2020 06:34:32 +0000 Subject: [PATCH 0573/1366] Translated using Weblate (Hebrew) Currently translated at 99.9% (3491 of 3493 strings) --- OsmAnd/res/values-iw/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 42a840fa87..54343e43d2 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -3911,4 +3911,6 @@ שם: א – ת סמלי התחלה/סיום תודה לך על רכישת ‚קווי מתאר’ + הימנעות משבילי הולכי רגל + הימנעות משבילי הולכי רגל \ No newline at end of file From 12aeebf6d32329cd1eca2589f6e22159bead16d4 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Thu, 8 Oct 2020 07:02:23 +0000 Subject: [PATCH 0574/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-ar/strings.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index c1426b8483..c695a1c813 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1074,7 +1074,7 @@ المسارات الرياضية وسائل المواصلات سمات أخرى للخريطة - العناصر الاخرى + العناصر الأخرى شريط المعلومات العدادات على اليمين العدادات على اليسار @@ -3413,7 +3413,7 @@ سترى الأيقونة فقط أثناء الملاحة أو أثناء التحرك. قيم تظهر أيقونة الخريطة فقط على الخريطة ، وتتغير أثناء التنقل إلى أيقونة التنقل. - تحقق وتبادل سجلات مفصلة من التطبيق + التحقق من السجلات التفصيلية للتطبيق ومشاركتها تعذر تحليل الهدف الجغرافي \'%s\'. الإذن مطلوب لاستخدام هذا الخيار. اعراض جانبية: سيفقد المسار الخاص بك جميع الأقسام التي لم يتحقق فيها معيار الحد الأدنى للسرعة (على سبيل المثال ، حيث تدفع دراجتك أعلى تل شديد الانحدار). أيضا ، لن تكون هناك معلومات حول فترات الراحة ، مثل الاستراحات. هذا له تأثيرات على أي تحليل أو مرحلة ما بعد المعالجة ، مثل عند محاولة تحديد المدة الإجمالية لرحلتك ، أو وقت الحركة ، أو متوسط سرعتك. @@ -3893,4 +3893,12 @@ الاسم: أ – ي رموز البدء/الانتهاء شكرا لشرائك \"خطوط الكنتور\" + رسوم الاشتراك ستفرض كل شهر. يمكنك إلغاء اشتراكك متى أردت عبر Google play. + سيتم تحصيل المبلغ على حساب AppGallery الخاص بك عند تأكيد الشراء. +\n +\nيتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل تاريخ التجديد. سيتم خصم حسابك على فترة التجديد (شهر/ثلاثة أشهر/سنة) فقط في تاريخ التجديد. +\n +\nيمكنك إدارة وإلغاء الاشتراكات الخاصة بك عن طريق الانتقال إلى إعدادات AppGallery. + تجنب الممرات + تجنب الممرات \ No newline at end of file From 324fb1e58a620407bb51d350b7cedf150ebbd880 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Wed, 7 Oct 2020 21:36:29 +0000 Subject: [PATCH 0575/1366] Translated using Weblate (Sardinian) Currently translated at 99.7% (3483 of 3493 strings) --- OsmAnd/res/values-sc/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index 57221ff561..06484d1e32 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3905,4 +3905,12 @@ Nùmene: A – Z Iconas de incumintzu/fine Gràtzias pro àere comporadu \'Curvas de livellu\' + Costu periòdicu de s\'abbonamentu. Lu podes anullare in AppGallery cando boles. + Su pagamentu at a èssere addebitadu a su contu tuo de AppGallery cando sa còmpora at a èssere cunfirmada. +\n +\nS\'abbonamentu si rinnovat a sa sola automaticamente, francu chi siat istadu annulladu in antis de sa die de su rinnovu. Su contu tuo at a bènnere addebitadu pro su perìodu de rinnovu (mese/tres meses/annu) in sa die de rinnovu ebbia. +\n +\nPodes amministrare e annullare sos abbonamentos tuos intrende in sas impostatziones de AppGallery tuas. + Èvita sos martzapiedis + Èvita sos martzapiedis \ No newline at end of file From 7e88d639a06e9cc66c2d076478a5014277859088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 8 Oct 2020 06:27:37 +0000 Subject: [PATCH 0576/1366] Translated using Weblate (Estonian) Currently translated at 99.4% (3473 of 3493 strings) --- OsmAnd/res/values-et/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index 8e58fdad52..fe5cbbfa20 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -3764,4 +3764,13 @@ Nimi: A – Z Ekraani väljalülitamine Ratastool edasi + Väldi jalgteid + Väldi jalgteid + Täname „Kõrgusjoonte“ ostu eest + Ostukinnituse saabumisel arveldame tellimuse eest sinu AppGallery konto alusel. +\n +\nKui sa ei tühista tellimust enne uue perioodi algust, siis tellimus pikeneb automaatselt ning arveldame järgmise ajavahemiku eest (kuu/kvartal/aasta) selle alguses. +\n +\nTellimust saad hallata ja tühistada AppGallery seadistustest. + Arveldame tellimuse eest valitud ajavahemiku alusel. Seda saad sa vabalt valitud ajal tühistada AppGallery\'s. \ No newline at end of file From b9fd31aa90e53d67608f0e343051d6b01fe758d2 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 8 Oct 2020 06:40:25 +0000 Subject: [PATCH 0577/1366] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3493 of 3493 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index cf0cc3fd99..1d6615754e 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3901,4 +3901,12 @@ 名稱:A – Z 開始/結束圖示 感謝您購買 \'Contour lines\' + 按選定週期收取訂閱費用。隨時在 AppGallery 上取消。 + 確認購買後將會從您的 AppGallery 帳號中付款。 +\n +\n除非在續訂日期前取消,否則就會自動續訂。您的帳號將只會在續訂日期收取訂閱週期(一個月/三個月/一年)的費用。 +\n +\n您可以在您的 AppGallery 設定中管理與取消您的訂閱。 + 避免人行道 + 避免人行道 \ No newline at end of file From fbdd3db40e014d3e840be57a5f4e4d6b3f567891 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Thu, 8 Oct 2020 06:10:21 +0000 Subject: [PATCH 0578/1366] Translated using Weblate (Arabic) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/ar/ --- OsmAnd-telegram/res/values-ar/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd-telegram/res/values-ar/strings.xml b/OsmAnd-telegram/res/values-ar/strings.xml index 1fb4149e0b..45b5d99ce7 100644 --- a/OsmAnd-telegram/res/values-ar/strings.xml +++ b/OsmAnd-telegram/res/values-ar/strings.xml @@ -267,4 +267,8 @@ تتبع حالة أوسماند العودة إلى OsmAnd %1$s منذ + إرسال التقرير + تصدير + سجل الاستخدام + التحقق من السجلات التفصيلية للتطبيق ومشاركتها \ No newline at end of file From e6c8d5e7500841f3f2bea33569f165680aa3aac5 Mon Sep 17 00:00:00 2001 From: yogiks Date: Thu, 8 Oct 2020 19:31:02 +0530 Subject: [PATCH 0579/1366] Add Kannada --- OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java b/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java index 34e5048930..d996678e44 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java @@ -27,7 +27,7 @@ public abstract class MapRenderingTypes { private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class); public static final String[] langs = new String[] { "af", "als", "ar", "az", "be", "bg", "bn", "bpy", "br", "bs", "ca", "ceb", "cs", "cy", "da", "de", "el", "eo", "es", "et", "eu", "fa", "fi", "fr", "fy", "ga", "gl", "he", "hi", "hsb", - "hr", "ht", "hu", "hy", "id", "is", "it", "ja", "ka", "ko", "ku", "la", "lb", "lo", "lt", "lv", "mk", "ml", "mr", "ms", "nds", "new", "nl", "nn", "no", "nv", "os", "pl", "pms", "pt", "ro", "ru", "sc", "sh", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tl", "tr", "uk", "vi", "vo", "zh", "zh-hans", "zh-hant", }; + "hr", "ht", "hu", "hy", "id", "is", "it", "ja", "ka", "kn", "ko", "ku", "la", "lb", "lo", "lt", "lv", "mk", "ml", "mr", "ms", "nds", "new", "nl", "nn", "no", "nv", "os", "pl", "pms", "pt", "ro", "ru", "sc", "sh", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tl", "tr", "uk", "vi", "vo", "zh", "zh-hans", "zh-hant", }; public final static byte RESTRICTION_NO_RIGHT_TURN = 1; From 4faf931d2011f5e146e89905ad308baf6b7fca2e Mon Sep 17 00:00:00 2001 From: sergosm Date: Thu, 8 Oct 2020 17:01:38 +0300 Subject: [PATCH 0580/1366] OpenGL verification --- .../osmand/plus/development/DevelopmentSettingsFragment.java | 2 +- .../osmand/plus/development/SettingsDevelopmentActivity.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/development/DevelopmentSettingsFragment.java b/OsmAnd/src/net/osmand/plus/development/DevelopmentSettingsFragment.java index 97e6bd12cd..774e5f47f2 100644 --- a/OsmAnd/src/net/osmand/plus/development/DevelopmentSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/development/DevelopmentSettingsFragment.java @@ -59,7 +59,7 @@ public class DevelopmentSettingsFragment extends BaseSettingsFragment { private void setupOpenglRenderPref() { SwitchPreferenceEx useOpenglRender = findPreference(settings.USE_OPENGL_RENDER.getId()); - if (app.getSettings().USE_OPENGL_RENDER.get() && NativeCoreContext.isInit()) { + if (Version.isOpenGlAvailable(app)) { assert useOpenglRender != null; useOpenglRender.setDescription(getString(R.string.use_opengl_render_descr)); useOpenglRender.setIconSpaceReserved(false); diff --git a/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java b/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java index f7e1fa064f..c500a28254 100644 --- a/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/SettingsDevelopmentActivity.java @@ -111,7 +111,7 @@ public class SettingsDevelopmentActivity extends SettingsBaseActivity { debug.addPreference(createCheckBoxPreference(settings.SHOULD_SHOW_FREE_VERSION_BANNER, R.string.show_free_version_banner, R.string.show_free_version_banner_description)); - + pref = new Preference(this); pref.setTitle(R.string.test_voice_prompts); pref.setSummary(R.string.play_commands_of_currently_selected_voice); From 800ffe1819b69bad5dd1394715f7371a4f99aa80 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 8 Oct 2020 20:35:53 +0300 Subject: [PATCH 0581/1366] Fix import profile by AIDL --- .../src/net/osmand/plus/settings/backend/SettingsHelper.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java index 0172531139..9831206962 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java @@ -2937,6 +2937,11 @@ public class SettingsHelper { for (ExportSettingsType settingsType : settingsTypes) { List settingsDataObjects = additionalData.get(settingsType); if (settingsDataObjects != null) { + for (Object object : settingsDataObjects) { + if (object instanceof ApplicationModeBean) { + settingsItems.add(new ProfileSettingsItem(app, null, (ApplicationModeBean) object)); + } + } settingsItems.addAll(prepareAdditionalSettingsItems(new ArrayList<>(settingsDataObjects))); } } From 674423b0581c31e059c9ed293b7d41718fc26ab5 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 8 Oct 2020 20:36:19 +0300 Subject: [PATCH 0582/1366] Fix sorting menu items --- .../src/net/osmand/plus/ContextMenuAdapter.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 26e173d568..102234a3cf 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -137,14 +137,18 @@ public class ContextMenuAdapter { Collections.sort(items, new Comparator() { @Override public int compare(ContextMenuItem item1, ContextMenuItem item2) { - if (DRAWER_SWITCH_PROFILE_ID.equals(item1.getId())) { - return -1; - } - if (DRAWER_CONFIGURE_PROFILE_ID.equals(item1.getId()) && DRAWER_SWITCH_PROFILE_ID.equals(item2.getId())) { + if (DRAWER_CONFIGURE_PROFILE_ID.equals(item1.getId()) + && DRAWER_SWITCH_PROFILE_ID.equals(item2.getId())) { return 1; - } - if (DRAWER_CONFIGURE_PROFILE_ID.equals(item1.getId())) { + } else if (DRAWER_SWITCH_PROFILE_ID.equals(item1.getId()) + && DRAWER_CONFIGURE_PROFILE_ID.equals(item2.getId())) { return -1; + } else if (DRAWER_SWITCH_PROFILE_ID.equals(item1.getId()) + || DRAWER_CONFIGURE_PROFILE_ID.equals(item1.getId())) { + return -1; + } else if (DRAWER_SWITCH_PROFILE_ID.equals(item2.getId()) + || DRAWER_CONFIGURE_PROFILE_ID.equals(item2.getId())) { + return 1; } int order1 = item1.getOrder(); int order2 = item2.getOrder(); From dc55878c922803a47ff6f534d5fde0dd9b8e312e Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 8 Oct 2020 22:45:39 +0300 Subject: [PATCH 0583/1366] Fix version upgrade and remove unnecessary changes --- .../osmand/plus/AppVersionUpgradeOnInit.java | 80 +++++++++---- .../osmand/plus/helpers/DayNightHelper.java | 28 ++--- .../plus/helpers/enums/AngularConstants.java | 3 +- .../plus/helpers/enums/AutoZoomMap.java | 4 +- .../plus/helpers/enums/DayNightMode.java | 2 +- .../plus/helpers/enums/DrivingRegion.java | 4 +- .../plus/helpers/enums/MetricsConstants.java | 3 +- .../plus/helpers/enums/SpeedConstants.java | 3 +- .../plus/mapmarkers/MapMarkersMode.java | 2 +- .../settings/backend/BooleanPreference.java | 8 +- .../backend/BooleanStringPreference.java | 4 +- .../settings/backend/CommonPreference.java | 53 +++++---- .../backend/ContextMenuItemsPreference.java | 8 +- .../backend/ContextMenuItemsSettings.java | 5 +- .../backend/EnumStringPreference.java | 8 +- .../settings/backend/FloatPreference.java | 8 +- .../backend/ImpassableRoadsStorage.java | 22 ++-- .../plus/settings/backend/IntPreference.java | 10 +- .../backend/IntermediatePointsStorage.java | 2 +- .../backend/ListStringPreference.java | 20 ++-- .../plus/settings/backend/LongPreference.java | 10 +- .../backend/MainContextMenuItemsSettings.java | 8 +- .../backend/OsmAndPreferencesDataStore.java | 10 +- .../settings/backend/OsmandPreference.java | 2 +- .../plus/settings/backend/OsmandSettings.java | 107 +++++------------- .../backend/PreferenceWithListener.java | 2 +- .../plus/settings/backend/SettingsHelper.java | 22 +++- .../backend/SettingsMapPointsStorage.java | 8 +- .../settings/backend/StringPreference.java | 8 +- .../src/net/osmand/plus/views/GPXLayer.java | 0 .../plus/views/layers/RulerControlLayer.java | 6 + .../osmand/plus/views/layers/RulerMode.java | 7 -- .../mapwidgets/MapInfoWidgetsFactory.java | 2 +- 33 files changed, 237 insertions(+), 232 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/views/GPXLayer.java delete mode 100644 OsmAnd/src/net/osmand/plus/views/layers/RulerMode.java diff --git a/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java b/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java index 49e354ea8b..9eeec4542b 100644 --- a/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java +++ b/OsmAnd/src/net/osmand/plus/AppVersionUpgradeOnInit.java @@ -7,8 +7,10 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; -import net.osmand.data.FavouritePoint; +import net.osmand.data.FavouritePoint.SpecialPointType; import net.osmand.data.LatLon; +import net.osmand.plus.AppInitializer.AppInitializeListener; +import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.api.SettingsAPI; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.CommonPreference; @@ -24,6 +26,7 @@ import java.util.List; import java.util.Map; class AppVersionUpgradeOnInit { + public static final String FIRST_TIME_APP_RUN = "FIRST_TIME_APP_RUN"; //$NON-NLS-1$ public static final String VERSION_INSTALLED_NUMBER = "VERSION_INSTALLED_NUMBER"; //$NON-NLS-1$ public static final String NUMBER_OF_STARTS = "NUMBER_OF_STARTS"; //$NON-NLS-1$ @@ -56,16 +59,14 @@ class AppVersionUpgradeOnInit { private int prevAppVersion; private boolean appVersionChanged; private boolean firstTime; - private OsmandSettings settings; AppVersionUpgradeOnInit(OsmandApplication app) { this.app = app; - settings = app.getSettings(); } @SuppressLint("ApplySharedPref") void upgradeVersion(SharedPreferences startPrefs, int lastVersion) { - if(!startPrefs.contains(NUMBER_OF_STARTS)) { + if (!startPrefs.contains(NUMBER_OF_STARTS)) { startPrefs.edit().putInt(NUMBER_OF_STARTS, 1).commit(); } else { startPrefs.edit().putInt(NUMBER_OF_STARTS, startPrefs.getInt(NUMBER_OF_STARTS, 0) + 1).commit(); @@ -81,7 +82,7 @@ class AppVersionUpgradeOnInit { } else { prevAppVersion = startPrefs.getInt(VERSION_INSTALLED_NUMBER, 0); if (needsUpgrade(startPrefs, lastVersion)) { - + OsmandSettings settings = app.getSettings(); if (prevAppVersion < VERSION_2_2) { settings.SHOW_DASHBOARD_ON_START.set(true); settings.SHOW_DASHBOARD_ON_MAP_SCREEN.set(true); @@ -121,13 +122,14 @@ class AppVersionUpgradeOnInit { startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, VERSION_3_7).commit(); } if (prevAppVersion < VERSION_3_7_01) { - app.getAppInitializer().addListener(new AppInitializer.AppInitializeListener() { + app.getAppInitializer().addListener(new AppInitializeListener() { @Override public void onProgress(AppInitializer init, AppInitializer.InitEvents event) { - if (event.equals(AppInitializer.InitEvents.FAVORITES_INITIALIZED)) { + if (event.equals(InitEvents.FAVORITES_INITIALIZED)) { app.getFavorites().fixBlackBackground(); } } + @Override public void onFinish(AppInitializer init) { } @@ -158,20 +160,20 @@ class AppVersionUpgradeOnInit { } public void resetFirstTimeRun(SharedPreferences startPrefs) { - if(startPrefs != null) { + if (startPrefs != null) { startPrefs.edit().remove(FIRST_TIME_APP_RUN).commit(); } } public int getNumberOfStarts(SharedPreferences startPrefs) { - if(startPrefs == null) { + if (startPrefs == null) { return 0; } return startPrefs.getInt(NUMBER_OF_STARTS, 1); } public long getFirstInstalledDays(SharedPreferences startPrefs) { - if(startPrefs == null) { + if (startPrefs == null) { return 0; } long nd = startPrefs.getLong(FIRST_INSTALLED, 0); @@ -183,9 +185,8 @@ class AppVersionUpgradeOnInit { return firstTime; } - - public void migratePreferences() { + OsmandSettings settings = app.getSettings(); migrateEnumPreferences(); SharedPreferences globalSharedPreferences = (SharedPreferences) settings.getGlobalPreferences(); Map globalPrefsMap = globalSharedPreferences.getAll(); @@ -213,7 +214,7 @@ class AppVersionUpgradeOnInit { } } } - for (OsmandPreference pref : settings.getGeneralPrefs()) { + for (OsmandPreference pref : getGeneralPrefs()) { if (pref instanceof CommonPreference) { CommonPreference commonPref = (CommonPreference) pref; Object defaultVal = commonPref.getModeValue(ApplicationMode.DEFAULT); @@ -224,7 +225,6 @@ class AppVersionUpgradeOnInit { } } } - String json = settings.getSettingsAPI().getString(settings.getGlobalPreferences(), "custom_app_profiles", ""); if (!Algorithms.isEmpty(json)) { Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); @@ -241,9 +241,10 @@ class AppVersionUpgradeOnInit { } public void migrateEnumPreferences() { - for (OsmandPreference pref : settings.getRegisteredPreferences().values()) { + OsmandSettings settings = app.getSettings(); + for (OsmandPreference pref : settings.getRegisteredPreferences().values()) { if (pref instanceof EnumStringPreference) { - EnumStringPreference enumPref = (EnumStringPreference) pref; + EnumStringPreference enumPref = (EnumStringPreference) pref; if (enumPref.isGlobal()) { migrateEnumPref(enumPref, (SharedPreferences) settings.getGlobalPreferences()); } else { @@ -256,6 +257,7 @@ class AppVersionUpgradeOnInit { } public void migrateQuickActionStates() { + OsmandSettings settings = app.getSettings(); String quickActionsJson = settings.getSettingsAPI().getString(settings.getGlobalPreferences(), "quick_action_new", ""); if (!Algorithms.isEmpty(quickActionsJson)) { Gson gson = new GsonBuilder().create(); @@ -282,9 +284,10 @@ class AppVersionUpgradeOnInit { } public void migrateHomeWorkParkingToFavorites() { + OsmandSettings settings = app.getSettings(); FavouritesDbHelper favorites = app.getFavorites(); SettingsAPI settingsAPI = settings.getSettingsAPI(); - Object globalPreferences= settings.getGlobalPreferences(); + Object globalPreferences = settings.getGlobalPreferences(); LatLon homePoint = null; float lat = settingsAPI.getFloat(globalPreferences, "home_point_lat", 0); @@ -299,10 +302,47 @@ class AppVersionUpgradeOnInit { workPoint = new LatLon(lat, lon); } if (homePoint != null) { - favorites.setSpecialPoint(homePoint, FavouritePoint.SpecialPointType.HOME, null); + favorites.setSpecialPoint(homePoint, SpecialPointType.HOME, null); } if (workPoint != null) { - favorites.setSpecialPoint(workPoint, FavouritePoint.SpecialPointType.WORK, null); + favorites.setSpecialPoint(workPoint, SpecialPointType.WORK, null); } } -} + + + public OsmandPreference[] getGeneralPrefs() { + OsmandSettings settings = app.getSettings(); + return new OsmandPreference[] { + settings.EXTERNAL_INPUT_DEVICE, + settings.CENTER_POSITION_ON_MAP, + settings.ROTATE_MAP, + settings.MAP_SCREEN_ORIENTATION, + settings.LIVE_MONITORING_URL, + settings.LIVE_MONITORING_MAX_INTERVAL_TO_SEND, + settings.LIVE_MONITORING_INTERVAL, + settings.LIVE_MONITORING, + settings.SHOW_TRIP_REC_NOTIFICATION, + settings.AUTO_SPLIT_RECORDING, + settings.SAVE_TRACK_MIN_SPEED, + settings.SAVE_TRACK_PRECISION, + settings.SAVE_TRACK_MIN_DISTANCE, + settings.SAVE_TRACK_INTERVAL, + settings.TRACK_STORAGE_DIRECTORY, + settings.SAVE_HEADING_TO_GPX, + settings.DISABLE_RECORDING_ONCE_APP_KILLED, + settings.SAVE_TRACK_TO_GPX, + settings.SAVE_GLOBAL_TRACK_REMEMBER, + settings.SAVE_GLOBAL_TRACK_INTERVAL, + settings.MAP_EMPTY_STATE_ALLOWED, + settings.DO_NOT_USE_ANIMATIONS, + settings.USE_KALMAN_FILTER_FOR_COMPASS, + settings.USE_MAGNETIC_FIELD_SENSOR_COMPASS, + settings.USE_TRACKBALL_FOR_MOVEMENTS, + settings.SPEED_SYSTEM, + settings.ANGULAR_UNITS, + settings.METRIC_SYSTEM, + settings.DRIVING_REGION, + settings.DRIVING_REGION_AUTOMATIC + }; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java b/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java index ea4f6a1ae7..d3ebe9d6ae 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java @@ -1,20 +1,6 @@ package net.osmand.plus.helpers; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import net.osmand.Location; -import net.osmand.PlatformUtil; -import net.osmand.StateChangedListener; -import net.osmand.plus.helpers.enums.DayNightMode; -import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.OsmandApplication; -import net.osmand.util.SunriseSunset; - -import org.apache.commons.logging.Log; - import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; @@ -22,6 +8,20 @@ import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.location.LocationManager; +import net.osmand.Location; +import net.osmand.PlatformUtil; +import net.osmand.StateChangedListener; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.helpers.enums.DayNightMode; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.util.SunriseSunset; + +import org.apache.commons.logging.Log; + +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + /** * Class to help determine if we want to render day or night map - it uses the * DayNightMode enumeration for its behavior
diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java b/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java index 9962144fa4..4041380fe1 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/AngularConstants.java @@ -24,5 +24,4 @@ public enum AngularConstants { public String getUnitSymbol() { return unit; } - -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java b/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java index f092c19be7..ad09424924 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/AutoZoomMap.java @@ -6,6 +6,7 @@ public enum AutoZoomMap { FARTHEST(R.string.auto_zoom_farthest, 1f, 15.5f), FAR(R.string.auto_zoom_far, 1.4f, 17f), CLOSE(R.string.auto_zoom_close, 2f, 19f); + public final float coefficient; public final int name; public final float maxZoom; @@ -14,6 +15,5 @@ public enum AutoZoomMap { this.name = name; this.coefficient = coefficient; this.maxZoom = maxZoom; - } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java b/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java index 9c8865e877..77f0eb8876 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/DayNightMode.java @@ -59,4 +59,4 @@ public enum DayNightMode { return new DayNightMode[]{AUTO, DAY, NIGHT}; } } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java b/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java index 70c825926e..60902c46b5 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/DrivingRegion.java @@ -54,9 +54,9 @@ public enum DrivingRegion { return DrivingRegion.JAPAN; } else if (df.getCountry().equalsIgnoreCase("au")) { return DrivingRegion.AUSTRALIA; - } else if(df.getCountry().equalsIgnoreCase(Locale.UK.getCountry())) { + } else if (df.getCountry().equalsIgnoreCase(Locale.UK.getCountry())) { return DrivingRegion.UK_AND_OTHERS; } return DrivingRegion.EUROPE_ASIA; } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java b/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java index 23034b5277..20f3804a6a 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/MetricsConstants.java @@ -26,5 +26,4 @@ public enum MetricsConstants { public String toTTSString() { return ttsString; } - -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java b/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java index 15a54513eb..1a4c512b8c 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java +++ b/OsmAnd/src/net/osmand/plus/helpers/enums/SpeedConstants.java @@ -29,5 +29,4 @@ public enum SpeedConstants { public String toShortString(Context ctx) { return ctx.getString(key); } - -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java index 840da1ad92..a9cf23ea75 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersMode.java @@ -34,4 +34,4 @@ public enum MapMarkersMode { public static MapMarkersMode[] possibleValues(Context context) { return new MapMarkersMode[]{TOOLBAR, WIDGETS, NONE}; } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java index 9a0c2a2391..9ff4d3069d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanPreference.java @@ -2,12 +2,12 @@ package net.osmand.plus.settings.backend; public class BooleanPreference extends CommonPreference { - BooleanPreference(OsmandSettings osmandSettings, String id, boolean defaultValue) { - super(osmandSettings, id, defaultValue); + BooleanPreference(OsmandSettings settings, String id, boolean defaultValue) { + super(settings, id, defaultValue); } @Override - public Boolean getValue(Object prefs, Boolean defaultValue) { + protected Boolean getValue(Object prefs, Boolean defaultValue) { return getSettingsAPI().getBoolean(prefs, getId(), defaultValue); } @@ -20,4 +20,4 @@ public class BooleanPreference extends CommonPreference { public Boolean parseString(String s) { return Boolean.parseBoolean(s); } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java index 8ca99f8521..1928fa60a7 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/BooleanStringPreference.java @@ -7,7 +7,7 @@ public class BooleanStringPreference extends BooleanPreference { } @Override - public Boolean getValue(Object prefs, Boolean defaultValue) { + protected Boolean getValue(Object prefs, Boolean defaultValue) { Boolean value; try { value = parseString(getSettingsAPI().getString(prefs, getId(), defaultValue.toString())); @@ -22,4 +22,4 @@ public class BooleanStringPreference extends BooleanPreference { protected boolean setValue(Object prefs, Boolean val) { return getSettingsAPI().edit(prefs).putString(getId(), val != null ? val.toString() : null).commit(); } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java index ea1c251375..62ce3a2450 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/CommonPreference.java @@ -10,25 +10,29 @@ import java.util.LinkedHashMap; import java.util.Map; public abstract class CommonPreference extends PreferenceWithListener { - private OsmandSettings osmandSettings; - private final String id; - private boolean global; - private T cachedValue; + + private OsmandSettings settings; private Object cachedPreference; - private boolean cache; - private Map defaultValues; + + private final String id; + + private T cachedValue; private T defaultValue; + private Map defaultValues; + + private boolean cache; + private boolean global; - public CommonPreference(OsmandSettings osmandSettings, String id, T defaultValue) { - this.osmandSettings = osmandSettings; + public CommonPreference(OsmandSettings settings, String id, T defaultValue) { + this.settings = settings; this.id = id; this.defaultValue = defaultValue; - osmandSettings.registerInternalPreference(id, this); + settings.registerInternalPreference(id, this); } // Methods to possibly override - public abstract T getValue(Object prefs, T defaultValue); + protected abstract T getValue(Object prefs, T defaultValue); protected abstract boolean setValue(Object prefs, T val); @@ -39,15 +43,15 @@ public abstract class CommonPreference extends PreferenceWithListener { } protected SettingsAPI getSettingsAPI() { - return osmandSettings.getSettingsAPI(); + return settings.getSettingsAPI(); } protected ApplicationMode getApplicationMode() { - return osmandSettings.getApplicationMode(); + return settings.getApplicationMode(); } protected OsmandApplication getContext() { - return osmandSettings.getContext(); + return settings.getContext(); } // common methods @@ -68,7 +72,7 @@ public abstract class CommonPreference extends PreferenceWithListener { } protected final Object getPreferences() { - return osmandSettings.getPreferences(global); + return settings.getPreferences(global); } @@ -86,7 +90,7 @@ public abstract class CommonPreference extends PreferenceWithListener { return set(obj); } - Object profilePrefs = osmandSettings.getProfilePreferences(mode); + Object profilePrefs = settings.getProfilePreferences(mode); boolean valueSaved = setValue(profilePrefs, obj); if (valueSaved && cache && cachedPreference == profilePrefs) { cachedValue = obj; @@ -121,7 +125,7 @@ public abstract class CommonPreference extends PreferenceWithListener { // TODO final protected T getDefaultValue() { - return getProfileDefaultValue(osmandSettings.currentMode); + return getProfileDefaultValue(settings.APPLICATION_MODE.get()); } @Override @@ -129,8 +133,6 @@ public abstract class CommonPreference extends PreferenceWithListener { this.defaultValue = newDefaultValue; } - - // TODO final @Override public T getModeValue(ApplicationMode mode) { @@ -138,7 +140,7 @@ public abstract class CommonPreference extends PreferenceWithListener { return get(); } T defaultV = getProfileDefaultValue(mode); - return getValue(osmandSettings.getProfilePreferences(mode), defaultV); + return getValue(settings.getProfilePreferences(mode), defaultV); } // TODO final @@ -148,7 +150,7 @@ public abstract class CommonPreference extends PreferenceWithListener { return cachedValue; } cachedPreference = getPreferences(); - cachedValue = getValue(cachedPreference, getProfileDefaultValue(osmandSettings.currentMode)); + cachedValue = getValue(cachedPreference, getProfileDefaultValue(settings.APPLICATION_MODE.get())); return cachedValue; } @@ -159,7 +161,7 @@ public abstract class CommonPreference extends PreferenceWithListener { @Override public final void resetToDefault() { - T o = getProfileDefaultValue(osmandSettings.currentMode); + T o = getProfileDefaultValue(settings.APPLICATION_MODE.get()); set(o); } @@ -186,12 +188,12 @@ public abstract class CommonPreference extends PreferenceWithListener { return false; } - public final boolean isSet() { - return osmandSettings.isSet(global, getId()); + public final boolean isSet() { + return settings.isSet(global, getId()); } public boolean isSetForMode(ApplicationMode mode) { - return osmandSettings.isSet(mode, getId()); + return settings.isSet(mode, getId()); } public final boolean isGlobal() { @@ -218,6 +220,7 @@ public abstract class CommonPreference extends PreferenceWithListener { } return false; } + // TODO final @Override public void readFromJson(JSONObject json, ApplicationMode appMode) throws JSONException { @@ -243,4 +246,4 @@ public abstract class CommonPreference extends PreferenceWithListener { T v = getModeValue(m); return toString(v); } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java index 4e562f1aca..12a83ea229 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ContextMenuItemsPreference.java @@ -6,13 +6,13 @@ public class ContextMenuItemsPreference extends CommonPreference