From c00c28e81116a28f2a3746e95e3a203256d56e16 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 28 Dec 2020 01:02:46 +0200 Subject: [PATCH 01/61] Online Routing UI - initial commit --- .../online_routing_engine_preference.xml | 35 ++ .../online_routing_preference_segment.xml | 185 ++++++++ .../preference_toolbar_with_action_button.xml | 95 ++++ OsmAnd/res/values/strings.xml | 11 +- .../profiles/SelectProfileBottomSheet.java | 11 +- .../onlinerouting/ExampleLocation.java | 26 ++ .../OnlineRoutingSegmentCard.java | 182 ++++++++ .../profiles/onlinerouting/ServerType.java | 22 + .../profiles/onlinerouting/VehicleType.java | 25 ++ .../OnlineRoutingEngineFragment.java | 409 ++++++++++++++++++ 10 files changed, 999 insertions(+), 2 deletions(-) create mode 100644 OsmAnd/res/layout/online_routing_engine_preference.xml create mode 100644 OsmAnd/res/layout/online_routing_preference_segment.xml create mode 100644 OsmAnd/res/layout/preference_toolbar_with_action_button.xml create mode 100644 OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java create mode 100644 OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java create mode 100644 OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java create mode 100644 OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java diff --git a/OsmAnd/res/layout/online_routing_engine_preference.xml b/OsmAnd/res/layout/online_routing_engine_preference.xml new file mode 100644 index 0000000000..69cc042252 --- /dev/null +++ b/OsmAnd/res/layout/online_routing_engine_preference.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/online_routing_preference_segment.xml b/OsmAnd/res/layout/online_routing_preference_segment.xml new file mode 100644 index 0000000000..0b1799e478 --- /dev/null +++ b/OsmAnd/res/layout/online_routing_preference_segment.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/preference_toolbar_with_action_button.xml b/OsmAnd/res/layout/preference_toolbar_with_action_button.xml new file mode 100644 index 0000000000..7c072f7daf --- /dev/null +++ b/OsmAnd/res/layout/preference_toolbar_with_action_button.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a78818557b..6a66dd03ea 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,7 +11,16 @@ Thx - Hardy --> - + Test route calculation + URL with all parameters will look like this: + Keep it empty if not + Enter param + Server URL + API key + Vehicle + Subtype + Edit online routing engine + Add online routing engine Allow intermittent water ways Allow intermittent water ways Allow streams and drains diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index eaf99b9503..da92070b65 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -22,7 +22,6 @@ import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; @@ -39,6 +38,7 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; +import net.osmand.plus.settings.fragments.OnlineRoutingEngineFragment; import net.osmand.router.RoutingConfiguration; import org.apache.commons.logging.Log; @@ -179,6 +179,15 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { }); } }); + addButtonItem(R.string.add_online_routing_engine, R.drawable.ic_world_globe_dark, new OnClickListener() { + @Override + public void onClick(View v) { + if (getActivity() != null) { + OnlineRoutingEngineFragment.showInstance(getActivity(), false); + } + dismiss(); + } + }); items.add(new BaseBottomSheetItem.Builder() .setCustomView(bottomSpaceView) .create()); diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java new file mode 100644 index 0000000000..ec1dd2149b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java @@ -0,0 +1,26 @@ +package net.osmand.plus.profiles.onlinerouting; + +import net.osmand.data.LatLon; + +public enum ExampleLocation { + AMSTERDAM("Amsterdam", new LatLon(52.379189, 4.899431)), + BERLIN("Berlin", new LatLon(52.520008, 13.404954)), + NEW_YORK("New York", new LatLon(43.000000, -75.000000)), + PARIS("Paris", new LatLon(48.864716, 2.349014)); + + ExampleLocation(String title, LatLon latLon) { + this.title = title; + this.latLon = latLon; + } + + private String title; + private LatLon latLon; + + public String getTitle() { + return title; + } + + public LatLon getLatLon() { + return latLon; + } +} diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java new file mode 100644 index 0000000000..3ea6c4386f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java @@ -0,0 +1,182 @@ +package net.osmand.plus.profiles.onlinerouting; + +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.CallbackWithObject; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; +import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; +import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.widgets.OsmandTextFieldBoxes; + +import java.util.List; + +public class OnlineRoutingSegmentCard extends BaseCard { + + private View headerContainer; + private TextView tvHeaderTitle; + private TextView tvHeaderSubtitle; + private RecyclerView rvSelectionMenu; + private HorizontalSelectionAdapter adapter; + private TextView tvDescription; + private View fieldBoxContainer; + private OsmandTextFieldBoxes textFieldBoxes; + private EditText editText; + private TextView tvHelperText; + private View bottomDivider; + private View button; + private View resultContainer; + private OnTextChangedListener onTextChangedListener; + + public OnlineRoutingSegmentCard(@NonNull MapActivity mapActivity) { + super(mapActivity); + build(mapActivity); + } + + @Override + public int getCardLayoutId() { + return R.layout.online_routing_preference_segment; + } + + @Override + protected void updateContent() { + headerContainer = view.findViewById(R.id.header); + tvHeaderTitle = view.findViewById(R.id.title); + tvHeaderSubtitle = view.findViewById(R.id.subtitle); + rvSelectionMenu = view.findViewById(R.id.selection_menu); + tvDescription = view.findViewById(R.id.description); + fieldBoxContainer = view.findViewById(R.id.field_box_container); + textFieldBoxes = view.findViewById(R.id.field_box); + editText = view.findViewById(R.id.edit_text); + tvHelperText = view.findViewById(R.id.helper_text); + bottomDivider = view.findViewById(R.id.bottom_divider); + button = view.findViewById(R.id.button); + resultContainer = view.findViewById(R.id.result_container); + + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + if (onTextChangedListener != null) { + boolean editedByUser = editText.getTag() == null; + String text = editText.getText().toString(); + onTextChangedListener.onTextChanged(editedByUser, text); + } + } + }); + } + + public void setHeaderTitle(@NonNull String title) { + showElements(headerContainer, tvHeaderTitle); + tvHeaderTitle.setText(title); + } + + public void setHeaderSubtitle(@NonNull String subtitle) { + showElements(headerContainer, tvHeaderSubtitle); + tvHeaderSubtitle.setText(subtitle); + } + + public void setSelectionMenu(List items, + String selectedItemTitle, + final CallbackWithObject callback) { + showElements(rvSelectionMenu); + rvSelectionMenu.setLayoutManager( + new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); + adapter = new HorizontalSelectionAdapter(app, nightMode); + adapter.setItems(items); + adapter.setSelectedItemByTitle(selectedItemTitle); + adapter.setListener(new HorizontalSelectionAdapterListener() { + @Override + public void onItemSelected(HorizontalSelectionItem item) { + if (callback.processResult(item)) { + adapter.setSelectedItem(item); + } + } + }); + rvSelectionMenu.setAdapter(adapter); + } + + public void setDescription(@NonNull String description) { + showElements(tvDescription); + tvDescription.setText(description); + } + + public void setFieldBoxLabelText(@NonNull String labelText) { + showElements(fieldBoxContainer); + textFieldBoxes.setLabelText(labelText); + } + + public void setFieldBoxHelperText(@NonNull String helperText) { + showElements(fieldBoxContainer, tvHelperText); + tvHelperText.setText(helperText); + } + + public void setEditedText(@NonNull String text) { + editText.setTag(""); // needed to indicate that the text was edited programmatically + editText.setText(text); + editText.setTag(null); + } + + public void showDivider() { + showElements(bottomDivider); + } + + public void setButton(OnClickListener listener) { + showElements(button); + button.setOnClickListener(listener); + UiUtilities.setupDialogButton(nightMode, button, + DialogButtonType.PRIMARY, R.string.test_route_calculation); + } + + public void showFieldBox() { + showElements(fieldBoxContainer); + } + + public void hideFieldBox() { + hideElements(fieldBoxContainer); + } + + private void showElements(View... views) { + changeVisibility(View.VISIBLE, views); + } + + private void hideElements(View... views) { + changeVisibility(View.GONE, views); + } + + private void changeVisibility(int visibility, View... views) { + for (View v : views) { + if (visibility != v.getVisibility()) { + v.setVisibility(visibility); + } + } + } + + public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener) { + this.onTextChangedListener = onTextChangedListener; + } + + public interface OnTextChangedListener { + void onTextChanged(boolean editedByUser, String text); + } +} diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java new file mode 100644 index 0000000000..d624aa269e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java @@ -0,0 +1,22 @@ +package net.osmand.plus.profiles.onlinerouting; + +public enum ServerType { + GRAPHHOPER("Graphhoper", "https://graphhopper.com/api/1/route?"), + OSRM("OSRM", "https://zlzk.biz/route/v1/"); + + ServerType(String title, String baseUrl) { + this.title = title; + this.baseUrl = baseUrl; + } + + private String title; + private String baseUrl; + + public String getTitle() { + return title; + } + + public String getBaseUrl() { + return baseUrl; + } +} diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java new file mode 100644 index 0000000000..78a0ac1e64 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java @@ -0,0 +1,25 @@ +package net.osmand.plus.profiles.onlinerouting; + +public enum VehicleType { + CAR("car", "Car"), + BIKE("bike", "Bike"), + FOOT("foot", "Foot"), + DRIVING("driving", "Driving"), + CUSTOM("custom", "Custom"); + + VehicleType(String key, String title) { + this.key = key; + this.title = title; + } + + private String key; + private String title; + + public String getKey() { + return key; + } + + public String getTitle() { + return title; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java new file mode 100644 index 0000000000..8e840f4a1b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java @@ -0,0 +1,409 @@ +package net.osmand.plus.settings.fragments; + +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.CallbackWithObject; +import net.osmand.data.LatLon; +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.activities.MapActivity; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; +import net.osmand.plus.profiles.onlinerouting.OnlineRoutingSegmentCard; +import net.osmand.plus.profiles.onlinerouting.OnlineRoutingSegmentCard.OnTextChangedListener; +import net.osmand.plus.profiles.onlinerouting.ServerType; +import net.osmand.plus.profiles.onlinerouting.ExampleLocation; +import net.osmand.plus.profiles.onlinerouting.VehicleType; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.util.Algorithms; + +import java.util.ArrayList; +import java.util.List; + +public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { + + public static final String TAG = OnlineRoutingEngineFragment.class.getSimpleName(); + + private static final String ENGINE_NAME_KEY = "engine_name"; + private static final String ENGINE_SERVER_KEY = "engine_server"; + private static final String ENGINE_SERVER_URL_KEY = "engine_server_url"; + private static final String ENGINE_VEHICLE_TYPE_KEY = "engine_vehicle_type"; + private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle"; + private static final String ENGINE_API_KEY_KEY = "engine_api_key"; + private static final String ENGINE_NAME_CHANGED_BY_USER_KEY = "engine_name_changed_by_user_key"; + private static final String EXAMPLE_LOCATION_KEY = "example_location"; + + private OnlineRoutingSegmentCard nameCard; + private OnlineRoutingSegmentCard serverCard; + private OnlineRoutingSegmentCard vehicleCard; + private OnlineRoutingSegmentCard apiKeyCard; + private OnlineRoutingSegmentCard exampleCard; + + private boolean isEditingMode; + private boolean nightMode; + + private OnlineRoutingEngineObject engine; + private ExampleLocation selectedLocation; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + engine = new OnlineRoutingEngineObject(); + if (savedInstanceState != null) { + restoreState(savedInstanceState); + } else { + initEngineState(); + } + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + OsmandApplication app = requireMyApplication(); + MapActivity mapActivity = getMapActivity(); + if (mapActivity == null) { + return null; + } + nightMode = !app.getSettings().isLightContent(); + + View view = UiUtilities.getInflater(getContext(), nightMode) + .inflate(R.layout.online_routing_engine_preference, container, false); + + if (Build.VERSION.SDK_INT >= 21) { + AndroidUtils.addStatusBarPadding21v(getContext(), view); + } + setupToolbar(view); + + ViewGroup segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); + + // create name card + nameCard = new OnlineRoutingSegmentCard(mapActivity); + nameCard.setDescription(getString(R.string.select_nav_profile_dialog_message)); + nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name)); + nameCard.setOnTextChangedListener(new OnTextChangedListener() { + @Override + public void onTextChanged(boolean changedByUser, String text) { + if (!isEditingMode && !engine.wasNameChangedByUser && changedByUser) { + engine.wasNameChangedByUser = true; + } + engine.name = text; + } + }); + nameCard.showDivider(); + segmentsContainer.addView(nameCard.getView()); + + // create server card + serverCard = new OnlineRoutingSegmentCard(mapActivity); + serverCard.setHeaderTitle(getString(R.string.shared_string_type)); + List serverItems = new ArrayList<>(); + for (ServerType server : ServerType.values()) { + serverItems.add(new HorizontalSelectionItem(server.getTitle(), server)); + } + serverCard.setSelectionMenu(serverItems, engine.serverType.getTitle(), + new CallbackWithObject() { + @Override + public boolean processResult(HorizontalSelectionItem result) { + ServerType server = (ServerType) result.getObject(); + if (engine.serverType != server) { + engine.serverType = server; + updateCardViews(nameCard, serverCard, exampleCard); + return true; + } + return false; + } + }); +// serverCard.setOnTextChangedListener(new OnTextChangedListener() { +// @Override +// public void onTextChanged(boolean editedByUser, String text) { +// engine.serverBaseUrl = text; +// } +// }); + serverCard.setFieldBoxLabelText(getString(R.string.shared_string_server_url)); + serverCard.showDivider(); + segmentsContainer.addView(serverCard.getView()); + + // create vehicle card + vehicleCard = new OnlineRoutingSegmentCard(mapActivity); + vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); + List vehicleItems = new ArrayList<>(); + for (VehicleType vehicle : VehicleType.values()) { + vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(), vehicle)); + } + vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.getTitle(), + new CallbackWithObject() { + @Override + public boolean processResult(HorizontalSelectionItem result) { + VehicleType vehicle = (VehicleType) result.getObject(); + if (engine.vehicleType != vehicle) { + engine.vehicleType = vehicle; + updateCardViews(nameCard, vehicleCard, exampleCard); + return true; + } + return false; + } + }); + vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); + vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { + @Override + public void onTextChanged(boolean editedByUser, String text) { + engine.customVehicleKey = text; + } + }); + vehicleCard.setEditedText(engine.customVehicleKey); + vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param)); + vehicleCard.showDivider(); + segmentsContainer.addView(vehicleCard.getView()); + + // create api key card + apiKeyCard = new OnlineRoutingSegmentCard(mapActivity); + apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); + apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); + apiKeyCard.setEditedText(engine.apiKey); + apiKeyCard.showDivider(); + apiKeyCard.setOnTextChangedListener(new OnTextChangedListener() { + @Override + public void onTextChanged(boolean editedByUser, String text) { + engine.apiKey = text; + updateCardViews(exampleCard); + } + }); + segmentsContainer.addView(apiKeyCard.getView()); + + // create example card + exampleCard = new OnlineRoutingSegmentCard(mapActivity); + exampleCard.setHeaderTitle(getString(R.string.shared_string_example)); + List locationItems = new ArrayList<>(); + for (ExampleLocation location : ExampleLocation.values()) { + locationItems.add(new HorizontalSelectionItem(location.getTitle(), location)); + } + exampleCard.setSelectionMenu(locationItems, selectedLocation.getTitle(), + new CallbackWithObject() { + @Override + public boolean processResult(HorizontalSelectionItem result) { + ExampleLocation location = (ExampleLocation) result.getObject(); + if (selectedLocation != location) { + selectedLocation = location; + updateCardViews(exampleCard); + return true; + } + return false; + } + }); + exampleCard.setFieldBoxHelperText(getString(R.string.online_routing_example_hint)); + exampleCard.setButton(new View.OnClickListener() { + @Override + public void onClick(View v) { + // make request to the server + } + }); + segmentsContainer.addView(exampleCard.getView()); + + View bottomSpaceView = new View(app); + int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top); + bottomSpaceView.setLayoutParams( + new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, space)); + segmentsContainer.addView(bottomSpaceView); + + View cancelButton = view.findViewById(R.id.dismiss_button); + UiUtilities.setupDialogButton(nightMode, cancelButton, + DialogButtonType.SECONDARY, R.string.shared_string_cancel); + cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); + + View applyButton = view.findViewById(R.id.right_bottom_button); + UiUtilities.setupDialogButton(nightMode, applyButton, + UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save); + applyButton.setVisibility(View.VISIBLE); + applyButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + // save engine to settings + } + }); + + updateCardViews(nameCard, serverCard, vehicleCard, exampleCard); + return view; + } + + private void setupToolbar(View mainView) { + Toolbar toolbar = (Toolbar) mainView.findViewById(R.id.toolbar); + ImageView navigationIcon = toolbar.findViewById(R.id.close_button); + navigationIcon.setImageResource(R.drawable.ic_action_close); + navigationIcon.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + TextView title = toolbar.findViewById(R.id.toolbar_title); + toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE); + View actionBtn = toolbar.findViewById(R.id.action_button); + if (isEditingMode) { + title.setText(getString(R.string.edit_online_routing_engine)); + ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon); + ivBtn.setImageDrawable( + getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete)); + actionBtn.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + // delete engine from settings + } + }); + } else { + title.setText(getString(R.string.add_online_routing_engine)); + actionBtn.setVisibility(View.GONE); + } + } + + private void updateCardViews(BaseCard ... cardsToUpdate) { + for (BaseCard card : cardsToUpdate) { + if (nameCard.equals(card)) { + if (!engine.wasNameChangedByUser) { + String name = String.format( + getString(R.string.ltr_or_rtl_combine_via_dash), + engine.serverType.getTitle(), engine.vehicleType.getTitle()); + nameCard.setEditedText(name); + } + + } else if (serverCard.equals(card)) { + serverCard.setHeaderSubtitle(engine.serverType.getTitle()); + serverCard.setEditedText(engine.serverType.getBaseUrl()); + + } else if (vehicleCard.equals(card)) { + vehicleCard.setHeaderSubtitle(engine.vehicleType.getTitle()); + if (engine.vehicleType == VehicleType.CUSTOM) { + vehicleCard.showFieldBox(); + } else { + vehicleCard.hideFieldBox(); + } + + } else if (exampleCard.equals(card)) { + exampleCard.setEditedText(getTestUrl()); + } + } + } + + private String getTestUrl() { + String baseUrl = engine.serverType.getBaseUrl(); + String vehicle = engine.getVehicleKey(); + + LatLon kievLatLon = new LatLon(50.431759, 30.517023); + LatLon destinationLatLon = selectedLocation.getLatLon(); + + if (engine.serverType == ServerType.GRAPHHOPER) { + return baseUrl + "point=" + kievLatLon.getLatitude() + + "," + kievLatLon.getLongitude() + + "&" + "point=" + destinationLatLon.getLatitude() + + "," + destinationLatLon.getLongitude() + + "&" + "vehicle=" + vehicle + + (!Algorithms.isEmpty(engine.apiKey) ? ("&" + "key=" + engine.apiKey) : ""); + } else { + return baseUrl + vehicle + "/" + kievLatLon.getLatitude() + + "," + kievLatLon.getLongitude() + + ";" + destinationLatLon.getLatitude() + + "," + destinationLatLon.getLongitude() + + "?geometries=geojson&overview=full"; + } + } + + public static void showInstance(FragmentActivity activity, boolean isEditingMode) { + OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); + fragment.isEditingMode = isEditingMode; + activity.getSupportFragmentManager().beginTransaction() + .add(R.id.fragmentContainer, fragment, TAG) + .addToBackStack(TAG).commitAllowingStateLoss(); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + saveState(outState); + } + + private void saveState(Bundle outState) { + outState.putString(ENGINE_NAME_KEY, engine.name); + outState.putString(ENGINE_SERVER_KEY, engine.serverType.name()); + outState.putString(ENGINE_SERVER_URL_KEY, engine.serverBaseUrl); + outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); + outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); + outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); + outState.putBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY, engine.wasNameChangedByUser); + outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name()); + } + + private void restoreState(Bundle savedState) { + engine.name = savedState.getString(ENGINE_NAME_KEY); + engine.serverType = ServerType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); + engine.serverBaseUrl = savedState.getString(ENGINE_SERVER_URL_KEY); + engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); + engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); + engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); + engine.wasNameChangedByUser = savedState.getBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY); + selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); + } + + + private void initEngineState() { + engine.serverType = ServerType.values()[0]; + engine.vehicleType = VehicleType.values()[0]; + selectedLocation = ExampleLocation.values()[0]; + } + + private void dismiss() { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.onBackPressed(); + } + } + + @Nullable + private MapActivity getMapActivity() { + FragmentActivity activity = getActivity(); + if (activity instanceof MapActivity) { + return (MapActivity) activity; + } else { + return null; + } + } + + private static class OnlineRoutingEngineObject { + private String name; + private ServerType serverType; + private String serverBaseUrl; + private VehicleType vehicleType; + private String customVehicleKey; + private String apiKey; + private boolean wasNameChangedByUser; + + public String getVehicleKey() { + if (vehicleType == VehicleType.CUSTOM) { + return customVehicleKey; + } + return vehicleType.getKey(); + } + } +} From 677a2c888b848b6b4ffbec88c550ba27940d0ce6 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 28 Dec 2020 10:45:53 +0200 Subject: [PATCH 02/61] rename "save" button --- .../settings/fragments/OnlineRoutingEngineFragment.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java index 8e840f4a1b..44924f7352 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java @@ -234,11 +234,11 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); - View applyButton = view.findViewById(R.id.right_bottom_button); - UiUtilities.setupDialogButton(nightMode, applyButton, + View saveButton = view.findViewById(R.id.right_bottom_button); + UiUtilities.setupDialogButton(nightMode, saveButton, UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save); - applyButton.setVisibility(View.VISIBLE); - applyButton.setOnClickListener(new OnClickListener() { + saveButton.setVisibility(View.VISIBLE); + saveButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // save engine to settings From 079da7b219729721ceb421d5805b00f31d623982 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 28 Dec 2020 12:42:31 +0200 Subject: [PATCH 03/61] Online Routing UI - refactoring part 1 --- .../online_routing_preference_segment.xml | 1 + .../osmand/plus/helpers/AndroidUiHelper.java | 8 +++ .../profiles/SelectProfileBottomSheet.java | 4 +- .../OnlineRoutingSegmentCard.java | 17 ++----- .../BasePreferenceBottomSheet.java | 2 +- .../fragments/GlobalSettingsFragment.java | 5 +- .../fragments/MainSettingsFragment.java | 5 +- .../fragments/NavigationFragment.java | 2 +- .../OnlineRoutingEngineFragment.java | 49 +++++++++++++------ .../fragments/ProfileAppearanceFragment.java | 2 +- 10 files changed, 59 insertions(+), 36 deletions(-) diff --git a/OsmAnd/res/layout/online_routing_preference_segment.xml b/OsmAnd/res/layout/online_routing_preference_segment.xml index 0b1799e478..bb52d533af 100644 --- a/OsmAnd/res/layout/online_routing_preference_segment.xml +++ b/OsmAnd/res/layout/online_routing_preference_segment.xml @@ -110,6 +110,7 @@ android:layout_height="wrap_content" android:inputType="textMultiLine" android:maxLines="4" + android:saveEnabled="false" android:scrollHorizontally="false" tools:text="Text" /> diff --git a/OsmAnd/src/net/osmand/plus/helpers/AndroidUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/AndroidUiHelper.java index 45f5fe3ff4..9a038b787f 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/AndroidUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/AndroidUiHelper.java @@ -102,6 +102,14 @@ public class AndroidUiHelper { } } } + + public static void setVisibility(int visibility, View ... views) { + for (View view : views) { + if (view != null && view.getVisibility() != visibility) { + view.setVisibility(visibility); + } + } + } public static boolean isXLargeDevice(@NonNull Activity ctx) { int lt = (ctx.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK); diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index da92070b65..d86e1945f7 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -183,7 +183,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { @Override public void onClick(View v) { if (getActivity() != null) { - OnlineRoutingEngineFragment.showInstance(getActivity(), false); + OnlineRoutingEngineFragment.showInstance(getActivity(), getAppMode(), false); } dismiss(); } @@ -367,6 +367,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { public static void showInstance(@NonNull FragmentActivity activity, @NonNull DialogMode dialogMode, @Nullable Fragment target, + ApplicationMode appMode, String selectedItemKey, boolean usedOnMap) { SelectProfileBottomSheet fragment = new SelectProfileBottomSheet(); @@ -375,6 +376,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { args.putString(SELECTED_KEY, selectedItemKey); fragment.setArguments(args); fragment.setUsedOnMap(usedOnMap); + fragment.setAppMode(appMode); fragment.setTargetFragment(target, 0); fragment.show(activity.getSupportFragmentManager(), TAG); } diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java index 3ea6c4386f..75d90202b7 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java +++ b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java @@ -16,6 +16,7 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; @@ -41,9 +42,9 @@ public class OnlineRoutingSegmentCard extends BaseCard { private View resultContainer; private OnTextChangedListener onTextChangedListener; - public OnlineRoutingSegmentCard(@NonNull MapActivity mapActivity) { + public OnlineRoutingSegmentCard(@NonNull MapActivity mapActivity, boolean nightMode) { super(mapActivity); - build(mapActivity); + this.nightMode = nightMode; } @Override @@ -157,19 +158,11 @@ public class OnlineRoutingSegmentCard extends BaseCard { } private void showElements(View... views) { - changeVisibility(View.VISIBLE, views); + AndroidUiHelper.setVisibility(View.VISIBLE, views); } private void hideElements(View... views) { - changeVisibility(View.GONE, views); - } - - private void changeVisibility(int visibility, View... views) { - for (View v : views) { - if (visibility != v.getVisibility()) { - v.setVisibility(visibility); - } - } + AndroidUiHelper.setVisibility(View.GONE, views); } public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener) { diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BasePreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BasePreferenceBottomSheet.java index 6a71538ff1..67e2bfcfa0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BasePreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BasePreferenceBottomSheet.java @@ -38,12 +38,12 @@ public abstract class BasePreferenceBottomSheet extends MenuBottomSheetDialogFra @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); if (savedInstanceState != null) { appMode = ApplicationMode.valueOfStringKey(savedInstanceState.getString(APP_MODE_KEY), null); applyQueryType = ApplyQueryType.valueOf(savedInstanceState.getString(APPLY_QUERY_TYPE)); profileDependent = savedInstanceState.getBoolean(PROFILE_DEPENDENT, false); } + super.onCreate(savedInstanceState); } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java index e957eb7748..fa7383228c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java @@ -125,8 +125,9 @@ public class GlobalSettingsFragment extends BaseSettingsFragment if (prefId.equals(settings.DEFAULT_APPLICATION_MODE.getId())) { if (getActivity() != null) { String defaultModeKey = settings.DEFAULT_APPLICATION_MODE.get().getStringKey(); - SelectProfileBottomSheet.showInstance(getActivity(), - DialogMode.DEFAULT_PROFILE, this, defaultModeKey, false); + SelectProfileBottomSheet.showInstance( + getActivity(), DialogMode.DEFAULT_PROFILE, this, + getSelectedAppMode(), defaultModeKey, false); } } else if (settings.SPEED_CAMERAS_UNINSTALLED.getId().equals(prefId) && !settings.SPEED_CAMERAS_UNINSTALLED.get()) { FragmentManager fm = getFragmentManager(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java index f7ae122851..fdd5508352 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java @@ -119,8 +119,9 @@ public class MainSettingsFragment extends BaseSettingsFragment implements OnSele return true; } else if (CREATE_PROFILE.equals(prefId)) { if (getActivity() != null) { - SelectProfileBottomSheet.showInstance(getActivity(), - DialogMode.BASE_PROFILE, this, null, false); + SelectProfileBottomSheet.showInstance( + getActivity(), DialogMode.BASE_PROFILE, this, + getSelectedAppMode(), null, false); } } else if (IMPORT_PROFILE.equals(prefId)) { final MapActivity mapActivity = getMapActivity(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java index 0720dc7714..de8481f222 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java @@ -126,7 +126,7 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect if (getActivity() != null) { SelectProfileBottomSheet.showInstance( getActivity(), SelectProfileBottomSheet.DialogMode.NAVIGATION_PROFILE, - this, routingProfileKey, false); + this, getSelectedAppMode(), routingProfileKey, false); } } return false; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java index 44924f7352..07460805a2 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java @@ -31,6 +31,7 @@ import net.osmand.plus.profiles.onlinerouting.ServerType; import net.osmand.plus.profiles.onlinerouting.ExampleLocation; import net.osmand.plus.profiles.onlinerouting.VehicleType; import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; import java.util.ArrayList; @@ -48,6 +49,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static final String ENGINE_API_KEY_KEY = "engine_api_key"; private static final String ENGINE_NAME_CHANGED_BY_USER_KEY = "engine_name_changed_by_user_key"; private static final String EXAMPLE_LOCATION_KEY = "example_location"; + private static final String APP_MODE_KEY = "app_mode"; private OnlineRoutingSegmentCard nameCard; private OnlineRoutingSegmentCard serverCard; @@ -56,7 +58,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private OnlineRoutingSegmentCard exampleCard; private boolean isEditingMode; - private boolean nightMode; + private ApplicationMode appMode; private OnlineRoutingEngineObject engine; private ExampleLocation selectedLocation; @@ -82,7 +84,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (mapActivity == null) { return null; } - nightMode = !app.getSettings().isLightContent(); + boolean nightMode = isNightMode(app); View view = UiUtilities.getInflater(getContext(), nightMode) .inflate(R.layout.online_routing_engine_preference, container, false); @@ -95,7 +97,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { ViewGroup segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); // create name card - nameCard = new OnlineRoutingSegmentCard(mapActivity); + nameCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + nameCard.build(mapActivity); nameCard.setDescription(getString(R.string.select_nav_profile_dialog_message)); nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name)); nameCard.setOnTextChangedListener(new OnTextChangedListener() { @@ -111,7 +114,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(nameCard.getView()); // create server card - serverCard = new OnlineRoutingSegmentCard(mapActivity); + serverCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + serverCard.build(mapActivity); serverCard.setHeaderTitle(getString(R.string.shared_string_type)); List serverItems = new ArrayList<>(); for (ServerType server : ServerType.values()) { @@ -141,7 +145,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(serverCard.getView()); // create vehicle card - vehicleCard = new OnlineRoutingSegmentCard(mapActivity); + vehicleCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + vehicleCard.build(mapActivity); vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); List vehicleItems = new ArrayList<>(); for (VehicleType vehicle : VehicleType.values()) { @@ -173,7 +178,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(vehicleCard.getView()); // create api key card - apiKeyCard = new OnlineRoutingSegmentCard(mapActivity); + apiKeyCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + apiKeyCard.build(mapActivity); apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); apiKeyCard.setEditedText(engine.apiKey); @@ -188,7 +194,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(apiKeyCard.getView()); // create example card - exampleCard = new OnlineRoutingSegmentCard(mapActivity); + exampleCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + exampleCard.build(mapActivity); exampleCard.setHeaderTitle(getString(R.string.shared_string_example)); List locationItems = new ArrayList<>(); for (ExampleLocation location : ExampleLocation.values()) { @@ -330,14 +337,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } - public static void showInstance(FragmentActivity activity, boolean isEditingMode) { - OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); - fragment.isEditingMode = isEditingMode; - activity.getSupportFragmentManager().beginTransaction() - .add(R.id.fragmentContainer, fragment, TAG) - .addToBackStack(TAG).commitAllowingStateLoss(); - } - @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -353,6 +352,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); outState.putBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY, engine.wasNameChangedByUser); outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name()); + if (appMode != null) { + outState.putString(APP_MODE_KEY, appMode.getStringKey()); + } } private void restoreState(Bundle savedState) { @@ -364,9 +366,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); engine.wasNameChangedByUser = savedState.getBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); + appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); } - private void initEngineState() { engine.serverType = ServerType.values()[0]; engine.vehicleType = VehicleType.values()[0]; @@ -380,6 +382,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } + protected boolean isNightMode(@NonNull OsmandApplication app) { + return !app.getSettings().isLightContentForMode(appMode); + } + @Nullable private MapActivity getMapActivity() { FragmentActivity activity = getActivity(); @@ -390,6 +396,17 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } + public static void showInstance(@NonNull FragmentActivity activity, + @NonNull ApplicationMode appMode, + boolean isEditingMode) { + OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); + fragment.isEditingMode = isEditingMode; + fragment.appMode = appMode; + activity.getSupportFragmentManager().beginTransaction() + .add(R.id.fragmentContainer, fragment, TAG) + .addToBackStack(TAG).commitAllowingStateLoss(); + } + private static class OnlineRoutingEngineObject { private String name; private ServerType serverType; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index 6913770773..7a42818745 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -403,7 +403,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O if (getActivity() != null) { SelectProfileBottomSheet.showInstance( getActivity(), DialogMode.BASE_PROFILE, ProfileAppearanceFragment.this, - selectedAppModeKey, false); + getSelectedAppMode(), selectedAppModeKey, false); } } } From ce32f41f3eb19eb5af8ab5299f4f2ef5cbfcaa0d Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 28 Dec 2020 17:56:30 +0200 Subject: [PATCH 04/61] Online Routing UI - refactoring part 2 --- ...xml => online_routing_engine_fragment.xml} | 0 .../online_routing_preference_segment.xml | 2 +- OsmAnd/res/values/strings.xml | 4 + .../OnlineRoutingCard.java} | 14 +- .../OnlineRoutingEngineFragment.java | 147 ++++++++++++------ .../onlinerouting/ServerType.java | 4 +- .../plus/onlinerouting/VehicleType.java | 29 ++++ .../profiles/SelectProfileBottomSheet.java | 2 +- .../onlinerouting/ExampleLocation.java | 26 ---- .../profiles/onlinerouting/VehicleType.java | 25 --- 10 files changed, 146 insertions(+), 107 deletions(-) rename OsmAnd/res/layout/{online_routing_engine_preference.xml => online_routing_engine_fragment.xml} (100%) rename OsmAnd/src/net/osmand/plus/{profiles/onlinerouting/OnlineRoutingSegmentCard.java => onlinerouting/OnlineRoutingCard.java} (95%) rename OsmAnd/src/net/osmand/plus/{settings/fragments => onlinerouting}/OnlineRoutingEngineFragment.java (79%) rename OsmAnd/src/net/osmand/plus/{profiles => }/onlinerouting/ServerType.java (73%) create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java delete mode 100644 OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java delete mode 100644 OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java diff --git a/OsmAnd/res/layout/online_routing_engine_preference.xml b/OsmAnd/res/layout/online_routing_engine_fragment.xml similarity index 100% rename from OsmAnd/res/layout/online_routing_engine_preference.xml rename to OsmAnd/res/layout/online_routing_engine_fragment.xml diff --git a/OsmAnd/res/layout/online_routing_preference_segment.xml b/OsmAnd/res/layout/online_routing_preference_segment.xml index bb52d533af..5f095e126c 100644 --- a/OsmAnd/res/layout/online_routing_preference_segment.xml +++ b/OsmAnd/res/layout/online_routing_preference_segment.xml @@ -108,7 +108,7 @@ android:id="@+id/edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="textMultiLine" + android:inputType="textMultiLine|textNoSuggestions" android:maxLines="4" android:saveEnabled="false" android:scrollHorizontally="false" diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 6a66dd03ea..cd6690f74a 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,10 @@ Thx - Hardy --> + Car + Bike + Foot + Driving Test route calculation URL with all parameters will look like this: Keep it empty if not diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java similarity index 95% rename from OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index 75d90202b7..48069e3f41 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/OnlineRoutingSegmentCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -1,4 +1,4 @@ -package net.osmand.plus.profiles.onlinerouting; +package net.osmand.plus.onlinerouting; import android.text.Editable; import android.text.TextWatcher; @@ -25,7 +25,7 @@ import net.osmand.plus.widgets.OsmandTextFieldBoxes; import java.util.List; -public class OnlineRoutingSegmentCard extends BaseCard { +public class OnlineRoutingCard extends BaseCard { private View headerContainer; private TextView tvHeaderTitle; @@ -42,7 +42,7 @@ public class OnlineRoutingSegmentCard extends BaseCard { private View resultContainer; private OnTextChangedListener onTextChangedListener; - public OnlineRoutingSegmentCard(@NonNull MapActivity mapActivity, boolean nightMode) { + public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode) { super(mapActivity); this.nightMode = nightMode; } @@ -149,6 +149,14 @@ public class OnlineRoutingSegmentCard extends BaseCard { DialogButtonType.PRIMARY, R.string.test_route_calculation); } + public void show() { + showElements(view); + } + + public void hide() { + hideElements(view); + } + public void showFieldBox() { showElements(fieldBoxContainer); } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java similarity index 79% rename from OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 07460805a2..71bfe6b09f 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -1,4 +1,4 @@ -package net.osmand.plus.settings.fragments; +package net.osmand.plus.onlinerouting; import android.os.Build; import android.os.Bundle; @@ -14,6 +14,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; @@ -25,11 +26,7 @@ import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; -import net.osmand.plus.profiles.onlinerouting.OnlineRoutingSegmentCard; -import net.osmand.plus.profiles.onlinerouting.OnlineRoutingSegmentCard.OnTextChangedListener; -import net.osmand.plus.profiles.onlinerouting.ServerType; -import net.osmand.plus.profiles.onlinerouting.ExampleLocation; -import net.osmand.plus.profiles.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.OnlineRoutingCard.OnTextChangedListener; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; @@ -51,11 +48,13 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String APP_MODE_KEY = "app_mode"; - private OnlineRoutingSegmentCard nameCard; - private OnlineRoutingSegmentCard serverCard; - private OnlineRoutingSegmentCard vehicleCard; - private OnlineRoutingSegmentCard apiKeyCard; - private OnlineRoutingSegmentCard exampleCard; + private OsmandApplication app; + + private OnlineRoutingCard nameCard; + private OnlineRoutingCard serverCard; + private OnlineRoutingCard vehicleCard; + private OnlineRoutingCard apiKeyCard; + private OnlineRoutingCard exampleCard; private boolean isEditingMode; private ApplicationMode appMode; @@ -63,9 +62,51 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private OnlineRoutingEngineObject engine; private ExampleLocation selectedLocation; + private enum ExampleLocation { + + AMSTERDAM("Amsterdam", + new LatLon(52.379189, 4.899431), + new LatLon( 52.308056, 4.764167)), + + BERLIN("Berlin", + new LatLon(52.520008, 13.404954), + new LatLon(52.3666652, 13.501997992)), + + NEW_YORK("New York", + new LatLon(43.000000, -75.000000), + new LatLon( 40.641766, -73.780968)), + + PARIS("Paris", + new LatLon(48.864716, 2.349014), + new LatLon(48.948437, 2.434931)); + + ExampleLocation(String name, LatLon cityCenterLatLon, LatLon cityAirportLatLon) { + this.name = name; + this.cityCenterLatLon = cityCenterLatLon; + this.cityAirportLatLon = cityAirportLatLon; + } + + private String name; + private LatLon cityCenterLatLon; + private LatLon cityAirportLatLon; + + public String getName() { + return name; + } + + public LatLon getCityCenterLatLon() { + return cityCenterLatLon; + } + + public LatLon getCityAirportLatLon() { + return cityAirportLatLon; + } + } + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + app = requireMyApplication(); engine = new OnlineRoutingEngineObject(); if (savedInstanceState != null) { restoreState(savedInstanceState); @@ -79,15 +120,14 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - OsmandApplication app = requireMyApplication(); MapActivity mapActivity = getMapActivity(); if (mapActivity == null) { return null; } - boolean nightMode = isNightMode(app); + boolean nightMode = isNightMode(); View view = UiUtilities.getInflater(getContext(), nightMode) - .inflate(R.layout.online_routing_engine_preference, container, false); + .inflate(R.layout.online_routing_engine_fragment, container, false); if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(getContext(), view); @@ -97,9 +137,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { ViewGroup segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); // create name card - nameCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + nameCard = new OnlineRoutingCard(mapActivity, nightMode); nameCard.build(mapActivity); nameCard.setDescription(getString(R.string.select_nav_profile_dialog_message)); + nameCard.setEditedText(engine.name); nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name)); nameCard.setOnTextChangedListener(new OnTextChangedListener() { @Override @@ -114,7 +155,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(nameCard.getView()); // create server card - serverCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + serverCard = new OnlineRoutingCard(mapActivity, nightMode); serverCard.build(mapActivity); serverCard.setHeaderTitle(getString(R.string.shared_string_type)); List serverItems = new ArrayList<>(); @@ -134,25 +175,25 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return false; } }); -// serverCard.setOnTextChangedListener(new OnTextChangedListener() { -// @Override -// public void onTextChanged(boolean editedByUser, String text) { -// engine.serverBaseUrl = text; -// } -// }); + serverCard.setOnTextChangedListener(new OnTextChangedListener() { + @Override + public void onTextChanged(boolean editedByUser, String text) { + engine.serverBaseUrl = text; + } + }); serverCard.setFieldBoxLabelText(getString(R.string.shared_string_server_url)); serverCard.showDivider(); segmentsContainer.addView(serverCard.getView()); // create vehicle card - vehicleCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + vehicleCard = new OnlineRoutingCard(mapActivity, nightMode); vehicleCard.build(mapActivity); vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); List vehicleItems = new ArrayList<>(); for (VehicleType vehicle : VehicleType.values()) { - vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(), vehicle)); + vehicleItems.add(new HorizontalSelectionItem(vehicle.toHumanString(app), vehicle)); } - vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.getTitle(), + vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.toHumanString(app), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { @@ -178,7 +219,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(vehicleCard.getView()); // create api key card - apiKeyCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + apiKeyCard = new OnlineRoutingCard(mapActivity, nightMode); apiKeyCard.build(mapActivity); apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); @@ -194,14 +235,14 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(apiKeyCard.getView()); // create example card - exampleCard = new OnlineRoutingSegmentCard(mapActivity, nightMode); + exampleCard = new OnlineRoutingCard(mapActivity, nightMode); exampleCard.build(mapActivity); exampleCard.setHeaderTitle(getString(R.string.shared_string_example)); List locationItems = new ArrayList<>(); for (ExampleLocation location : ExampleLocation.values()) { - locationItems.add(new HorizontalSelectionItem(location.getTitle(), location)); + locationItems.add(new HorizontalSelectionItem(location.getName(), location)); } - exampleCard.setSelectionMenu(locationItems, selectedLocation.getTitle(), + exampleCard.setSelectionMenu(locationItems, selectedLocation.getName(), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { @@ -292,16 +333,21 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (!engine.wasNameChangedByUser) { String name = String.format( getString(R.string.ltr_or_rtl_combine_via_dash), - engine.serverType.getTitle(), engine.vehicleType.getTitle()); + engine.serverType.getTitle(), engine.vehicleType.toHumanString(app)); nameCard.setEditedText(name); } } else if (serverCard.equals(card)) { serverCard.setHeaderSubtitle(engine.serverType.getTitle()); serverCard.setEditedText(engine.serverType.getBaseUrl()); + if (engine.serverType == ServerType.GRAPHHOPER) { + apiKeyCard.show(); + } else { + apiKeyCard.hide(); + } } else if (vehicleCard.equals(card)) { - vehicleCard.setHeaderSubtitle(engine.vehicleType.getTitle()); + vehicleCard.setHeaderSubtitle(engine.vehicleType.toHumanString(app)); if (engine.vehicleType == VehicleType.CUSTOM) { vehicleCard.showFieldBox(); } else { @@ -318,22 +364,22 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { String baseUrl = engine.serverType.getBaseUrl(); String vehicle = engine.getVehicleKey(); - LatLon kievLatLon = new LatLon(50.431759, 30.517023); - LatLon destinationLatLon = selectedLocation.getLatLon(); + LatLon startPoint = selectedLocation.getCityCenterLatLon(); + LatLon endPoint = selectedLocation.getCityAirportLatLon(); if (engine.serverType == ServerType.GRAPHHOPER) { - return baseUrl + "point=" + kievLatLon.getLatitude() - + "," + kievLatLon.getLongitude() - + "&" + "point=" + destinationLatLon.getLatitude() - + "," + destinationLatLon.getLongitude() + return baseUrl + "?" + "point=" + startPoint.getLatitude() + + "," + startPoint.getLongitude() + + "&" + "point=" + endPoint.getLatitude() + + "," + endPoint.getLongitude() + "&" + "vehicle=" + vehicle + (!Algorithms.isEmpty(engine.apiKey) ? ("&" + "key=" + engine.apiKey) : ""); } else { - return baseUrl + vehicle + "/" + kievLatLon.getLatitude() - + "," + kievLatLon.getLongitude() - + ";" + destinationLatLon.getLatitude() - + "," + destinationLatLon.getLongitude() - + "?geometries=geojson&overview=full"; + return baseUrl + vehicle + "/" + startPoint.getLatitude() + + "," + startPoint.getLongitude() + + ";" + endPoint.getLatitude() + + "," + endPoint.getLongitude() + + "?" + "geometries=geojson"; } } @@ -382,7 +428,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } - protected boolean isNightMode(@NonNull OsmandApplication app) { + private boolean isNightMode() { return !app.getSettings().isLightContentForMode(appMode); } @@ -399,12 +445,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public static void showInstance(@NonNull FragmentActivity activity, @NonNull ApplicationMode appMode, boolean isEditingMode) { - OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); - fragment.isEditingMode = isEditingMode; - fragment.appMode = appMode; - activity.getSupportFragmentManager().beginTransaction() - .add(R.id.fragmentContainer, fragment, TAG) - .addToBackStack(TAG).commitAllowingStateLoss(); + FragmentManager fm = activity.getSupportFragmentManager(); + if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) { + OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); + fragment.isEditingMode = isEditingMode; + fragment.appMode = appMode; + fm.beginTransaction() + .add(R.id.fragmentContainer, fragment, TAG) + .addToBackStack(TAG).commitAllowingStateLoss(); + } } private static class OnlineRoutingEngineObject { diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java similarity index 73% rename from OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java index d624aa269e..7eb30798d5 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ServerType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java @@ -1,7 +1,7 @@ -package net.osmand.plus.profiles.onlinerouting; +package net.osmand.plus.onlinerouting; public enum ServerType { - GRAPHHOPER("Graphhoper", "https://graphhopper.com/api/1/route?"), + GRAPHHOPER("Graphhoper", "https://graphhopper.com/api/1/route"), OSRM("OSRM", "https://zlzk.biz/route/v1/"); ServerType(String title, String baseUrl) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java new file mode 100644 index 0000000000..7a4d44b714 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java @@ -0,0 +1,29 @@ +package net.osmand.plus.onlinerouting; + +import android.content.Context; + +import net.osmand.plus.R; + +public enum VehicleType { + CAR("car", R.string.routing_engine_vehicle_type_car), + BIKE("bike", R.string.routing_engine_vehicle_type_bike), + FOOT("foot", R.string.routing_engine_vehicle_type_foot), + DRIVING("driving", R.string.routing_engine_vehicle_type_driving), + CUSTOM("-", R.string.shared_string_custom); + + VehicleType(String key, int titleId) { + this.key = key; + this.titleId = titleId; + } + + private String key; + private int titleId; + + public String getKey() { + return key; + } + + public String toHumanString(Context ctx) { + return ctx.getString(titleId); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index d86e1945f7..af1289e85b 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -38,7 +38,7 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; -import net.osmand.plus.settings.fragments.OnlineRoutingEngineFragment; +import net.osmand.plus.onlinerouting.OnlineRoutingEngineFragment; import net.osmand.router.RoutingConfiguration; import org.apache.commons.logging.Log; diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java deleted file mode 100644 index ec1dd2149b..0000000000 --- a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/ExampleLocation.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.osmand.plus.profiles.onlinerouting; - -import net.osmand.data.LatLon; - -public enum ExampleLocation { - AMSTERDAM("Amsterdam", new LatLon(52.379189, 4.899431)), - BERLIN("Berlin", new LatLon(52.520008, 13.404954)), - NEW_YORK("New York", new LatLon(43.000000, -75.000000)), - PARIS("Paris", new LatLon(48.864716, 2.349014)); - - ExampleLocation(String title, LatLon latLon) { - this.title = title; - this.latLon = latLon; - } - - private String title; - private LatLon latLon; - - public String getTitle() { - return title; - } - - public LatLon getLatLon() { - return latLon; - } -} diff --git a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java deleted file mode 100644 index 78a0ac1e64..0000000000 --- a/OsmAnd/src/net/osmand/plus/profiles/onlinerouting/VehicleType.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.osmand.plus.profiles.onlinerouting; - -public enum VehicleType { - CAR("car", "Car"), - BIKE("bike", "Bike"), - FOOT("foot", "Foot"), - DRIVING("driving", "Driving"), - CUSTOM("custom", "Custom"); - - VehicleType(String key, String title) { - this.key = key; - this.title = title; - } - - private String key; - private String title; - - public String getKey() { - return key; - } - - public String getTitle() { - return title; - } -} \ No newline at end of file From 1649c066ff986011857e91c0c35910151ac1ec05 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 29 Dec 2020 00:58:26 +0200 Subject: [PATCH 05/61] Fix HorizontalSelectionAdapter selected item has wrong background width --- .../mapcontextmenu/other/HorizontalSelectionAdapter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java index 2299a62c7a..b26a377266 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java @@ -67,8 +67,9 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter Date: Wed, 30 Dec 2020 10:09:17 +0200 Subject: [PATCH 06/61] Online Routing UI - Implement Test button --- .../bottom_sheet_item_with_descr_64dp.xml | 56 +++++++++++++++++ OsmAnd/res/values/strings.xml | 1 + .../plus/onlinerouting/OnlineRoutingCard.java | 11 ++-- .../OnlineRoutingEngineFragment.java | 63 +++++++++++++++++-- 4 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml new file mode 100644 index 0000000000..2ff6a1bf58 --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index cd6690f74a..f10d9be2f0 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Error, recheck parameters Car Bike Foot diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index 48069e3f41..bd4ca4c735 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -39,7 +39,6 @@ public class OnlineRoutingCard extends BaseCard { private TextView tvHelperText; private View bottomDivider; private View button; - private View resultContainer; private OnTextChangedListener onTextChangedListener; public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode) { @@ -65,7 +64,6 @@ public class OnlineRoutingCard extends BaseCard { tvHelperText = view.findViewById(R.id.helper_text); bottomDivider = view.findViewById(R.id.bottom_divider); button = view.findViewById(R.id.button); - resultContainer = view.findViewById(R.id.result_container); editText.addTextChangedListener(new TextWatcher() { @Override @@ -138,15 +136,18 @@ public class OnlineRoutingCard extends BaseCard { editText.setTag(null); } + public String getEditedText() { + return editText.getText().toString(); + } + public void showDivider() { showElements(bottomDivider); } - public void setButton(OnClickListener listener) { + public void setButton(String title, OnClickListener listener) { showElements(button); button.setOnClickListener(listener); - UiUtilities.setupDialogButton(nightMode, button, - DialogButtonType.PRIMARY, R.string.test_route_calculation); + UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title); } public void show() { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 71bfe6b09f..3d5b90444c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -16,6 +16,8 @@ import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import net.osmand.AndroidNetworkUtils; +import net.osmand.AndroidNetworkUtils.OnRequestResultListener; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; import net.osmand.data.LatLon; @@ -31,6 +33,9 @@ import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.List; @@ -55,6 +60,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private OnlineRoutingCard vehicleCard; private OnlineRoutingCard apiKeyCard; private OnlineRoutingCard exampleCard; + private View testResultsContainer; private boolean isEditingMode; private ApplicationMode appMode; @@ -125,10 +131,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return null; } boolean nightMode = isNightMode(); - - View view = UiUtilities.getInflater(getContext(), nightMode) - .inflate(R.layout.online_routing_engine_fragment, container, false); - + inflater = UiUtilities.getInflater(getContext(), nightMode); + View view = inflater.inflate( + R.layout.online_routing_engine_fragment, container, false); if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(getContext(), view); } @@ -256,14 +261,19 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } }); exampleCard.setFieldBoxHelperText(getString(R.string.online_routing_example_hint)); - exampleCard.setButton(new View.OnClickListener() { + exampleCard.setButton(getString(R.string.test_route_calculation), new View.OnClickListener() { @Override public void onClick(View v) { - // make request to the server + testEngineWork(); } }); segmentsContainer.addView(exampleCard.getView()); + testResultsContainer = inflater.inflate( + R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false); + testResultsContainer.setVisibility(View.GONE); + segmentsContainer.addView(testResultsContainer); + View bottomSpaceView = new View(app); int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top); bottomSpaceView.setLayoutParams( @@ -383,6 +393,47 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } + private void testEngineWork() { + final ServerType server = engine.serverType; + final ExampleLocation location = selectedLocation; + AndroidNetworkUtils.sendRequestAsync(app, exampleCard.getEditedText(), null, + null, false, false, new OnRequestResultListener() { + @Override + public void onResult(String response) { + boolean resultOk = false; + if (response != null) { + try { + JSONObject obj = new JSONObject(response); + + if (server == ServerType.GRAPHHOPER) { + resultOk = obj.has("paths"); + } else if (server == ServerType.OSRM) { + resultOk = obj.has("routes"); + } + } catch (JSONException e) { + + } + } + showTestResults(resultOk, location); + } + }); + } + + private void showTestResults(boolean resultOk, ExampleLocation location) { + testResultsContainer.setVisibility(View.VISIBLE); + ImageView ivImage = testResultsContainer.findViewById(R.id.icon); + TextView tvTitle = testResultsContainer.findViewById(R.id.title); + TextView tvDescription = testResultsContainer.findViewById(R.id.description); + if (resultOk) { + ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_gdirections_dark)); + tvTitle.setText(getString(R.string.shared_string_ok)); + } else { + ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert)); + tvTitle.setText(getString(R.string.message_error_recheck_parameters)); + } + tvDescription.setText(location.getName()); + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); From 802221dbc11881aceb09f18b4c828036182b7637 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Wed, 30 Dec 2020 22:56:50 +0200 Subject: [PATCH 07/61] Online Routing UI - Add / Delete / Save in settings --- ..._item_with_descr_and_radio_and_eng_btn.xml | 111 +++++++++++++ ...om_sheet_item_with_descr_and_radio_btn.xml | 6 +- .../src/net/osmand/plus/AppInitializer.java | 2 + .../net/osmand/plus/OsmandApplication.java | 6 + .../onlinerouting/OnlineRoutingEngine.java | 85 ++++++++++ .../OnlineRoutingEngineFragment.java | 90 ++++++++-- .../onlinerouting/OnlineRoutingHelper.java | 157 ++++++++++++++++++ .../plus/onlinerouting/VehicleType.java | 10 ++ .../OnlineRoutingEngineDataObject.java | 13 ++ .../plus/profiles/ProfileDataUtils.java | 41 +++-- .../profiles/SelectProfileBottomSheet.java | 39 +++-- .../plus/settings/backend/OsmandSettings.java | 3 + 12 files changed, 516 insertions(+), 47 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java create mode 100644 OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml new file mode 100644 index 0000000000..d81614fbb1 --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml index 4bace93e9f..a346825302 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml @@ -9,7 +9,7 @@ diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index eda57e3c28..424855f2a0 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -44,6 +44,7 @@ import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; +import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper; import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.quickaction.QuickActionRegistry; @@ -467,6 +468,7 @@ public class AppInitializer implements IProgress { app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class); app.quickActionRegistry = startupInit(new QuickActionRegistry(app.getSettings()), QuickActionRegistry.class); app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class); + app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class); initOpeningHoursParser(); } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index db7c0d6433..8deb9c81a8 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -66,6 +66,7 @@ import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.monitoring.LiveMonitoringHelper; +import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper; import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.quickaction.QuickActionRegistry; @@ -158,6 +159,7 @@ public class OsmandApplication extends MultiDexApplication { QuickActionRegistry quickActionRegistry; OsmOAuthHelper osmOAuthHelper; MeasurementEditingContext measurementEditingContext; + OnlineRoutingHelper onlineRoutingHelper; private Resources localizedResources; private Map customRoutingConfigs = new ConcurrentHashMap<>(); @@ -475,6 +477,10 @@ public class OsmandApplication extends MultiDexApplication { this.measurementEditingContext = context; } + public OnlineRoutingHelper getOnlineRoutingHelper() { + return onlineRoutingHelper; + } + public TransportRoutingHelper getTransportRoutingHelper() { return transportRoutingHelper; } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java new file mode 100644 index 0000000000..164b56439c --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java @@ -0,0 +1,85 @@ +package net.osmand.plus.onlinerouting; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.util.Algorithms; + +import java.util.HashMap; +import java.util.Map; + +public class OnlineRoutingEngine { + + public enum EngineParameterType { + CUSTOM_SERVER_URL, + API_KEY + } + + private String stringKey; + private String name; + private ServerType serverType; + private String vehicleKey; + private Map params; + + public OnlineRoutingEngine(@Nullable String stringKey, + @NonNull String name, + @NonNull ServerType serverType, + @NonNull String vehicleKey, + Map params) { + if (stringKey == null) { + stringKey = generateKey(vehicleKey); + } + this.stringKey = stringKey; + this.name = name; + this.serverType = serverType; + this.vehicleKey = vehicleKey; + this.params = params; + } + + public String getStringKey() { + return stringKey; + } + + public String getName() { + return name; + } + + public ServerType getServerType() { + return serverType; + } + + public String getVehicleKey() { + return vehicleKey; + } + + public Map getParams() { + return params; + } + + public String getBaseUrl() { + String customServerUrl = getParameter(EngineParameterType.CUSTOM_SERVER_URL); + if (!Algorithms.isEmpty(customServerUrl)) { + return customServerUrl; + } else { + return serverType.getBaseUrl(); + } + } + + public String getParameter(EngineParameterType paramType) { + if (params != null) { + return params.get(paramType.name()); + } + return null; + } + + public void putParameter(EngineParameterType paramType, String paramValue) { + if (params == null) { + params = new HashMap<>(); + } + params.put(paramType.name(), paramValue); + } + + private static String generateKey(String vehicleKey) { + return "online_" + vehicleKey + "_" + System.currentTimeMillis(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 3d5b90444c..e777fa6609 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -29,6 +29,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.onlinerouting.OnlineRoutingCard.OnTextChangedListener; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameterType; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; @@ -52,8 +53,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static final String ENGINE_NAME_CHANGED_BY_USER_KEY = "engine_name_changed_by_user_key"; private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String APP_MODE_KEY = "app_mode"; + private static final String EDITED_ENGINE_KEY = "edited_engine_key"; private OsmandApplication app; + private OnlineRoutingHelper helper; private OnlineRoutingCard nameCard; private OnlineRoutingCard serverCard; @@ -62,17 +65,17 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private OnlineRoutingCard exampleCard; private View testResultsContainer; - private boolean isEditingMode; private ApplicationMode appMode; private OnlineRoutingEngineObject engine; private ExampleLocation selectedLocation; + private String editedEngineKey; private enum ExampleLocation { AMSTERDAM("Amsterdam", new LatLon(52.379189, 4.899431), - new LatLon( 52.308056, 4.764167)), + new LatLon(52.308056, 4.764167)), BERLIN("Berlin", new LatLon(52.520008, 13.404954), @@ -80,11 +83,11 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { NEW_YORK("New York", new LatLon(43.000000, -75.000000), - new LatLon( 40.641766, -73.780968)), + new LatLon(40.641766, -73.780968)), PARIS("Paris", new LatLon(48.864716, 2.349014), - new LatLon(48.948437, 2.434931)); + new LatLon(48.948437, 2.434931)); ExampleLocation(String name, LatLon cityCenterLatLon, LatLon cityAirportLatLon) { this.name = name; @@ -113,11 +116,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); app = requireMyApplication(); + helper = app.getOnlineRoutingHelper(); engine = new OnlineRoutingEngineObject(); if (savedInstanceState != null) { restoreState(savedInstanceState); } else { - initEngineState(); + initState(); } } @@ -150,7 +154,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { nameCard.setOnTextChangedListener(new OnTextChangedListener() { @Override public void onTextChanged(boolean changedByUser, String text) { - if (!isEditingMode && !engine.wasNameChangedByUser && changedByUser) { + if (!isEditingMode() && !engine.wasNameChangedByUser && changedByUser) { engine.wasNameChangedByUser = true; } engine.name = text; @@ -183,7 +187,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { serverCard.setOnTextChangedListener(new OnTextChangedListener() { @Override public void onTextChanged(boolean editedByUser, String text) { - engine.serverBaseUrl = text; + if (editedByUser) { + engine.customServerUrl = text; + } } }); serverCard.setFieldBoxLabelText(getString(R.string.shared_string_server_url)); @@ -299,7 +305,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { saveButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - // save engine to settings + saveChanges(); + dismiss(); } }); @@ -320,7 +327,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { TextView title = toolbar.findViewById(R.id.toolbar_title); toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE); View actionBtn = toolbar.findViewById(R.id.action_button); - if (isEditingMode) { + if (isEditingMode()) { title.setText(getString(R.string.edit_online_routing_engine)); ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon); ivBtn.setImageDrawable( @@ -328,7 +335,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { actionBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - // delete engine from settings + deleteEngine(); + dismiss(); } }); } else { @@ -337,7 +345,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } - private void updateCardViews(BaseCard ... cardsToUpdate) { + private void updateCardViews(BaseCard... cardsToUpdate) { for (BaseCard card : cardsToUpdate) { if (nameCard.equals(card)) { if (!engine.wasNameChangedByUser) { @@ -349,7 +357,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } else if (serverCard.equals(card)) { serverCard.setHeaderSubtitle(engine.serverType.getTitle()); - serverCard.setEditedText(engine.serverType.getBaseUrl()); + serverCard.setEditedText(engine.getBaseUrl()); if (engine.serverType == ServerType.GRAPHHOPER) { apiKeyCard.show(); } else { @@ -360,6 +368,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { vehicleCard.setHeaderSubtitle(engine.vehicleType.toHumanString(app)); if (engine.vehicleType == VehicleType.CUSTOM) { vehicleCard.showFieldBox(); + vehicleCard.setEditedText(engine.getVehicleKey()); } else { vehicleCard.hideFieldBox(); } @@ -370,6 +379,22 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } + private void saveChanges() { + OnlineRoutingEngine engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.name, + engine.serverType, engine.getVehicleKey(), null); + + engineToSave.putParameter(EngineParameterType.CUSTOM_SERVER_URL, engine.customServerUrl); + if (engine.serverType == ServerType.GRAPHHOPER) { + engineToSave.putParameter(EngineParameterType.API_KEY, engine.apiKey); + } + + helper.saveEngine(engineToSave); + } + + private void deleteEngine() { + helper.deleteEngine(editedEngineKey); + } + private String getTestUrl() { String baseUrl = engine.serverType.getBaseUrl(); String vehicle = engine.getVehicleKey(); @@ -434,6 +459,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { tvDescription.setText(location.getName()); } + private boolean isEditingMode() { + return editedEngineKey != null; + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -443,7 +472,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void saveState(Bundle outState) { outState.putString(ENGINE_NAME_KEY, engine.name); outState.putString(ENGINE_SERVER_KEY, engine.serverType.name()); - outState.putString(ENGINE_SERVER_URL_KEY, engine.serverBaseUrl); + outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl); outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); @@ -452,24 +481,45 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (appMode != null) { outState.putString(APP_MODE_KEY, appMode.getStringKey()); } + outState.putString(EDITED_ENGINE_KEY, editedEngineKey); } private void restoreState(Bundle savedState) { engine.name = savedState.getString(ENGINE_NAME_KEY); engine.serverType = ServerType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); - engine.serverBaseUrl = savedState.getString(ENGINE_SERVER_URL_KEY); + engine.customServerUrl = savedState.getString(ENGINE_SERVER_URL_KEY); engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); engine.wasNameChangedByUser = savedState.getBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); + editedEngineKey = savedState.getString(EDITED_ENGINE_KEY); } - private void initEngineState() { + private void initState() { engine.serverType = ServerType.values()[0]; engine.vehicleType = VehicleType.values()[0]; selectedLocation = ExampleLocation.values()[0]; + + if (isEditingMode()) { + OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey); + if (editedEngine != null) { + engine.name = editedEngine.getName(); + engine.wasNameChangedByUser = true; + engine.serverType = editedEngine.getServerType(); + engine.customServerUrl = editedEngine.getParameter(EngineParameterType.CUSTOM_SERVER_URL); + String vehicleKey = editedEngine.getVehicleKey(); + if (vehicleKey != null) { + VehicleType vehicleType = VehicleType.getVehicleByKey(vehicleKey); + if (vehicleType == VehicleType.CUSTOM) { + engine.customVehicleKey = vehicleKey; + } + engine.vehicleType = vehicleType; + } + engine.apiKey = editedEngine.getParameter(EngineParameterType.API_KEY); + } + } } private void dismiss() { @@ -495,12 +545,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public static void showInstance(@NonNull FragmentActivity activity, @NonNull ApplicationMode appMode, - boolean isEditingMode) { + String editedEngineKey) { FragmentManager fm = activity.getSupportFragmentManager(); if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) { OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); - fragment.isEditingMode = isEditingMode; fragment.appMode = appMode; + fragment.editedEngineKey = editedEngineKey; fm.beginTransaction() .add(R.id.fragmentContainer, fragment, TAG) .addToBackStack(TAG).commitAllowingStateLoss(); @@ -510,7 +560,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static class OnlineRoutingEngineObject { private String name; private ServerType serverType; - private String serverBaseUrl; + private String customServerUrl; private VehicleType vehicleType; private String customVehicleKey; private String apiKey; @@ -522,5 +572,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } return vehicleType.getKey(); } + + public String getBaseUrl() { + return customServerUrl != null ? customServerUrl : serverType.getBaseUrl(); + } } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java new file mode 100644 index 0000000000..cc652f35b2 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -0,0 +1,157 @@ +package net.osmand.plus.onlinerouting; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandSettings; +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.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OnlineRoutingHelper { + + private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class); + + private OsmandApplication app; + private OsmandSettings settings; + private List cachedEngines; + private Map cachedEnginesMap; + + public OnlineRoutingHelper(OsmandApplication app) { + this.app = app; + this.settings = app.getSettings(); + loadFromSettings(); + } + + @NonNull + public List getEngines() { + return cachedEngines; + } + + public OnlineRoutingEngine getEngineByKey(String stringKey) { + return cachedEnginesMap.get(stringKey); + } + + public void saveEngine(@NonNull OnlineRoutingEngine engine) { + String stringKey = engine.getStringKey(); + OnlineRoutingEngine existedEngine = cachedEnginesMap.get(stringKey); + if (existedEngine != null) { + int index = cachedEngines.indexOf(existedEngine); + cachedEngines.set(index, engine); + } else { + cachedEngines.add(engine); + } + cachedEnginesMap.put(stringKey, engine); + saveToSettings(); + } + + public void deleteEngine(@NonNull String stringKey) { + OnlineRoutingEngine engine = getEngineByKey(stringKey); + if (engine != null) { + deleteEngine(engine); + } + } + + public void deleteEngine(@NonNull OnlineRoutingEngine engine) { + String stringKey = engine.getStringKey(); + if (cachedEnginesMap.containsKey(stringKey)) { + OnlineRoutingEngine existedEngine = cachedEnginesMap.remove(stringKey); + cachedEngines.remove(existedEngine); + saveToSettings(); + } + } + + private void loadFromSettings() { + cachedEngines = readFromSettings(); + cachedEnginesMap = new HashMap<>(); + for (OnlineRoutingEngine engine : cachedEngines) { + cachedEnginesMap.put(engine.getStringKey(), engine); + } + } + + @NonNull + private List readFromSettings() { + List engines = new ArrayList<>(); + String jsonString = settings.ONLINE_ROUTING_ENGINES.get(); + if (!Algorithms.isEmpty(jsonString)) { + try { + JSONObject json = new JSONObject(jsonString); + readFromJson(json, engines); + } catch (JSONException e) { + LOG.debug("Error when read setting from JSON"); + } + } + return engines; + } + + private void saveToSettings() { + if (!Algorithms.isEmpty(cachedEngines)) { + JSONObject json = new JSONObject(); + if (writeToJson(json, cachedEngines)) { + settings.ONLINE_ROUTING_ENGINES.set(json.toString()); + } + } else { + settings.ONLINE_ROUTING_ENGINES.set(null); + } + } + + private void readFromJson(JSONObject json, List engines) { + try { + if (!json.has("items")) { + return; + } + Gson gson = new Gson(); + Type type = new TypeToken>() { + }.getType(); + JSONArray itemsJson = json.getJSONArray("items"); + for (int i = 0; i < itemsJson.length(); i++) { + JSONObject object = itemsJson.getJSONObject(i); + String key = object.getString("key"); + String name = object.getString("name"); + String vehicleKey = object.getString("vehicle"); + ServerType serverType = ServerType.valueOf(object.getString("serverType")); + String paramsString = object.getString("params"); + HashMap params = gson.fromJson(paramsString, type); + engines.add(new OnlineRoutingEngine(key, name, serverType, vehicleKey, params)); + } + } catch (JSONException e) { + LOG.debug("Error when read setting from JSON internal"); + } + } + + private boolean writeToJson(JSONObject json, List engines) { + JSONArray jsonArray = new JSONArray(); + Gson gson = new Gson(); + Type type = new TypeToken>() { + }.getType(); + try { + for (OnlineRoutingEngine engine : engines) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("key", engine.getStringKey()); + jsonObject.put("name", engine.getName()); + jsonObject.put("serverType", engine.getServerType().name()); + jsonObject.put("vehicle", engine.getVehicleKey()); + jsonObject.put("params", gson.toJson(engine.getParams(), type)); + jsonArray.put(jsonObject); + } + json.put("items", jsonArray); + return true; + } catch (JSONException e) { + LOG.debug("Error when write engines to JSON"); + return false; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java index 7a4d44b714..a3ca17681c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java @@ -3,6 +3,7 @@ package net.osmand.plus.onlinerouting; import android.content.Context; import net.osmand.plus.R; +import net.osmand.util.Algorithms; public enum VehicleType { CAR("car", R.string.routing_engine_vehicle_type_car), @@ -26,4 +27,13 @@ public enum VehicleType { public String toHumanString(Context ctx) { return ctx.getString(titleId); } + + public static VehicleType getVehicleByKey(String key) { + for (VehicleType v : values()) { + if (Algorithms.objectEquals(v.getKey(), key)) { + return v; + } + } + return CUSTOM; + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java new file mode 100644 index 0000000000..cd812b3363 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java @@ -0,0 +1,13 @@ +package net.osmand.plus.profiles; + +public class OnlineRoutingEngineDataObject extends ProfileDataObject { + + public OnlineRoutingEngineDataObject(String name, + String description, + String stringKey, + int iconRes, + boolean isSelected, + ProfileIconColors iconColor) { + super(name, description, stringKey, iconRes, isSelected, iconColor); + } +} diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java index 4cbc9b1940..fd146778a7 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java @@ -5,6 +5,8 @@ import android.content.Context; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine; +import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.router.GeneralRouter; import net.osmand.router.RoutingConfiguration; @@ -66,6 +68,15 @@ public class ProfileDataUtils { return result; } + public static List getOnlineRoutingProfiles(OsmandApplication app) { + List objects = new ArrayList<>(); + for (OnlineRoutingEngine engine : app.getOnlineRoutingHelper().getEngines()) { + objects.add(new OnlineRoutingEngineDataObject(engine.getName(), + engine.getBaseUrl(), engine.getStringKey(), R.drawable.ic_world_globe_dark, false, null)); + } + return objects; + } + public static Map> getRoutingProfilesByFileNames(OsmandApplication app) { Map> result = new HashMap<>(); for (final RoutingProfileDataObject profile : getRoutingProfiles(app).values()) { @@ -83,24 +94,24 @@ public class ProfileDataUtils { public static Map getRoutingProfiles(OsmandApplication context) { Map profilesObjects = new HashMap<>(); - profilesObjects.put(RoutingProfileDataObject.RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), new RoutingProfileDataObject( - RoutingProfileDataObject.RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), - context.getString(RoutingProfileDataObject.RoutingProfilesResources.STRAIGHT_LINE_MODE.getStringRes()), + profilesObjects.put(RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), new RoutingProfileDataObject( + RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), + context.getString(RoutingProfilesResources.STRAIGHT_LINE_MODE.getStringRes()), context.getString(R.string.special_routing_type), - RoutingProfileDataObject.RoutingProfilesResources.STRAIGHT_LINE_MODE.getIconRes(), + RoutingProfilesResources.STRAIGHT_LINE_MODE.getIconRes(), false, null)); - profilesObjects.put(RoutingProfileDataObject.RoutingProfilesResources.DIRECT_TO_MODE.name(), new RoutingProfileDataObject( - RoutingProfileDataObject.RoutingProfilesResources.DIRECT_TO_MODE.name(), - context.getString(RoutingProfileDataObject.RoutingProfilesResources.DIRECT_TO_MODE.getStringRes()), + profilesObjects.put(RoutingProfilesResources.DIRECT_TO_MODE.name(), new RoutingProfileDataObject( + RoutingProfilesResources.DIRECT_TO_MODE.name(), + context.getString(RoutingProfilesResources.DIRECT_TO_MODE.getStringRes()), context.getString(R.string.special_routing_type), - RoutingProfileDataObject.RoutingProfilesResources.DIRECT_TO_MODE.getIconRes(), + RoutingProfilesResources.DIRECT_TO_MODE.getIconRes(), false, null)); if (context.getBRouterService() != null) { - profilesObjects.put(RoutingProfileDataObject.RoutingProfilesResources.BROUTER_MODE.name(), new RoutingProfileDataObject( - RoutingProfileDataObject.RoutingProfilesResources.BROUTER_MODE.name(), - context.getString(RoutingProfileDataObject.RoutingProfilesResources.BROUTER_MODE.getStringRes()), + profilesObjects.put(RoutingProfilesResources.BROUTER_MODE.name(), new RoutingProfileDataObject( + RoutingProfilesResources.BROUTER_MODE.name(), + context.getString(RoutingProfilesResources.BROUTER_MODE.getStringRes()), context.getString(R.string.third_party_routing_type), - RoutingProfileDataObject.RoutingProfilesResources.BROUTER_MODE.getIconRes(), + RoutingProfilesResources.BROUTER_MODE.getIconRes(), false, null)); } @@ -123,9 +134,9 @@ public class ProfileDataUtils { String fileName = router.getFilename(); if (!Algorithms.isEmpty(fileName)) { description = fileName; - } else if (RoutingProfileDataObject.RoutingProfilesResources.isRpValue(name.toUpperCase())) { - iconRes = RoutingProfileDataObject.RoutingProfilesResources.valueOf(name.toUpperCase()).getIconRes(); - name = app.getString(RoutingProfileDataObject.RoutingProfilesResources.valueOf(name.toUpperCase()).getStringRes()); + } else if (RoutingProfilesResources.isRpValue(name.toUpperCase())) { + iconRes = RoutingProfilesResources.valueOf(name.toUpperCase()).getIconRes(); + name = app.getString(RoutingProfilesResources.valueOf(name.toUpperCase()).getStringRes()); } profilesObjects.put(routerKey, new RoutingProfileDataObject(routerKey, name, description, iconRes, false, fileName)); diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index af1289e85b..ebc554040a 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -149,17 +149,23 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { items.add(new TitleItem(getString(R.string.select_nav_profile_dialog_title))); items.add(new LongDescriptionItem(getString(R.string.select_nav_profile_dialog_message))); for (int i = 0; i < profiles.size(); i++) { - final RoutingProfileDataObject profile = (RoutingProfileDataObject) profiles.get(i); boolean showBottomDivider = false; - if (i < profiles.size() - 1) { - RoutingProfileDataObject nextProfile = (RoutingProfileDataObject) profiles.get(i + 1); - if (profile.getFileName() == null) { - showBottomDivider = nextProfile.getFileName() != null; - } else { - showBottomDivider = !profile.getFileName().equals(nextProfile.getFileName()); + if (profiles.get(i) instanceof RoutingProfileDataObject) { + final RoutingProfileDataObject profile = (RoutingProfileDataObject) profiles.get(i); + if (i < profiles.size() - 1) { + if (profiles.get(i + 1) instanceof RoutingProfileDataObject) { + RoutingProfileDataObject nextProfile = (RoutingProfileDataObject) profiles.get(i + 1); + if (profile.getFileName() == null) { + showBottomDivider = nextProfile.getFileName() != null; + } else { + showBottomDivider = !profile.getFileName().equals(nextProfile.getFileName()); + } + } else { + showBottomDivider = true; + } } } - addProfileItem(profile, showBottomDivider); + addProfileItem(profiles.get(i), showBottomDivider); } items.add(new DividerItem(app)); items.add(new LongDescriptionItem(app.getString(R.string.osmand_routing_promo))); @@ -183,7 +189,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { @Override public void onClick(View v) { if (getActivity() != null) { - OnlineRoutingEngineFragment.showInstance(getActivity(), getAppMode(), false); + OnlineRoutingEngineFragment.showInstance(getActivity(), getAppMode(), null); } dismiss(); } @@ -229,7 +235,10 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; int iconDefaultColorResId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; - View itemView = UiUtilities.getInflater(getContext(), nightMode).inflate(R.layout.bottom_sheet_item_with_descr_and_radio_btn, null); + View itemView = UiUtilities.getInflater(getContext(), nightMode).inflate( + profile instanceof OnlineRoutingEngineDataObject ? + R.layout.bottom_sheet_item_with_descr_and_radio_and_eng_btn : + R.layout.bottom_sheet_item_with_descr_and_radio_btn, null); TextView tvTitle = itemView.findViewById(R.id.title); TextView tvDescription = itemView.findViewById(R.id.description); ImageView ivIcon = itemView.findViewById(R.id.icon); @@ -262,7 +271,14 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { args.putString(PROFILE_KEY_ARG, profile.getStringKey()); Fragment target = getTargetFragment(); if (target instanceof OnSelectProfileCallback) { - ((OnSelectProfileCallback) target).onProfileSelected(args); + if (profile instanceof OnlineRoutingEngineDataObject) { + if (getActivity() != null) { + OnlineRoutingEngineFragment.showInstance(getActivity(), getAppMode(), profile.getStringKey()); + } + dismiss(); + } else { + ((OnSelectProfileCallback) target).onProfileSelected(args); + } } dismiss(); } @@ -347,6 +363,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { case NAVIGATION_PROFILE: profiles.addAll(ProfileDataUtils.getSortedRoutingProfiles(app)); + profiles.addAll(ProfileDataUtils.getOnlineRoutingProfiles(app)); break; case DEFAULT_PROFILE: diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index b3cd8fb9a6..0019b7bffb 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -48,6 +48,7 @@ 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.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.profiles.LocationIcon; import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.ProfileIconColors; @@ -1015,6 +1016,8 @@ public class OsmandSettings { ROUTE_SERVICE.setModeDefaultValue(ApplicationMode.AIRCRAFT, RouteService.STRAIGHT); } + public final CommonPreference ONLINE_ROUTING_ENGINES = new StringPreference(this, "online_routing_engines", null); + public final CommonPreference NAVIGATION_ICON = new EnumStringPreference<>(this, "navigation_icon", NavigationIcon.DEFAULT, NavigationIcon.values()).makeProfile().cache(); { From 38a3e8c6fea11a4a01d4751f7804f2ea20553b95 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 3 Jan 2021 20:28:47 +0200 Subject: [PATCH 08/61] Online Routing UI - refactoring part 3 --- ...et_item_with_descr_radio_and_icon_btn.xml} | 0 .../plus/onlinerouting/OnlineRoutingCard.java | 12 ++ .../onlinerouting/OnlineRoutingEngine.java | 69 ++++--- .../OnlineRoutingEngineFragment.java | 176 ++++++++++-------- .../onlinerouting/OnlineRoutingHelper.java | 14 +- .../plus/onlinerouting/VehicleType.java | 15 +- .../OnlineRoutingEngineDataObject.java | 9 +- .../plus/profiles/ProfileDataUtils.java | 4 +- .../profiles/SelectProfileBottomSheet.java | 2 +- 9 files changed, 186 insertions(+), 115 deletions(-) rename OsmAnd/res/layout/{bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml => bottom_sheet_item_with_descr_radio_and_icon_btn.xml} (100%) diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml similarity index 100% rename from OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_and_eng_btn.xml rename to OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index bd4ca4c735..1b9e7f3b29 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -4,6 +4,7 @@ import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.view.View.OnClickListener; +import android.view.View.OnFocusChangeListener; import android.widget.EditText; import android.widget.TextView; @@ -11,6 +12,7 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -83,6 +85,16 @@ public class OnlineRoutingCard extends BaseCard { } } }); + + editText.setOnFocusChangeListener(new OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + editText.setSelection(editText.getText().length()); + AndroidUtils.showSoftKeyboard(getMapActivity(), editText); + } + } + }); } public void setHeaderTitle(@NonNull String title) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java index 164b56439c..10ba169cb1 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java @@ -1,8 +1,10 @@ package net.osmand.plus.onlinerouting; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import android.content.Context; +import androidx.annotation.NonNull; + +import net.osmand.plus.R; import net.osmand.util.Algorithms; import java.util.HashMap; @@ -10,40 +12,39 @@ import java.util.Map; public class OnlineRoutingEngine { + public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; + public enum EngineParameterType { CUSTOM_SERVER_URL, + CUSTOM_NAME, API_KEY } private String stringKey; - private String name; private ServerType serverType; private String vehicleKey; - private Map params; + private Map params = new HashMap<>(); - public OnlineRoutingEngine(@Nullable String stringKey, - @NonNull String name, + public OnlineRoutingEngine(@NonNull String stringKey, @NonNull ServerType serverType, @NonNull String vehicleKey, Map params) { - if (stringKey == null) { - stringKey = generateKey(vehicleKey); - } + this(stringKey, serverType, vehicleKey); + this.params = params; + } + + public OnlineRoutingEngine(@NonNull String stringKey, + @NonNull ServerType serverType, + @NonNull String vehicleKey) { this.stringKey = stringKey; - this.name = name; this.serverType = serverType; this.vehicleKey = vehicleKey; - this.params = params; } public String getStringKey() { return stringKey; } - public String getName() { - return name; - } - public ServerType getServerType() { return serverType; } @@ -66,20 +67,40 @@ public class OnlineRoutingEngine { } public String getParameter(EngineParameterType paramType) { - if (params != null) { - return params.get(paramType.name()); - } - return null; + return params.get(paramType.name()); } public void putParameter(EngineParameterType paramType, String paramValue) { - if (params == null) { - params = new HashMap<>(); - } params.put(paramType.name(), paramValue); } - private static String generateKey(String vehicleKey) { - return "online_" + vehicleKey + "_" + System.currentTimeMillis(); + public String getName(@NonNull Context ctx) { + String customName = getParameter(EngineParameterType.CUSTOM_NAME); + if (customName != null) { + return customName; + } else { + return getStandardName(ctx); + } + } + + private String getStandardName(@NonNull Context ctx) { + return getStandardName(ctx, serverType, vehicleKey); + } + + public static String getStandardName(@NonNull Context ctx, + @NonNull ServerType serverType, + @NonNull String vehicleKey) { + String vehicleTitle = VehicleType.toHumanString(ctx, vehicleKey); + String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash); + return String.format(pattern, serverType.getTitle(), vehicleTitle); + } + + public static OnlineRoutingEngine createNewEngine(@NonNull ServerType serverType, + @NonNull String vehicleKey) { + return new OnlineRoutingEngine(generateKey(), serverType, vehicleKey); + } + + private static String generateKey() { + return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index e777fa6609..18b24a8762 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -1,5 +1,6 @@ package net.osmand.plus.onlinerouting; +import android.content.Context; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; @@ -50,14 +51,16 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static final String ENGINE_VEHICLE_TYPE_KEY = "engine_vehicle_type"; private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle"; private static final String ENGINE_API_KEY_KEY = "engine_api_key"; - private static final String ENGINE_NAME_CHANGED_BY_USER_KEY = "engine_name_changed_by_user_key"; private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String APP_MODE_KEY = "app_mode"; private static final String EDITED_ENGINE_KEY = "edited_engine_key"; private OsmandApplication app; + private MapActivity mapActivity; private OnlineRoutingHelper helper; + private View view; + private ViewGroup segmentsContainer; private OnlineRoutingCard nameCard; private OnlineRoutingCard serverCard; private OnlineRoutingCard vehicleCard; @@ -116,6 +119,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); app = requireMyApplication(); + mapActivity = getMapActivity(); helper = app.getOnlineRoutingHelper(); engine = new OnlineRoutingEngineObject(); if (savedInstanceState != null) { @@ -130,41 +134,48 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - MapActivity mapActivity = getMapActivity(); - if (mapActivity == null) { - return null; - } - boolean nightMode = isNightMode(); - inflater = UiUtilities.getInflater(getContext(), nightMode); - View view = inflater.inflate( + view = getInflater().inflate( R.layout.online_routing_engine_fragment, container, false); + segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(getContext(), view); } - setupToolbar(view); + setupToolbar((Toolbar) view.findViewById(R.id.toolbar)); - ViewGroup segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); + setupNameCard(); + setupServerCard(); + setupVehicleCard(); + setupApiKeyCard(); + setupExampleCard(); + setupResultsContainer(); + addSpaceSegment(); - // create name card - nameCard = new OnlineRoutingCard(mapActivity, nightMode); + setupButtons(); + + updateCardViews(nameCard, serverCard, vehicleCard, exampleCard); + return view; + } + + private void setupNameCard() { + nameCard = new OnlineRoutingCard(mapActivity, isNightMode()); nameCard.build(mapActivity); nameCard.setDescription(getString(R.string.select_nav_profile_dialog_message)); - nameCard.setEditedText(engine.name); + nameCard.setEditedText(engine.getName(app)); nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name)); nameCard.setOnTextChangedListener(new OnTextChangedListener() { @Override public void onTextChanged(boolean changedByUser, String text) { - if (!isEditingMode() && !engine.wasNameChangedByUser && changedByUser) { - engine.wasNameChangedByUser = true; + if (changedByUser) { + engine.customName = text; } - engine.name = text; } }); nameCard.showDivider(); segmentsContainer.addView(nameCard.getView()); + } - // create server card - serverCard = new OnlineRoutingCard(mapActivity, nightMode); + private void setupServerCard() { + serverCard = new OnlineRoutingCard(mapActivity, isNightMode()); serverCard.build(mapActivity); serverCard.setHeaderTitle(getString(R.string.shared_string_type)); List serverItems = new ArrayList<>(); @@ -195,16 +206,17 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { serverCard.setFieldBoxLabelText(getString(R.string.shared_string_server_url)); serverCard.showDivider(); segmentsContainer.addView(serverCard.getView()); + } - // create vehicle card - vehicleCard = new OnlineRoutingCard(mapActivity, nightMode); + private void setupVehicleCard() { + vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode()); vehicleCard.build(mapActivity); vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); List vehicleItems = new ArrayList<>(); for (VehicleType vehicle : VehicleType.values()) { - vehicleItems.add(new HorizontalSelectionItem(vehicle.toHumanString(app), vehicle)); + vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(app), vehicle)); } - vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.toHumanString(app), + vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.getTitle(app), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { @@ -221,16 +233,20 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { @Override public void onTextChanged(boolean editedByUser, String text) { - engine.customVehicleKey = text; + if (editedByUser) { + engine.customVehicleKey = text; + updateCardViews(nameCard, exampleCard); + } } }); vehicleCard.setEditedText(engine.customVehicleKey); vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param)); vehicleCard.showDivider(); segmentsContainer.addView(vehicleCard.getView()); + } - // create api key card - apiKeyCard = new OnlineRoutingCard(mapActivity, nightMode); + private void setupApiKeyCard() { + apiKeyCard = new OnlineRoutingCard(mapActivity, isNightMode()); apiKeyCard.build(mapActivity); apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); @@ -244,9 +260,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } }); segmentsContainer.addView(apiKeyCard.getView()); + } - // create example card - exampleCard = new OnlineRoutingCard(mapActivity, nightMode); + private void setupExampleCard() { + exampleCard = new OnlineRoutingCard(mapActivity, isNightMode()); exampleCard.build(mapActivity); exampleCard.setHeaderTitle(getString(R.string.shared_string_example)); List locationItems = new ArrayList<>(); @@ -274,48 +291,24 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } }); segmentsContainer.addView(exampleCard.getView()); + } - testResultsContainer = inflater.inflate( + private void setupResultsContainer() { + testResultsContainer = getInflater().inflate( R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false); testResultsContainer.setVisibility(View.GONE); segmentsContainer.addView(testResultsContainer); + } - View bottomSpaceView = new View(app); + private void addSpaceSegment() { int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top); + View bottomSpaceView = new View(app); bottomSpaceView.setLayoutParams( new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, space)); segmentsContainer.addView(bottomSpaceView); - - View cancelButton = view.findViewById(R.id.dismiss_button); - UiUtilities.setupDialogButton(nightMode, cancelButton, - DialogButtonType.SECONDARY, R.string.shared_string_cancel); - cancelButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - - view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); - - View saveButton = view.findViewById(R.id.right_bottom_button); - UiUtilities.setupDialogButton(nightMode, saveButton, - UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save); - saveButton.setVisibility(View.VISIBLE); - saveButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - saveChanges(); - dismiss(); - } - }); - - updateCardViews(nameCard, serverCard, vehicleCard, exampleCard); - return view; } - private void setupToolbar(View mainView) { - Toolbar toolbar = (Toolbar) mainView.findViewById(R.id.toolbar); + private void setupToolbar(Toolbar toolbar) { ImageView navigationIcon = toolbar.findViewById(R.id.close_button); navigationIcon.setImageResource(R.drawable.ic_action_close); navigationIcon.setOnClickListener(new OnClickListener() { @@ -348,10 +341,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void updateCardViews(BaseCard... cardsToUpdate) { for (BaseCard card : cardsToUpdate) { if (nameCard.equals(card)) { - if (!engine.wasNameChangedByUser) { - String name = String.format( - getString(R.string.ltr_or_rtl_combine_via_dash), - engine.serverType.getTitle(), engine.vehicleType.toHumanString(app)); + if (Algorithms.isEmpty(engine.customName)) { + String name = OnlineRoutingEngine.getStandardName(app, engine.serverType, engine.getVehicleKey()); nameCard.setEditedText(name); } @@ -365,7 +356,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } else if (vehicleCard.equals(card)) { - vehicleCard.setHeaderSubtitle(engine.vehicleType.toHumanString(app)); + vehicleCard.setHeaderSubtitle(engine.vehicleType.getTitle(app)); if (engine.vehicleType == VehicleType.CUSTOM) { vehicleCard.showFieldBox(); vehicleCard.setEditedText(engine.getVehicleKey()); @@ -379,11 +370,43 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } + private void setupButtons() { + boolean nightMode = isNightMode(); + View cancelButton = view.findViewById(R.id.dismiss_button); + UiUtilities.setupDialogButton(nightMode, cancelButton, + DialogButtonType.SECONDARY, R.string.shared_string_cancel); + cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); + + View saveButton = view.findViewById(R.id.right_bottom_button); + UiUtilities.setupDialogButton(nightMode, saveButton, + UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save); + saveButton.setVisibility(View.VISIBLE); + saveButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + saveChanges(); + dismiss(); + } + }); + } + private void saveChanges() { - OnlineRoutingEngine engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.name, - engine.serverType, engine.getVehicleKey(), null); + OnlineRoutingEngine engineToSave; + if (isEditingMode()) { + engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.serverType, engine.getVehicleKey()); + } else { + engineToSave = OnlineRoutingEngine.createNewEngine(engine.serverType, engine.getVehicleKey()); + } engineToSave.putParameter(EngineParameterType.CUSTOM_SERVER_URL, engine.customServerUrl); + engineToSave.putParameter(EngineParameterType.CUSTOM_NAME, engine.customName); if (engine.serverType == ServerType.GRAPHHOPER) { engineToSave.putParameter(EngineParameterType.API_KEY, engine.apiKey); } @@ -470,13 +493,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void saveState(Bundle outState) { - outState.putString(ENGINE_NAME_KEY, engine.name); + outState.putString(ENGINE_NAME_KEY, engine.customName); outState.putString(ENGINE_SERVER_KEY, engine.serverType.name()); outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl); outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); - outState.putBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY, engine.wasNameChangedByUser); outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name()); if (appMode != null) { outState.putString(APP_MODE_KEY, appMode.getStringKey()); @@ -485,13 +507,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void restoreState(Bundle savedState) { - engine.name = savedState.getString(ENGINE_NAME_KEY); + engine.customName = savedState.getString(ENGINE_NAME_KEY); engine.serverType = ServerType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); engine.customServerUrl = savedState.getString(ENGINE_SERVER_URL_KEY); engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); - engine.wasNameChangedByUser = savedState.getBoolean(ENGINE_NAME_CHANGED_BY_USER_KEY); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); editedEngineKey = savedState.getString(EDITED_ENGINE_KEY); @@ -505,8 +526,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (isEditingMode()) { OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey); if (editedEngine != null) { - engine.name = editedEngine.getName(); - engine.wasNameChangedByUser = true; + engine.customName = editedEngine.getParameter(EngineParameterType.CUSTOM_NAME); engine.serverType = editedEngine.getServerType(); engine.customServerUrl = editedEngine.getParameter(EngineParameterType.CUSTOM_SERVER_URL); String vehicleKey = editedEngine.getVehicleKey(); @@ -543,6 +563,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } + private LayoutInflater getInflater() { + return UiUtilities.getInflater(mapActivity, isNightMode()); + } + public static void showInstance(@NonNull FragmentActivity activity, @NonNull ApplicationMode appMode, String editedEngineKey) { @@ -558,13 +582,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private static class OnlineRoutingEngineObject { - private String name; + private String customName; private ServerType serverType; private String customServerUrl; private VehicleType vehicleType; private String customVehicleKey; private String apiKey; - private boolean wasNameChangedByUser; public String getVehicleKey() { if (vehicleType == VehicleType.CUSTOM) { @@ -576,5 +599,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public String getBaseUrl() { return customServerUrl != null ? customServerUrl : serverType.getBaseUrl(); } + + public String getName(Context ctx) { + if (customName != null) { + return customName; + } + return OnlineRoutingEngine.getStandardName(ctx, serverType, getVehicleKey()); + } } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index cc652f35b2..8a9e42bd54 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -91,7 +91,7 @@ public class OnlineRoutingHelper { JSONObject json = new JSONObject(jsonString); readFromJson(json, engines); } catch (JSONException e) { - LOG.debug("Error when read setting from JSON"); + LOG.debug("Error when create a new JSONObject: " + e.toString()); } } return engines; @@ -108,7 +108,7 @@ public class OnlineRoutingHelper { } } - private void readFromJson(JSONObject json, List engines) { + private static void readFromJson(JSONObject json, List engines) { try { if (!json.has("items")) { return; @@ -120,19 +120,18 @@ public class OnlineRoutingHelper { for (int i = 0; i < itemsJson.length(); i++) { JSONObject object = itemsJson.getJSONObject(i); String key = object.getString("key"); - String name = object.getString("name"); String vehicleKey = object.getString("vehicle"); ServerType serverType = ServerType.valueOf(object.getString("serverType")); String paramsString = object.getString("params"); HashMap params = gson.fromJson(paramsString, type); - engines.add(new OnlineRoutingEngine(key, name, serverType, vehicleKey, params)); + engines.add(new OnlineRoutingEngine(key, serverType, vehicleKey, params)); } } catch (JSONException e) { - LOG.debug("Error when read setting from JSON internal"); + LOG.debug("Error when reading engines from JSON: " + e.toString()); } } - private boolean writeToJson(JSONObject json, List engines) { + private static boolean writeToJson(JSONObject json, List engines) { JSONArray jsonArray = new JSONArray(); Gson gson = new Gson(); Type type = new TypeToken>() { @@ -141,7 +140,6 @@ public class OnlineRoutingHelper { for (OnlineRoutingEngine engine : engines) { JSONObject jsonObject = new JSONObject(); jsonObject.put("key", engine.getStringKey()); - jsonObject.put("name", engine.getName()); jsonObject.put("serverType", engine.getServerType().name()); jsonObject.put("vehicle", engine.getVehicleKey()); jsonObject.put("params", gson.toJson(engine.getParams(), type)); @@ -150,7 +148,7 @@ public class OnlineRoutingHelper { json.put("items", jsonArray); return true; } catch (JSONException e) { - LOG.debug("Error when write engines to JSON"); + LOG.debug("Error when writing engines to JSON: " + e.toString()); return false; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java index a3ca17681c..3e3fea6660 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java @@ -2,6 +2,8 @@ package net.osmand.plus.onlinerouting; import android.content.Context; +import androidx.annotation.NonNull; + import net.osmand.plus.R; import net.osmand.util.Algorithms; @@ -10,7 +12,7 @@ public enum VehicleType { BIKE("bike", R.string.routing_engine_vehicle_type_bike), FOOT("foot", R.string.routing_engine_vehicle_type_foot), DRIVING("driving", R.string.routing_engine_vehicle_type_driving), - CUSTOM("-", R.string.shared_string_custom); + CUSTOM("", R.string.shared_string_custom); VehicleType(String key, int titleId) { this.key = key; @@ -24,10 +26,19 @@ public enum VehicleType { return key; } - public String toHumanString(Context ctx) { + public String getTitle(Context ctx) { return ctx.getString(titleId); } + public static String toHumanString(@NonNull Context ctx, + @NonNull String key) { + VehicleType vehicleType = getVehicleByKey(key); + if (vehicleType == CUSTOM) { + return Algorithms.capitalizeFirstLetter(key); + } + return vehicleType.getTitle(ctx); + } + public static VehicleType getVehicleByKey(String key) { for (VehicleType v : values()) { if (Algorithms.objectEquals(v.getKey(), key)) { diff --git a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java index cd812b3363..46a35ea67e 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java @@ -1,13 +1,12 @@ package net.osmand.plus.profiles; +import net.osmand.plus.R; + public class OnlineRoutingEngineDataObject extends ProfileDataObject { public OnlineRoutingEngineDataObject(String name, String description, - String stringKey, - int iconRes, - boolean isSelected, - ProfileIconColors iconColor) { - super(name, description, stringKey, iconRes, isSelected, iconColor); + String stringKey) { + super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null); } } diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java index fd146778a7..f769f69bdb 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java @@ -71,8 +71,8 @@ public class ProfileDataUtils { public static List getOnlineRoutingProfiles(OsmandApplication app) { List objects = new ArrayList<>(); for (OnlineRoutingEngine engine : app.getOnlineRoutingHelper().getEngines()) { - objects.add(new OnlineRoutingEngineDataObject(engine.getName(), - engine.getBaseUrl(), engine.getStringKey(), R.drawable.ic_world_globe_dark, false, null)); + objects.add(new OnlineRoutingEngineDataObject( + engine.getName(app), engine.getBaseUrl(), engine.getStringKey())); } return objects; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index ebc554040a..df2bd8b879 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -237,7 +237,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { View itemView = UiUtilities.getInflater(getContext(), nightMode).inflate( profile instanceof OnlineRoutingEngineDataObject ? - R.layout.bottom_sheet_item_with_descr_and_radio_and_eng_btn : + R.layout.bottom_sheet_item_with_descr_radio_and_icon_btn : R.layout.bottom_sheet_item_with_descr_and_radio_btn, null); TextView tvTitle = itemView.findViewById(R.id.title); TextView tvDescription = itemView.findViewById(R.id.description); From a1e3eb37c474f701d6ef9f47ecbc1d7df025b94d Mon Sep 17 00:00:00 2001 From: Temuri Doghonadze Date: Mon, 4 Jan 2021 06:30:19 +0100 Subject: [PATCH 09/61] Added translation using Weblate (Georgian) --- OsmAnd/res/values-ka/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 OsmAnd/res/values-ka/phrases.xml diff --git a/OsmAnd/res/values-ka/phrases.xml b/OsmAnd/res/values-ka/phrases.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/OsmAnd/res/values-ka/phrases.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 59fb961e3fb6a1273dcf2383232cba6cc828500f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20H=C3=A5ll?= Date: Sat, 2 Jan 2021 21:52:49 +0000 Subject: [PATCH 10/61] Translated using Weblate (Swedish) Currently translated at 65.0% (2335 of 3591 strings) --- OsmAnd/res/values-sv/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index 4a7805d1bc..692e68f62c 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -3098,4 +3098,7 @@ Vänligen tillhandahåll fullständig kod Betalningen för prenumerationen är i enlighet med vad som valts. Du kan avbryta den i AppGallery när som hellst. Undvik resor till fots Undvik resor till + Ladda ner Wikipedia kartor + Få information om sevärdheter från Wikipedia, en inbunden samling av offline artiklar om ställen och destinationer. + \ No newline at end of file From c0fbb18de7add8738c8c287e2fb42bfe06769d1c Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Sun, 3 Jan 2021 14:18:31 +0000 Subject: [PATCH 11/61] Translated using Weblate (French) Currently translated at 100.0% (3591 of 3591 strings) --- OsmAnd/res/values-fr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 137cfe1597..65ac4718b2 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4006,4 +4006,5 @@ Autoriser les voies navigables intermittentes Autoriser les cours d’eau et les drains Autoriser les cours d’eau et les drains + Nombre d\'annonces vocales \ No newline at end of file From f158d9d0e29e4dd6d38927ab414d9ea3dd9b4122 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 3 Jan 2021 09:11:19 +0000 Subject: [PATCH 12/61] Translated using Weblate (German) Currently translated at 100.0% (3591 of 3591 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 95344ac93f..870673e61e 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4031,4 +4031,5 @@ Bäche und Entwässerungsgräben erlauben Gewässer erlauben, die nicht ständig Wasser führen Gewässer erlauben, die nicht ständig Wasser führen + Zeiten der Sprachansagen \ No newline at end of file From cc580fcd56fd62fc8bd42f561bd4560f98818e61 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Sat, 2 Jan 2021 23:21:55 +0000 Subject: [PATCH 13/61] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3591 of 3591 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 5fecd504a6..0bd95661ef 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4023,4 +4023,5 @@ Надавати перевагу пішохідним маршрутам Дозволити потоки та стічні канали Дозволити потоки та стічні канали + Голосові підказки \ No newline at end of file From 5b4acae42f31675845260dd8da3a6844d2ac34b4 Mon Sep 17 00:00:00 2001 From: Temuri Doghonadze Date: Mon, 4 Jan 2021 05:29:58 +0000 Subject: [PATCH 14/61] Translated using Weblate (Georgian) Currently translated at 61.0% (2193 of 3591 strings) --- OsmAnd/res/values-ka/strings.xml | 574 ++++++++++++++++++++++++++----- 1 file changed, 487 insertions(+), 87 deletions(-) diff --git a/OsmAnd/res/values-ka/strings.xml b/OsmAnd/res/values-ka/strings.xml index a3f8153e60..517a391d20 100644 --- a/OsmAnd/res/values-ka/strings.xml +++ b/OsmAnd/res/values-ka/strings.xml @@ -5,13 +5,13 @@ მარცხენა მხარეს საჭის გამომყენებელი ქვეყნებისათვის. საწყისი პოზიცია ნაპოვნი ჯერ არაა. პოზიცია უცნობია. - გამჭირვალობის შეცვლა (0 - გამჭირვალე, 255 - გაუმჭირვალე) + გამჭირვალობა (0 - გამჭირვალე, 255 - გაუმჭირვალე) გნებავთ ჩამოტვირთვის შეწყვეტა? პროგრამის მთავარი თვისებების გამოსაყენებლად თქვენ გჭირდებათ მონაცემები რომლებიც გამოიყენება გათიშულ რეჟიმში, რომელიც შეგიძლიათ ჩამოტვირთოთ (პარამეტრები->მონაცემები გათიშვისას). ამის შემდეგ თქვენ შეგეძლებათ ძებნა როგორც მისამართის, ასევე საჯარო ტრანსპორტის მიხედვით. ბაზური რუკა საჭიროა პროგრამის ფუნქციონირებისათვის და არჩეულ იქნა გადმოსაწერად. არაფერი არ იქნა ნაპოვნი. თუ ვერ პოულობთ თქვენი რეგიონის რუკას, შეგიძლიათ შექმნათ თვითონ. (იხილეთ https://osmand.net). მიმდინარე რუკები (ნახაზები) - გათიშული რუკები (ვექტორული) + სტანდარტული რუკები (ვექტორული) გათიშული რუკების ჩამოტვირთვა, მართვა და დეტალები. "ჩართეთ მიმდინარე რუკების დამატება სხვადასხვა წყაროების სანახავად" მიმდინარე რუკები @@ -51,7 +51,7 @@ მენიუში დაბრუნება დაპატარავება გადიდება - გადიდების ზომა + გადიდების დონე ჩრდილოეთი ჩრდილო-ჩრდილო-აღმოსავლეთი ჩრდილო-აღმოსავლეთი @@ -68,9 +68,9 @@ დასავლეთი-ჩრდილო-დასავლეთი ჩრდილო-დასავლეთი ჩრდილოეთი-ჩრდილო-დასავლეთი - წინა + წინ წინა მარჯვენა - მარჯვენა + მარჯვნივ უკანა მარჯვენა უკან უკანა მარცხნივ @@ -97,14 +97,14 @@ ბილიკებისა და გზების მანათობელი ფერებით ჩვენება. POI-ს ჩასწორება გათიშულ რეჟიმში ყოველთვის გამოვიყენოთ POI-ს ჩასწორების გათიშული რეჟიმი. წინააღმდეგ შემთხვევაში ცვლილებები მყისიერად აიტვირთება. - აპლიკაციაში POI-ის ცვლილებები არ ეხება ჩამოტვირთულ რუკის ფაილებს. ცვლილებები ინახება ლოკალურ ფაილში. + აპლიკაციაში POI-ის ცვლილებები არ ეხება ჩამოტვირთულ რუკის ფაილებს. ცვლილებები ინახება თქვენს მოწყობილობაში. ატვირთვა… - {0} POI/Bugs ატვირთულია + {0} POI/notes ატვირთულია ყველას ატვირთვა ცვლილების OSM-ზე ატვირთვა ცვლილების წაშლა OSM POI-ის ასინქრონული ჩასწორება: - ადგილობრივად შენახული OSM POI-ები/Bugs + ადგილობრივად შენახული OSM POI-ები ადგილობრივ ბაზაში შენახული OSM POI-ების/Bugs ჩვენება და მართვა. მიუთითეთ მიმდინარე რეჟიმში დევნის ინტერვალი. ცოცხალი დევნის ინტერვალი @@ -122,10 +122,10 @@ ევროპა ევროპა - საფრანგეთი ევროპა - გერმანია - ევროპა/აზია - რუსეთი + რუსეთი აფრიკა აზია - ოკეანეთი + ავსტრალია და ოკეანეთი მსოფლიო რუკები მსოფლიო ვიკიპედია ჩაწერილი ხმოვანი პაკეტები @@ -173,32 +173,32 @@ ფაილისათვის სახელის გადარქმევა შეუძლებელია. ფაილი მოცემული სახელით უკვე არსებობს. ძებნის შედეგები შეიცავს რამოდენიმე POI კატეგორიას. - ადგილობრივი მონაცემები POI-ს ძებნისათვის არ არსებობს. + POI-ების მოსაძებნად გთხოვთ ჩამოწეროთ გათიშული რუკები. სახელით ძებნა POI-ის მონაცემთა ფაილის \'%1$s\', არსებობს ასლი და მისი წაშლა შესაძლებელია. ლოკალური ფაილი POI-ის ცვლილებების შესანახად ნაპოვნი არ იქნა და მისი შექმნა შეუძლებელია. განახლება OsmAnd+-მდე - სერვერი შეიცავს რუკის ფაილებს რომლებიც არაა შესაბამისი აპლიკაციის მიმდინარე ვერსიასთან. გთხოვთ განაახლოთ აპლიკაცია მათ ჩამოსაწერად და გამოსაყენებლად. + ახალი რუკების გამოსაყენებლად გთხოვთ განაახლოთ აპლიკაცია. სახელის გადარქმევა მიმდინარე POI-ს ძებნა სახელით მდებარეობის ძებნა… - მდებარეობა (ნაპოვნია) + ჩემი მდებარეობა (ნაპოვნია) მისამართი… რჩეულები… არააღწერილი - უკანასკნელად ნანახი რუკის ხედი - ძებნა ახლოს : + მიდინარე რუკის ცენტრი + საწყისი : ახლოს ძებნა გზა შეინახა წარმატებით. სახელი \'%1$s\'. ფაილის სახელი: ფაილი მოცემული სახელით უკვე არსებობს. შენახვა GPX ფაილების OSM-ში ატვირთვა. ისინი გამოიყენება რუკების გასაუმჯობესებლად. - %1$d %2$d -დან წარმატებით აიტვირთა. + ატვირთულია %1$d %2$d -დან. OSM-ში გაგზავნა მეტი დეტალები რუკის შესახებ ვექტორული რუკის დეტალების (გზების და ა.შ.) ჩვენება პატარა გადიდებისას. - რჩეული წერტილები წარმატებით წაიშალა. + რჩეული წერტილები წაშლილია. თქვენ აპირებთ წაშალოთ %1$d რჩეული და %2$d რჩეულთა ჯგუფი. დარწმუნებული ხართ? საწყისი მეგობრები @@ -206,13 +206,13 @@ სახელი კატეგორია არა, მადლობა - მსოფლიოს ბაზური რუკა, რომელიც შეიცავს მთელ მსოფლიოს პატარა გადიდებისას, არ არსებობს. გთხოვთ გადმოწეროთ World_basemap_x.obf. - დასტაში \"offline\" sdcard-ზე არ არსებობს მონაცემები. გთხოვთ გადმოწეროთ რუკებით გათიშულ რეჟიმში სარგებლობისათვის . + მსოფლიოს ბაზური რუკა, რომელიც შეიცავს მთელ მსოფლიოს პატარა გადიდებისას, არ არსებობს. ტ6გთხოვთ გადმოწეროთ World_basemap_x.obf. + გთხოვთ გადმოწეროთ რუკები გათიშულ რეჟიმში სარგებლობისათვის . "\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 . გავაგრძელოთ? გათიშული მონაცემების მმართველი. @@ -239,7 +239,7 @@ არჩეული ენა არაა მხარდაჭერილი ანდროიდის მიმდინარე ვერსიის TTS ძრავის მიერ. გნებავთ მოვძებნოთ სხვა ძრავი market-ში\? წინააღმდეგ შემთხვევაში გამოყენებულ იქნება მიმდინარე TTS ენა\? ნაკლული მონაცემები არჩეული ენის შესაბამისი მონაცემების პოვნა შეუძლებელია. გნებავთ მაღაზიაში მათი მოძებნა? - GPX-ის უკუღმა მიმართულება + უკუღმა მიმართულება მიმდინარე მიმართულების გამოყენება მიმდინარე ბილიკის დევნა ამ ლოკაციისათვის არსებობს გათიშული ვექტორული რუკა.\n\t\n\tაქტივაციისათვის \'მენიუ\' -> \'ხედის გამართვა\' -> \'რუკის წყარო…\' -> \'გათიშული ვექტორული რუკები\'. @@ -247,7 +247,7 @@ აირჩიეთ არხი ხმოვანი ბრძანებებისათვის. ხმოვანი დარეკვა შეტყობინების ხმა - მუსიკის ხმა + მუსიკის/ნავიგაციის ხმა შეუძლებელია %1$s -ის ჩამოტვირთვა, გთხოვთ თავიდან დააყენოთ აპლიკაცია. გამჭირვალობის შეცვლა. გამჭირვალობა @@ -275,7 +275,7 @@ შემდეგი წინა სიგრძისა და სიჩქარის ერთეულები. - გაზომვის ერთეული + სიგრძის ერთეულები მილი/ფუტი მილი/იარდი კილომეტრი/მეტრი @@ -288,7 +288,7 @@ მდებარეობის სანახავად მიჰყევით ბმულს %1$s ან ანდროიდის ბმულს %2$s მდებარეობის გაგზავნა მდებარეობის გაზიარება - გზის წერტილი \'\'{0}\'\' წარმატებით დაემატა + გზის წერტილი \'\'{0}\'\' დამატებულია ჩაწერილი GPX ბილიკისათვის სანავიგაციო წერტილის დამატება ადმინისტრაციული ბარიერი @@ -310,7 +310,7 @@ სპორტი ნოყიერი ტურიზმი - სატრანსპორტო + ტრანსპორტი მისამართების ინდექსირება… რუკების ინდექსირება… POI-ის ინდექსირება… @@ -319,7 +319,7 @@ კმ კმ/ს - ამოღებული რუკის ფორმატი \'\'{0}\'\'-ს მხარდაჭერა ამოღებულია + რუკის ფორმატის \'\'{0}\'\'-ს მხარდაჭერა ამოღებულია მანქანის შეკეთება უახლოესი POI ხელით შეყვანილი ფილტრი @@ -331,7 +331,7 @@ ინდექსი \'\'{0}\'\' არ ეტევა მეხსიერებაში ინდექსის ვერსიის \'\'{0}\'\' მხარდაჭერა არ არსებობს OsmAnd-ის გათიშული ნავიგაცია არის საცდელი თვისება რომებიც არ მუშაობს 20 კმ-ზე მეტი მანძილებისათვის.\n\nნავიგაციის სერვისი დროებით გადართულია მიმდინარე სერვისზე CloudMade. - შეუძლებელია მითითებული დასტის პოვნა. + მითითებული დასტის პოვნა შეუძლებელია. შესანახი დასტა დაყენებულია OsmAnd-ის წინა ვერსია. მთელი გათიშული მონაცემების მხარდაჭერილია და გამოყენებულ იქნება ახალ აპლიკაციაში. რჩეული წერტილების გამოსაყენებლად ისინი უნდა დააექსპორტოთ ძველიდან და შეიტანოთ ახალში. ვერსია {0}-ის ჩადგმა წარმატებულად დამთავრდა ({1}). @@ -343,7 +343,7 @@ უფასო ვერსიის შეწირულობის აქტივობა ვერ ვიპოვე GPS სტატუსის აპლიკაცია. გნებავთ მისი მოძებნა მაღაზიაში? ხმოვანი ბრძანებები მიუწვდომელია. გთხოვთ გადახვიდეთ პარამეტრებში, აირჩიოთ მხარდაჭერილი ხმოვანი პაკეტი და დააყენოთ ის. - ხმოვანი ბრძანებები არჩეული არაა + აირჩიეთ ხმოვანი დამხმარის პაკეტი დღე ღამე მზის ჩასვლა/ამოსვლა @@ -359,13 +359,13 @@ ჩართეთ უსწრაფესი გზის დასათვლელად ან გამორთეთ უმოკლესისათვის. გადიდებისას {0} გადმოსაწერია {1} ნაწილი ({2} MB) რუკის გადმოწერა - აირჩიეთ მაქსიმალური გადიდება ჩასატვირთად + მაქსიმალური გადიდება ჩასატვირთად რუკის გადმოწერა შეუძლებელია გაგრძელებადი რენდერი მიყოლებული რენდერის ჩვენება ცალცალკე სურათების ჩვენების მაგიერ. მონიშნული არეალის რენდერის დროს მოხდა შეცდომა. მდებარეობის პარამეტრები … - რენდერერი წარმატებით ჩაიტვირთა + რენდერერი ჩატვირთულია მოხდა შეცდომა: რენდერერი არ ჩაიტვირთა. ვექტორული მარენდერებელი რენდერის გარეგნობის არჩევა @@ -380,7 +380,7 @@ ტრანსპორტის ძებნა (არ მოიძებნა): ტრანსპორტის პასუხები ({0} -მდე): ტრანსპორტის თავიდან ძებნა - ხმა + ჩაწერილი ხმა ვექტორული რუკები ჩატვირთული არ იქნა GPX ფაილები /tracks დასტაში ნაპოვნი არ იქნა GPX მონაცემების კითხვის შეცდომა. @@ -390,7 +390,7 @@ POI-ს წაშლა კომპასისაკენ მოძრაობის მიმართულებით - არ შეაბრუნო + არ შეაბრუნო (ჩრდილოეთი ყოველთვის ზემოთკენაა) რუკის გასწორება: რუკის ორიენტაცია დეტალები გზის შესახებ @@ -409,7 +409,7 @@ გზა რჩეულები OSM-ის ხოჭოები - POI… + POI შრე… რუკის წყარო… ხედის აღწერა POI-ის ძებნა @@ -441,8 +441,10 @@ ხმოვანი მონაცემები მხარდაჭერილი არაა ხმოვანი მონაცემები დაზიანებულია არჩეული ხმოვანი მონაცემები მიუწვდომელია - SDcard მიუწვდომელია.\nთქვენ არ შეგეძლებათ რუკების დანახვა ან რაიმეს ძებნა. - SDcard იმყოფება მხოლოდ-კითხვის რეჟიმში.\nთქვენ შეგიძლიათ მხოლოდ უკვე ჩატვირთული რუკების გამოყენება. ინტერნეტიდან ჩამოტვირთვა შეუძლებელია. + მეხსერების ბარათი მიუწვდომელია. +\nთქვენ არ შეგეძლებათ რუკების დანახვა ან რაიმეს ძებნა. + მეხსიერების ბარათი იმყოფება მხოლოდ-კითხვის რეჟიმში. +\nთქვენ შეგიძლიათ მხოლოდ უკვე ჩატვირთული რუკების გამოყენება. ინტერნეტიდან ჩამოტვირთვა შეუძლებელია. ფაილის განშლა… შებრუნდით მარჯვნივ და წინ შებრუნდით მკვეთრად მარჯვნივ და წინ @@ -454,8 +456,8 @@ მიმართულება გვიან რაიონების გადმოწერა - სიგნალის ძებნა… - რუკაზე უკანასკნელი მდებარეობის მოძიება + სიგნალის ლოდინი… + მიმდინარე რუკის ცენტრის ახლოს ძებნა ახლო ძიება იგივე როგორც მოწყობილობაზე პორტრეტი @@ -480,11 +482,11 @@ რუკაზე საზოგადოებრივი ტრანსპორტის გაჩერებების ჩვენება. გაჩერებების ჩვენება OsmAnd - სანავიგაციო აპლიკაცია - POI მონაცემები წარმატებით განახლდა (ჩატვირთულ იქნა {0}) + POI მონაცემები განახლდა (ჩაიტვირთა {0}) შეცდომა ლოკალური POI სიის განახლებისას. შეცდომა მონაცემების სერვერიდან კითხვისას. გათიშული POI მონაცემები ამ არეალისათვის ხელმიუწვდომელია - პატარა ზომის გადიდებისათვის POI-ის განახლება არ შეიძლება + გაადიდეთ POI-ების ჩასასწორებლად POI-ის განახლება განვანახლო ლოკალური მონაცემები ინტერნეტიდან? ქალაქი: {0} @@ -500,7 +502,7 @@ მიმდინარეობს ძებნა… მისამართის ძებნა… მისამართის OSM Nominatim -ით ძებნა - სახლის ნომერი, ქუჩა, ქალაქი + ონლაინ ძებნა: სახლის ნომერი, ქუჩა, ქალაქი გათიშული ინტერნეტი მაქს. მიმდინარე გადიდება @@ -510,7 +512,7 @@ ნავიგაციის სერვისი შენახვის დასტა SDCard-ზე მიუწვდომელია! ჩამოვტვირთო {0} - {1} ? - გათიშული მონაცემები {0}-სათვის უკვე არსებობს ({1}). გნებავთ მისი განახლება ({2}) ? + გათიშული მონაცემები {0}-სათვის უკვე არსებობს ({1}). განვაახლო ({2}) \? მისამართი ჩამოტვირთვა დასრულებულია წვდომადი რაიონების სიის ჩამოტვირთვა… @@ -519,7 +521,7 @@ რჩეული წერტილები არ არსებობს შეცვლა ჩვენება მხოლოდ - მიყოლა + მიყოლის დაწყება აირჩიეთ გადაადგილების ტიპი (არჩევანი): გთხოვთ ჯერ აირჩიოთ მიმართულება მიმართულებები @@ -543,12 +545,12 @@ ახალი გზა დათვლილია. დაშორება მიხვედით. კოორდინატები არასწორია! - OsmAnd-ის რუკაზე დაბრუნება + რუკაზე დაბრუნება დახურვა მონაცემების კითხვა… ლოკალური მონაცემების კითხვა… ბოლოს გაშვებული OsmAnd მოკვდა. ჟურნალის ფაილია {0}. გთხოვთ მოგვწეროთ ჟურნალის ფაილი და როგორ მოხდა ეს. - GPX ძიების SD-ზე შენახვა… + GPX ფაილის შენახვა… დამთავრდა ინტერნეტის გამოყენება გზის დასათვლელად. მიმდინარე ნავიგაციის გამოყენება @@ -576,20 +578,20 @@ ძებნა მისამართით აირჩიეთ შენობა აირჩიეთ ქუჩა - აირჩიეთ ქალაქი + აირჩიეთ ქალაქი ან საფოსტო კოდი აირჩიეთ ქვეყანა ხედვის კუთხის ჩვენება რუკის 3D ხედვის ჩართვა. რუკის 3D ხედვა ბოლოს გამოყენებული POI-ის რუკაზე ჩვენება. - POI-ის ჩვენება + POI შრის ჩვენება აირჩიეთ მიმდინარე ან ქეშირებული რუკის ნაწილის წყარო. რუკის წყარო რუკის წყარო ინტერნეტის გამოყენება - მდებარეობის ჩვენება + თქვენი მდებარეობის ჩვენება GPS კოორდინატების რუკაზე ჩვენება - ინტერნეტის გამოყენება ნაკლული რუკის წარწერების ჩამოსატვირთად + ნაკლული რუკის წარწერების გადმოწერა ნავიგაციის აპლიკაცია გასვლა ძებნა @@ -599,23 +601,23 @@ ქალაქის ინკრემენტულად ძებნა. ქალაქის/საფოსტო ინდექსის საპოვნელად შეიყვანეთ პირველი 3 ან მეტი სიმბოლო ქუჩის ინკრემენტული ძებნა შენობის ინკრემენტული ძებნა - აირჩიეთ რაიონი სიიდან + ჯერ აირჩიეთ რაიონი აირჩიეთ მკვეთი ქუჩა უახლოესი დასახლებული პუნქტები რუკის დათვალიერება - მანქანა - ველოსიპედი - ფეხით მოსიარულე + მანქანით + ველოსიპედით + ფეხით ცენტრი ძირი შეიყვანეთ განედი და გრძედი არჩეულ ფორმატში (D - გრადუსი, M - წუთ, S - წამი) განედი გრძედი - DDD.DD + DDD.DDDDD DDD MM.MMM DDD MM SS.S რუკაზე ჩვენება - აირჩიეთ მისამართი + მისამართი რაიონი ქალაქი ქუჩა @@ -631,11 +633,11 @@ არა რჩეულის სახელი რჩეული - რჩეული წერტილი \'\'{0}\'\' წარმატებით დაემატა. + რჩეული წერტილი \'\'{0}\'\' დაემატა. რჩეულის ჩასწორება რჩეულის წაშლა გნებავთ რჩეული წერტილის \'%s\' წაშლა? - რჩეული წერტილი {0} წარმატებით წაიშალა. + რჩეული წერტილი {0} წაშლილია. შეტყობინება ავტორი კომენტარი დამატებულია @@ -646,12 +648,12 @@ წავშალო {0} (კომენტარი)? POI-ს წაშლა წაშლა - POI წარმატებით წაიშალა + წაშლილია ჩამატება შეცვლა - მოქმედება {0} წარმატებით დასრულდა. - გაუთვალისწინებელი შეცდომა {0}-ის შესრულების დროს. - {0}-ს შესრულების დროს მოხდა შეცდომა I/O. + მოქმედება {0} დასრულებულია. + შეცდომა {0}-ის შესრულების დროს. + {0}-ის I/O შეცდომა. უჯრედის მონაცემები ჩატვირთული არაა გახსნა კომენტარი @@ -662,8 +664,8 @@ ფილტრი ჩაწერა როგორც წავშალო მონიშნული ფილტრი? - წაიშალა ფილტრი %1$s - შეიქმნა ფილტრი %1$s + წაიშალა ფილტრი \'%1$s\' + შეიქმნა ფილტრი \'%1$s\' გზის მონაცემები ფორმატი POI - ინტერესის წერტილი @@ -672,7 +674,7 @@ ტრანსპორტის ძებნა რჩეულებში ძებნა ყველა მიწისზედა რუკის ობიექტის გამჭირვალედ ჩვენება. - პოლიგონების გარეშე + პოლიგონები რენდერის რეჟიმი რუკის გაუმჯობესება მომხმარებლის პროფილის მიხედვით აირჩიეთ მინიმალური გადიდების ზომა რუკის საჩვენებლად. შეიძლება საჭირო გახდეს SRTM ფაილი: @@ -689,7 +691,7 @@ საკუთარი მანქანის გაჩერებიდან გამოყვანა გაფრთხილება - შეტყობინება თქვენი მანქანის გამოყვენის შესახებ კალენდარში უკვე არსებობს. ის დარჩება ხელით წაშლამდე დარჩება კალენდარში. + შეტყობინება თქვენი მანქანის გამოყვანის შესახებ კალენდარში უკვე არსებობს. ის კალენდარში ხელით წაშლამდე დარჩება. პარკინგის დროის ლიმიტის დაყენება გნებავთ დაყენებული მანქანის მდებარეობის წაშლა? პარკინგის მაჩვენებლის წაშლა @@ -723,9 +725,9 @@ კომპასის გამოყენება გზის გადათვლა სასურველი წერტილის პოვნის შემთხვევაში წინა გზა არ დასრულებულა. გნებავთ მისი გაყოლა? (%1$s წმ) - სიჩქარის კამერების ჩვენება - სიჩქარის ლიმიტების ჩვენება - ფასიანი გზებისათვის გვერდის ავლა + სიჩქარის კამერები + სიჩქარის ლიმიტები + ფასიანი გზებისათვის თავის არიდება ქუჩის სახელი გამართვა სად ვარ @@ -741,11 +743,11 @@ შემდეგი შესახვევი (პატარა) მეორე შემდეგი შესახვევი პატარა რუკა - ეკრანის ჩაკეტვის ჩართვა/გამორთვა + ეკრანის ჩაკეტვა ეკრანი ჩაკეტილია დააყენეთ გაღვიძების ინტერვალი: - დააჭირეთ ბოქლომს ეკრანის გასახსნელად - ეკრანზე ჩაკეტვის მოხსნა + ეკრანის გასაღებად შეეხეთ ბოქლომს + ჩაკეტვის მოხსნა პროგრამის ფონურ რეჟიმში გაშვება შეჩერდით \nგაშვებულია ფონურ რეჟიმში @@ -753,8 +755,8 @@ ინფორმაცია დღეღამის შესახებ რენდერის ატრიბუტები ეკრანის გამართვა - ბილიკების ჩვენება - მოუკირწყლავი გზებისათვის თავის არიდება + ბილიკები + მოუკირწყლავი გზებისათვისთვის თავის არიდება ბორნისათვის თავის არიდება თავის არიდება… გაფრთხილებების ჩვენება… @@ -762,7 +764,7 @@ მანათობელი გზები სახაზავის ჩვენება ხედვის მიმართულება - გამჭირვალე ხედი + გამჭირვალე ღილაკები გაგრძელებადი ელ-ფოსტა მზის ამოსვლა: %1$s \nჩასვლა: %2$s @@ -788,19 +790,19 @@ გთხოვთ ჩართოთ GPS ჟურნალირების სერვისები გზა ვერ მოიძებნა - გზის სანიშნის მოცილება - გზის სანიშნი %1$s - გზის სანიშნი %1$s - გზის ბოლო ნიშნის დამატება - გზის პირველი წერტილის დამატება - გზის ბოლო წერტილის დამატება - გზის პირველი წერტილის დამატება + დანიშნულების წერტილის წაშლა + დანიშნულების წერტილი %1$s + შუალედური დანიშნულების წერტილი %1$s + დანიშნულების წერტილის ბოლო ნიშნის დამატება + დანიშნულების ადგილის პირველი წერტილის დამატება + დანიშნულების ადგილის ბოლო წერტილის დამატება + დანიშნულების ადგილის პირველი წერტილის დამატება დანიშნულების წერტილის შეცვლა თქვენ უკვე მიუთითეთ დანიშნულების წერტილი: გზის ნიშნულები - გზის ნიშნანი %1$s მეტისმეტად შორსაა უახლოესი გზიდან. + დანიშნულების წერტილი %1$s მეტისმეტად შორსაა უახლოესი გზიდან. თქვენ მიაღწიეთ თქვენს დანიშნულების წერტილს - გზის წერტილად დამატება + შუალედურ დანიშნულების წერტილად დამატება საბოლოო წერტილი მეტისმეტად სორსაა უახლოესი გზიდან. ჭდის დამატება ზუსტი რეჟიმი… @@ -815,7 +817,7 @@ ნავიგაციისას პიზიციის გზებისათვის მიბმა. გზისთვის მიბმა OsmAnd არის ნავიგაციის აპლიკაცია ღია წყაროთი გათიშული და ონლაინ რუკების მხარდაჭერით - გზის წერტილი + შუალედური დანიშნულების პუნქტი აუდიო/ვიდეო მონაცემები დარწმუნებული ბრძანდებით რომ გნებავთ ნავიგაციის შეწყვეტა? დარწმუნებული ბრძანდებით რომ გნებავთ გაასუფთაოთ თქვენი დანიშნულების წერტილი? @@ -1251,7 +1253,7 @@ აირჩიეთ საიმპორტო პუნქტები. Mapillary-ში დამატება OpenPlaceReviews-ში დამატება - + თვალთვალი გზის ჩაწერა ჯგუფის ჩასწორება @@ -1798,4 +1800,402 @@ პირადი შემობრუნება თეთრი + %1$d გადმოწერა + ბილიკების ჩვენება + ბილიკების დამალვა + ბილიკების ჩვენება/დამალვა + გამოსვლა + %1$s-ით + ნაჩვენები ბილიკები + მეტის ჩვენება + წინა გზა + სამსახურის დამატება + სახლის დამატება + შუალედური დანიშნულების წერტილები + ხმოვანი დახმარება + ნავიგაციის სიმულაცია + საზოგადოებრივი ტრანსპორტი + გზის დათვლა… + ფეხით + შუალედური წერტილი + შუალედურის დამატება + დანიშნულების პუნქტის დაყენება + ღამის რეჟიმი + დღის რეჟიმი + გავუშვა OsmAnd\? + OsmAnd + მოქმედების ჩასწორება + მოგზაურთა გიდები + მოგზაურთა გიდები + გზისთვის თვალყურის დევნება + გზისთვის თვალყურის დევნება + GPX ფაილი + შუალედური დრო + ყველას გადმოწერა + სურათების ჩვენება + აპლიკაციის რესტარტი + OsmAnd-ის ჯგუფი + პოპულარული ადგილები + ფასიანი დამატება + ფასიანი აპლიკაცია + ეს რეგიონი + ჩასწორების დაწყება + ფაილის გადმოწერა + განახლება ხელმისაწვდომია + გათიშული Wikipedia + ულიმიტო გადმოწერები + ერთხელ გადახდა + აირჩიეთ გეგმა + სურათების გადმოწერა + მოგზაურობის წიგნაკი + სურათების გადმოწერა + სურათების კეში + ტურისტული გიდები + სტატია წაშლილია + დამახსოვრებული სტატიები + ჯგუფი წაშლილია + ახლოდან დაწყება + ბოლოდან დაწყება + შეიყვანეთ განედი + შეიყვანეთ გრძედი + რუკა იმპორტირებულია + წინ გვირაბია + OSM სანიშნები + ყველა მონაცემი + თვითგამოცხადების პერიოდი + ჭკვიანი თვითგამოცხადება + აირჩიეთ პროფილი, რომელიც გამოყენებული იქნება აპლიკაციის სტარტისას. + საფეხმავლო ბილიკებისთვის პრიორიტეტის მიცემა + საფეხმავლო ბილიკებისთვის პრიორიტეტის მიცემა + არხების და ნაკადულების ჩვენება + არხების და რუების ჩვენება + საზღვაო მილი + POI-ის ატვირთვა + მოქმედების წაშლა + მოქმედების შეცვლა + მოქმედების შექმნა + მანამდე სანახავი + შემდეგ სანახავი + მარშრუტის წერტილები + საცობი იწოვება + არა-საავტომობილო გზები + გაყოფის ინტერვალი + ბორცვების შემცველი შრე + მარკერების ისტორია + GPX ფაილის OpenStreetMap-ში გაგზავნა + შეიყვანეთ მძიმით დაცილებული ჭდეები. + OSM სანიშნის დახურვა + სურათის ატვირთვა შეუძლებელია. გთხოვთ, სცადოთ მოგვიანებით + გთხოვთ მონიშნოთ ფაილში ჩასაწერი მონაცემები. + ადგილი საკმარისი არაა + ყველა წერტილის რევერსი + GPS ფაილი ცარიელია + უკანა გზა + მთლიანი გზა + შემდეგი ნაწილი + ნავიგაციის პროფილი + სასრიალო + უკრაინული + ფაილის ტიპის არჩევა + OSC ფაილი + უსახელო მდებარეობა + POI ჭდეები + სახელის გარეშე + იღება + იღება + შემოწირულობები სულ + ტიპით + თარიღით + ჩაინიშნეთ! + ჯგუფების იმპორტი + რჩეულების კატეგორია + შემდეგი ველი + სანიშნის სახელის გადარქმევა + გავლილად მონიშვნა + მთელს ეკრანზე + ფაილის იმპორტი + არასწორი მონაცემები + არასწორი ფორმატი + წინ და უკან + გზა დათვლილია + რუკის ჩვენება + მუქი ნარინჯისფერი + შენიშვნის ჩასწორება + კოორდინატების ფორმატი + კოორდინატების შეყვანა + გზის გეგმა + ჩემი მდებარეობა + პოზიციის გამოყენება + გავლილის დამალვა + გავლილის ჩვენება + დალაგება: + წელს + გააქტიურება + დალაგება + დაშორების მაჩვენებელი + წერტილის გადაადგილება + რჩეულის დამატება + ხაზის დამატება + ხაზის ჩასწორება + გზის წერტილი + GPX ფაილის სახელი: + მანძილის გაზომვა + ნავიგაციის დაწყება/დასრულება + ნავიგაციის პაუზა/გაგრძელება + გამჭირვალე ვარდისფერი + რადიუსის მზომავი + შეიყვანეთ მომხმარებელი + არასწორი მომხმარებლის სახელი + Mapillary-ის გახსნა + ონლაინ სურათები + %1$s-ში + საზღვაო რუკები + შეძენების აღდგენა + მარჯვენასაჭიანი მოძრაობა + პარკინგის პარამეტრები + არასწორი OLC +\n + რუკის წყაროები + შრის დამატება + რუკის შრეები + რუკის სტილი + POI-ის სია + რუკის გამართვა + %1$s-ის დამალვა + %1$s-ის ჩვენება + POI-ს ჩვენება/დამალვა + რჩეულების დამალვა + რჩეულების ჩვენება + რჩეულების ჩვენება/დამალვა + მოქმედების წაშლა + მოქმედების დამატება + რჩეულის დამატება + მოქმედების ჩასწორება + მოქმედების დამატება + ხმის გაჩუმება + გაჩუმების გამორთვა + ხმის ჩართვა/გამორთვა + POI-ს დამატება + ეკრანი %d + მოქმედება %d + სწრაფი მოქმედება + წყლის დამალვა + ჩინური (ტრადიციული) + ჩინური (გამარტივებული) + ბელარუსული (ლათინური) + სერბული (ლათინური) + POI-ს ატვირთვა + გზის ანგარიში + მეტის დამატება… + მონაცემები არაა + საშობაო POI + მუქი ყავისფერი + ღია ყავისფერი + სახელების ტრანსლიტერაცია + კატეგორიების ჩასწორება + არჩეული კატეგორიები + ახალი ფილტრი + ფილტრის წაშლა + ფილტრის შენახვა + ფილტრები + მიწისქვეშა ობიექტები + წაშლილია + წაშლილია + გზა დაბლოკილია + POI ხატულები + ყველაფრის გაუქმება + საწყისი წერტილი + განახლების ზომა + არჩეული არაა + მეხსიერების ზომა + კლიპის სიგრძე + განახლების დრო + ხელმისაწვდომი რუკები + განახლებები მიმდინარე რეჟიმში + ახლა განახლება + ცოცხალ რეჟიმში განახლება + კიბეების თავიდან აცილება + არა კიბეები + მენიუს გამოყენება + ხელსაწყოების პანელის გამოყენება + გზის ტიპი + GPX-ს სიგანე + GPX ფერი + შენიშვნა დახურულია + შენიშვნა შექმნილია + შენიშვნის დახურვა + შენიშვნის თავიდან გახსნა + კომენტარის დამატება + შენიშვნის შექმნა + OSM შენიშვნა + ალბანური (ტოსკა) + ქვედა გერმანული + მეტის წაკითხვა + შეთავაზებული ობიექტები + რუკის აღწერა + ტექნიკური სტატიები + რუკის თვალიერება + პირველი გაშვება + ახალი ვერსია + QR კოდი + რუკის ჩვენება + რუკა გადმოწერილია + მდებარეობის გაზიარება + %.1f მბ + კატეგორიის სახელი + მსოფლიო რუკები + რეგიონალური რუკები + სრული ვერსია + კატეგორია + ახლის დამატება + მოგზაურობის ჩაწერა + ინფორმაცია რჩეულის შესახებ + რჩეულის დამატება + ახლახანს მონახულებული ადგილები + სამუშაო დღეები + POI-ს ტიპი + საკონტაქტო ინფორმაცია + იკეტება + იღება + შენობის ნომერი + ხელსაწყოთა პანელის გამართვა + შეცდომა: {0} + კიდევ სცადეთ + ატვირთულია {0}/{1} + ცვლილების წაშლა + დეტალების ჩვენება + გასვლა + სიმაღლის ლიმიტი + სახლების ნომრები + რუკების საცავი + შიდა მეხსიერება + ხელით მითითებული + მრავალმომხმარებლიანი საცავი + გარე მეხსიერება + აღწერის ჩვენება. + არ გამოიყენო + ინფორმაცია A-GPS-ის შესახებ + რუკების გადმოწერა + მიმდინარე გზა + გნებავთ ისტორიის გასუფთავება\? + თქვენს მიერ ჩასწორებული + OSM-ის ჩასწორებები + ძირითადი პარამეტრები + ნავიგაციის პარამეტრები + მთლიანი სია + ჩემი ადგილები + ჩემი მდებარეობა + ყველას ჩვენება + მოქმედება {0} + გაუთვალისწინებელი შეცდომა + შენიშვნის მოხსნა + გზის წერტილები + გზის ნაწილები + სახელის გადარქმევა შეუძლებელია. + შენიშვნის გაზიარება + ონლაინ რუკა + A/V შენიშვნები + გაფრთხილება საცობის შესახებ + კალათა + ჩასადები + ნივთები + დღე გავიდა + მხოლოდ გზები + სასრიალო ქანობები + მოწყობილობის მეხსიერება + თავისუფალია %1$s + თხილამურების მოვლა + პარკინგის ადგილი + ხმოვანი მოთხოვნები + სტატუსის ველი + ჟურნალიზაციის ინტერვალი + მოგზაურობის ჩაწერა + მიწისქვეშა გზები + ადგილობრივი სახელები + გზის წერტილები: %1$s + ქვეგზები: %1$s + წყლის დონე + მისამართები + საწვავის დასაზოგი გზა + უჯრა + უგზო ადგილი + მონიშნული გზა + გზა + გზები + გზები + გაკეთება + შიგნით + სია + პარამეტრები + თავიდან + თავიდან ჩატვირთვა + Mapillary + დამატება + დაპაუზებული + ხილვადი + გაფრთხილებები + ღილაკები + მართვის პანელი + დამატებები + გზები + დამატებები + გადაცილებულია + + გადმოწერა + ქვევერსია + პროქსი + ადგილობრივი + შიგნით + იგივეს დატოვება + უკვე მაქვს ანგარიში + ძებნის ისტორია + უფლების მინიჭება + თავისუფალი ადგილი + რუკების ძებნა… + დავიწყოთ + მიწისზედა ობიექტები + კოორდინატების ძებნა + სორბული (ზედა) + ღიაა 24/7 + ღიაა + მეხსიერების ბარათი + კოორდინატების ფორმატი + ესპანური (ამერიკული) + მიმდინარე ბილიკი + უნგრული (ზრდილობიანი) + ტაქტილური მიმართულებები + მაგნიტური დამჭერი + დაყენებული არაა + ხეების სია + გაშლილი სია + ცარიელი სია + სიის ჩამოშლა + შეიყვანეთ აღწერა. + შეიყვანეთ კატეგორია + შეიყვანეთ სახელი + აირჩიეთ კატეგორია + ნაგულისხმევი ფერი + რუკის რეჟიმი + სრული ანგარიში + გადატანა ↓ + ნავიგაციის დასრულება + გზის თავიდან აცილება + ზიარი მეხსიერება + ზედა პანელი + გზის გადათვლა + გამოწერის პარამეტრები + თვიური გადასახადი + ხარდაჭერილი რეგიონი + საზოგადო სახელი + სხვა სანიშნები + ანონიმურად ატვირთვა + რუკის სანიშნი + რუკის სანიშნები + აქტიური სანიშნები + მიმდევრობის შებრუნება + პოლიგონების ჩვენება + პარკინგის პოვნა + ცვლილებების შენახვა + ელ-ფოსტა + მეტის წაკითხვა \ No newline at end of file From 11f70f63abd3e86fd77beb8ec300d1bc29952df4 Mon Sep 17 00:00:00 2001 From: ace shadow Date: Sun, 3 Jan 2021 20:02:34 +0000 Subject: [PATCH 15/61] Translated using Weblate (Slovak) Currently translated at 100.0% (3591 of 3591 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 ca4436bcc3..27d1976a65 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -4027,4 +4027,5 @@ Povoliť potoky a odtokové kanály Povoliť dočasné vodné toky Povoliť dočasné vodné toky + Časy hlasových pokynov \ No newline at end of file From eccf0cbe18548ff7a2d0e886e300ef6f5465e490 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sun, 3 Jan 2021 05:13:34 +0000 Subject: [PATCH 16/61] Translated using Weblate (Hebrew) Currently translated at 99.9% (3590 of 3591 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 90f56acd71..9b60953f9d 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4031,4 +4031,5 @@ לאפשר מקטעים עם דרכי מים עונתיים „ציבורי” משמעו שהעקבות מופיעים באופן ציבורי בעקבות ה־GPS שלך וברישומי עקבות GPS ציבוריים וברישומי מעקב ציבוריים עם חותמות זמן בתצורה גולמית. הנתונים שמוגשים דרך ה־API אינם מפנים אל עמוד העקבות שלך. חותמות הזמן של נקודות המעקב אינן זמינות דרך ה־API של ה־GPS ונקודות המעקב אינן מסודרות בהתאם לזמן שתועדו. „פרטי” משמעות שהעקבות לא תופענה ברישומים ציבוריים אך נקודות מעקב ממתוכן תהיינה זמינות בסדר אקראי דרך ה־API הציבורי של ה־GPS ללא חותמות זמן. + זמני הכרזות \ No newline at end of file From 67041ec0828660763fe71ae7e45a4f0a9f40f007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Sun, 3 Jan 2021 20:58:26 +0000 Subject: [PATCH 17/61] Translated using Weblate (Czech) Currently translated at 97.7% (3511 of 3591 strings) --- OsmAnd/res/values-cs/strings.xml | 94 ++++++++++++++++---------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 6cbc3a9714..3159e5591a 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -1,6 +1,6 @@ - Off-line vektorová mapa pro toto místo není dostupná. Stáhněte jí v \'Nastavení\' (\'Stáhnout mapy\'), nebo se přepněte na modul \'Online mapy\'. + Stáhněte si off-line vektorovou mapu pro tuto oblast v menu \'Nastavení\' (\'Stáhnout mapy\'), nebo se přepněte na modul \'Online mapy\'. Nahrát GPX soubory do OSM? Viditelnost Tagy @@ -24,17 +24,17 @@ sever severoseverovýchod severovýchod - východovýchodosever + východoseverovýchod východ - východovýchodojih + východojihovýchod jihovýchod jihojihovýchod jih jihojihozápad jihozápad - západozápadojih + západojihozápad západ - západozápadosever + západoseverozápad severozápad severoseverozápad vpřed @@ -53,7 +53,7 @@ Podle stran (8 sektorů) Podle hodin (12 sektorů) Styl interpretace směrů - Vyberte způsob vyjádření relativního směru pohybu. + Vyberte způsob vyjádření relativního směru pohybu Spustit automatické ohlašování Zastavit automatické ohlašování Jsem zde @@ -64,16 +64,16 @@ Fluorescentní barvy Použít fluorescentní barvy pro zobrazení cest a tras. Off-line editace - Vždy používat off-line editaci. + Pokud je povolena off-line editace, změny budou nejprve uloženy lokálně a odeslány až na žádost, jinak budou změny odeslány ihned. Změny POI bodů v aplikaci nemají vliv na zobrazení stažených map, změny se ukládají do souboru ve vašem zařízení. Nahrávání… - {0} POI/Poznámek bylo odesláno + {0} POI/poznámek bylo odesláno Odeslat všechny - Odeslat změny do OSM + Odeslat změnu do OSM Smazat změnu Off-line editace OSM: - OSM POI body/poznámky uložené na zařízení - Zobrazit a spravovat OSM POI body/poznámky uložené v databázi na zařízení. + OSM POI/poznámky uložené v zařízení + Zobrazit a spravovat OSM POI/poznámky uložené v databázi v zařízení. Zadejte interval nahrávání pozice na server. Interval přímého přenosu Zadejte webovou adresu serveru pro přímý přenos pozice. Parametry: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}. @@ -97,7 +97,7 @@ Mapy celého světa a tematické mapy Celý svět - Wikipedie Hlasové pokyny (nahrávky, omezené funkce) - Hlasové pokyny (TTS-generované) + Hlasové pokyny (TTS, doporučeno) Wikipedie (off-line) Uživatelsky definované Soubor exportu obsahující Oblíbené již existuje. Nahradit ho\? @@ -110,9 +110,9 @@ Spravovat mapové soubory Stáhnout a spravovat off-line mapy uložené ve vašem zařízení. Obecné - Nastavení displeje, jazyka, zvuku a dalších parametrů. + Nastavení zobrazení a dalších společných parametrů aplikace. Vaše OSM uživatelské jméno - Vaše uživatelské jméno na openstreetmap.org. + Potřebné pro přispívání do openstreetmap.org. Heslo Služba na pozadí OsmAnd běží na pozadí i při vypnuté obrazovce. @@ -139,10 +139,10 @@ Velké město Zastavit simulaci Zapnout animaci - Nelze přejmenovat soubor. - Soubor tohoto jména již existuje. - Vašemu dotazu odpovídá několik kategorií POI: - Lokální data pro vyhledávání POI není dostupný. + Nepodařilo se přejmenovat soubor. + Soubor s tímto názvem již existuje. + Bylo nalezeno několik souvisejících kategorií POI. + Stáhněte si offline data pro vyhledávání POI. Hledat podle jména Soubor s POI daty \'%1$s\' již není potřeba a může být smazán. Lokální soubor pro úpravu POI bodů nebyl nalezen a ani nemohl být vytvořen. @@ -168,7 +168,7 @@ Více mapových detailů Zobrazit některé detaily vektorové mapy (silnice, atd.) již při menším zvětšení. Oblíbené body smazány. - Chystáte se smazat %1$d Oblíbených a %2$d skupin Oblíbených. Opravdu smazat\? + Opravdu chcete smazat %1$d Oblíbených a %2$d skupin Oblíbených\? Doma Přátelé Místa @@ -194,7 +194,7 @@ Mapová data Záloha Hlasové pokyny (TTS) - Hlasové pokyny (media) + Hlasové pokyny (nahrané) On-line mapy a dlaždice v mezipaměti Standardní mapy (vektorové) Data POI @@ -248,25 +248,25 @@ Vyberte jeden z balíčků OsmAnd k nainstalování Speciální aktivita pro vývojovou verzi Nové hledání - Zvolte velikost písma ve jménech na mapě. + Velikost písma pro názvy na mapě: Velikost písma Rozbalování nových dat… - On-line navigaci nelze použít, protože připojení k Internetu není k dispozici. + On-line navigaci nelze použít bez připojení k internetu. Nepodporovaný jazyk - Vybraný jazyk není podporován nainstalovaným TTS enginem. Najít jiný TTS v obchodě\? Jinak bude použit výchozí TTS jazyk. + Vybraný jazyk není podporován nainstalovaným TTS (text-to-speech) modulem Androidu. Bude použit výchozí TTS jazyk. Najít jiný TTS modul v obchodě\? Chybějící data Přejít do obchodu pro stažení vybraného jazyka\? - Obrátit GPX trasu + Obrátit směr stopy Použít současný cíl trasy Projet celou trasu Pro tuto oblast je k dispozici offline vektorová mapa. -\t -\t Pro zobrazení zvolte Menu → Nastavení mapy → Zdroj map… → Vektorové off-line mapy. +\n\t +\n\tPro zobrazení zvolte Menu → Nastavení mapy → Zdroj map… → Vektorové off-line mapy. Kanál pro navádění - Zvolte kanál poskytující hlasové navádění. + Zvolte reproduktor pro hlasové navádění. Zvuk telefonního hovoru (přeruší Bluetooth autorádio) Upozornění - Média/Zvuk navigace + Média/zvuky navigace Data pro mapovou vrstvu %1$s nelze stáhnout, reinstalace může pomoci. Upravit průhlednost překryvné mapy. Průhlednost překryvu @@ -279,9 +279,9 @@ Překryvná mapa… Žádná Překryvná mapa - Vyberte překryvnou mapu. + Vyberte překryvnou mapu Mapa již nainstalována, \'Nastavení\' budou aktualizována. - Vyberte mapy k instalaci nebo aktualizaci. + Vyberte (dlaždicové) mapy k instalaci nebo aktualizaci. Nelze provést tuto akci bez připojení k Internetu. Instalovat další… Použít rastrové mapy pro cokoli nad tuto úroveň. @@ -289,7 +289,7 @@ Nelze provést offline hledání. Hledat pomocí polohy Podle systému - Volba jazyka (projeví se jakmile bude OsmAnd restartován). + Jazyk zobrazení aplikace (projeví se po restartu OsmAnd). Jazyk Další Předchozí @@ -310,18 +310,18 @@ GPX bod na trase \'\'{0}\'\' byl přidán Přidat bod na zaznamenávanou GPX trasu Off-line navigace je experimentální a funguje jen pro větší vzdálenosti než 20 km. Navigace je dočasně přepnuta na on-line CloudMade. - Nemohu najít zadaný adresář. + Nepodařilo se najít zadaný adresář. Adresář pro data Aplikace pro zobrazení stavu GPS není nainstalovaná. Hledat v obchodě? Hlasové navádění je nedostupné. Přejděte do „Nastavení“ → „Nastavení navigace“ → „Hlasová data“ a vyberte nebo stáhněte balíček s hlasovými pokyny. - Žádná hlasová data nejsou zvolena + Zvolte balíček hlasových údajů Zaškrtněte pro zobrazení statistik o vykreslování mapy. Sledovat vykreslování Den Noc Východ/západ slunce Senzor osvětlení - Vyberte logiku pro přepínání mezi denním a nočním režimem. + Upravte přepínání mezi denním a nočním režimem. Denní/noční režim Stáhnout {0} souborů ({1} MB)? vybráno {0} položek @@ -332,24 +332,24 @@ Zapněte pro výpočet nejrychlejší trasy nebo vypněte pro ekonomickou trasu. Pro zvětšení {0} je třeba stáhnout {1} mapových dlaždic, celkem {2} MB Stáhnout mapu - Vyberte maximální zvětšení stahovaných map + Maximální přiblížení pro přednačítání Tuto mapu nelze stáhnout Průběžné vykreslování Při zaškrtnuté volbě se mapa bude vykreslovat postupně. - Nelze vykreslit vybranou oblast + Nepodařilo se vykreslit vybranou oblast. Nedostatek paměti pro zobrazení vybrané oblasti Možnosti bodu… Vykreslovač načten - Nepodařilo se načíst vykreslovač + Nepodařilo se načíst vykreslovací modul. Vektorový vykreslovač - Vyberte styl vektorového vykreslování. + Vyberte styl vykreslování Zobrazit webovou stránku bodu Zobrazit telefonní číslo bodu Webová stránka telefon vyhledat Vysoké rozlišení - Použít mapu s vysokým rozlišením pro jemné displeje. + Neroztahovat (a nerozmazávat) mapové dlaždice na displejích s vysokou hustotou bodů. Pozice ještě není známa. Hledat veřejnou dopravu Hledání dopravy (žádný cíl): @@ -358,15 +358,15 @@ Nahrávka hlasu Vektorové mapy nebyly načteny Žádné GPX soubory nebyly nalezeny v adresáři tracks - Nelze načíst GPX data + Nepodařilo se načíst GPX data. Vektorové off-line mapy - Hledat dopravu ze zastávky + Hledat dopravu na zastávce Upravit POI Smazat POI Směr kompasu Směr pohybu Neotáčet (sever vždy nahoru) - Zvolte směr natočení mapy. + Směr natočení mapy: Natočení mapy Ukázat cestu Oblíbená místa importována @@ -374,7 +374,7 @@ Oblíbená místa uložena do {0} Žádná Oblíbená místa k uložení Importovat - Nelze načíst GPX + Nepodařilo se načíst GPX. Odeslat hlášení Na paměťové kartě nelze najít žádné stáhnuté mapy. Psaním hledejte POI @@ -383,7 +383,7 @@ Yandex doprava Cesta Oblíbené - OSM Poznámky (on-line) + OSM poznámky (online) Vrstva POI… Zdroj map… Mapová data @@ -398,9 +398,9 @@ GPS sekund min. - Vyberte interval pro zaměřování polohy pro službu na pozadí. + Interval probuzení pro službu na pozadí: Interval zaměřování GPS - Vyberte způsob získání polohy pro službu na pozadí. + Způsob získání polohy službou na pozadí: Poskytovatel polohy Sleduje vaši pozici i když je obrazovka vypnutá. Sledování polohy na pozadí @@ -415,7 +415,7 @@ Inicializace hlasových dat… Nepodporovaná verze hlasových dat Zvolené hlasové údaje jsou poškozené - Vybraná hlasová data jsou nedostupná + Vybraný balíček hlasových dat není dostupný Paměťová karta není dostupná. \nNeuvidíte mapu a nebudete moci ani nic najít. Paměťová karta má zakázaný zápis. From 11bd4038f39c74bf3097bec75cbc5ff4eb49d73d Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Sun, 3 Jan 2021 16:59:32 +0000 Subject: [PATCH 18/61] Translated using Weblate (Sardinian) Currently translated at 99.7% (3583 of 3591 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 764c40e408..473e0bae95 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -4024,4 +4024,5 @@ Permite flussos e iscàrrigos Permite caminos de abba intermitentes Permite caminos de abba intermitentes + Nùmeru de annùntzios vocales \ No newline at end of file From a6be1025285d4568f1229da02f1a997dad980952 Mon Sep 17 00:00:00 2001 From: Will Owy Date: Sun, 3 Jan 2021 23:27:09 +0000 Subject: [PATCH 19/61] Translated using Weblate (Italian) Currently translated at 76.8% (2984 of 3881 strings) --- OsmAnd/res/values-it/phrases.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OsmAnd/res/values-it/phrases.xml b/OsmAnd/res/values-it/phrases.xml index cf0dcb6921..12ecad8876 100644 --- a/OsmAnd/res/values-it/phrases.xml +++ b/OsmAnd/res/values-it/phrases.xml @@ -2992,4 +2992,24 @@ Freccia Vibrazione Pressione + Moneta souvenir + Drive-through: no + Gobba + Fuoripista + Fuoripista + Bacheca + Segnaletica sentiero + Wiki gujarati + Wiki yoruba + Wiki ciuvascio + Wiki baschiro + wiki tagico + Wiki asturiano-leonese + Wiki chirghisa + Wiki min meridionale + Wiki minangkabau + Wiki waray + Wiki maratino + Wiki malayalam + Wiki frisone occidentale \ No newline at end of file From f8986e366aa85a9d169d0f9604aab9009f12ff78 Mon Sep 17 00:00:00 2001 From: Franco Date: Sun, 3 Jan 2021 01:37:19 +0000 Subject: [PATCH 20/61] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3591 of 3591 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 101029bd57..cb5bb0ca9b 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -4032,4 +4032,5 @@ Permitir arroyos y desagües Permite cursos de agua intermitentes Permitir cursos de agua intermitentes + Tiempo de los avisos por voz \ No newline at end of file From e9813d22497a2160fe5d657e8557b9e111d48a60 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sun, 3 Jan 2021 00:49:06 +0000 Subject: [PATCH 21/61] Translated using Weblate (Esperanto) Currently translated at 100.0% (3591 of 3591 strings) --- OsmAnd/res/values-eo/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 32dfa4de74..bf083e4542 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -4027,4 +4027,5 @@ Permesi riveretojn kaj fosaĵojn Permesi navigi per periode sekiĝantaj akvovojoj Permesi sezonajn akvovojojn + Tempoj de voĉaj anoncoj \ No newline at end of file From 180158616031710ed5ad2043ed7e7a165b9b84c7 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 4 Jan 2021 02:04:02 +0000 Subject: [PATCH 22/61] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3591 of 3591 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 17c657df59..115f04c6d7 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -4022,4 +4022,5 @@ 允許溪流與水溝 允許間歇水路 允許間歇水路 + 語音提示時間 \ No newline at end of file From 589eb8ed371c01f69945089d99f75cdf3fe846eb Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 4 Jan 2021 02:06:55 +0000 Subject: [PATCH 23/61] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3881 of 3881 strings) --- OsmAnd/res/values-zh-rTW/phrases.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml index 8778b0b0b5..d7224cb178 100644 --- a/OsmAnd/res/values-zh-rTW/phrases.xml +++ b/OsmAnd/res/values-zh-rTW/phrases.xml @@ -3898,4 +3898,7 @@ 公共洗衣區 垃圾站 游泳區 + 蝙蝠隧道 + 蝙蝠橋 + 野生動物穿越 \ No newline at end of file From 3e9ef3914b3b3962d00e2803bdd2ad6411cb6523 Mon Sep 17 00:00:00 2001 From: Kseniia Date: Mon, 4 Jan 2021 10:08:10 +0200 Subject: [PATCH 24/61] add filterPoiByType() --- .../java/net/osmand/search/SearchUICore.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java index e63870b1a7..14a4566279 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java @@ -204,6 +204,7 @@ public class SearchUICore { for (SearchResult rs : lstUnique) { same = sameSearchResult(rs, r); if (same) { + filterPoiByType(rs, r, lst); break; } } @@ -217,6 +218,24 @@ public class SearchUICore { } } } + + private void filterPoiByType(SearchResult r1, SearchResult r2, List list) { + if (r1.object instanceof Amenity) { + + Amenity a1 = (Amenity) r1.object; + Amenity a2 = (Amenity) r2.object; + + if (!(a2.getSubType().equals("building") || a2.getSubType().contains("internet")) + && (a1.getSubType().equals("building") || a1.getSubType().contains("internet"))) { + + int index = list.indexOf(r1); + + if (list.contains(r1)) { + list.set(index, r2); + } + } + } + } public boolean sameSearchResult(SearchResult r1, SearchResult r2) { if (r1.location != null && r2.location != null && @@ -244,10 +263,16 @@ public class SearchUICore { String type2 = a2.getType().getKeyName(); String subType1 = a1.getSubType(); String subType2 = a2.getSubType(); - if(a1.getId().longValue() == a2.getId().longValue() && (subType1.equals("building") || subType2.equals("building"))) { + + if (a1.getId().longValue() == a2.getId().longValue() + && ((subType1.equals("building") || subType2.equals("building")))) { return true; } if (!type1.equals(type2)) { + if (a1.getId().longValue() == a2.getId().longValue() && subType1.contains("internet") + || subType2.contains("internet")) { + return true; + } return false; } if (type1.equals("natural")) { From 6dce77097e5370d4f7384a13e5c1cef8a2251eb2 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 4 Jan 2021 18:01:22 +0500 Subject: [PATCH 25/61] Fix #10509 Opt out of sending metrics to Google when using WebView --- OsmAnd/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index 025b1ce53c..03556d73cb 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -63,7 +63,8 @@ - + + From 29edac0125e9b92b5e54c0a3e1a11dddb4053735 Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 5 Jan 2021 12:36:02 +0200 Subject: [PATCH 26/61] add option to copy address; --- OsmAnd/res/values/strings.xml | 1 + .../osmand/plus/mapcontextmenu/other/ShareMenu.java | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a78818557b..fb403c340c 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + Copy address Allow intermittent water ways Allow intermittent water ways Allow streams and drains diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java index 7323e52b5d..aba6ca8277 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java @@ -36,6 +36,7 @@ public class ShareMenu extends BaseMenuController { public enum ShareItem { MESSAGE(R.drawable.ic_action_message, R.string.shared_string_send), CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy), + ADDRESS(R.drawable.ic_action_copy, R.string.copy_address), NAME(R.drawable.ic_action_copy, R.string.copy_location_name), COORDINATES(R.drawable.ic_action_copy, R.string.copy_coordinates), GEO(R.drawable.ic_world_globe_dark, R.string.share_geo), @@ -66,6 +67,7 @@ public class ShareMenu extends BaseMenuController { List list = new LinkedList<>(); list.add(ShareItem.MESSAGE); list.add(ShareItem.CLIPBOARD); + list.add(ShareItem.ADDRESS); list.add(ShareItem.NAME); list.add(ShareItem.COORDINATES); list.add(ShareItem.GEO); @@ -121,6 +123,15 @@ public class ShareMenu extends BaseMenuController { case CLIPBOARD: ShareDialog.sendToClipboard(mapActivity, sms); break; + case ADDRESS: + if (!Algorithms.isEmpty(address)) { + ShareDialog.sendToClipboard(mapActivity, address); + } else { + Toast.makeText(mapActivity, + R.string.no_address_found, + Toast.LENGTH_LONG).show(); + } + break; case NAME: if (!Algorithms.isEmpty(title)) { ShareDialog.sendToClipboard(mapActivity, title); From b9339cdab55bd43a1a973671c99ee8ad4b26cb99 Mon Sep 17 00:00:00 2001 From: Kseniia Date: Tue, 5 Jan 2021 15:11:14 +0200 Subject: [PATCH 27/61] fix filter by building and internet poi --- .../java/net/osmand/search/SearchUICore.java | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java index 14a4566279..573068d207 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java @@ -204,7 +204,6 @@ public class SearchUICore { for (SearchResult rs : lstUnique) { same = sameSearchResult(rs, r); if (same) { - filterPoiByType(rs, r, lst); break; } } @@ -218,24 +217,6 @@ public class SearchUICore { } } } - - private void filterPoiByType(SearchResult r1, SearchResult r2, List list) { - if (r1.object instanceof Amenity) { - - Amenity a1 = (Amenity) r1.object; - Amenity a2 = (Amenity) r2.object; - - if (!(a2.getSubType().equals("building") || a2.getSubType().contains("internet")) - && (a1.getSubType().equals("building") || a1.getSubType().contains("internet"))) { - - int index = list.indexOf(r1); - - if (list.contains(r1)) { - list.set(index, r2); - } - } - } - } public boolean sameSearchResult(SearchResult r1, SearchResult r2) { if (r1.location != null && r2.location != null && @@ -263,7 +244,7 @@ public class SearchUICore { String type2 = a2.getType().getKeyName(); String subType1 = a1.getSubType(); String subType2 = a2.getSubType(); - + if (a1.getId().longValue() == a2.getId().longValue() && ((subType1.equals("building") || subType2.equals("building")))) { return true; @@ -275,6 +256,7 @@ public class SearchUICore { } return false; } + if (type1.equals("natural")) { similarityRadius = 50000; } else if (subType1.equals(subType2)) { @@ -1012,16 +994,20 @@ public class SearchUICore { // here 2 points are amenity Amenity a1 = (Amenity) o1.object; Amenity a2 = (Amenity) o2.object; - String type1 = a1.getType().getKeyName(); - String type2 = a2.getType().getKeyName(); - int cmp = c.collator.compare(type1, type2); - if (cmp != 0) { - return cmp; - } - + String subType1 = a1.getSubType() == null ? "" : a1.getSubType(); String subType2 = a2.getSubType() == null ? "" : a2.getSubType(); - cmp = c.collator.compare(subType1, subType2); + + int cmp; + + if(subType1.equals("building") || subType1.contains("internet")) { + cmp = 1; + } else if(subType2.equals("building") || subType2.contains("internet")) { + cmp = -1; + } else { + cmp = c.collator.compare(subType1, subType2); + } + if (cmp != 0) { return cmp; } From 29b71365756fa124048d0cc4daa226662b387202 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 5 Jan 2021 15:17:26 +0200 Subject: [PATCH 28/61] Fix map link parsing --- OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java index b8e176529a..e4e6fac9dd 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java @@ -90,7 +90,7 @@ public class IntentHelper { String zoom = data.getQueryParameter("z"); int z = settings.getLastKnownMapZoom(); if (zoom != null) { - z = Integer.parseInt(zoom); + z = (int) Double.parseDouble(zoom); } settings.setMapLocationToShow(lt, ln, z, new PointDescription(lt, ln)); } catch (NumberFormatException e) { From 2fb22fbf2f3369a011036785a02d5d71fd0e0cd2 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 5 Jan 2021 16:07:31 +0200 Subject: [PATCH 29/61] Fix #10437 --- .../layout/fragment_wikivoyage_article_dialog.xml | 1 + OsmAnd/src/net/osmand/AndroidUtils.java | 12 ++++++++++++ .../src/net/osmand/plus/activities/ExitActivity.java | 2 ++ .../osmand/plus/activities/PrintDialogActivity.java | 3 ++- .../plus/dialogs/HelpArticleDialogFragment.java | 1 + .../osmand/plus/mapillary/MapillaryImageDialog.java | 1 + .../plus/wikipedia/WikipediaDialogFragment.java | 3 +-- .../article/WikivoyageArticleDialogFragment.java | 1 + 8 files changed, 21 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml index 232e041b75..c001ab748e 100644 --- a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml +++ b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml @@ -63,6 +63,7 @@ android:layout_width="match_parent" android:layout_weight="1" android:layout_height="0dp"> + = Build.VERSION_CODES.N) { + OsmandApplication app = (OsmandApplication) activity.getApplicationContext(); + app.checkPreferredLocale(); + activity.getResources().updateConfiguration( + new Configuration(app.getResources().getConfiguration()), + activity.getResources().getDisplayMetrics()); + } + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java b/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java index 67beabb1ad..5097a4f0cc 100644 --- a/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java @@ -1,5 +1,6 @@ package net.osmand.plus.activities; +import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import android.app.Activity; @@ -14,6 +15,7 @@ public class ExitActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.help_activity); + AndroidUtils.fixWebViewResetsLocaleToUserDefault(this); dis = getIntent().getBooleanExtra(DISABLE_SERVICE, true); } diff --git a/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java b/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java index 6c7e4d6579..b2211a639d 100644 --- a/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java @@ -3,7 +3,7 @@ */ package net.osmand.plus.activities; -import android.view.Window; +import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import android.annotation.SuppressLint; @@ -43,6 +43,7 @@ public class PrintDialogActivity extends ActionBarProgressActivity { getSupportActionBar().setTitle(R.string.print_route); setContentView(R.layout.print_dialog); + AndroidUtils.fixWebViewResetsLocaleToUserDefault(this); webView = (WebView) findViewById(R.id.printDialogWebview); Intent intent = getIntent(); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java index 42a036599c..3c47372356 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java @@ -54,6 +54,7 @@ public class HelpArticleDialogFragment extends DialogFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_help_article, container, false); + AndroidUtils.fixWebViewResetsLocaleToUserDefault(getActivity()); Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); toolbar.setNavigationIcon(AndroidUtils.getNavigationIconResId(getContext())); diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java index 7b9cd23b69..d20f03f4fe 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java @@ -220,6 +220,7 @@ public class MapillaryImageDialog extends ContextMenuCardDialog { @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) private View getWebView() { View view = getMapActivity().getLayoutInflater().inflate(R.layout.mapillary_web_view, null); + AndroidUtils.fixWebViewResetsLocaleToUserDefault(getMapActivity()); final WebView webView = view.findViewById(R.id.webView); webView.setBackgroundColor(Color.argb(1, 0, 0, 0)); final View noInternetView = view.findViewById(R.id.mapillaryNoInternetLayout); diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java index 72ea3560cb..1ea89040cd 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java @@ -17,7 +17,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.webkit.WebSettings; -import android.webkit.WebView; import android.widget.ImageView; import android.widget.TextView; @@ -28,7 +27,6 @@ import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.Toolbar; import androidx.browser.customtabs.CustomTabsIntent; import androidx.core.content.ContextCompat; -import androidx.core.view.MotionEventCompat; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -74,6 +72,7 @@ public class WikipediaDialogFragment extends WikiArticleBaseDialogFragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View mainView = inflater.inflate(R.layout.wikipedia_dialog_fragment, container, false); + AndroidUtils.fixWebViewResetsLocaleToUserDefault(getActivity()); setupToolbar((Toolbar) mainView.findViewById(R.id.toolbar)); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index 9303fb7b84..bc322b31fe 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -91,6 +91,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme } final View mainView = inflate(R.layout.fragment_wikivoyage_article_dialog, container); + AndroidUtils.fixWebViewResetsLocaleToUserDefault(getActivity()); setupToolbar((Toolbar) mainView.findViewById(R.id.toolbar)); From e482971f65de05e38df95d9a27a57c818f2ad5bf Mon Sep 17 00:00:00 2001 From: Mehmet Akif Dokuzoglu Date: Mon, 4 Jan 2021 08:54:43 +0000 Subject: [PATCH 30/61] Translated using Weblate (Turkish) Currently translated at 100.0% (3591 of 3591 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 76669e85df..6b794136f0 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3982,4 +3982,5 @@ Dere ve kanalizasyonlara izin ver Aralıklı su yollarına izin verin Aralıklı su yollarına izin ver + Sesli uyarı zamanı \ No newline at end of file From 319f397a512eb07231c1437d07f2a1c24ab15d6e Mon Sep 17 00:00:00 2001 From: Exum Solem Date: Mon, 4 Jan 2021 12:55:40 +0000 Subject: [PATCH 31/61] Translated using Weblate (Spanish) Currently translated at 100.0% (3591 of 3591 strings) --- OsmAnd/res/values-es/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 484933e2aa..ae61a43fae 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -4019,4 +4019,5 @@ Permitir arroyos y desagües Permitir arroyos y desagües Permitir vías de agua intermitentes + Tiempo de indicaciones por voz \ No newline at end of file From 8e6df772be6a66c67db484a263e0074f9a34556f Mon Sep 17 00:00:00 2001 From: Temuri Doghonadze Date: Mon, 4 Jan 2021 16:30:53 +0000 Subject: [PATCH 32/61] Translated using Weblate (Georgian) Currently translated at 65.2% (2344 of 3591 strings) --- OsmAnd/res/values-ka/strings.xml | 152 +++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/OsmAnd/res/values-ka/strings.xml b/OsmAnd/res/values-ka/strings.xml index 517a391d20..a39fb02b7b 100644 --- a/OsmAnd/res/values-ka/strings.xml +++ b/OsmAnd/res/values-ka/strings.xml @@ -2198,4 +2198,156 @@ ცვლილებების შენახვა ელ-ფოსტა მეტის წაკითხვა + OAuth-ით შესვლა + ლოკალური რუკები + OpenStreetMap-ზე შესვლა + გთხოვთ, შეხვიდეთ OpenStreetMap.org-ზე + გამოიყენეთ მომხმარებელ და პაროლი + გამოწერის მართვა + OpenPlaceReviews.org-ზე +\nრეგისტრაცია + რუკები, როლებიც შეიძლება დაგჭირდეთ + სტატია ნაპოვნი არაა + ვიკიპედიის მონაცემების გადმოწერა + ულიმიტო წვდომა + რუკების საათობრივი განახლება + რუკების თვიური განახლება + %1$s - ის ყიდვა + მხოლოდ Wifi-ზე + მხოლოდ Wifi-ზე + OSM-ის მომხმარებელი და პაროლი + ხაზად შენახვა + გზის წერტილი 1 + %2$d %1$d-დან + ბოლოს ჩასწორებული + აირჩიეთ სიგანე + მიმართულების ისრები + მოტოციკლი Enduro + მოტორიანი სკუტერი + Mapillary-ის ჩვენება/დამალვა + Mapillary-ის დამალვა + Mapillary-ის ჩვენება + წავშალოთ ყველა\? + ეკრანის კონტროლი + ნავიგაციის ინსტრუქციები + ჩართვის ღილაკი + SQLiteDB ფაილი + ვადა + საცავის ფორმატი + პროფილის დამატება + პარკინგის ადგილები + სწრაფი მოქმედება + რადიუსის მზომი + მანძილის გაზომვა + რუკის სანიშნები + OsmAnd-ის შესყიდვები + ნავიგაციის პროფილები + დამატებითი რუკები + %1$s, %2$s + ყველა ენა + რენდერის სტილი + კუთხე: %s° + მინიმალური გადაადგილება + მინიმალური სიზუსტე + მინიმალური სიჩქარე + Web მისამართი + გზის გადათვლა + ჟურნალის სიზუსტე + პროფილის იმპორტი + %1$s: %2$s + %1$s-%2$s + არჩეული პროფილი + პროფილის გარეგნობა + პროფილის ჩასწორება + აირჩიეთ ფერი + მთავარი პროფილი + %s-ის გადმოწერა + სეგმენტების შეერთება + გამორთვა + დამატებული პროფილები + აირჩიეთ ხატულა + სამარშრუტო ავტობუსი + ნავიგაციის ტიპი + პროფილის სახელი + არა, მადლობა + ნანახი ეკრანები + გადმოწერილი რუკები + კორდინატების ღილაკი + GPS-ის ძებნა + ტრანსპორტის ტიპი + არ გადააადგილო + რუკების გადაადგილება + ჟურნალის გაგზავნა + ბორნების არიდება + ბორნების გარეშე + მიწისქვეშა გადასასვლელების გარეშე + მატარებლის არიდება + მატარებლის გარეშე + ავტობუსების გარეშე + ტრამვაის არიდება + ტრამვაის გარეშე + კუთის საზომი ერთეული + %s რეჟიმი + საწყისი წერტილი + პროფილის იმპორტი + პროფილის ექსპორტი + ბორცვების დამალვა/ჩვენება + ბორცვების დამალვა + ბორცვების ჩვენება + %1$s კბ + %1$s მბ + %1$s გბ + %1$s ტბ + სიგანის ლიმიტი + თხილამურის სიძნელე + თხილამურის ტიპი + ნაგულისხმევად + მანქანის პარამეტრები + OsmAnd-ის გამართვა + პროფილის გადართვა + პროფილის გამართვა + ნავიგაციის გამართვა + დაყენებული დამატებები + რუკის ხედი + რუკის გარეგნობა + შეტყობინება ჩართვისას + ცვლილების გაუქმება + პარამეტრის შეცვლა + UTM სტანდარტი + გამოწერის გაუქმება + მაშინ %1$s + 3 თვე + სალაშქრო მანქანა (RV) + ღია გზა + ზედაპირის სიმყარე + უმეტესად რბილი + უმეტესად მყარი + მყარი (მოუკირწყლავი) + მყარი (დაგებული) + მოყინული გზა + ზამთრის გზა + გზის ტიპი + გზის ტიპები + მეხუთე დონე + მეოთხე დონე + მესამე დონე + მეორე დონე + პირველი დონე + პირადი გადამყვანი + ახალი პროფილი + ნაგულისხმევი სიჩქარე + მაქს. სიჩქარე + მინ. სიჩქარე + შეგროვებული მონაცემები + სასრიალო ტურიზმი + აპლიკაციის პროფილები + BRouter (გათიშული) + სწორი ხაზი + პლანერი + პროფილის წაშლა + ცვლილებების შენახვა + სახელი უკვე არსებობს + ბაზური პროფილი + ტიპი: %s + რეჟიმი: %s \ No newline at end of file From 3dd3870faa333cff3c259cd4d87e0df0befc3dd6 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Mon, 4 Jan 2021 06:59:53 +0000 Subject: [PATCH 33/61] Translated using Weblate (Arabic) Currently translated at 100.0% (3591 of 3591 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 80095419cd..7da14706cc 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4014,4 +4014,5 @@ السماح بالتيارات والمصارف السماح بالممرات المائية المتقطعة السماح بالممرات المائية المتقطعة + مطالبة صوتية \ No newline at end of file From 4d43286f8e5efcb09ba1227b6bd365d426b06773 Mon Sep 17 00:00:00 2001 From: scai Date: Mon, 4 Jan 2021 15:17:57 +0000 Subject: [PATCH 34/61] Translated using Weblate (German) Currently translated at 99.9% (3880 of 3881 strings) --- OsmAnd/res/values-de/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml index 028d5b5da0..bae219d165 100644 --- a/OsmAnd/res/values-de/phrases.xml +++ b/OsmAnd/res/values-de/phrases.xml @@ -222,7 +222,7 @@ Gärtner Flüssiggasspeicher Tor - Gemischtwarenhandlung + Allgemeines Geschäft Geysir Geschenkeladen Gletscher From a0d044609e2a0156a55f1caf4c93dcb50bbef20f Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Mon, 4 Jan 2021 17:11:58 +0000 Subject: [PATCH 35/61] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3591 of 3591 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 e39bfa1ccb..2064a07de1 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4022,4 +4022,5 @@ Permitir riachos e drenos Permitir vias de água intermitentes Permitir vias de água intermitentes + Horários de avisos de voz \ No newline at end of file From a0f133ec52c56ec6ac428cb7c9b6d39c7b4c0e40 Mon Sep 17 00:00:00 2001 From: Exum Solem Date: Mon, 4 Jan 2021 12:56:36 +0000 Subject: [PATCH 36/61] Translated using Weblate (Spanish (American)) Currently translated at 100.0% (3591 of 3591 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 311a2c875c..783a216b59 100644 --- a/OsmAnd/res/values-es-rUS/strings.xml +++ b/OsmAnd/res/values-es-rUS/strings.xml @@ -4029,4 +4029,5 @@ Perfil de usuario Perfil de OsmAnd Elige el perfil que será usado al iniciar la aplicación. + Tiempo de indicaciones por voz \ No newline at end of file From 2c29858735a241024b3c6d334e39311e8fe6357c Mon Sep 17 00:00:00 2001 From: CJTmmr Date: Mon, 4 Jan 2021 20:56:55 +0000 Subject: [PATCH 37/61] Translated using Weblate (Dutch) Currently translated at 94.4% (3393 of 3591 strings) --- OsmAnd/res/values-nl/strings.xml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index 88fcee0486..b9061fecbf 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -3745,8 +3745,8 @@ Selecteer een track waaraan je een nieuw segment wil toevoegen. Selecteer een trackbestand om te openen. Weet u zeker dat u alle wijzigingen in de geplande route wilt annuleren door deze te sluiten\? - Opsmukken voor - Opsmukken na + "Alles wegknippen voor dit punt" + Alles wegknippen na dit punt Wijzig het routetype voor Wijzig het routetype na • Bijgewerkt Plan een route functie: maakt het mogelijk om verschillende navigatietypes per segment te gebruiken en tracks op te nemen @@ -3925,4 +3925,19 @@ Foto\'s zijn afkomstig van het open data-project OpenPlaceReviews.org. Om uw foto\'s te uploaden, moet u zich aanmelden op deze website. Maak een nieuw account aan Ik heb al een account + %1$s * %2$s + Licht vliegtuig + Segmenten samenvoegen + Hiervoor splitsen + Hierna splitsen + Nieuw segment toevoegen + OsmAnd-profiel + Gebruikersprofiel + Volgorde van alle punten omdraaien + Laatst gebruikt + Voorkeur voor ongebaande wandelwegen + Voorkeur voor Hike-routes + Beken en sloten gebruiken + Beken en sloten gebruiken + Waterwegen die periodiek water voeren gebruiken \ No newline at end of file From ae9fc3234cbb766fa742e393fcbd3053e72c4173 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 5 Jan 2021 17:36:30 +0100 Subject: [PATCH 38/61] Update script --- .../src/main/java/net/osmand/search/core/SearchCoreFactory.java | 2 +- 1 file changed, 1 insertion(+), 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 c221d2ca77..5c2faf0b51 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 @@ -650,7 +650,7 @@ public class SearchCoreFactory { if (p.hasObjectType(ObjectType.POI_TYPE)) { return -1; } - if (p.getUnknownWordToSearch().length() >= FIRST_WORD_MIN_LENGTH || p.getRadiusLevel() > 1) { + if (p.getUnknownWordToSearch().length() >= FIRST_WORD_MIN_LENGTH || p.isFirstUnknownSearchWordComplete()) { return SEARCH_AMENITY_BY_NAME_API_PRIORITY_IF_3_CHAR; } return -1; From 03dc11febea776e585ea88946c5f3a37d2b28c44 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 5 Jan 2021 21:03:06 +0300 Subject: [PATCH 39/61] Fix travel bookmarks --- .../plus/wikipedia/WikiArticleHelper.java | 37 ++-- .../WikivoyageArticleDialogFragment.java | 2 +- .../plus/wikivoyage/data/TravelArticle.java | 30 ++- .../plus/wikivoyage/data/TravelDbHelper.java | 12 +- .../plus/wikivoyage/data/TravelHelper.java | 3 +- .../data/TravelLocalDataHelper.java | 206 +++++++++++------- .../plus/wikivoyage/data/TravelObfHelper.java | 20 +- .../data/WikivoyageSearchHistoryItem.java | 27 ++- .../explore/SavedArticlesRvAdapter.java | 7 +- 9 files changed, 217 insertions(+), 127 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java index a0ced8eb86..56137a780c 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleHelper.java @@ -289,33 +289,39 @@ public class WikiArticleHelper { @Nullable public static String getPartialContent(String source) { - if (source == null) { + if (Algorithms.isEmpty(source)) { return null; } String content = source.replaceAll("\\n", ""); int firstParagraphStart = content.indexOf(P_OPENED); int firstParagraphEnd = content.indexOf(P_CLOSED); firstParagraphEnd = firstParagraphEnd < firstParagraphStart ? content.indexOf(P_CLOSED, firstParagraphStart) : firstParagraphEnd; - if (firstParagraphStart == -1 || firstParagraphEnd == -1 - || firstParagraphEnd < firstParagraphStart) { - return null; - } - String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length()); - while (firstParagraphHtml.substring(P_OPENED.length(), firstParagraphHtml.length() - P_CLOSED.length()).trim().isEmpty() - && (firstParagraphEnd + P_CLOSED.length()) < content.length()) { - firstParagraphStart = content.indexOf(P_OPENED, firstParagraphEnd); - firstParagraphEnd = firstParagraphStart == -1 ? -1 : content.indexOf(P_CLOSED, firstParagraphStart); - if (firstParagraphStart != -1 && firstParagraphEnd != -1) { - firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length()); - } else { - break; + String firstParagraphHtml = null; + if (firstParagraphStart != -1 && firstParagraphEnd != -1 + && firstParagraphEnd >= firstParagraphStart) { + firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length()); + while (firstParagraphHtml.substring(P_OPENED.length(), firstParagraphHtml.length() - P_CLOSED.length()).trim().isEmpty() + && (firstParagraphEnd + P_CLOSED.length()) < content.length()) { + firstParagraphStart = content.indexOf(P_OPENED, firstParagraphEnd); + firstParagraphEnd = firstParagraphStart == -1 ? -1 : content.indexOf(P_CLOSED, firstParagraphStart); + if (firstParagraphStart != -1 && firstParagraphEnd != -1) { + firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length()); + } else { + break; + } } } + if (Algorithms.isEmpty(firstParagraphHtml)) { + firstParagraphHtml = source; + } + if (Algorithms.isEmpty(firstParagraphHtml)) { + return null; + } + String firstParagraphText = Html.fromHtml(firstParagraphHtml.replaceAll("(<(/)(a|img)>)|(<(a|img).+?>)|()", "")) .toString().trim(); String[] phrases = firstParagraphText.split("\\. "); - StringBuilder res = new StringBuilder(); int limit = Math.min(phrases.length, PARTIAL_CONTENT_PHRASES); for (int i = 0; i < limit; i++) { @@ -324,7 +330,6 @@ public class WikiArticleHelper { res.append(". "); } } - return res.toString(); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index 9303fb7b84..2d450eaa6b 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -373,7 +373,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme @NonNull String title, @NonNull String lang) { TravelArticleIdentifier articleId = app.getTravelHelper().getArticleId(title, lang); - return showInstance(app, fm, articleId, lang); + return articleId != null && showInstance(app, fm, articleId, lang); } public static boolean showInstance(@NonNull OsmandApplication app, diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java index d4ee0027e7..9a5aca4fa1 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java @@ -9,11 +9,9 @@ import androidx.annotation.Nullable; import androidx.annotation.Size; import net.osmand.GPXUtilities.GPXFile; -import net.osmand.Location; -import net.osmand.aidl.search.SearchResult; -import net.osmand.data.LatLon; +import net.osmand.IndexConstants; +import net.osmand.plus.OsmandApplication; import net.osmand.util.Algorithms; -import net.osmand.util.MapUtils; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; @@ -22,8 +20,6 @@ import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; -import java.util.Arrays; -import java.util.Objects; public class TravelArticle { @@ -40,22 +36,40 @@ public class TravelArticle { String imageTitle; GPXFile gpxFile; String routeId; - String routeSource; + String routeSource = ""; long originalId; String lang; String contentsJson; String aggregatedPartOf; - String fullContent; + + long lastModified; @NonNull public TravelArticleIdentifier generateIdentifier() { return new TravelArticleIdentifier(this); } + @NonNull + public static String getTravelBook(@NonNull OsmandApplication app, @NonNull File file) { + return file.getPath().replace(app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).getPath() + "/", ""); + } + + @Nullable + public String getTravelBook(@NonNull OsmandApplication app) { + return file != null ? getTravelBook(app, file) : null; + } + public File getFile() { return file; } + public long getLastModified() { + if (lastModified > 0) { + return lastModified; + } + return file != null ? file.lastModified() : 0; + } + public String getTitle() { return title; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java index 53ac5866a9..38380015c3 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java @@ -563,6 +563,9 @@ public class TravelDbHelper implements TravelHelper { cursor.close(); } } + if (res == null) { + res = localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang); + } return res; } @@ -643,13 +646,19 @@ public class TravelDbHelper implements TravelHelper { cursor.close(); } } + if (res.isEmpty()) { + List articles = localDataHelper.getSavedArticles(articleId.file, articleId.routeId); + for (TravelArticle a : articles) { + res.add(a.getLang()); + } + } return res; } @NonNull private TravelArticle readArticle(SQLiteCursor cursor) { TravelArticle res = new TravelArticle(); - + res.file = selectedTravelBook; res.title = cursor.getString(0); try { res.content = Algorithms.gzipToString(cursor.getBlob(1)).trim(); @@ -671,7 +680,6 @@ public class TravelDbHelper implements TravelHelper { } catch (IOException e) { LOG.error(e.getMessage(), e); } - return res; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java index 4d512888db..87b5bc1e95 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java @@ -56,8 +56,7 @@ public interface TravelHelper { File createGpxFile(@NonNull final TravelArticle article); // TODO: this method should be deleted once TravelDBHelper is deleted - // For TravelOBFHelper it could always return "" and should be no problem - // Bookmarks should be refactored properly to support multiple files + @Nullable String getSelectedTravelBookName(); String getWikivoyageFileName(); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index 3cb7cf776e..288b71dd88 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -4,11 +4,13 @@ package net.osmand.plus.wikivoyage.data; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.IndexConstants; import net.osmand.plus.OsmandApplication; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; -import net.osmand.plus.wikipedia.WikiArticleHelper; +import net.osmand.util.Algorithms; +import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -24,12 +26,12 @@ public class TravelLocalDataHelper { private static final int HISTORY_ITEMS_LIMIT = 300; - private WikivoyageLocalDataDbHelper dbHelper; + private final WikivoyageLocalDataDbHelper dbHelper; private Map historyMap = new HashMap<>(); private List savedArticles = new ArrayList<>(); - private Set listeners = new HashSet<>(); + private final Set listeners = new HashSet<>(); public void addListener(Listener listener) { listeners.add(listener); @@ -70,21 +72,21 @@ public class TravelLocalDataHelper { } public void addToHistory(@NonNull TravelArticle article) { - addToHistory(article.getTitle(), article.getLang(), article.getIsPartOf()); - } + File file = article.getFile(); + String title = article.getTitle(); + String lang = article.getLang(); + String isPartOf = article.getIsPartOf(); - public void addToHistory(String title, String lang, String isPartOf) { - String key = getHistoryKey(lang, title); - WikivoyageSearchHistoryItem item = historyMap.get(key); - boolean newItem = item == null; - if (newItem) { - item = new WikivoyageSearchHistoryItem(); - } + WikivoyageSearchHistoryItem item = new WikivoyageSearchHistoryItem(); + item.articleFile = file; item.articleTitle = title; item.lang = lang; item.isPartOf = isPartOf; item.lastAccessed = System.currentTimeMillis(); - if (newItem) { + + String key = item.getKey(); + boolean exists = historyMap.containsKey(key); + if (!exists) { dbHelper.addHistoryItem(item); historyMap.put(key, item); } else { @@ -98,10 +100,6 @@ public class TravelLocalDataHelper { } } - static String getHistoryKey(String lang, String title) { - return lang + ":"+title; - } - @NonNull public List getSavedArticles() { return new ArrayList<>(savedArticles); @@ -109,19 +107,8 @@ public class TravelLocalDataHelper { public void addArticleToSaved(@NonNull TravelArticle article) { if (!isArticleSaved(article)) { - TravelArticle saved = new TravelArticle(); - saved.title = article.title; - saved.lang = article.lang; - saved.aggregatedPartOf = article.aggregatedPartOf; - saved.imageTitle = article.imageTitle; - saved.content = WikiArticleHelper.getPartialContent(article.getContent()); - saved.lat = article.lat; - saved.lon = article.lon; - saved.routeId = article.routeId; - saved.fullContent = article.getContent(); - saved.contentsJson = article.contentsJson; - savedArticles.add(saved); - dbHelper.addSavedArticle(saved); + savedArticles.add(article); + dbHelper.addSavedArticle(article); notifySavedUpdated(); } } @@ -164,17 +151,29 @@ public class TravelLocalDataHelper { } @Nullable - public TravelArticle getSavedArticle(String routeId, String lang) { + public TravelArticle getSavedArticle(File file, String routeId, String lang) { for (TravelArticle article : savedArticles) { - if (article.routeId != null && article.routeId.equals(routeId) - && article.lang != null && article.lang.equals(lang)) { - article.content = article.fullContent; + if (Algorithms.objectEquals(article.file, file) + && Algorithms.stringsEqual(article.routeId, routeId) + && Algorithms.stringsEqual(article.lang, lang)) { return article; } } return null; } + @NonNull + public List getSavedArticles(File file, String routeId) { + List articles = new ArrayList<>(); + for (TravelArticle article : savedArticles) { + if (Algorithms.objectEquals(article.file, file) + && Algorithms.stringsEqual(article.routeId, routeId)) { + articles.add(article); + } + } + return articles; + } + public interface Listener { void savedArticlesUpdated(); @@ -182,7 +181,7 @@ public class TravelLocalDataHelper { private static class WikivoyageLocalDataDbHelper { - private static final int DB_VERSION = 6; + private static final int DB_VERSION = 7; private static final String DB_NAME = "wikivoyage_local_data"; private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history"; @@ -219,6 +218,7 @@ public class TravelLocalDataHelper { private static final String BOOKMARKS_COL_ROUTE_ID = "route_id"; private static final String BOOKMARKS_COL_CONTENT_JSON = "content_json"; private static final String BOOKMARKS_COL_CONTENT = "content"; + private static final String BOOKMARKS_COL_LAST_MODIFIED = "last_modified"; private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " + BOOKMARKS_TABLE_NAME + " (" + @@ -226,25 +226,26 @@ public class TravelLocalDataHelper { BOOKMARKS_COL_LANG + " TEXT, " + BOOKMARKS_COL_IS_PART_OF + " TEXT, " + BOOKMARKS_COL_IMAGE_TITLE + " TEXT, " + - BOOKMARKS_COL_PARTIAL_CONTENT + " TEXT, " + BOOKMARKS_COL_TRAVEL_BOOK + " TEXT, " + BOOKMARKS_COL_LAT + " double, " + BOOKMARKS_COL_LON + " double, " + BOOKMARKS_COL_ROUTE_ID + " TEXT, " + BOOKMARKS_COL_CONTENT_JSON + " TEXT, " + - BOOKMARKS_COL_CONTENT + " TEXT" + ");"; + BOOKMARKS_COL_CONTENT + " TEXT, " + + BOOKMARKS_COL_LAST_MODIFIED + " long" + ");"; private static final String BOOKMARKS_TABLE_SELECT = "SELECT " + BOOKMARKS_COL_ARTICLE_TITLE + ", " + BOOKMARKS_COL_LANG + ", " + BOOKMARKS_COL_IS_PART_OF + ", " + BOOKMARKS_COL_IMAGE_TITLE + ", " + - BOOKMARKS_COL_PARTIAL_CONTENT + ", " + + BOOKMARKS_COL_TRAVEL_BOOK + ", " + BOOKMARKS_COL_LAT + ", " + BOOKMARKS_COL_LON + ", " + BOOKMARKS_COL_ROUTE_ID + ", " + BOOKMARKS_COL_CONTENT_JSON + ", " + - BOOKMARKS_COL_CONTENT + + BOOKMARKS_COL_CONTENT + ", " + + BOOKMARKS_COL_LAST_MODIFIED + " FROM " + BOOKMARKS_TABLE_NAME; private final OsmandApplication context; @@ -253,8 +254,12 @@ public class TravelLocalDataHelper { this.context = context; } + @Nullable private SQLiteConnection openConnection(boolean readonly) { SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly); + if (conn == null) { + return null; + } if (conn.getVersion() < DB_VERSION) { if (readonly) { conn.close(); @@ -283,7 +288,7 @@ public class TravelLocalDataHelper { if (oldVersion < 3) { conn.execSQL("ALTER TABLE " + HISTORY_TABLE_NAME + " ADD " + HISTORY_COL_TRAVEL_BOOK + " TEXT"); conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_TRAVEL_BOOK + " TEXT"); - String selectedTravelBookName = getSelectedTravelBookName(); + String selectedTravelBookName = context.getTravelHelper().getSelectedTravelBookName(); if (selectedTravelBookName != null) { Object[] args = new Object[]{selectedTravelBookName}; conn.execSQL("UPDATE " + HISTORY_TABLE_NAME + " SET " + HISTORY_COL_TRAVEL_BOOK + " = ?", args); @@ -301,20 +306,23 @@ public class TravelLocalDataHelper { conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_CONTENT_JSON + " TEXT"); conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_CONTENT + " TEXT"); } + if (oldVersion < 7) { + conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_LAST_MODIFIED + " long"); + conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME + + " SET " + BOOKMARKS_COL_CONTENT + " = " + BOOKMARKS_COL_PARTIAL_CONTENT + + " WHERE " + BOOKMARKS_COL_CONTENT + " is null"); + conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME + + " SET " + BOOKMARKS_COL_PARTIAL_CONTENT + " = null"); + } } @NonNull Map getAllHistoryMap() { Map res = new LinkedHashMap<>(); - String travelBook = getSelectedTravelBookName(); - if (travelBook == null) { - return res; - } SQLiteConnection conn = openConnection(true); if (conn != null) { try { - String query = HISTORY_TABLE_SELECT + " WHERE " + HISTORY_COL_TRAVEL_BOOK + " = ?"; - SQLiteCursor cursor = conn.rawQuery(query, new String[]{travelBook}); + SQLiteCursor cursor = conn.rawQuery(HISTORY_TABLE_SELECT, null); if (cursor != null) { if (cursor.moveToFirst()) { do { @@ -322,8 +330,8 @@ public class TravelLocalDataHelper { res.put(item.getKey(), item); } while (cursor.moveToNext()); } + cursor.close(); } - cursor.close(); } finally { conn.close(); } @@ -331,8 +339,8 @@ public class TravelLocalDataHelper { return res; } - void addHistoryItem(WikivoyageSearchHistoryItem item) { - String travelBook = getSelectedTravelBookName(); + void addHistoryItem(@NonNull WikivoyageSearchHistoryItem item) { + String travelBook = item.getTravelBook(context); if (travelBook == null) { return; } @@ -349,8 +357,8 @@ public class TravelLocalDataHelper { } } - void updateHistoryItem(WikivoyageSearchHistoryItem item) { - String travelBook = getSelectedTravelBookName(); + void updateHistoryItem(@NonNull WikivoyageSearchHistoryItem item) { + String travelBook = item.getTravelBook(context); if (travelBook == null) { return; } @@ -371,8 +379,8 @@ public class TravelLocalDataHelper { } } - void removeHistoryItem(WikivoyageSearchHistoryItem item) { - String travelBook = getSelectedTravelBookName(); + void removeHistoryItem(@NonNull WikivoyageSearchHistoryItem item) { + String travelBook = item.getTravelBook(context); if (travelBook == null) { return; } @@ -391,16 +399,10 @@ public class TravelLocalDataHelper { } void clearAllHistory() { - String travelBook = getSelectedTravelBookName(); - if (travelBook == null) { - return; - } SQLiteConnection conn = openConnection(false); if (conn != null) { try { - conn.execSQL("DELETE FROM " + HISTORY_TABLE_NAME + - " WHERE " + HISTORY_COL_TRAVEL_BOOK + " = ?", - new Object[]{travelBook}); + conn.execSQL("DELETE FROM " + HISTORY_TABLE_NAME); } finally { conn.close(); } @@ -410,19 +412,21 @@ public class TravelLocalDataHelper { @NonNull List readSavedArticles() { List res = new ArrayList<>(); - String travelBook = getSelectedTravelBookName(); - if (travelBook == null) { - return res; - } SQLiteConnection conn = openConnection(true); if (conn != null) { try { - String query = BOOKMARKS_TABLE_SELECT + " WHERE " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?"; - SQLiteCursor cursor = conn.rawQuery(query, new String[]{travelBook}); + SQLiteCursor cursor = conn.rawQuery(BOOKMARKS_TABLE_SELECT, null); if (cursor != null) { if (cursor.moveToFirst()) { do { - res.add(readSavedArticle(cursor)); + TravelArticle dbArticle = readSavedArticle(cursor); + TravelArticle article = context.getTravelHelper().getArticleById(dbArticle.generateIdentifier(), dbArticle.lang); + if (article != null && article.getLastModified() > dbArticle.getLastModified()) { + updateSavedArticle(dbArticle, article); + res.add(article); + } else { + res.add(dbArticle); + } } while (cursor.moveToNext()); } cursor.close(); @@ -434,8 +438,8 @@ public class TravelLocalDataHelper { return res; } - void addSavedArticle(TravelArticle article) { - String travelBook = getSelectedTravelBookName(); + void addSavedArticle(@NonNull TravelArticle article) { + String travelBook = article.getTravelBook(context); if (travelBook == null) { return; } @@ -447,26 +451,26 @@ public class TravelLocalDataHelper { BOOKMARKS_COL_LANG + ", " + BOOKMARKS_COL_IS_PART_OF + ", " + BOOKMARKS_COL_IMAGE_TITLE + ", " + - BOOKMARKS_COL_PARTIAL_CONTENT + ", " + BOOKMARKS_COL_TRAVEL_BOOK + ", " + BOOKMARKS_COL_LAT + ", " + BOOKMARKS_COL_LON + ", " + BOOKMARKS_COL_ROUTE_ID + ", " + BOOKMARKS_COL_CONTENT_JSON + ", " + - BOOKMARKS_COL_CONTENT + + BOOKMARKS_COL_CONTENT + ", " + + BOOKMARKS_COL_LAST_MODIFIED + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; conn.execSQL(query, new Object[]{article.title, article.lang, - article.aggregatedPartOf, article.imageTitle, article.content, + article.aggregatedPartOf, article.imageTitle, travelBook, article.lat, article.lon, article.routeId, article.contentsJson, - article.fullContent}); + article.content, article.getFile().lastModified()}); } finally { conn.close(); } } } - void removeSavedArticle(TravelArticle article) { - String travelBook = getSelectedTravelBookName(); + void removeSavedArticle(@NonNull TravelArticle article) { + String travelBook = article.getTravelBook(context); if (travelBook == null) { return; } @@ -475,44 +479,78 @@ public class TravelLocalDataHelper { try { conn.execSQL("DELETE FROM " + BOOKMARKS_TABLE_NAME + " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + + " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + " AND " + BOOKMARKS_COL_LANG + " = ?" + " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?", - new Object[]{article.title, article.lang, travelBook}); + new Object[]{article.title, article.routeId, article.lang, travelBook}); } finally { conn.close(); } } } - @Nullable - private String getSelectedTravelBookName() { - return context.getTravelHelper().getSelectedTravelBookName(); + void updateSavedArticle(@NonNull TravelArticle odlArticle, @NonNull TravelArticle newArticle) { + String travelBook = odlArticle.getTravelBook(context); + if (travelBook == null) { + return; + } + SQLiteConnection conn = openConnection(false); + if (conn != null) { + try { + conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME + " SET " + + BOOKMARKS_COL_ARTICLE_TITLE + " = ?, " + + BOOKMARKS_COL_LANG + " = ?, " + + BOOKMARKS_COL_IS_PART_OF + " = ?, " + + BOOKMARKS_COL_IMAGE_TITLE + " = ?, " + + BOOKMARKS_COL_TRAVEL_BOOK + " = ?, " + + BOOKMARKS_COL_LAT + " = ?, " + + BOOKMARKS_COL_LON + " = ?, " + + BOOKMARKS_COL_ROUTE_ID + " = ?, " + + BOOKMARKS_COL_CONTENT_JSON + " = ?, " + + BOOKMARKS_COL_CONTENT + " = ?, " + + BOOKMARKS_COL_LAST_MODIFIED + " = ?, " + + "WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ? " + + " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + + " AND " + BOOKMARKS_COL_LANG + " = ?" + + " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?", + new Object[]{newArticle.title, newArticle.lang, newArticle.aggregatedPartOf, + newArticle.imageTitle, travelBook, newArticle.lat, newArticle.lon, + newArticle.routeId, newArticle.content, newArticle.contentsJson, + odlArticle.title, odlArticle.routeId, odlArticle.lang, travelBook}); + + } finally { + conn.close(); + } + } } + @NonNull private WikivoyageSearchHistoryItem readHistoryItem(SQLiteCursor cursor) { WikivoyageSearchHistoryItem res = new WikivoyageSearchHistoryItem(); res.articleTitle = cursor.getString(cursor.getColumnIndex(HISTORY_COL_ARTICLE_TITLE)); res.lang = cursor.getString(cursor.getColumnIndex(HISTORY_COL_LANG)); res.isPartOf = cursor.getString(cursor.getColumnIndex(HISTORY_COL_IS_PART_OF)); res.lastAccessed = cursor.getLong(cursor.getColumnIndex(HISTORY_COL_LAST_ACCESSED)); - return res; } + @NonNull private TravelArticle readSavedArticle(SQLiteCursor cursor) { TravelArticle res = new TravelArticle(); - res.title = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_ARTICLE_TITLE)); res.lang = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_LANG)); res.aggregatedPartOf = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_IS_PART_OF)); res.imageTitle = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_IMAGE_TITLE)); - res.content = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_PARTIAL_CONTENT)); + res.content = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_CONTENT)); res.lat = cursor.getDouble(cursor.getColumnIndex(BOOKMARKS_COL_LAT)); res.lon = cursor.getDouble(cursor.getColumnIndex(BOOKMARKS_COL_LON)); res.routeId = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_ROUTE_ID)); res.contentsJson = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_CONTENT_JSON)); - res.fullContent = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_CONTENT)); - + String travelBook = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_TRAVEL_BOOK)); + if (!Algorithms.isEmpty(travelBook)) { + res.file = context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR + travelBook); + res.lastModified = cursor.getLong(cursor.getColumnIndex(BOOKMARKS_COL_LAST_MODIFIED)); + } return res; } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 5130b349f7..94a9d73033 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -278,7 +278,7 @@ public class TravelObfHelper implements TravelHelper { parts = null; } Map> navMap = new HashMap<>(); - Set headers = new LinkedHashSet(); + Set headers = new LinkedHashSet<>(); Map headerObjs = new HashMap<>(); Map> amenityMap = new HashMap<>(); for (BinaryMapIndexReader reader : getReaders()) { @@ -335,7 +335,7 @@ public class TravelObfHelper implements TravelHelper { navMap.put(rs.isPartOf, l); } l.add(rs); - if (headers != null && headers.contains(a.getTitle())) { + if (headers.contains(a.getTitle())) { headerObjs.put(a.getTitle(), rs); } } @@ -365,7 +365,7 @@ public class TravelObfHelper implements TravelHelper { @Override public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang) { TravelArticle article = getCachedArticle(articleId, lang); - return article == null ? findArticleById(articleId, lang) : article; + return article == null ? localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang) : article; } @Nullable @@ -390,10 +390,11 @@ public class TravelObfHelper implements TravelHelper { private TravelArticle findArticleById(@NonNull final TravelArticleIdentifier articleId, final String lang) { TravelArticle article = null; + final boolean isDbArticle = articleId.file != null && articleId.file.getName().endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT); final List amenities = new ArrayList<>(); for (BinaryMapIndexReader reader : getReaders()) { try { - if (articleId.file != null && !articleId.file.equals(reader.getFile())) { + if (articleId.file != null && !articleId.file.equals(reader.getFile()) && !isDbArticle) { continue; } SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, @@ -404,7 +405,7 @@ public class TravelObfHelper implements TravelHelper { @Override public boolean publish(Amenity amenity) { if (Algorithms.stringsEqual(articleId.routeId, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null))) - && Algorithms.stringsEqual(articleId.routeSource, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null)))) { + && Algorithms.stringsEqual(articleId.routeSource, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null))) || isDbArticle) { amenities.add(amenity); done = true; } @@ -519,10 +520,15 @@ public class TravelObfHelper implements TravelHelper { ArrayList res = new ArrayList<>(); TravelArticle article = getArticleById(articleId, ""); if (article != null) { - Map articles = cachedArticles.get(articleId); + Map articles = cachedArticles.get(article.generateIdentifier()); if (articles != null) { res.addAll(articles.keySet()); } + } else { + List articles = localDataHelper.getSavedArticles(articleId.file, articleId.routeId); + for (TravelArticle a : articles) { + res.add(a.getLang()); + } } return res; } @@ -547,7 +553,7 @@ public class TravelObfHelper implements TravelHelper { @Override public String getSelectedTravelBookName() { - return ""; + return null; } @Override diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageSearchHistoryItem.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageSearchHistoryItem.java index aee3b183b4..cc41d2582d 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageSearchHistoryItem.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageSearchHistoryItem.java @@ -1,17 +1,36 @@ package net.osmand.plus.wikivoyage.data; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.plus.OsmandApplication; + +import java.io.File; + public class WikivoyageSearchHistoryItem { + File articleFile; String articleTitle; String lang; String isPartOf; long lastAccessed; - - - public String getKey() { - return TravelLocalDataHelper.getHistoryKey(lang, articleTitle); + + public static String getKey(String lang, String title, @Nullable File file) { + return lang + ":" + title + (file != null ? ":" + file.getName() : ""); } + public String getKey() { + return getKey(lang, articleTitle, articleFile); + } + + public File getArticleFile() { + return articleFile; + } + + @Nullable + public String getTravelBook(@NonNull OsmandApplication app) { + return articleFile != null ? TravelArticle.getTravelBook(app, articleFile) : null; + } public String getArticleTitle() { return articleTitle; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index 77989b695b..8996e4d375 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -22,6 +22,7 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.widgets.tools.CropCircleTransformation; +import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.WikivoyageUtils; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; @@ -102,7 +103,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter Date: Tue, 5 Jan 2021 21:19:24 +0100 Subject: [PATCH 40/61] Fix so we don't store old versions of indexes --- .../osmand/binary/CachedOsmandIndexes.java | 112 +++++++++--------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java b/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java index 63c81d13fa..d13bb63cd1 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java @@ -30,41 +30,43 @@ import net.osmand.binary.OsmandIndex.TransportPart; import org.apache.commons.logging.Log; public class CachedOsmandIndexes { - + private OsmAndStoredIndex storedIndex; private OsmAndStoredIndex.Builder storedIndexBuilder; private Log log = PlatformUtil.getLog(CachedOsmandIndexes.class); private boolean hasChanged = true; - + public static final int VERSION = 2; public void addToCache(BinaryMapIndexReader reader, File f) { hasChanged = true; - if(storedIndexBuilder == null) { + if (storedIndexBuilder == null) { storedIndexBuilder = OsmandIndex.OsmAndStoredIndex.newBuilder(); storedIndexBuilder.setVersion(VERSION); storedIndexBuilder.setDateCreated(System.currentTimeMillis()); - if(storedIndex != null) { - for(FileIndex ex : storedIndex.getFileIndexList()) { - storedIndexBuilder.addFileIndex(ex); + if (storedIndex != null) { + for (FileIndex ex : storedIndex.getFileIndexList()) { + if (!ex.getFileName().equals(f.getName())) { + storedIndexBuilder.addFileIndex(ex); + } } } } - + FileIndex.Builder fileIndex = OsmandIndex.FileIndex.newBuilder(); long d = reader.getDateCreated(); - fileIndex.setDateModified(d== 0?f.lastModified() : d); + fileIndex.setDateModified(d == 0 ? f.lastModified() : d); fileIndex.setSize(f.length()); fileIndex.setVersion(reader.getVersion()); fileIndex.setFileName(f.getName()); - for(MapIndex index : reader.getMapIndexes()) { + for (MapIndex index : reader.getMapIndexes()) { MapPart.Builder map = OsmandIndex.MapPart.newBuilder(); map.setSize(index.getLength()); map.setOffset(index.getFilePointer()); - if(index.getName() != null) { + if (index.getName() != null) { map.setName(index.getName()); } - for(MapRoot mr : index.getRoots() ) { + for (MapRoot mr : index.getRoots()) { MapLevel.Builder lev = OsmandIndex.MapLevel.newBuilder(); lev.setSize(mr.length); lev.setOffset(mr.filePointer); @@ -78,36 +80,36 @@ public class CachedOsmandIndexes { } fileIndex.addMapIndex(map); } - - for(AddressRegion index : reader.getAddressIndexes()) { + + for (AddressRegion index : reader.getAddressIndexes()) { AddressPart.Builder addr = OsmandIndex.AddressPart.newBuilder(); addr.setSize(index.getLength()); addr.setOffset(index.getFilePointer()); - if(index.getName() != null) { + if (index.getName() != null) { addr.setName(index.getName()); } - if(index.getEnName() != null) { + if (index.getEnName() != null) { addr.setNameEn(index.getEnName()); } addr.setIndexNameOffset(index.getIndexNameOffset()); - for(CitiesBlock mr : index.getCities() ) { + for (CitiesBlock mr : index.getCities()) { CityBlock.Builder cblock = OsmandIndex.CityBlock.newBuilder(); cblock.setSize(mr.length); cblock.setOffset(mr.filePointer); cblock.setType(mr.type); addr.addCities(cblock); } - for(String s : index.getAttributeTagsTable()) { + for (String s : index.getAttributeTagsTable()) { addr.addAdditionalTags(s); } fileIndex.addAddressIndex(addr); } - - for(PoiRegion index : reader.getPoiIndexes()) { + + for (PoiRegion index : reader.getPoiIndexes()) { PoiPart.Builder poi = OsmandIndex.PoiPart.newBuilder(); poi.setSize(index.getLength()); poi.setOffset(index.getFilePointer()); - if(index.getName() != null) { + if (index.getName() != null) { poi.setName(index.getName()); } poi.setLeft(index.left31); @@ -116,12 +118,12 @@ public class CachedOsmandIndexes { poi.setBottom(index.bottom31); fileIndex.addPoiIndex(poi.build()); } - - for(TransportIndex index : reader.getTransportIndexes()) { + + for (TransportIndex index : reader.getTransportIndexes()) { TransportPart.Builder transport = OsmandIndex.TransportPart.newBuilder(); transport.setSize(index.getLength()); transport.setOffset(index.getFilePointer()); - if(index.getName() != null) { + if (index.getName() != null) { transport.setName(index.getName()); } transport.setLeft(index.getLeft()); @@ -130,33 +132,33 @@ public class CachedOsmandIndexes { transport.setBottom(index.getBottom()); transport.setStopsTableLength(index.stopsFileLength); transport.setStopsTableOffset(index.stopsFileOffset); -// if(index.incompleteRoutesLength > 0) { + // if(index.incompleteRoutesLength > 0) { transport.setIncompleteRoutesLength(index.incompleteRoutesLength); transport.setIncompleteRoutesOffset(index.incompleteRoutesOffset); -// } + // } transport.setStringTableLength(index.stringTable.length); transport.setStringTableOffset(index.stringTable.fileOffset); fileIndex.addTransportIndex(transport); } - - for(RouteRegion index : reader.getRoutingIndexes()) { + + for (RouteRegion index : reader.getRoutingIndexes()) { RoutingPart.Builder routing = OsmandIndex.RoutingPart.newBuilder(); routing.setSize(index.getLength()); routing.setOffset(index.getFilePointer()); - if(index.getName() != null) { + if (index.getName() != null) { routing.setName(index.getName()); } - for(RouteSubregion sub : index.getSubregions()) { + for (RouteSubregion sub : index.getSubregions()) { addRouteSubregion(routing, sub, false); } - for(RouteSubregion sub : index.getBaseSubregions()) { + for (RouteSubregion sub : index.getBaseSubregions()) { addRouteSubregion(routing, sub, true); } fileIndex.addRoutingIndex(routing); } - + storedIndexBuilder.addFileIndex(fileIndex); - + } private void addRouteSubregion(RoutingPart.Builder routing, RouteSubregion sub, boolean base) { @@ -171,7 +173,7 @@ public class CachedOsmandIndexes { rpart.setShifToData(sub.shiftToData); routing.addSubregions(rpart); } - + public BinaryMapIndexReader getReader(File f) throws IOException { RandomAccessFile mf = new RandomAccessFile(f.getPath(), "r"); FileIndex found = null; @@ -191,26 +193,26 @@ public class CachedOsmandIndexes { reader = new BinaryMapIndexReader(mf, f); addToCache(reader, f); if (log.isDebugEnabled()) { - log.debug("Initializing db " + f.getAbsolutePath() + " " + (System.currentTimeMillis() - val ) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + log.debug("Initializing db " + f.getAbsolutePath() + " " + (System.currentTimeMillis() - val) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } else { reader = initFileIndex(found, mf, f); } return reader; } - + private BinaryMapIndexReader initFileIndex(FileIndex found, RandomAccessFile mf, File f) throws IOException { BinaryMapIndexReader reader = new BinaryMapIndexReader(mf, f, false); reader.version = found.getVersion(); reader.dateCreated = found.getDateModified(); - - for(MapPart index : found.getMapIndexList()) { + + for (MapPart index : found.getMapIndexList()) { MapIndex mi = new MapIndex(); mi.length = (int) index.getSize(); mi.filePointer = (int) index.getOffset(); mi.name = index.getName(); - - for(MapLevel mr : index.getLevelsList()) { + + for (MapLevel mr : index.getLevelsList()) { MapRoot root = new MapRoot(); root.length = (int) mr.getSize(); root.filePointer = (int) mr.getOffset(); @@ -226,15 +228,15 @@ public class CachedOsmandIndexes { reader.indexes.add(mi); reader.basemap = reader.basemap || mi.isBaseMap(); } - - for(AddressPart index : found.getAddressIndexList()) { + + for (AddressPart index : found.getAddressIndexList()) { AddressRegion mi = new AddressRegion(); mi.length = (int) index.getSize(); mi.filePointer = (int) index.getOffset(); mi.name = index.getName(); mi.enName = index.getNameEn(); mi.indexNameOffset = index.getIndexNameOffset(); - for(CityBlock mr : index.getCitiesList() ) { + for (CityBlock mr : index.getCitiesList()) { CitiesBlock cblock = new CitiesBlock(); cblock.length = (int) mr.getSize(); cblock.filePointer = (int) mr.getOffset(); @@ -245,8 +247,8 @@ public class CachedOsmandIndexes { reader.addressIndexes.add(mi); reader.indexes.add(mi); } - - for(PoiPart index : found.getPoiIndexList()) { + + for (PoiPart index : found.getPoiIndexList()) { PoiRegion mi = new PoiRegion(); mi.length = (int) index.getSize(); mi.filePointer = (int) index.getOffset(); @@ -258,14 +260,14 @@ public class CachedOsmandIndexes { reader.poiIndexes.add(mi); reader.indexes.add(mi); } - - for(TransportPart index : found.getTransportIndexList()) { + + for (TransportPart index : found.getTransportIndexList()) { TransportIndex mi = new TransportIndex(); mi.length = (int) index.getSize(); mi.filePointer = (int) index.getOffset(); mi.name = index.getName(); mi.left = index.getLeft(); - mi.right =index.getRight(); + mi.right = index.getRight(); mi.top = index.getTop(); mi.bottom = index.getBottom(); mi.stopsFileLength = index.getStopsTableLength(); @@ -278,14 +280,14 @@ public class CachedOsmandIndexes { reader.transportIndexes.add(mi); reader.indexes.add(mi); } - - for(RoutingPart index : found.getRoutingIndexList()) { + + for (RoutingPart index : found.getRoutingIndexList()) { RouteRegion mi = new RouteRegion(); mi.length = (int) index.getSize(); mi.filePointer = (int) index.getOffset(); mi.name = index.getName(); - - for(RoutingSubregion mr : index.getSubregionsList()) { + + for (RoutingSubregion mr : index.getSubregionsList()) { RouteSubregion sub = new RouteSubregion(mi); sub.length = (int) mr.getSize(); sub.filePointer = (int) mr.getOffset(); @@ -294,7 +296,7 @@ public class CachedOsmandIndexes { sub.top = mr.getTop(); sub.bottom = mr.getBottom(); sub.shiftToData = mr.getShifToData(); - if(mr.getBasemap()) { + if (mr.getBasemap()) { mi.basesubregions.add(sub); } else { mi.subregions.add(sub); @@ -303,7 +305,7 @@ public class CachedOsmandIndexes { reader.routingIndexes.add(mi); reader.indexes.add(mi); } - + return reader; } @@ -313,7 +315,7 @@ public class CachedOsmandIndexes { try { storedIndex = OsmandIndex.OsmAndStoredIndex.newBuilder().mergeFrom(is).build(); hasChanged = false; - if(storedIndex.getVersion() != version){ + if (storedIndex.getVersion() != version) { storedIndex = null; } } finally { @@ -321,7 +323,7 @@ public class CachedOsmandIndexes { } log.info("Initialize cache " + (System.currentTimeMillis() - time)); } - + public void writeToFile(File f) throws IOException { if (hasChanged) { FileOutputStream outputStream = new FileOutputStream(f); From d74e57db84858661acb66007c3a2a73182aa8b1c Mon Sep 17 00:00:00 2001 From: Kseniia Date: Tue, 5 Jan 2021 22:49:39 +0200 Subject: [PATCH 41/61] refactoring --- .../java/net/osmand/search/SearchUICore.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java index 573068d207..f8b738a509 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java @@ -41,10 +41,13 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class SearchUICore { @@ -67,6 +70,8 @@ public class SearchUICore { private MapPoiTypes poiTypes; private static boolean debugMode = false; + + private static final Set FILTER_DUPLICATE_POI_SUBTYPE = Stream.of("building").collect((Collectors.toCollection(TreeSet::new))); public SearchUICore(MapPoiTypes poiTypes, String locale, boolean transliterate) { this.poiTypes = poiTypes; @@ -245,18 +250,20 @@ public class SearchUICore { String subType1 = a1.getSubType(); String subType2 = a2.getSubType(); - if (a1.getId().longValue() == a2.getId().longValue() - && ((subType1.equals("building") || subType2.equals("building")))) { + boolean isEqualId = a1.getId().longValue() == a2.getId().longValue(); + + if (isEqualId && (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) + || FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2))) { return true; + } if (!type1.equals(type2)) { - if (a1.getId().longValue() == a2.getId().longValue() && subType1.contains("internet") - || subType2.contains("internet")) { + if (isEqualId && (subType1.contains("internet") || subType2.contains("internet"))) { return true; } return false; } - + if (type1.equals("natural")) { similarityRadius = 50000; } else if (subType1.equals(subType2)) { @@ -1000,9 +1007,9 @@ public class SearchUICore { int cmp; - if(subType1.equals("building") || subType1.contains("internet")) { + if(FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) || subType1.contains("internet")) { cmp = 1; - } else if(subType2.equals("building") || subType2.contains("internet")) { + } else if(FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2) || subType2.contains("internet")) { cmp = -1; } else { cmp = c.collator.compare(subType1, subType2); From be80a4c5748bdcbb9b4e3fa02869c0938044fe31 Mon Sep 17 00:00:00 2001 From: Kseniia Date: Tue, 5 Jan 2021 23:29:26 +0200 Subject: [PATCH 42/61] refactoring --- .../java/net/osmand/search/SearchUICore.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java index f8b738a509..589dfb3b3f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java @@ -34,6 +34,7 @@ import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; @@ -71,7 +72,7 @@ public class SearchUICore { private static boolean debugMode = false; - private static final Set FILTER_DUPLICATE_POI_SUBTYPE = Stream.of("building").collect((Collectors.toCollection(TreeSet::new))); + private static final Set FILTER_DUPLICATE_POI_SUBTYPE = new TreeSet(Arrays.asList("building", "internet_access_yes")); public SearchUICore(MapPoiTypes poiTypes, String locale, boolean transliterate) { this.poiTypes = poiTypes; @@ -249,16 +250,17 @@ public class SearchUICore { String type2 = a2.getType().getKeyName(); String subType1 = a1.getSubType(); String subType2 = a2.getSubType(); - - boolean isEqualId = a1.getId().longValue() == a2.getId().longValue(); + boolean isEqualId = a1.getId().longValue() == a2.getId().longValue(); + if (isEqualId && (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) || FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2))) { return true; } if (!type1.equals(type2)) { - if (isEqualId && (subType1.contains("internet") || subType2.contains("internet"))) { + if (isEqualId && (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) + || FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2))) { return true; } return false; @@ -1001,20 +1003,20 @@ public class SearchUICore { // here 2 points are amenity Amenity a1 = (Amenity) o1.object; Amenity a2 = (Amenity) o2.object; - + String subType1 = a1.getSubType() == null ? "" : a1.getSubType(); String subType2 = a2.getSubType() == null ? "" : a2.getSubType(); - + int cmp; - - if(FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) || subType1.contains("internet")) { + + if (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1)) { cmp = 1; - } else if(FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2) || subType2.contains("internet")) { + } else if (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2)) { cmp = -1; } else { cmp = c.collator.compare(subType1, subType2); } - + if (cmp != 0) { return cmp; } From 3096f6f8fde3facfd016f95487ae514a0e796a8b Mon Sep 17 00:00:00 2001 From: Kseniia Date: Wed, 6 Jan 2021 00:05:21 +0200 Subject: [PATCH 43/61] refactoring --- .../java/net/osmand/search/SearchUICore.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java index 589dfb3b3f..df8c2bd5be 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/SearchUICore.java @@ -47,8 +47,6 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class SearchUICore { @@ -72,7 +70,8 @@ public class SearchUICore { private static boolean debugMode = false; - private static final Set FILTER_DUPLICATE_POI_SUBTYPE = new TreeSet(Arrays.asList("building", "internet_access_yes")); + private static final Set FILTER_DUPLICATE_POI_SUBTYPE = new TreeSet( + Arrays.asList("building", "internet_access_yes")); public SearchUICore(MapPoiTypes poiTypes, String locale, boolean transliterate) { this.poiTypes = poiTypes; @@ -252,17 +251,12 @@ public class SearchUICore { String subType2 = a2.getSubType(); boolean isEqualId = a1.getId().longValue() == a2.getId().longValue(); - + if (isEqualId && (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) || FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2))) { return true; - } - if (!type1.equals(type2)) { - if (isEqualId && (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1) - || FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2))) { - return true; - } + } else if (!type1.equals(type2)) { return false; } @@ -1004,19 +998,29 @@ public class SearchUICore { Amenity a1 = (Amenity) o1.object; Amenity a2 = (Amenity) o2.object; + String type1 = a1.getType().getKeyName(); + String type2 = a2.getType().getKeyName(); String subType1 = a1.getSubType() == null ? "" : a1.getSubType(); String subType2 = a2.getSubType() == null ? "" : a2.getSubType(); - int cmp; + int cmp = 0; if (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1)) { cmp = 1; } else if (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2)) { cmp = -1; - } else { - cmp = c.collator.compare(subType1, subType2); + } + + if (cmp != 0) { + return cmp; } + cmp = c.collator.compare(type1, type2); + if (cmp != 0) { + return cmp; + } + + cmp = c.collator.compare(subType1, subType2); if (cmp != 0) { return cmp; } From 37bfc759b181009c3cd322601b3339919f92eff5 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 6 Jan 2021 00:30:00 +0200 Subject: [PATCH 44/61] Update CachedOsmandIndexes after map download --- .../net/osmand/binary/CachedOsmandIndexes.java | 16 ++++++++-------- .../plus/download/DownloadIndexesThread.java | 2 +- .../osmand/plus/resources/ResourceManager.java | 8 ++++++-- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java b/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java index d13bb63cd1..56b5731577 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/CachedOsmandIndexes.java @@ -1,11 +1,5 @@ package net.osmand.binary; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; - import net.osmand.PlatformUtil; import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion; import net.osmand.binary.BinaryMapAddressReaderAdapter.CitiesBlock; @@ -29,6 +23,12 @@ import net.osmand.binary.OsmandIndex.TransportPart; import org.apache.commons.logging.Log; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; + public class CachedOsmandIndexes { private OsmAndStoredIndex storedIndex; @@ -174,10 +174,10 @@ public class CachedOsmandIndexes { routing.addSubregions(rpart); } - public BinaryMapIndexReader getReader(File f) throws IOException { + public BinaryMapIndexReader getReader(File f, boolean useStoredIndex) throws IOException { RandomAccessFile mf = new RandomAccessFile(f.getPath(), "r"); FileIndex found = null; - if (storedIndex != null) { + if (storedIndex != null && useStoredIndex) { for (int i = 0; i < storedIndex.getFileIndexCount(); i++) { FileIndex fi = storedIndex.getFileIndex(i); if (f.length() == fi.getSize() && f.getName().equals(fi.getFileName())) { diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 3355d67a32..9d47f57762 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -576,7 +576,7 @@ public class DownloadIndexesThread { manager.indexVoiceFiles(this); manager.indexFontFiles(this); if (vectorMapsToReindex) { - warnings = manager.indexingMaps(this); + warnings = manager.indexingMaps(this, filesToReindex); } List wns = manager.indexAdditionalMaps(this); if (wns != null) { diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index ffd8bb4e83..db1c3c96d6 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -621,7 +621,11 @@ public class ResourceManager { } } - public List indexingMaps(final IProgress progress) { + public List indexingMaps(IProgress progress) { + return indexingMaps(progress, Collections.emptyList()); + } + + public List indexingMaps(final IProgress progress, List filesToReindex) { long val = System.currentTimeMillis(); ArrayList files = new ArrayList(); File appPath = context.getAppPath(null); @@ -688,7 +692,7 @@ public class ResourceManager { try { BinaryMapIndexReader mapReader = null; try { - mapReader = cachedOsmandIndexes.getReader(f); + mapReader = cachedOsmandIndexes.getReader(f, !filesToReindex.contains(f)); if (mapReader.getVersion() != IndexConstants.BINARY_MAP_VERSION) { mapReader = null; } From de2704a62709e006746079a3f786ae48b8feb046 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 6 Jan 2021 04:36:21 +0200 Subject: [PATCH 45/61] add to context menu option to show nearby poi with the same type; --- OsmAnd/res/values/strings.xml | 1 + .../plus/mapcontextmenu/MenuBuilder.java | 108 ++++++++++++++---- .../builders/AmenityMenuBuilder.java | 16 ++- .../builders/FavouritePointMenuBuilder.java | 4 +- .../controllers/AmenityMenuController.java | 2 +- 5 files changed, 102 insertions(+), 29 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index fb403c340c..1e8391a3d8 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + Nearby POI Copy address Allow intermittent water ways Allow intermittent water ways diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 1d419a6b09..d4f60024f6 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -41,6 +41,8 @@ import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; +import net.osmand.osm.PoiCategory; +import net.osmand.osm.PoiType; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.*; import net.osmand.plus.activities.ActivityResultListener; @@ -51,6 +53,7 @@ import net.osmand.plus.mapcontextmenu.builders.cards.CardsRowBuilder; 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.AmenityMenuController; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; import net.osmand.plus.openplacereviews.AddPhotosBottomSheetDialogFragment; import net.osmand.plus.openplacereviews.OPRConstants; @@ -92,12 +95,15 @@ public class MenuBuilder { protected boolean matchWidthDivider; protected boolean light; private long objectId; + private String objectType; private LatLon latLon; private boolean hidden; private boolean showTitleIfTruncated = true; private boolean showNearestWiki = false; + private boolean showNearestPoi = false; private boolean showOnlinePhotos = true; protected List nearestWiki = new ArrayList<>(); + protected List nearestPoi = new ArrayList<>(); private List menuPlugins = new ArrayList<>(); @Nullable private CardsRowBuilder onlinePhotoCardsRow; @@ -208,10 +214,18 @@ public class MenuBuilder { return showNearestWiki; } + public boolean isShowNearestPoi() { + return showNearestPoi; + } + public void setShowNearestWiki(boolean showNearestWiki) { this.showNearestWiki = showNearestWiki; } + public void setShowNearestPoi(boolean showNearestPoi) { + this.showNearestPoi = showNearestPoi; + } + public void setShowTitleIfTruncated(boolean showTitleIfTruncated) { this.showTitleIfTruncated = showTitleIfTruncated; } @@ -229,6 +243,11 @@ public class MenuBuilder { this.showNearestWiki = showNearestWiki; } + public void setShowNearestPoi(boolean showNearestPoi, String objectType) { + this.objectType = objectType; + this.showNearestPoi = showNearestPoi; + } + public void addMenuPlugin(OsmandPlugin plugin) { menuPlugins.add(plugin); } @@ -246,6 +265,7 @@ public class MenuBuilder { buildTitleRow(view); } buildNearestWikiRow(view); + buildNearestPoiRow(view); if (needBuildPlainMenuItems()) { buildPlainMenuItems(view); } @@ -325,10 +345,20 @@ public class MenuBuilder { } protected void buildNearestWikiRow(View view) { - if (processNearestWiki() && nearestWiki.size() > 0) { - buildRow(view, R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", 0, - true, getCollapsableWikiView(view.getContext(), true), - false, 0, false, null, false); + buildNearestRow(view, nearestWiki, processNearestWiki(), + R.drawable.ic_action_wikipedia, app.getString(R.string.wiki_around)); + } + + protected void buildNearestPoiRow(View view) { + buildNearestRow(view, nearestPoi, processNearestPoi(), + nearestPoi.isEmpty() ? 0 : AmenityMenuController.getRightIconId(nearestPoi.get(0)), + app.getString(R.string.poi_around)); + } + + protected void buildNearestRow(View view, List nearestAmenities, boolean process, int iconId, String text) { + if (process && nearestAmenities.size() > 0) { + buildRow(view, iconId, null, text + " (" + nearestAmenities.size() + ")", 0, true, + getCollapsableView(view.getContext(), true, nearestAmenities), false, 0, false, null, false); } } @@ -1118,20 +1148,25 @@ public class MenuBuilder { return new CollapsableView(textView, this, collapsed); } - protected CollapsableView getCollapsableWikiView(Context context, boolean collapsed) { + protected CollapsableView getCollapsableView(Context context, boolean collapsed, List nearestAmenities) { LinearLayout view = (LinearLayout) buildCollapsableContentView(context, collapsed, true); - for (final Amenity wiki : nearestWiki) { + for (final Amenity poi : nearestAmenities) { TextViewEx button = buildButtonInCollapsableView(context, false, false); - String name = wiki.getName(preferredMapAppLang, transliterateNames); + String name = poi.getName(preferredMapAppLang, transliterateNames); + if (Algorithms.isBlank(name)) { + PoiCategory pc = poi.getType(); + PoiType pt = pc.getPoiTypeByKeyName(poi.getSubType()); + name = pt.getTranslation(); + } button.setText(name); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - LatLon latLon = new LatLon(wiki.getLocation().getLatitude(), wiki.getLocation().getLongitude()); - PointDescription pointDescription = mapActivity.getMapLayers().getPoiMapLayer().getObjectName(wiki); - mapActivity.getContextMenu().show(latLon, pointDescription, wiki); + LatLon latLon = new LatLon(poi.getLocation().getLatitude(), poi.getLocation().getLongitude()); + PointDescription pointDescription = mapActivity.getMapLayers().getPoiMapLayer().getObjectName(poi); + mapActivity.getContextMenu().show(latLon, pointDescription, poi); } }); view.addView(button); @@ -1192,21 +1227,7 @@ public class MenuBuilder { protected boolean processNearestWiki() { if (showNearestWiki && latLon != null) { - QuadRect rect = MapUtils.calculateLatLonBbox( - latLon.getLatitude(), latLon.getLongitude(), 250); - PoiUIFilter wikiPoiFilter = app.getPoiFilters().getTopWikiPoiFilter(); - - nearestWiki = getAmenities(rect, wikiPoiFilter); - - Collections.sort(nearestWiki, new Comparator() { - - @Override - public int compare(Amenity o1, Amenity o2) { - double d1 = MapUtils.getDistance(latLon, o1.getLocation()); - double d2 = MapUtils.getDistance(latLon, o2.getLocation()); - return Double.compare(d1, d2); - } - }); + nearestWiki = getSortedAmenities(app.getPoiFilters().getTopWikiPoiFilter()); Long id = objectId; List wikiList = new ArrayList<>(); for (Amenity wiki : nearestWiki) { @@ -1220,6 +1241,43 @@ public class MenuBuilder { return false; } + protected boolean processNearestPoi() { + if (showNearestPoi && latLon != null) { + nearestPoi = getSortedAmenities(app.getPoiFilters().getShowAllPOIFilter()); + Long id = objectId; + String type = objectType; + List poiList = new ArrayList<>(); + for (Amenity poi : nearestPoi) { + if (poi.getId().equals(id) || !Algorithms.stringsEqual(poi.getSubType(), type)) { + poiList.add(poi); + } + } + nearestPoi.removeAll(poiList); + return true; + } + return false; + } + + private List getSortedAmenities(PoiUIFilter filter) { + final LatLon latLon = getLatLon(); + QuadRect rect = MapUtils.calculateLatLonBbox( + latLon.getLatitude(), latLon.getLongitude(), 250); + + List nearestAmenities = getAmenities(rect, filter); + + Collections.sort(nearestAmenities, new Comparator() { + + @Override + public int compare(Amenity o1, Amenity o2) { + double d1 = MapUtils.getDistance(latLon, o1.getLocation()); + double d2 = MapUtils.getDistance(latLon, o2.getLocation()); + return Double.compare(d1, d2); + } + }); + + return nearestAmenities; + } + private List getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) { return wikiPoiFilter.searchAmenities(rect.top, rect.left, rect.bottom, rect.right, -1, null); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 12b1b0d497..b72c1a60f5 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -35,6 +35,7 @@ import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.mapcontextmenu.CollapsableView; import net.osmand.plus.mapcontextmenu.MenuBuilder; +import net.osmand.plus.mapcontextmenu.controllers.AmenityMenuController; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.views.layers.POIMapLayer; @@ -79,6 +80,7 @@ public class AmenityMenuBuilder extends MenuBuilder { super(mapActivity); this.amenity = amenity; setShowNearestWiki(true, amenity.getId()); + setShowNearestPoi(true, amenity.getSubType()); metricSystem = mapActivity.getMyApplication().getSettings().METRIC_SYSTEM.get(); } @@ -86,6 +88,10 @@ public class AmenityMenuBuilder extends MenuBuilder { protected void buildNearestWikiRow(View view) { } + @Override + protected void buildNearestPoiRow(View view) { + } + private void buildRow(View view, int iconId, String text, String textPrefix, boolean collapsable, final CollapsableView collapsableView, int textColor, boolean isWiki, boolean isText, boolean needLinks, @@ -664,11 +670,19 @@ public class AmenityMenuBuilder extends MenuBuilder { if (processNearestWiki() && nearestWiki.size() > 0) { AmenityInfoRow wikiInfo = new AmenityInfoRow( "nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true, - getCollapsableWikiView(view.getContext(), true), + getCollapsableView(view.getContext(), true, nearestWiki), 0, false, false, false, 1000, null, false, false, false, 0); buildAmenityRow(view, wikiInfo); } + if (processNearestPoi() && nearestPoi.size() > 0) { + AmenityInfoRow poiInfo = new AmenityInfoRow( + "nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.poi_around) + " (" + nearestPoi.size() + ")", true, + getCollapsableView(view.getContext(), true, nearestPoi), + 0, false, false, false, 1000, null, false, false, false, 0); + buildAmenityRow(view, poiInfo); + } + if (osmEditingEnabled && amenity.getId() != null && amenity.getId() > 0 && (amenity.getId() % 2 == 0 || (amenity.getId() >> 1) < Integer.MAX_VALUE)) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/FavouritePointMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/FavouritePointMenuBuilder.java index 1e6df280a3..03110c8b32 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/FavouritePointMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/FavouritePointMenuBuilder.java @@ -59,9 +59,9 @@ public class FavouritePointMenuBuilder extends MenuBuilder { } @Override - protected void buildNearestWikiRow(View view) { + protected void buildNearestRow(View view, List nearestAmenities, boolean process, int iconId, String text) { if (originObject == null || !(originObject instanceof Amenity)) { - super.buildNearestWikiRow(view); + super.buildNearestRow(view, nearestAmenities, process, iconId, text); } } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java index 11564a1b73..e67b8dc11b 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java @@ -116,7 +116,7 @@ public class AmenityMenuController extends MenuController { return getRightIconId(amenity); } - private static int getRightIconId(Amenity amenity) { + public static int getRightIconId(Amenity amenity) { String id = null; PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType()); if (st != null) { From 6d7c647a644dfe5b8c63b1a1fc581e2b788f71bc Mon Sep 17 00:00:00 2001 From: letypequividelespoubelles Date: Tue, 5 Jan 2021 21:59:54 +0000 Subject: [PATCH 46/61] Translated using Weblate (French) Currently translated at 99.9% (3603 of 3606 strings) --- OsmAnd/res/values-fr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 65ac4718b2..faca31403e 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4007,4 +4007,5 @@ Autoriser les cours d’eau et les drains Autoriser les cours d’eau et les drains Nombre d\'annonces vocales + Laisser vide sinon \ No newline at end of file From 3cfdec720780876a35613558b0b2beedf62b9a9d Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Tue, 5 Jan 2021 18:02:00 +0000 Subject: [PATCH 47/61] Translated using Weblate (French) Currently translated at 99.9% (3603 of 3606 strings) --- OsmAnd/res/values-fr/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index faca31403e..f3d030e821 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4008,4 +4008,15 @@ Autoriser les cours d’eau et les drains Nombre d\'annonces vocales Laisser vide sinon + Sous-type + Véhicule + Clé d\'API + URL du serveur + Saisissez le paramètre + Calculer un itinéraire d’essai + En voiture + A pieds + Vélo + Automobile + Erreur, vérifiez les paramètres \ No newline at end of file From 02afd3e67f9cca5c3cc74e057c9fdda6ac67893d Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Wed, 6 Jan 2021 06:35:15 +0000 Subject: [PATCH 48/61] Translated using Weblate (French) Currently translated at 99.9% (3603 of 3606 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 f3d030e821..633470a815 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4007,7 +4007,7 @@ Autoriser les cours d’eau et les drains Autoriser les cours d’eau et les drains Nombre d\'annonces vocales - Laisser vide sinon + Si non, laissez vide Sous-type Véhicule Clé d\'API From 43d243c07e9a446585ba5887e5d37f9a576ccfb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 5 Jan 2021 17:29:01 +0000 Subject: [PATCH 49/61] Translated using Weblate (Turkish) Currently translated at 100.0% (3606 of 3606 strings) --- OsmAnd/res/values-tr/strings.xml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 6b794136f0..fccc6158e3 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -1701,7 +1701,7 @@ Etiketi Kaldır Gecelik derlemeleri indir. kurar - Sokak Aydınlatma + Sokak aydınlatma Vekil sunucu Bir proxy sunucusu belirtin. Gizlilik @@ -3982,5 +3982,20 @@ Dere ve kanalizasyonlara izin ver Aralıklı su yollarına izin verin Aralıklı su yollarına izin ver - Sesli uyarı zamanı + Sesli uyarı zamanları + Çevrim içi yönlendirme motoru ekle + Çevrim içi yönlendirme motorunu düzenle + Alt tür + Araç + API anahtarı + Sunucu URL\'si + Parametre gir + Değilse boş tut + Tüm parametreleri ile URL şu şekilde görünecektir: + Güzergah hesaplamayı test et + Araba sürme + Yürüme + Bisiklet + Araba + Hata, parametreleri tekrar gözden geçirin \ No newline at end of file From 1a1bb9ca90dd5c93fb444ad1ad035dcf231b0bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Tue, 5 Jan 2021 19:56:48 +0000 Subject: [PATCH 50/61] Translated using Weblate (Hungarian) Currently translated at 100.0% (3606 of 3606 strings) --- OsmAnd/res/values-hu/strings.xml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index 2142695973..a9e91052bd 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -585,7 +585,7 @@ Keresztező utca kijelölése Legközelebbi hasznos létesítmények Térképböngészés - Vezetés + Autóvezetés Kerékpározás Gyaloglás Középen @@ -1292,7 +1292,7 @@ Közeli érdekes helyek (POI) Letöltöd a hiányzó térképeket %1$s (%2$d MB)? Térképböngészés - Autó + Személyautó Kerékpár Gyalogos Ez a bővítmény aktiválja a nyomvonalak rögzítésének és mentésének lehetőségét, ha megnyomja a GPX naplózó gombot a térképképernyőn, valamint képes minden navigációs útvonalat automatikusan egy GPX-fájlba naplózni. @@ -4019,4 +4019,20 @@ Patakok és vízelvezető árkok engedélyezése Időszakos vízfolyások engedélyezése Időszakos vízfolyások engedélyezése + Autóvezetés + Gyaloglás + Kerékpár + Személyautó + Hangutasítások ideje + Online útvonaltervező hozzáadása + Online útvonaltervező szerkesztése + Altípus + Jármű + API-kulcs + Kiszolgáló URL-je + Paraméter megadása + Hagyja üresen, ha nem + Az összes paraméterrel rendelkező URL így néz ki: + Útvonaltervezés kipróbálása + Hiba, ellenőrizze újra a paramétereket \ No newline at end of file From 1db6d38bf356f5338d49d9ac6c4af88164ecef70 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 5 Jan 2021 19:40:49 +0000 Subject: [PATCH 51/61] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3606 of 3606 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 0bd95661ef..4e70eb1284 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4024,4 +4024,19 @@ Дозволити потоки та стічні канали Дозволити потоки та стічні канали Голосові підказки + Додати мережний рушій маршрутизації + Змінити мережний рушій маршрутизації + Підтип + Транспортний засіб + Ключ API + URL-адреса сервера + Введіть параметр + Залиште порожнім, якщо ні + URL-адреса з усіма параметрами виглядатиме так: + Тестове обчислення маршруту + Водіння + Пішки + Велосипед + Автомобіль + Помилка, повторно перевірте параметри \ No newline at end of file From 3c1e653e002567d6d60758783ece0b8c92fac3b0 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 5 Jan 2021 17:43:01 +0000 Subject: [PATCH 52/61] Translated using Weblate (Hebrew) Currently translated at 99.9% (3605 of 3606 strings) --- OsmAnd/res/values-iw/strings.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 9b60953f9d..f2f971e562 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4032,4 +4032,19 @@ „ציבורי” משמעו שהעקבות מופיעים באופן ציבורי בעקבות ה־GPS שלך וברישומי עקבות GPS ציבוריים וברישומי מעקב ציבוריים עם חותמות זמן בתצורה גולמית. הנתונים שמוגשים דרך ה־API אינם מפנים אל עמוד העקבות שלך. חותמות הזמן של נקודות המעקב אינן זמינות דרך ה־API של ה־GPS ונקודות המעקב אינן מסודרות בהתאם לזמן שתועדו. „פרטי” משמעות שהעקבות לא תופענה ברישומים ציבוריים אך נקודות מעקב ממתוכן תהיינה זמינות בסדר אקראי דרך ה־API הציבורי של ה־GPS ללא חותמות זמן. זמני הכרזות + הוספת מנוע ניווט מקוון + עריכת מנוע הניווט המקוון + תת־סוג + כלי רכב + מפתח API + כתובת השרת + נא למלא משתנים + להשאיר ריק אם לא + כתובת עם כל המשתנים נראית כך: + בדיקת חישוב מסלול + נהיגה + ברגל + אופנוע + מכונית + שגיאה, נא לבדוק את המשתנים מחדש \ No newline at end of file From 5b49cedd1e6a274f3b61a3bc23528ad18903abed Mon Sep 17 00:00:00 2001 From: letypequividelespoubelles Date: Tue, 5 Jan 2021 22:04:46 +0000 Subject: [PATCH 53/61] Translated using Weblate (French) Currently translated at 99.8% (3876 of 3881 strings) --- OsmAnd/res/values-fr/phrases.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-fr/phrases.xml b/OsmAnd/res/values-fr/phrases.xml index 92e6a64d53..1d225381f7 100644 --- a/OsmAnd/res/values-fr/phrases.xml +++ b/OsmAnd/res/values-fr/phrases.xml @@ -3895,4 +3895,9 @@ Robinet Vaccination : covid19 Vaccination + Tunnel à chauve-souris + Pont à chauve- + Passage à faune + Zone de + Lavoir \ No newline at end of file From 87c3e3b53defa52aad5f40a0970562e846ec53ba Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Tue, 5 Jan 2021 23:58:49 +0000 Subject: [PATCH 54/61] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3606 of 3606 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 2064a07de1..8516bae334 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4023,4 +4023,19 @@ Permitir vias de água intermitentes Permitir vias de água intermitentes Horários de avisos de voz + Adicionar mecanismo de roteamento online + Editar mecanismo de roteamento online + Subtipo + Veículo + Chave de API + URL do servidor + Digite o parâmetro + Mantenha-o vazio se não + O URL com todos os parâmetros terá a seguinte aparência: + Cálculo da rota de teste + Dirigindo + + Bicicleta + Carro + Erro, verifique novamente os parâmetros \ No newline at end of file From a7612e369d5f1e5283e19ca7a6ab73b713e5a688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 5 Jan 2021 17:28:37 +0000 Subject: [PATCH 55/61] Translated using Weblate (Turkish) Currently translated at 80.7% (3132 of 3881 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 6fef6292b4..cf6117a083 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -944,7 +944,7 @@ Yerel yürüyüş güzergahı Yürüyüş yolu başvurusu Çalışma saatleri - Koleksiyon kez + Toplama zamanları Açıklama Telefon İnternet sitesi @@ -3137,4 +3137,12 @@ Göçmen olmayan vizeleri Askeri denetim noktası Yürüyüş denetim noktası + Dolap türü: sokak aydınlatması + Dolap türü: su yönetimi + Dolap türü: atık + Dolap türü: posta hizmeti + Dolap türü: gaz + Dolap türü: kablo tv + Dolap türü: telefon + Dolap türü: elektrik \ No newline at end of file From 599544e7ba31faf7db06a717e4eb060668b6ca41 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 6 Jan 2021 12:00:17 +0200 Subject: [PATCH 56/61] recovering deleted string value after merge --- 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 492d9d1428..df56f768f2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -4027,6 +4027,6 @@ Prefer routes of this difficulty, although routing over harder or easier pistes is still possible if shorter. Off-piste \'Freeride\' and \'Off-piste\' are unofficial routes and passages. Typically ungroomed, unmaintained and not checked in the evening. Enter at your own risk. - + Voice prompts times From 2ebbcb8a9078d19107c92de76aa8b50194f0b62e Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 6 Jan 2021 13:41:15 +0200 Subject: [PATCH 57/61] fix typo --- OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index b8835ff2c6..b2cef88e80 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -2544,7 +2544,7 @@ public class GPXUtilities { if (maxlat == null) { maxlat = parser.getAttributeValue("", "maxLat"); } - if (maxlat == null) { + if (maxlon == null) { maxlon = parser.getAttributeValue("", "maxLon"); } From 190d33681d87d8f4041df970d455d0bfb0f95e57 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 6 Jan 2021 18:12:18 +0200 Subject: [PATCH 58/61] add amenity field to MenuBuilder; remove excess R.string.poi_around; code reduction; --- OsmAnd/res/values/strings.xml | 1 - .../plus/mapcontextmenu/MenuBuilder.java | 41 ++++--------------- .../builders/AmenityMenuBuilder.java | 7 ++-- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index df56f768f2..4991659469 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,7 +12,6 @@ --> - Nearby POI Copy address Error, recheck parameters Car diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index d4f60024f6..227411a5dc 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -94,8 +94,7 @@ public class MenuBuilder { private boolean firstRow; protected boolean matchWidthDivider; protected boolean light; - private long objectId; - private String objectType; + private Amenity amenity; private LatLon latLon; private boolean hidden; private boolean showTitleIfTruncated = true; @@ -238,14 +237,8 @@ public class MenuBuilder { this.showOnlinePhotos = showOnlinePhotos; } - public void setShowNearestWiki(boolean showNearestWiki, long objectId) { - this.objectId = objectId; - this.showNearestWiki = showNearestWiki; - } - - public void setShowNearestPoi(boolean showNearestPoi, String objectType) { - this.objectType = objectType; - this.showNearestPoi = showNearestPoi; + public void setAmenity(Amenity amenity) { + this.amenity = amenity; } public void addMenuPlugin(OsmandPlugin plugin) { @@ -352,7 +345,7 @@ public class MenuBuilder { protected void buildNearestPoiRow(View view) { buildNearestRow(view, nearestPoi, processNearestPoi(), nearestPoi.isEmpty() ? 0 : AmenityMenuController.getRightIconId(nearestPoi.get(0)), - app.getString(R.string.poi_around)); + app.getString(R.string.speak_poi)); } protected void buildNearestRow(View view, List nearestAmenities, boolean process, int iconId, String text) { @@ -1155,9 +1148,7 @@ public class MenuBuilder { TextViewEx button = buildButtonInCollapsableView(context, false, false); String name = poi.getName(preferredMapAppLang, transliterateNames); if (Algorithms.isBlank(name)) { - PoiCategory pc = poi.getType(); - PoiType pt = pc.getPoiTypeByKeyName(poi.getSubType()); - name = pt.getTranslation(); + name = AmenityMenuController.getTypeStr(poi); } button.setText(name); @@ -1228,14 +1219,6 @@ public class MenuBuilder { protected boolean processNearestWiki() { if (showNearestWiki && latLon != null) { nearestWiki = getSortedAmenities(app.getPoiFilters().getTopWikiPoiFilter()); - Long id = objectId; - List wikiList = new ArrayList<>(); - for (Amenity wiki : nearestWiki) { - if (wiki.getId().equals(id)) { - wikiList.add(wiki); - } - } - nearestWiki.removeAll(wikiList); return true; } return false; @@ -1243,16 +1226,9 @@ public class MenuBuilder { protected boolean processNearestPoi() { if (showNearestPoi && latLon != null) { - nearestPoi = getSortedAmenities(app.getPoiFilters().getShowAllPOIFilter()); - Long id = objectId; - String type = objectType; - List poiList = new ArrayList<>(); - for (Amenity poi : nearestPoi) { - if (poi.getId().equals(id) || !Algorithms.stringsEqual(poi.getSubType(), type)) { - poiList.add(poi); - } - } - nearestPoi.removeAll(poiList); + PoiCategory pc = amenity.getType(); + PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType()); + nearestPoi = getSortedAmenities(app.getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + pt.getKeyName())); return true; } return false; @@ -1264,6 +1240,7 @@ public class MenuBuilder { latLon.getLatitude(), latLon.getLongitude(), 250); List nearestAmenities = getAmenities(rect, filter); + nearestAmenities.remove(amenity); Collections.sort(nearestAmenities, new Comparator() { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index b72c1a60f5..4a31a750e6 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -79,8 +79,9 @@ public class AmenityMenuBuilder extends MenuBuilder { public AmenityMenuBuilder(@NonNull MapActivity mapActivity, final @NonNull Amenity amenity) { super(mapActivity); this.amenity = amenity; - setShowNearestWiki(true, amenity.getId()); - setShowNearestPoi(true, amenity.getSubType()); + setAmenity(amenity); + setShowNearestWiki(true); + setShowNearestPoi(true); metricSystem = mapActivity.getMyApplication().getSettings().METRIC_SYSTEM.get(); } @@ -677,7 +678,7 @@ public class AmenityMenuBuilder extends MenuBuilder { if (processNearestPoi() && nearestPoi.size() > 0) { AmenityInfoRow poiInfo = new AmenityInfoRow( - "nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.poi_around) + " (" + nearestPoi.size() + ")", true, + "nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.speak_poi) + " (" + nearestPoi.size() + ")", true, getCollapsableView(view.getContext(), true, nearestPoi), 0, false, false, false, 1000, null, false, false, false, 0); buildAmenityRow(view, poiInfo); From 8d930b508a7c84004aced50dc6009f9d38696eee Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 6 Jan 2021 18:23:59 +0200 Subject: [PATCH 59/61] fix crash auth without internet connection; fix other crash; --- .../plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java | 6 +++++- .../src/net/osmand/plus/osmedit/oauth/OsmOAuthHelper.java | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java index d1c9f36e9a..abc5d1f407 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthAuthorizationAdapter.java @@ -138,7 +138,11 @@ public class OsmOAuthAuthorizationAdapter { @Override protected void onPostExecute(@NonNull OAuth1RequestToken requestToken) { - loadWebView(rootLayout, nightMode, client.getService().getAuthorizationUrl(requestToken)); + if (requestToken != null) { + loadWebView(rootLayout, nightMode, client.getService().getAuthorizationUrl(requestToken)); + } else { + app.showShortToastMessage(app.getString(R.string.internet_not_available)); + } } } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthHelper.java b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthHelper.java index 8db1079b8b..0eed60b924 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthHelper.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/oauth/OsmOAuthHelper.java @@ -45,7 +45,11 @@ public class OsmOAuthHelper { } public void authorize(@NonNull String oauthVerifier) { - authorizationAdapter.authorize(oauthVerifier, this); + if (oauthVerifier != null) { + authorizationAdapter.authorize(oauthVerifier, this); + } else { + updateAdapter(); + } } public void resetAuthorization() { From 38249b1122c100b9131a19411fb76fc60199fae3 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Wed, 6 Jan 2021 18:58:50 +0200 Subject: [PATCH 60/61] Fix #10437 (2) --- OsmAnd/res/layout/fragment_help_article.xml | 2 +- .../fragment_wikivoyage_article_dialog.xml | 2 +- OsmAnd/res/layout/help_activity.xml | 3 +- OsmAnd/res/layout/mapillary_web_view.xml | 4 +- OsmAnd/res/layout/print_dialog.xml | 2 +- .../res/layout/wikipedia_dialog_fragment.xml | 2 +- .../ObservableWebView.java | 5 +- OsmAnd/src/net/osmand/AndroidUtils.java | 12 ----- .../osmand/plus/activities/ExitActivity.java | 2 - .../plus/activities/PrintDialogActivity.java | 2 - .../dialogs/HelpArticleDialogFragment.java | 1 - .../builders/cards/AbstractCard.java | 6 ++- .../plus/mapillary/MapillaryImageDialog.java | 1 - .../GpxDescriptionDialogFragment.java | 3 +- .../net/osmand/plus/widgets/WebViewEx.java | 49 +++++++++++++++++++ .../wikipedia/WikipediaDialogFragment.java | 1 - .../WikivoyageArticleDialogFragment.java | 1 - 17 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/widgets/WebViewEx.java diff --git a/OsmAnd/res/layout/fragment_help_article.xml b/OsmAnd/res/layout/fragment_help_article.xml index cd4456a080..bb6e44b2a2 100644 --- a/OsmAnd/res/layout/fragment_help_article.xml +++ b/OsmAnd/res/layout/fragment_help_article.xml @@ -14,7 +14,7 @@ app:theme="?attr/toolbar_theme" android:background="?attr/pstsTabBackground"/> - diff --git a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml index c001ab748e..76fe893831 100644 --- a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml +++ b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml @@ -64,7 +64,7 @@ android:layout_weight="1" android:layout_height="0dp"> - diff --git a/OsmAnd/res/layout/help_activity.xml b/OsmAnd/res/layout/help_activity.xml index 8ae5922aa6..d7f2d97070 100644 --- a/OsmAnd/res/layout/help_activity.xml +++ b/OsmAnd/res/layout/help_activity.xml @@ -4,7 +4,8 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - diff --git a/OsmAnd/res/layout/mapillary_web_view.xml b/OsmAnd/res/layout/mapillary_web_view.xml index 3afc91e2af..3e2459b375 100644 --- a/OsmAnd/res/layout/mapillary_web_view.xml +++ b/OsmAnd/res/layout/mapillary_web_view.xml @@ -4,12 +4,12 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - + - diff --git a/OsmAnd/res/layout/wikipedia_dialog_fragment.xml b/OsmAnd/res/layout/wikipedia_dialog_fragment.xml index 91714016cd..ae21c22585 100644 --- a/OsmAnd/res/layout/wikipedia_dialog_fragment.xml +++ b/OsmAnd/res/layout/wikipedia_dialog_fragment.xml @@ -74,7 +74,7 @@ android:layout_height="0dp" android:layout_weight="1"> - diff --git a/OsmAnd/src/com/github/ksoichiro/android/observablescrollview/ObservableWebView.java b/OsmAnd/src/com/github/ksoichiro/android/observablescrollview/ObservableWebView.java index 3e023f74a5..30ee12b52b 100644 --- a/OsmAnd/src/com/github/ksoichiro/android/observablescrollview/ObservableWebView.java +++ b/OsmAnd/src/com/github/ksoichiro/android/observablescrollview/ObservableWebView.java @@ -23,12 +23,13 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.webkit.WebView; + +import net.osmand.plus.widgets.WebViewEx; /** * WebView that its scroll position can be observed. */ -public class ObservableWebView extends WebView implements Scrollable { +public class ObservableWebView extends WebViewEx implements Scrollable { // Fields that should be saved onSaveInstanceState private int mPrevScrollY; diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index f1ad8fd72d..545e7b7391 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -968,16 +968,4 @@ public class AndroidUtils { } return null; } - - public static void fixWebViewResetsLocaleToUserDefault(Activity activity) { - // issue details: https://issuetracker.google.com/issues/37113860 - // also see: https://gist.github.com/amake/0ac7724681ac1c178c6f95a5b09f03ce - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - OsmandApplication app = (OsmandApplication) activity.getApplicationContext(); - app.checkPreferredLocale(); - activity.getResources().updateConfiguration( - new Configuration(app.getResources().getConfiguration()), - activity.getResources().getDisplayMetrics()); - } - } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java b/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java index 5097a4f0cc..67beabb1ad 100644 --- a/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/ExitActivity.java @@ -1,6 +1,5 @@ package net.osmand.plus.activities; -import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import android.app.Activity; @@ -15,7 +14,6 @@ public class ExitActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.help_activity); - AndroidUtils.fixWebViewResetsLocaleToUserDefault(this); dis = getIntent().getBooleanExtra(DISABLE_SERVICE, true); } diff --git a/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java b/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java index b2211a639d..0963b4d782 100644 --- a/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/PrintDialogActivity.java @@ -3,7 +3,6 @@ */ package net.osmand.plus.activities; -import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import android.annotation.SuppressLint; @@ -43,7 +42,6 @@ public class PrintDialogActivity extends ActionBarProgressActivity { getSupportActionBar().setTitle(R.string.print_route); setContentView(R.layout.print_dialog); - AndroidUtils.fixWebViewResetsLocaleToUserDefault(this); webView = (WebView) findViewById(R.id.printDialogWebview); Intent intent = getIntent(); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java index 3c47372356..42a036599c 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/HelpArticleDialogFragment.java @@ -54,7 +54,6 @@ public class HelpArticleDialogFragment extends DialogFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_help_article, container, false); - AndroidUtils.fixWebViewResetsLocaleToUserDefault(getActivity()); Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); toolbar.setNavigationIcon(AndroidUtils.getNavigationIconResId(getContext())); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/AbstractCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/AbstractCard.java index 82d935b091..73964b03d1 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/AbstractCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/AbstractCard.java @@ -1,6 +1,7 @@ package net.osmand.plus.mapcontextmenu.builders.cards; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.Intent; @@ -23,6 +24,7 @@ import androidx.core.content.ContextCompat; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.widgets.WebViewEx; public abstract class AbstractCard { @@ -55,7 +57,7 @@ public abstract class AbstractCard { @SuppressLint("SetJavaScriptEnabled") @SuppressWarnings("deprecation") - protected static void openUrl(@NonNull Context ctx, + protected static void openUrl(@NonNull Activity ctx, @NonNull OsmandApplication app, @Nullable String title, @NonNull String url, @@ -90,7 +92,7 @@ public abstract class AbstractCard { } }); - final WebView wv = new WebView(ctx); + final WebView wv = new WebViewEx(ctx); wv.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java index d20f03f4fe..7b9cd23b69 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageDialog.java @@ -220,7 +220,6 @@ public class MapillaryImageDialog extends ContextMenuCardDialog { @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) private View getWebView() { View view = getMapActivity().getLayoutInflater().inflate(R.layout.mapillary_web_view, null); - AndroidUtils.fixWebViewResetsLocaleToUserDefault(getMapActivity()); final WebView webView = view.findViewById(R.id.webView); webView.setBackgroundColor(Color.argb(1, 0, 0, 0)); final View noInternetView = view.findViewById(R.id.mapillaryNoInternetLayout); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GpxDescriptionDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/GpxDescriptionDialogFragment.java index 7cab05bc3a..aa17926449 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GpxDescriptionDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GpxDescriptionDialogFragment.java @@ -19,6 +19,7 @@ import com.google.android.material.appbar.AppBarLayout; import net.osmand.AndroidUtils; import net.osmand.plus.R; import net.osmand.plus.base.BaseOsmAndDialogFragment; +import net.osmand.plus.widgets.WebViewEx; public class GpxDescriptionDialogFragment extends BaseOsmAndDialogFragment { @@ -48,7 +49,7 @@ public class GpxDescriptionDialogFragment extends BaseOsmAndDialogFragment { AppBarLayout appBar = new AppBarLayout(ctx); appBar.addView(topBar); - WebView webView = new WebView(ctx); + WebView webView = new WebViewEx(ctx); webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); webView.getSettings().setTextZoom((int) (getResources().getConfiguration().fontScale * 100f)); Bundle args = getArguments(); diff --git a/OsmAnd/src/net/osmand/plus/widgets/WebViewEx.java b/OsmAnd/src/net/osmand/plus/widgets/WebViewEx.java new file mode 100644 index 0000000000..c83e1110cb --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/widgets/WebViewEx.java @@ -0,0 +1,49 @@ +package net.osmand.plus.widgets; + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.util.AttributeSet; +import android.webkit.WebView; + +import net.osmand.plus.OsmandApplication; + +public class WebViewEx extends WebView { + + public WebViewEx(Context context) { + super(context); + fixWebViewResetsLocaleToUserDefault(context); + } + + public WebViewEx(Context context, AttributeSet attrs) { + super(context, attrs); + fixWebViewResetsLocaleToUserDefault(context); + } + + public WebViewEx(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + fixWebViewResetsLocaleToUserDefault(context); + } + + public WebViewEx(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + fixWebViewResetsLocaleToUserDefault(context); + } + + public WebViewEx(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) { + super(context, attrs, defStyleAttr, privateBrowsing); + fixWebViewResetsLocaleToUserDefault(context); + } + + public void fixWebViewResetsLocaleToUserDefault(Context ctx) { + // issue details: https://issuetracker.google.com/issues/37113860 + // also see: https://gist.github.com/amake/0ac7724681ac1c178c6f95a5b09f03ce + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + OsmandApplication app = (OsmandApplication) ctx.getApplicationContext(); + app.checkPreferredLocale(); + ctx.getResources().updateConfiguration( + new Configuration(app.getResources().getConfiguration()), + ctx.getResources().getDisplayMetrics()); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java index 1ea89040cd..17a8500361 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaDialogFragment.java @@ -72,7 +72,6 @@ public class WikipediaDialogFragment extends WikiArticleBaseDialogFragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View mainView = inflater.inflate(R.layout.wikipedia_dialog_fragment, container, false); - AndroidUtils.fixWebViewResetsLocaleToUserDefault(getActivity()); setupToolbar((Toolbar) mainView.findViewById(R.id.toolbar)); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index bc322b31fe..9303fb7b84 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -91,7 +91,6 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme } final View mainView = inflate(R.layout.fragment_wikivoyage_article_dialog, container); - AndroidUtils.fixWebViewResetsLocaleToUserDefault(getActivity()); setupToolbar((Toolbar) mainView.findViewById(R.id.toolbar)); From 7a59047a5df0d23241e4777db0ac5538a6a60c16 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 6 Jan 2021 19:42:13 +0200 Subject: [PATCH 61/61] Fix nearest wiki --- .../plus/mapcontextmenu/MenuBuilder.java | 46 +++++++++++++------ .../builders/AmenityMenuBuilder.java | 2 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 227411a5dc..d11d27d34c 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -29,12 +29,14 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ContextThemeWrapper; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; + import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.data.Amenity; @@ -44,7 +46,12 @@ import net.osmand.data.QuadRect; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; import net.osmand.osm.io.NetworkUtils; -import net.osmand.plus.*; +import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.Version; import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; @@ -68,6 +75,7 @@ import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.tools.ClickableSpanTouchListener; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; + import org.apache.commons.logging.Log; import org.openplacereviews.opendb.util.exception.FailedVerificationException; @@ -75,7 +83,13 @@ import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; @@ -214,8 +228,8 @@ public class MenuBuilder { } public boolean isShowNearestPoi() { - return showNearestPoi; - } + return showNearestPoi; + } public void setShowNearestWiki(boolean showNearestWiki) { this.showNearestWiki = showNearestWiki; @@ -1217,27 +1231,31 @@ public class MenuBuilder { } protected boolean processNearestWiki() { - if (showNearestWiki && latLon != null) { - nearestWiki = getSortedAmenities(app.getPoiFilters().getTopWikiPoiFilter()); - return true; + if (showNearestWiki && latLon != null && amenity != null) { + PoiUIFilter filter = app.getPoiFilters().getTopWikiPoiFilter(); + if (filter != null) { + nearestWiki = getSortedAmenities(filter, latLon); + return true; + } } return false; } protected boolean processNearestPoi() { - if (showNearestPoi && latLon != null) { + if (showNearestPoi && latLon != null && amenity != null) { PoiCategory pc = amenity.getType(); PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType()); - nearestPoi = getSortedAmenities(app.getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + pt.getKeyName())); - return true; + PoiUIFilter filter = app.getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + pt.getKeyName()); + if (filter != null) { + nearestPoi = getSortedAmenities(filter, latLon); + return true; + } } return false; } - private List getSortedAmenities(PoiUIFilter filter) { - final LatLon latLon = getLatLon(); - QuadRect rect = MapUtils.calculateLatLonBbox( - latLon.getLatitude(), latLon.getLongitude(), 250); + private List getSortedAmenities(PoiUIFilter filter, final LatLon latLon) { + QuadRect rect = MapUtils.calculateLatLonBbox(latLon.getLatitude(), latLon.getLongitude(), 250); List nearestAmenities = getAmenities(rect, filter); nearestAmenities.remove(amenity); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 4a31a750e6..c0db653e3e 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -81,7 +81,7 @@ public class AmenityMenuBuilder extends MenuBuilder { this.amenity = amenity; setAmenity(amenity); setShowNearestWiki(true); - setShowNearestPoi(true); + setShowNearestPoi(!amenity.getType().isWiki()); metricSystem = mapActivity.getMyApplication().getSettings().METRIC_SYSTEM.get(); }