diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 1d1a4691d8..cd8bf89570 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -469,7 +469,9 @@
-
+
+#include
+#include
+#include "routing/routing_options.hpp"
+
+unsigned int makeValue(jint option)
+{
+ return 1u >> option;
+}
+
+extern "C"
+{
+
+JNIEXPORT jboolean JNICALL
+Java_com_mapswithme_maps_bookmarks_data_RoutingOptions_nativeHasOption(JNIEnv * env, jclass clazz, jint option)
+{
+ CHECK(g_framework, ("Framework isn't created yet!"));
+ routing::RoutingOptions routingOptions = routing::RoutingOptions::LoadCarOptionsFromSettings();
+ routing::RoutingOptions::Road road = static_cast(makeValue(option));
+ return static_cast(routingOptions.Has(road));
+}
+
+JNIEXPORT void JNICALL
+Java_com_mapswithme_maps_bookmarks_data_RoutingOptions_nativeAddOption(JNIEnv * env, jclass clazz, jint option)
+{
+ CHECK(g_framework, ("Framework isn't created yet!"));
+ routing::RoutingOptions routingOptions = routing::RoutingOptions::LoadCarOptionsFromSettings();
+ routing::RoutingOptions::Road road = static_cast(makeValue(option));
+ routingOptions.Add(road);
+ routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions);
+}
+
+
+JNIEXPORT void JNICALL
+Java_com_mapswithme_maps_bookmarks_data_RoutingOptions_nativeRemoveOption(JNIEnv * env, jclass clazz, jint option)
+{
+ CHECK(g_framework, ("Framework isn't created yet!"));
+ routing::RoutingOptions routingOptions = routing::RoutingOptions::LoadCarOptionsFromSettings();
+ routing::RoutingOptions::Road road = static_cast(makeValue(option));
+ routingOptions.Remove(road);
+ routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions);
+}
+}
diff --git a/android/res/layout/fragment_driving_options.xml b/android/res/layout/fragment_driving_options.xml
new file mode 100644
index 0000000000..f0f4dfb83e
--- /dev/null
+++ b/android/res/layout/fragment_driving_options.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/res/menu/menu_driving_options.xml b/android/res/menu/menu_driving_options.xml
new file mode 100644
index 0000000000..e43d9e1059
--- /dev/null
+++ b/android/res/menu/menu_driving_options.xml
@@ -0,0 +1,11 @@
+
+
diff --git a/android/res/xml/prefs_main.xml b/android/res/xml/prefs_main.xml
index 5e75457216..e197518697 100644
--- a/android/res/xml/prefs_main.xml
+++ b/android/res/xml/prefs_main.xml
@@ -112,6 +112,13 @@
android:entries="@array/power_management_scheme"
android:entryValues="@array/power_management_scheme_values"
android:order="15"/>
+
+
+
mTasks = new Stack<>();
@@ -2694,4 +2698,29 @@ public class MwmActivity extends BaseMwmFragmentActivity
getActivity().startLocationToPoint(null, false);
}
}
+
+ public void showUnableCalculateRouteDialog()
+ {
+ com.mapswithme.maps.dialog.AlertDialog dialog = new com.mapswithme.maps.dialog.AlertDialog.Builder()
+ .setTitleId(R.string.unable_to_recalc_title)
+ .setMessageId(R.string.unable_to_recalc_subtitle)
+ .setPositiveBtnId(R.string.ok)
+ .setReqCode(REQ_CODE_ERROR_CALCULATE_ROUTE)
+ .setFragManagerStrategyType(com.mapswithme.maps.dialog.AlertDialog.FragManagerStrategyType.ACTIVITY_FRAGMENT_MANAGER)
+ .build();
+ dialog.show(getSupportFragmentManager(), ERROR_CALCULATE_ROUTE);
+ }
+
+ public void showUnableCalculateRouteFirstTimeDialog()
+ {
+ com.mapswithme.maps.dialog.AlertDialog dialog = new com.mapswithme.maps.dialog.AlertDialog.Builder()
+ .setTitleId(R.string.unable_to_calc_alert_subtitle)
+ .setMessageId(R.string.unable_to_calc_alert_subtitle)
+ .setPositiveBtnId(R.string.options)
+ .setNegativeBtnId(R.string.cancel)
+ .setReqCode(REQ_CODE_ERROR_CALCULATE_ROUTE_FIRST_TIME)
+ .setFragManagerStrategyType(com.mapswithme.maps.dialog.AlertDialog.FragManagerStrategyType.ACTIVITY_FRAGMENT_MANAGER)
+ .build();
+ dialog.show(getSupportFragmentManager(), ERROR_CALCULATE_ROUTE_FIRST_TIME);
+ }
}
diff --git a/android/src/com/mapswithme/maps/bookmarks/data/RoutingOptions.java b/android/src/com/mapswithme/maps/bookmarks/data/RoutingOptions.java
new file mode 100644
index 0000000000..c23f7b8515
--- /dev/null
+++ b/android/src/com/mapswithme/maps/bookmarks/data/RoutingOptions.java
@@ -0,0 +1,8 @@
+package com.mapswithme.maps.bookmarks.data;
+
+public class RoutingOptions
+{
+ public static native void nativeAddOption(int option);
+ public static native void nativeRemoveOption(int option);
+ public static native boolean nativeHasOption(int option);
+}
diff --git a/android/src/com/mapswithme/maps/settings/DrivingOptionsActivity.java b/android/src/com/mapswithme/maps/settings/DrivingOptionsActivity.java
new file mode 100644
index 0000000000..dc63a0a948
--- /dev/null
+++ b/android/src/com/mapswithme/maps/settings/DrivingOptionsActivity.java
@@ -0,0 +1,26 @@
+package com.mapswithme.maps.settings;
+
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+
+import com.mapswithme.maps.base.BaseMwmFragmentActivity;
+
+public class DrivingOptionsActivity extends BaseMwmFragmentActivity
+{
+ public static final String BUNDLE_REQUIRE_OPTIONS_MENU = "require_options_menu";
+
+ @Override
+ protected Class extends Fragment> getFragmentClass()
+ {
+ return DrivingOptionsFragment.class;
+ }
+
+ public static void startOptionMenuActivity(@NonNull FragmentActivity activity)
+ {
+ Intent intent = new Intent(activity, DrivingOptionsActivity.class)
+ .putExtra(BUNDLE_REQUIRE_OPTIONS_MENU, true);
+ activity.startActivity(intent);
+ }
+}
diff --git a/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java b/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java
new file mode 100644
index 0000000000..2484a1de38
--- /dev/null
+++ b/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java
@@ -0,0 +1,101 @@
+package com.mapswithme.maps.settings;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.Switch;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmToolbarFragment;
+import com.mapswithme.maps.bookmarks.data.RoutingOptions;
+
+public class DrivingOptionsFragment extends BaseMwmToolbarFragment
+{
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState)
+ {
+ View root = inflater.inflate(R.layout.fragment_driving_options, container, false);
+ initViews(root);
+ setHasOptionsMenu(hasBundleOptionsMenu());
+ return root;
+ }
+
+ private boolean hasBundleOptionsMenu()
+ {
+ Bundle arguments = getArguments();
+ if (arguments == null)
+ return false;
+
+ return arguments.getBoolean(DrivingOptionsActivity.BUNDLE_REQUIRE_OPTIONS_MENU, false);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
+ {
+ inflater.inflate(R.menu.menu_tags_done, menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ if (item.getItemId() == R.id.done)
+ {
+ requireActivity().finish();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void initViews(@NonNull View root)
+ {
+ Switch avoidTollsBtn = root.findViewById(R.id.avoid_tolls_btn);
+ CompoundButton.OnCheckedChangeListener tollBtnListener =
+ new ToggleRoutingOptionListener(RoadType.TOLL);
+ avoidTollsBtn.setOnCheckedChangeListener(tollBtnListener);
+
+ Switch avoidMotorwaysBtn = root.findViewById(R.id.avoid_motorways_btn);
+ CompoundButton.OnCheckedChangeListener motorwayBtnListener =
+ new ToggleRoutingOptionListener(RoadType.MOTORWAY);
+ avoidMotorwaysBtn.setOnCheckedChangeListener(motorwayBtnListener);
+
+ Switch avoidFerriesBtn = root.findViewById(R.id.avoid_ferries_btn);
+ CompoundButton.OnCheckedChangeListener ferryBtnListener =
+ new ToggleRoutingOptionListener(RoadType.FERRY);
+ avoidFerriesBtn.setOnCheckedChangeListener(ferryBtnListener);
+
+ Switch avoidDirtyRoadsBtn = root.findViewById(R.id.avoid_dirty_roads_btn);
+ CompoundButton.OnCheckedChangeListener dirtyBtnListener =
+ new ToggleRoutingOptionListener(RoadType.DIRTY);
+ avoidDirtyRoadsBtn.setOnCheckedChangeListener(dirtyBtnListener);
+ }
+
+ private static class ToggleRoutingOptionListener implements CompoundButton.OnCheckedChangeListener
+ {
+ @NonNull
+ private final RoadType mRoadType;
+
+ private ToggleRoutingOptionListener(@NonNull RoadType roadType)
+ {
+ mRoadType = roadType;
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
+ {
+ if (isChecked)
+ RoutingOptions.nativeAddOption(mRoadType.ordinal());
+ else
+ RoutingOptions.nativeRemoveOption(mRoadType.ordinal());
+ }
+ }
+}
diff --git a/android/src/com/mapswithme/maps/settings/RoadType.java b/android/src/com/mapswithme/maps/settings/RoadType.java
new file mode 100644
index 0000000000..e194981211
--- /dev/null
+++ b/android/src/com/mapswithme/maps/settings/RoadType.java
@@ -0,0 +1,10 @@
+package com.mapswithme.maps.settings;
+
+public enum RoadType
+{
+ USUAL,
+ TOLL,
+ MOTORWAY,
+ FERRY,
+ DIRTY
+}
diff --git a/routing/routing_options.cpp b/routing/routing_options.cpp
index 9067ad5eda..7b9d8a140f 100644
--- a/routing/routing_options.cpp
+++ b/routing/routing_options.cpp
@@ -121,7 +121,7 @@ RoutingOptions::Road ChooseMainRoutingOptionRoad(RoutingOptions options)
string DebugPrint(RoutingOptions const & routingOptions)
{
ostringstream ss;
- ss << "RoutingOptions: {";
+ ss << "RoadType: {";
bool wasAppended = false;
auto const append = [&](RoutingOptions::Road road) {