diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index c1fdc7c5de..04996c9fa1 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,12 @@ Thx - Hardy --> + All previous segments will be recalculated using selected profile. + All next segments will be recalculated using selected profile. + Only selected segment will be recalculated using selected profile. + All previous segments + Previous segment + All next segments System Default Resume trip recording Pause trip recording diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 32b469db06..74bdbce787 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -34,6 +34,7 @@ import net.osmand.util.MapUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -61,11 +62,11 @@ public class MeasurementEditingContext { private boolean inAddPointMode; private int calculatedPairs; private int pointsToCalculateSize; - private CalculationMode calculationMode = WHOLE_TRACK; + private CalculationMode lastCalculationMode = WHOLE_TRACK; private SnapToRoadProgressListener progressListener; private ApplicationMode appMode = DEFAULT_APP_MODE; private RouteCalculationProgress calculationProgress; - private final Map, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>(); + private Map, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>(); public enum CalculationMode { NEXT_SEGMENT, @@ -195,12 +196,12 @@ public class MeasurementEditingContext { return gpxData != null && gpxData.getGpxFile() != null && gpxData.getGpxFile().hasRoute(); } - public CalculationMode getCalculationMode() { - return calculationMode; + public CalculationMode getLastCalculationMode() { + return lastCalculationMode; } - public void setCalculationMode(CalculationMode calculationMode) { - this.calculationMode = calculationMode; + public void setLastCalculationMode(CalculationMode lastCalculationMode) { + this.lastCalculationMode = lastCalculationMode; } void setProgressListener(SnapToRoadProgressListener progressListener) { @@ -237,6 +238,14 @@ public class MeasurementEditingContext { return distance; } + public Map, RoadSegmentData> getRoadSegmentData() { + return new HashMap<>(roadSegmentData); + } + + public void setRoadSegmentData(Map, RoadSegmentData> roadSegmentData) { + this.roadSegmentData = new ConcurrentHashMap<>(roadSegmentData); + } + public boolean hasRoute() { return !roadSegmentData.isEmpty(); } @@ -350,6 +359,19 @@ public class MeasurementEditingContext { return selectedPointPosition == getPoints().size() - 1; } + public ApplicationMode getSelectedPointAppMode() { + return getPointAppMode(selectedPointPosition); + } + + public ApplicationMode getBeforeSelectedPointAppMode() { + return getPointAppMode(Math.max(selectedPointPosition - 1, 0)); + } + + private ApplicationMode getPointAppMode(int pointPosition) { + String profileType = getPoints().get(pointPosition).getProfileType(); + return ApplicationMode.valueOfStringKey(profileType, MeasurementEditingContext.DEFAULT_APP_MODE); + } + public void scheduleRouteCalculateIfNotEmpty() { if (application == null || (before.points.size() == 0 && after.points.size() == 0)) { return; diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 736ed66d50..db1aa41bd8 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -63,6 +63,8 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.measurementtool.GpxApproximationFragment.GpxApproximationFragmentListener; import net.osmand.plus.measurementtool.GpxData.ActionType; import net.osmand.plus.measurementtool.OptionsBottomSheetDialogFragment.OptionsFragmentListener; +import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsDialogMode; +import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsDialogType; import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsFragmentListener; import net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener; import net.osmand.plus.measurementtool.SelectedPointBottomSheetDialogFragment.SelectedPointFragmentListener; @@ -71,6 +73,7 @@ import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter.Measuremen import net.osmand.plus.measurementtool.command.AddPointCommand; import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand; import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand; +import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand.ChangeRouteType; import net.osmand.plus.measurementtool.command.ClearPointsCommand; import net.osmand.plus.measurementtool.command.MovePointCommand; import net.osmand.plus.measurementtool.command.RemovePointCommand; @@ -101,8 +104,10 @@ import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.ADD_TO_ import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.SelectFileListener; import static net.osmand.plus.measurementtool.StartPlanRouteBottomSheet.StartPlanRouteListener; -import static net.osmand.plus.measurementtool.command.ClearPointsCommand.*; -import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.*; +import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode; +import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.AFTER; +import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.ALL; +import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.BEFORE; public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener, OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener { @@ -573,7 +578,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route if (editingCtx.isNewData() || editingCtx.hasRoutePoints() || editingCtx.hasRoute() || editingCtx.getPointsCount() < 2) { RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), - this, editingCtx.getCalculationMode(), + this, RouteBetweenPointsDialogType.WHOLE_ROUTE_CALCULATION, + editingCtx.getLastCalculationMode() == CalculationMode.NEXT_SEGMENT + ? RouteBetweenPointsDialogMode.SINGLE + : RouteBetweenPointsDialogMode.ALL, editingCtx.getAppMode()); } else { SnapTrackWarningBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), this); @@ -759,12 +767,24 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route @Override public void onChangeRouteTypeBefore() { - + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), + this, RouteBetweenPointsDialogType.PREV_ROUTE_CALCULATION, + RouteBetweenPointsDialogMode.SINGLE, + editingCtx.getBeforeSelectedPointAppMode()); + } } @Override public void onChangeRouteTypeAfter() { - + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), + this, RouteBetweenPointsDialogType.NEXT_ROUTE_CALCULATION, + RouteBetweenPointsDialogMode.SINGLE, + editingCtx.getSelectedPointAppMode()); + } } @Override @@ -780,6 +800,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route @Override public void onCloseRouteDialog() { toolBarController.setTitle(previousToolBarTitle); + editingCtx.setSelectedPointPosition(-1); MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { mapActivity.refreshMap(); @@ -787,10 +808,26 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } @Override - public void onChangeApplicationMode(ApplicationMode mode, CalculationMode calculationMode) { + public void onChangeApplicationMode(ApplicationMode mode, RouteBetweenPointsDialogType dialogType, + RouteBetweenPointsDialogMode dialogMode) { MeasurementToolLayer measurementLayer = getMeasurementLayer(); if (measurementLayer != null) { - editingCtx.getCommandManager().execute(new ChangeRouteModeCommand(measurementLayer, mode, calculationMode)); + ChangeRouteType changeRouteType = ChangeRouteType.NEXT_SEGMENT; + switch (dialogType) { + case WHOLE_ROUTE_CALCULATION: + changeRouteType = dialogMode == RouteBetweenPointsDialogMode.SINGLE + ? ChangeRouteType.LAST_SEGMENT : ChangeRouteType.WHOLE_ROUTE; + break; + case NEXT_ROUTE_CALCULATION: + changeRouteType = dialogMode == RouteBetweenPointsDialogMode.SINGLE + ? ChangeRouteType.NEXT_SEGMENT : ChangeRouteType.ALL_NEXT_SEGMENTS; + break; + case PREV_ROUTE_CALCULATION: + changeRouteType = dialogMode == RouteBetweenPointsDialogMode.SINGLE + ? ChangeRouteType.PREV_SEGMENT : ChangeRouteType.ALL_PREV_SEGMENTS; + break; + } + editingCtx.getCommandManager().execute(new ChangeRouteModeCommand(measurementLayer, mode, changeRouteType, editingCtx.getSelectedPointPosition())); updateUndoRedoButton(false, redoBtn); updateUndoRedoButton(true, undoBtn); disable(upDownBtn); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java index 29f1294a42..1cad5b12aa 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java @@ -26,7 +26,6 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode; import net.osmand.plus.settings.backend.ApplicationMode; import org.apache.commons.logging.Log; @@ -36,8 +35,6 @@ import java.util.List; import static net.osmand.plus.UiUtilities.CustomRadioButtonType.LEFT; import static net.osmand.plus.UiUtilities.CustomRadioButtonType.RIGHT; -import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.NEXT_SEGMENT; -import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.WHOLE_TRACK; import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE; public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDialogFragment { @@ -45,27 +42,42 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial private static final Log LOG = PlatformUtil.getLog(RouteBetweenPointsBottomSheetDialogFragment.class); public static final String TAG = RouteBetweenPointsBottomSheetDialogFragment.class.getSimpleName(); public static final int STRAIGHT_LINE_TAG = -1; - public static final String CALCULATION_MODE_KEY = "calculation_type"; + public static final String DIALOG_TYPE_KEY = "dialog_type_key"; + public static final String DEFAULT_DIALOG_MODE_KEY = "default_dialog_mode_key"; public static final String ROUTE_APP_MODE_KEY = "route_app_mode"; private boolean nightMode; private boolean portrait; private TextView btnDescription; - private CalculationMode calculationMode = WHOLE_TRACK; + private RouteBetweenPointsDialogType dialogType = RouteBetweenPointsDialogType.WHOLE_ROUTE_CALCULATION; + private RouteBetweenPointsDialogMode defaultDialogMode = RouteBetweenPointsDialogMode.SINGLE; private ApplicationMode appMode; private LinearLayout customRadioButton; + public enum RouteBetweenPointsDialogType { + WHOLE_ROUTE_CALCULATION, + NEXT_ROUTE_CALCULATION, + PREV_ROUTE_CALCULATION + } + + public enum RouteBetweenPointsDialogMode { + SINGLE, + ALL, + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle args = getArguments(); if (args != null) { appMode = ApplicationMode.valueOfStringKey(args.getString(ROUTE_APP_MODE_KEY), null); - calculationMode = (CalculationMode) args.get(CALCULATION_MODE_KEY); + dialogType = (RouteBetweenPointsDialogType) args.get(DIALOG_TYPE_KEY); + defaultDialogMode = (RouteBetweenPointsDialogMode) args.get(DEFAULT_DIALOG_MODE_KEY); } if (savedInstanceState != null) { - calculationMode = (CalculationMode) savedInstanceState.get(CALCULATION_MODE_KEY); + dialogType = (RouteBetweenPointsDialogType) savedInstanceState.get(DIALOG_TYPE_KEY); + defaultDialogMode = (RouteBetweenPointsDialogMode) savedInstanceState.get(DEFAULT_DIALOG_MODE_KEY); } OsmandApplication app = requiredMyApplication(); nightMode = app.getDaynightHelper().isNightModeForMapControls(); @@ -89,10 +101,10 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial }); customRadioButton = mainView.findViewById(R.id.custom_radio_buttons); - TextView segmentBtn = mainView.findViewById(R.id.left_button); - segmentBtn.setText(R.string.next_segment); - TextView wholeTrackBtn = mainView.findViewById(R.id.right_button); - wholeTrackBtn.setText(R.string.whole_track); + TextView singleModeButton = mainView.findViewById(R.id.left_button); + singleModeButton.setText(getButtonText(RouteBetweenPointsDialogMode.SINGLE)); + TextView allModeButton = mainView.findViewById(R.id.right_button); + allModeButton.setText(getButtonText(RouteBetweenPointsDialogMode.ALL)); btnDescription = mainView.findViewById(R.id.button_description); LinearLayout navigationType = mainView.findViewById(R.id.navigation_types_container); @@ -108,7 +120,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial } Fragment fragment = getTargetFragment(); if (fragment instanceof RouteBetweenPointsFragmentListener) { - ((RouteBetweenPointsFragmentListener) fragment).onChangeApplicationMode(mode, calculationMode); + ((RouteBetweenPointsFragmentListener) fragment).onChangeApplicationMode(mode, dialogType, defaultDialogMode); } dismiss(); } @@ -127,22 +139,82 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial } } - segmentBtn.setOnClickListener(new View.OnClickListener() { + singleModeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - updateModeButtons(NEXT_SEGMENT); + setDefaultDialogMode(RouteBetweenPointsDialogMode.SINGLE); } }); - wholeTrackBtn.setOnClickListener(new View.OnClickListener() { + allModeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - updateModeButtons(WHOLE_TRACK); + setDefaultDialogMode(RouteBetweenPointsDialogMode.ALL); } }); - updateModeButtons(calculationMode); + updateModeButtons(); return mainView; } + private String getButtonText(RouteBetweenPointsDialogMode dialogMode) { + switch (dialogType) { + case WHOLE_ROUTE_CALCULATION: + switch (dialogMode) { + case SINGLE: + return getString(R.string.next_segment); + case ALL: + return getString(R.string.whole_track); + } + break; + case NEXT_ROUTE_CALCULATION: + switch (dialogMode) { + case SINGLE: + return getString(R.string.next_segment); + case ALL: + return getString(R.string.all_next_segments); + } + break; + case PREV_ROUTE_CALCULATION: + switch (dialogMode) { + case SINGLE: + return getString(R.string.previous_segment); + case ALL: + return getString(R.string.all_previous_segments); + } + break; + } + return ""; + } + + private String getButtonDescr(RouteBetweenPointsDialogMode dialogMode) { + switch (dialogType) { + case WHOLE_ROUTE_CALCULATION: + switch (dialogMode) { + case SINGLE: + return getString(R.string.rourte_between_points_next_segment_button_desc); + case ALL: + return getString(R.string.rourte_between_points_whole_track_button_desc); + } + break; + case NEXT_ROUTE_CALCULATION: + switch (dialogMode) { + case SINGLE: + return getString(R.string.only_selected_segment_recalc); + case ALL: + return getString(R.string.all_next_segments_will_be_recalc); + } + break; + case PREV_ROUTE_CALCULATION: + switch (dialogMode) { + case SINGLE: + return getString(R.string.only_selected_segment_recalc); + case ALL: + return getString(R.string.all_previous_segments_will_be_recalc); + } + break; + } + return ""; + } + private void addDelimiterView(LinearLayout container) { View row = UiUtilities.getInflater(getContext(), nightMode).inflate(R.layout.divider, container, false); View divider = row.findViewById(R.id.divider); @@ -152,19 +224,19 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial container.addView(row); } - private void updateModeButtons(CalculationMode calculationMode) { - if (calculationMode == NEXT_SEGMENT) { - UiUtilities.updateCustomRadioButtons(getMyApplication(), customRadioButton, nightMode, LEFT); - btnDescription.setText(R.string.rourte_between_points_next_segment_button_desc); - } else { - btnDescription.setText(R.string.rourte_between_points_whole_track_button_desc); - UiUtilities.updateCustomRadioButtons(getMyApplication(), customRadioButton, nightMode, RIGHT); - } - setCalculationMode(calculationMode); + public void setDefaultDialogMode(RouteBetweenPointsDialogMode defaultDialogMode) { + this.defaultDialogMode = defaultDialogMode; + updateModeButtons(); + } + + public void updateModeButtons() { + UiUtilities.updateCustomRadioButtons(getMyApplication(), customRadioButton, nightMode, + defaultDialogMode == RouteBetweenPointsDialogMode.SINGLE ? LEFT : RIGHT); + btnDescription.setText(getButtonDescr(defaultDialogMode)); } private void addProfileView(LinearLayout container, View.OnClickListener onClickListener, Object tag, - Drawable icon, CharSequence title, boolean check) { + Drawable icon, CharSequence title, boolean check) { View row = UiUtilities.getInflater(getContext(), nightMode) .inflate(R.layout.bottom_sheet_item_with_radio_btn, container, false); ((RadioButton) row.findViewById(R.id.compound_button)).setChecked(check); @@ -195,7 +267,8 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putSerializable(CALCULATION_MODE_KEY, calculationMode); + outState.putSerializable(DIALOG_TYPE_KEY, dialogType); + outState.putSerializable(DEFAULT_DIALOG_MODE_KEY, defaultDialogMode); } @Override @@ -207,18 +280,17 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial super.onDestroyView(); } - public void setCalculationMode(CalculationMode calculationMode) { - this.calculationMode = calculationMode; - } - - public static void showInstance(FragmentManager fm, Fragment targetFragment, CalculationMode calculationMode, - ApplicationMode applicationMode) { + public static void showInstance(FragmentManager fm, Fragment targetFragment, + RouteBetweenPointsDialogType dialogType, + RouteBetweenPointsDialogMode defaultDialogMode, + ApplicationMode applicationMode) { try { if (!fm.isStateSaved()) { RouteBetweenPointsBottomSheetDialogFragment fragment = new RouteBetweenPointsBottomSheetDialogFragment(); Bundle args = new Bundle(); args.putString(ROUTE_APP_MODE_KEY, applicationMode != null ? applicationMode.getStringKey() : null); - args.putSerializable(CALCULATION_MODE_KEY, calculationMode); + args.putSerializable(DIALOG_TYPE_KEY, dialogType); + args.putSerializable(DEFAULT_DIALOG_MODE_KEY, defaultDialogMode); fragment.setArguments(args); fragment.setTargetFragment(targetFragment, 0); fragment.show(fm, TAG); @@ -232,7 +304,8 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial void onCloseRouteDialog(); - void onChangeApplicationMode(ApplicationMode mode, CalculationMode calculationMode); + void onChangeApplicationMode(ApplicationMode mode, RouteBetweenPointsDialogType dialogType, + RouteBetweenPointsDialogMode dialogMode); } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java index 23c8426abb..9fac103fc5 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java @@ -157,6 +157,46 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo items.add(new OptionsDividerItem(getContext())); + BaseBottomSheetItem changeRouteTypeBefore = new BottomSheetItemWithDescription.Builder() + .setDescription(getDescription(true)) + .setIcon(getRouteTypeIcon(true)) + .setTitle(getString(R.string.plan_route_change_route_type_before)) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Fragment targetFragment = getTargetFragment(); + if (targetFragment instanceof SelectedPointFragmentListener) { + ((SelectedPointFragmentListener) targetFragment).onChangeRouteTypeBefore(); + } + dismiss(); + } + }) + .setDisabled(editingCtx.isFirstPointSelected()) + .create(); + items.add(changeRouteTypeBefore); + + BaseBottomSheetItem changeRouteTypeAfter = new BottomSheetItemWithDescription.Builder() + .setDescription(getDescription(false)) + .setIcon(getRouteTypeIcon(false)) + .setTitle(getString(R.string.plan_route_change_route_type_after)) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Fragment targetFragment = getTargetFragment(); + if (targetFragment instanceof SelectedPointFragmentListener) { + ((SelectedPointFragmentListener) targetFragment).onChangeRouteTypeAfter(); + } + dismiss(); + } + }) + .setDisabled(editingCtx.isLastPointSelected()) + .create(); + items.add(changeRouteTypeAfter); + + items.add(new OptionsDividerItem(getContext())); + BaseBottomSheetItem deleteItem = new SimpleBottomSheetItem.Builder() .setIcon(getIcon(R.drawable.ic_action_delete_dark, nightMode ? R.color.color_osm_edit_delete : R.color.color_osm_edit_delete)) @@ -283,12 +323,11 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo @Nullable private Drawable getRouteTypeIcon(boolean before) { - Drawable icon = getContentIcon(R.drawable.ic_action_split_interval); - int pos = editingCtx.getSelectedPointPosition(); - pos = before ? pos : Math.max(pos - 1, 0); - String profileType = editingCtx.getPoints().get(pos).getProfileType(); - ApplicationMode routeAppMode = ApplicationMode.valueOfStringKey(profileType, null); - if (routeAppMode != null) { + ApplicationMode routeAppMode = before ? editingCtx.getBeforeSelectedPointAppMode() : editingCtx.getSelectedPointAppMode(); + Drawable icon; + if (MeasurementEditingContext.DEFAULT_APP_MODE.equals(routeAppMode)) { + icon = getContentIcon(R.drawable.ic_action_split_interval); + } else { icon = getIcon(routeAppMode.getIconRes(), routeAppMode.getIconColorInfo().getColor(nightMode)); } return icon; diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java b/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java index aa3e8b0c05..9d3e9efaf0 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java @@ -1,12 +1,17 @@ package net.osmand.plus.measurementtool.command; +import android.util.Pair; + import net.osmand.GPXUtilities.WptPt; import net.osmand.plus.measurementtool.MeasurementEditingContext; +import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.settings.backend.ApplicationMode; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode; import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE; @@ -15,41 +20,87 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand { private List oldPoints; private List newPoints; + private Map, RoadSegmentData> oldRoadSegmentData; + private Map, RoadSegmentData> newRoadSegmentData; private ApplicationMode oldMode; private ApplicationMode newMode; - private CalculationMode oldCalculationMode; - private CalculationMode newCalculationMode; + private ChangeRouteType changeRouteType; + private int pointIndex; + + public enum ChangeRouteType { + LAST_SEGMENT, + WHOLE_ROUTE, + NEXT_SEGMENT, + ALL_NEXT_SEGMENTS, + PREV_SEGMENT, + ALL_PREV_SEGMENTS + } public ChangeRouteModeCommand(MeasurementToolLayer measurementLayer, ApplicationMode newMode, - CalculationMode newCalculationMode) { + ChangeRouteType changeRouteType, int pointIndex) { super(measurementLayer); this.newMode = newMode; - this.newCalculationMode = newCalculationMode; - MeasurementEditingContext editingCtx = getEditingCtx(); - oldMode = editingCtx.getAppMode(); - oldCalculationMode = editingCtx.getCalculationMode(); + this.changeRouteType = changeRouteType; + this.pointIndex = pointIndex; + this.oldMode = getEditingCtx().getAppMode(); } @Override public boolean execute() { MeasurementEditingContext editingCtx = getEditingCtx(); oldPoints = new ArrayList<>(editingCtx.getPoints()); + oldRoadSegmentData = editingCtx.getRoadSegmentData(); newPoints = new ArrayList<>(oldPoints.size()); + newRoadSegmentData = new HashMap<>(oldRoadSegmentData); if (oldPoints.size() > 0) { for (WptPt pt : oldPoints) { WptPt point = new WptPt(pt); point.copyExtensions(pt); newPoints.add(point); } - switch (newCalculationMode) { - case NEXT_SEGMENT: + switch (changeRouteType) { + case LAST_SEGMENT: { updateProfileType(newPoints.get(newPoints.size() - 1)); + editingCtx.setLastCalculationMode(CalculationMode.NEXT_SEGMENT); + newRoadSegmentData = null; break; - case WHOLE_TRACK: + } + case WHOLE_ROUTE: { for (WptPt pt : newPoints) { updateProfileType(pt); } + editingCtx.setLastCalculationMode(CalculationMode.WHOLE_TRACK); + newRoadSegmentData.clear(); break; + } + case NEXT_SEGMENT: { + if (pointIndex >= 0 && pointIndex < newPoints.size()) { + updateProfileType(newPoints.get(pointIndex)); + } + newRoadSegmentData.remove(getPairAt(pointIndex)); + break; + } + case ALL_NEXT_SEGMENTS: { + for (int i = pointIndex; i >= 0 && i < newPoints.size(); i++) { + updateProfileType(newPoints.get(i)); + newRoadSegmentData.remove(getPairAt(i)); + } + break; + } + case PREV_SEGMENT: { + if (pointIndex > 0 && pointIndex < newPoints.size()) { + updateProfileType(newPoints.get(pointIndex - 1)); + newRoadSegmentData.remove(getPairAt(pointIndex - 1)); + } + break; + } + case ALL_PREV_SEGMENTS: { + for (int i = 0; i < pointIndex && i < newPoints.size(); i++) { + updateProfileType(newPoints.get(i)); + newRoadSegmentData.remove(getPairAt(i)); + } + break; + } } } executeCommand(); @@ -61,11 +112,8 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand { MeasurementEditingContext editingCtx = getEditingCtx(); editingCtx.getPoints().clear(); editingCtx.addPoints(oldPoints); - editingCtx.setCalculationMode(oldCalculationMode); editingCtx.setAppMode(oldMode); - if (newCalculationMode == CalculationMode.WHOLE_TRACK) { - editingCtx.clearSnappedToRoadPoints(); - } + editingCtx.setRoadSegmentData(oldRoadSegmentData); editingCtx.updateCacheForSnap(); } @@ -79,14 +127,24 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand { return MeasurementCommandType.CHANGE_ROUTE_MODE; } + private Pair getPairAt(int pointIndex) { + WptPt first = pointIndex >= 0 && pointIndex < newPoints.size() ? newPoints.get(pointIndex) : null; + WptPt second = pointIndex >= 0 && pointIndex < newPoints.size() - 1 ? newPoints.get(pointIndex + 1) : null; + return new Pair<>(first, second); + } + private void executeCommand() { MeasurementEditingContext editingCtx = getEditingCtx(); editingCtx.getPoints().clear(); editingCtx.addPoints(newPoints); - editingCtx.setCalculationMode(newCalculationMode); - editingCtx.setAppMode(newMode); - if (newCalculationMode == CalculationMode.WHOLE_TRACK) { - editingCtx.clearSnappedToRoadPoints(); + if (newPoints.isEmpty()) { + editingCtx.setAppMode(newMode); + } else { + WptPt lastPoint = newPoints.get(newPoints.size() - 1); + editingCtx.setAppMode(ApplicationMode.valueOfStringKey(lastPoint.getProfileType(), DEFAULT_APP_MODE)); + } + if (newRoadSegmentData != null) { + editingCtx.setRoadSegmentData(newRoadSegmentData); } editingCtx.updateCacheForSnap(); }