diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index 8ee98527bd..a1e257cef2 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -1290,6 +1290,17 @@ public class GPXUtilities { return pt; } + public TrkSegment getTrkSegment() { + for (GPXUtilities.Track t : tracks) { + for (TrkSegment s : t.segments) { + if (s.points.size() > 0) { + return s; + } + } + } + return null; + } + public void addTrkSegment(List points) { removeGeneralTrackIfExists(); diff --git a/OsmAnd/res/layout/follow_track_options.xml b/OsmAnd/res/layout/follow_track_options.xml index 73426d0b10..69f0c467c3 100644 --- a/OsmAnd/res/layout/follow_track_options.xml +++ b/OsmAnd/res/layout/follow_track_options.xml @@ -63,6 +63,7 @@ android:id="@+id/bottom_container" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="?attr/route_info_bg" android:foreground="@drawable/bg_contextmenu_shadow" android:foregroundGravity="top|fill_horizontal"> diff --git a/OsmAnd/res/layout/gpx_track_item.xml b/OsmAnd/res/layout/gpx_track_item.xml index a18a6b23c2..37a9724423 100644 --- a/OsmAnd/res/layout/gpx_track_item.xml +++ b/OsmAnd/res/layout/gpx_track_item.xml @@ -165,33 +165,33 @@ - + android:layout_marginLeft="@dimen/favorites_icon_right_margin" + android:visibility="gone" + osmand:srcCompat="@drawable/ic_action_gsave_dark" /> - + android:visibility="gone" + osmand:srcCompat="@drawable/ic_action_rec_stop" /> - + android:visibility="gone" + osmand:srcCompat="@drawable/ic_overflow_menu_white" /> + Select another track Choose track file to follow or import it from device. Choose track file to follow Follow track diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 91938e89a1..0ecac7c905 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -882,11 +882,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route public void addNewGpxData(GPXFile gpxFile) { QuadRect rect = gpxFile.getRect(); - TrkSegment segment = getTrkSegment(gpxFile); - NewGpxData newGpxData = new NewGpxData(gpxFile, rect, segment == null - ? ActionType.ADD_ROUTE_POINTS - : ActionType.EDIT_SEGMENT, - segment); + TrkSegment segment = gpxFile.getTrkSegment(); + ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT; + NewGpxData newGpxData = new NewGpxData(gpxFile, rect, actionType, segment); + editingCtx.setNewGpxData(newGpxData); initMeasurementMode(newGpxData); QuadRect qr = newGpxData.getRect(); @@ -897,17 +896,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } } - private TrkSegment getTrkSegment(GPXFile gpxFile) { - for (GPXUtilities.Track t : gpxFile.tracks) { - for (TrkSegment s : t.segments) { - if (s.points.size() > 0) { - return s; - } - } - } - return null; - } - private void removePoint(MeasurementToolLayer measurementLayer, int position) { if (measurementLayer != null) { editingCtx.getCommandManager().execute(new RemovePointCommand(measurementLayer, position)); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index edf89a9bdf..1ed0ece313 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -20,9 +20,11 @@ import androidx.annotation.NonNull; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; +import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; +import net.osmand.data.QuadRect; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -34,9 +36,15 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.measurementtool.MeasurementEditingContext; +import net.osmand.plus.measurementtool.MeasurementToolFragment; +import net.osmand.plus.measurementtool.NewGpxData; +import net.osmand.plus.measurementtool.NewGpxData.ActionType; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; import net.osmand.plus.routepreparationmenu.cards.ImportTrackCard; +import net.osmand.plus.routepreparationmenu.cards.SelectTrackCard; +import net.osmand.plus.routepreparationmenu.cards.TrackEditCard; import net.osmand.plus.routepreparationmenu.cards.TracksToFollowCard; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; @@ -52,11 +60,14 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca private static final Log log = PlatformUtil.getLog(FollowTrackFragment.class); + private static final String SELECTING_TRACK = "selecting_track"; + private OsmandApplication app; private ImportHelper importHelper; private GPXFile gpxFile; + private boolean selectingTrack; private int menuTitleHeight; @Override @@ -105,11 +116,10 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca gpxFile = routeParamsBuilder.getFile(); } - Bundle arguments = getArguments(); if (savedInstanceState != null) { - - } else if (arguments != null) { - + selectingTrack = savedInstanceState.getBoolean(SELECTING_TRACK, gpxFile == null); + } else { + selectingTrack = gpxFile == null; } } @@ -152,22 +162,35 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca } private void setupCards() { - final MapActivity mapActivity = getMapActivity(); + MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { ViewGroup cardsContainer = getCardsContainer(); cardsContainer.removeAllViews(); - ImportTrackCard importTrackCard = new ImportTrackCard(mapActivity); - importTrackCard.setListener(this); - cardsContainer.addView(importTrackCard.build(mapActivity)); + if (gpxFile == null || selectingTrack) { + ImportTrackCard importTrackCard = new ImportTrackCard(mapActivity); + importTrackCard.setListener(this); + cardsContainer.addView(importTrackCard.build(mapActivity)); - File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); - List selectedTrackNames = GpxUiHelper.getSelectedTrackNames(app); - List list = GpxUiHelper.getSortedGPXFilesInfo(dir, selectedTrackNames, false); - if (list.size() > 0) { - TracksToFollowCard tracksCard = new TracksToFollowCard(mapActivity, list); - tracksCard.setListener(this); - cardsContainer.addView(tracksCard.build(mapActivity)); + File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); + List selectedTrackNames = GpxUiHelper.getSelectedTrackNames(app); + List list = GpxUiHelper.getSortedGPXFilesInfo(dir, selectedTrackNames, false); + if (list.size() > 0) { + String defaultCategory = app.getString(R.string.shared_string_all); + TracksToFollowCard tracksCard = new TracksToFollowCard(mapActivity, list, defaultCategory); + tracksCard.setListener(this); + cardsContainer.addView(tracksCard.build(mapActivity)); + } + } else { + File file = new File(gpxFile.path); + GPXInfo gpxInfo = new GPXInfo(gpxFile.path, file.lastModified(), file.length()); + TrackEditCard importTrackCard = new TrackEditCard(mapActivity, gpxInfo); + importTrackCard.setListener(this); + cardsContainer.addView(importTrackCard.build(mapActivity)); + + SelectTrackCard selectTrackCard = new SelectTrackCard(mapActivity); + selectTrackCard.setListener(this); + cardsContainer.addView(selectTrackCard.build(mapActivity)); } } } @@ -198,6 +221,12 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca exitTrackAppearanceMode(); } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(SELECTING_TRACK, selectingTrack); + } + private void enterTrackAppearanceMode() { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { @@ -257,6 +286,11 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca if (mapActivity != null) { if (card instanceof ImportTrackCard) { importTrack(); + } else if (card instanceof TrackEditCard) { + editTrack(); + dismiss(); + } else if (card instanceof SelectTrackCard) { + updateSelectionMode(true); } } } @@ -281,11 +315,13 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); if (selectedGpxFile != null) { selectTrackToFollow(selectedGpxFile.getGpxFile()); + updateSelectionMode(false); } else { CallbackWithObject callback = new CallbackWithObject() { @Override public boolean processResult(GPXFile[] result) { selectTrackToFollow(result[0]); + updateSelectionMode(false); return true; } }; @@ -298,12 +334,18 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca private void selectTrackToFollow(GPXFile gpxFile) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { + this.gpxFile = gpxFile; mapActivity.getMapActions().setGPXRouteParams(gpxFile); app.getTargetPointsHelper().updateRouteAndRefresh(true); app.getRoutingHelper().recalculateRouteDueToSettingsChange(); } } + private void updateSelectionMode(boolean selecting) { + this.selectingTrack = selecting; + setupCards(); + } + public void importTrack() { Intent intent = ImportHelper.getImportTrackIntent(); try { @@ -333,6 +375,20 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca } } + public void editTrack() { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null && gpxFile != null) { + QuadRect rect = gpxFile.getRect(); + GPXUtilities.TrkSegment segment = gpxFile.getTrkSegment(); + ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT; + NewGpxData newGpxData = new NewGpxData(gpxFile, rect, actionType, segment); + + MeasurementEditingContext editingContext = new MeasurementEditingContext(); + editingContext.setNewGpxData(newGpxData); + MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), editingContext); + } + } + private void updateCardsLayout() { View mainView = getMainView(); if (mainView != null) { diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/SelectTrackCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/SelectTrackCard.java new file mode 100644 index 0000000000..9544d6c8fa --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/SelectTrackCard.java @@ -0,0 +1,55 @@ +package net.osmand.plus.routepreparationmenu.cards; + +import android.graphics.Typeface; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.ForegroundColorSpan; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.FontCache; + +public class SelectTrackCard extends BaseCard { + + public SelectTrackCard(@NonNull MapActivity mapActivity) { + super(mapActivity); + } + + @Override + public int getCardLayoutId() { + return R.layout.bottom_sheet_item_simple; + } + + @Override + protected void updateContent() { + Typeface typeface = FontCache.getRobotoMedium(app); + String title = app.getString(R.string.select_another_track); + SpannableString spannable = UiUtilities.createCustomFontSpannable(typeface, title, title, title); + ForegroundColorSpan colorSpan = new ForegroundColorSpan(getActiveColor()); + spannable.setSpan(colorSpan, 0, title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + TextView titleTv = view.findViewById(R.id.title); + titleTv.setText(spannable); + + ImageView icon = view.findViewById(R.id.icon); + icon.setImageDrawable(getActiveIcon(R.drawable.ic_action_folder)); + + int minHeight = app.getResources().getDimensionPixelSize(R.dimen.route_info_list_text_padding); + view.setMinimumHeight(minHeight); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CardListener listener = getListener(); + if (listener != null) { + listener.onCardPressed(SelectTrackCard.this); + } + } + }); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java new file mode 100644 index 0000000000..bf41f7b111 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java @@ -0,0 +1,74 @@ +package net.osmand.plus.routepreparationmenu.cards; + +import android.graphics.drawable.ColorDrawable; +import android.view.View; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import net.osmand.AndroidUtils; +import net.osmand.IndexConstants; +import net.osmand.plus.GPXDatabase.GpxDataItem; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.GpxUiHelper; +import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.util.Algorithms; + +import java.io.File; + +public class TrackEditCard extends BaseCard { + + private GPXInfo gpxInfo; + + public TrackEditCard(MapActivity mapActivity, GPXInfo gpxInfo) { + super(mapActivity); + this.gpxInfo = gpxInfo; + } + + @Override + public int getCardLayoutId() { + return R.layout.gpx_track_item; + } + + private GpxDataItem getDataItem(GpxUiHelper.GPXInfo info) { + return app.getGpxDbHelper().getItem(new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), info.getFileName())); + } + + @Override + protected void updateContent() { + int minCardHeight = app.getResources().getDimensionPixelSize(R.dimen.setting_list_item_large_height); + int listContentPadding = app.getResources().getDimensionPixelSize(R.dimen.list_content_padding); + + String fileName = Algorithms.getFileWithoutDirs(gpxInfo.getFileName()); + String title = GpxUiHelper.getGpxTitle(fileName); + GpxDataItem dataItem = getDataItem(gpxInfo); + GpxUiHelper.updateGpxInfoView(view, title, gpxInfo, dataItem, false, app); + + ImageView trackIcon = view.findViewById(R.id.icon); + trackIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_polygom_dark)); + trackIcon.setVisibility(View.VISIBLE); + + ImageButton editButton = view.findViewById(R.id.show_on_map); + editButton.setVisibility(View.VISIBLE); + editButton.setImageDrawable(getContentIcon(R.drawable.ic_action_edit_dark)); + editButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CardListener listener = getListener(); + if (listener != null) { + listener.onCardPressed(TrackEditCard.this); + } + } + }); + + LinearLayout container = view.findViewById(R.id.container); + container.setMinimumHeight(minCardHeight); + AndroidUtils.setPadding(container, listContentPadding, 0, 0, 0); + + int activeColor = getActiveColor(); + int bgColor = UiUtilities.getColorWithAlpha(activeColor, 0.1f); + view.setBackgroundDrawable(new ColorDrawable(bgColor)); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java index 6ee164f54c..2d3b57d3ca 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java @@ -26,9 +26,10 @@ public class TracksToFollowCard extends BaseCard { private GpxTrackAdapter tracksAdapter; - public TracksToFollowCard(MapActivity mapActivity, List gpxInfoList) { + public TracksToFollowCard(MapActivity mapActivity, List gpxInfoList, String selectedCategory) { super(mapActivity); this.gpxInfoList = gpxInfoList; + this.selectedCategory = selectedCategory; gpxInfoCategories = getGpxInfoCategories(); }