diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_switch_pad_32.xml b/OsmAnd/res/layout/bottom_sheet_item_with_switch_pad_32.xml
new file mode 100644
index 0000000000..4658df14df
--- /dev/null
+++ b/OsmAnd/res/layout/bottom_sheet_item_with_switch_pad_32.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/layout/track_segments_container.xml b/OsmAnd/res/layout/card_container.xml
similarity index 100%
rename from OsmAnd/res/layout/track_segments_container.xml
rename to OsmAnd/res/layout/card_container.xml
diff --git a/OsmAnd/res/layout/track_menu.xml b/OsmAnd/res/layout/track_menu.xml
index 598372776f..9d33f73e88 100644
--- a/OsmAnd/res/layout/track_menu.xml
+++ b/OsmAnd/res/layout/track_menu.xml
@@ -54,11 +54,15 @@
android:layout_weight="1"
android:orientation="vertical">
-
-
-
-
-
+
\ No newline at end of file
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index e390145312..80ed944fcf 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -12,6 +12,11 @@
-->
+ Change folder
+ Rename track
+ Edit track
+ Upload to OpenStreetMap
+ Analyze by intervals (split interval)
Empty
Select folder or add new one
Select folder
diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java
index fed5346212..580450df60 100644
--- a/OsmAnd/src/net/osmand/FileUtils.java
+++ b/OsmAnd/src/net/osmand/FileUtils.java
@@ -8,8 +8,6 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
-import net.osmand.GPXUtilities.GPXFile;
-import net.osmand.GPXUtilities.Metadata;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
@@ -107,6 +105,7 @@ public class FileUtils {
SelectedGpxFile selected = helper.getSelectedFileByPath(src.getAbsolutePath());
app.getGpxDbHelper().rename(src, dest);
if (selected != null && selected.getGpxFile() != null) {
+ selected.resetSplitProcessed();
selected.getGpxFile().path = dest.getAbsolutePath();
helper.updateSelectedGpxFile(selected);
}
diff --git a/OsmAnd/src/net/osmand/plus/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/GPXDatabase.java
index c010b2964e..74dc02be9c 100644
--- a/OsmAnd/src/net/osmand/plus/GPXDatabase.java
+++ b/OsmAnd/src/net/osmand/plus/GPXDatabase.java
@@ -465,7 +465,7 @@ public class GPXDatabase {
return false;
}
- public boolean rename(File currentFile, File newFile) {
+ public boolean rename(@Nullable GpxDataItem item, File currentFile, File newFile) {
SQLiteConnection db = openConnection(false);
if (db != null){
try {
@@ -478,6 +478,9 @@ public class GPXDatabase {
GPX_COL_DIR + " = ? " +
" WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?",
new Object[] { newFileName, newFileDir, fileName, fileDir });
+ if (item != null) {
+ item.file = newFile;
+ }
} finally {
db.close();
}
diff --git a/OsmAnd/src/net/osmand/plus/GpxDbHelper.java b/OsmAnd/src/net/osmand/plus/GpxDbHelper.java
index d5e05e8db3..c27c74f636 100644
--- a/OsmAnd/src/net/osmand/plus/GpxDbHelper.java
+++ b/OsmAnd/src/net/osmand/plus/GpxDbHelper.java
@@ -68,9 +68,8 @@ public class GpxDbHelper {
}
public boolean rename(File currentFile, File newFile) {
- boolean res = db.rename(currentFile, newFile);
- itemsCache.remove(currentFile);
- return res;
+ GpxDataItem item = itemsCache.get(currentFile);
+ return db.rename(item, currentFile, newFile);
}
public boolean updateColor(GpxDataItem item, int color) {
diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java
index cb1ad6b79d..879dad90d1 100644
--- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java
+++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java
@@ -861,6 +861,10 @@ public class GpxSelectionHelper {
return color;
}
+ public void resetSplitProcessed() {
+ splitProcessed = false;
+ }
+
public List getDisplayGroups(OsmandApplication app) {
if (modifiedTime != gpxFile.modifiedTime || !splitProcessed) {
update(app);
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index e41792225b..4e3cbd2885 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -67,8 +67,7 @@ import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
-import net.osmand.plus.mapmarkers.MapMarker;
-import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkerChangedListener;
+import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OnDismissDialogFragmentListener;
import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmAndLocationSimulation;
@@ -80,7 +79,6 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.Version;
import net.osmand.plus.activities.search.SearchActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
-import net.osmand.plus.base.ContextMenuFragment;
import net.osmand.plus.base.FailSafeFuntions;
import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.chooseplan.OsmLiveGoneDialog;
@@ -108,10 +106,11 @@ import net.osmand.plus.helpers.ScrollHelper.OnScrollEventListener;
import net.osmand.plus.importfiles.ImportHelper;
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
-import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapcontextmenu.builders.cards.dialogs.ContextMenuCardDialogFragment;
import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
+import net.osmand.plus.mapmarkers.MapMarker;
+import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkerChangedListener;
import net.osmand.plus.mapmarkers.PlanRouteFragment;
import net.osmand.plus.measurementtool.GpxApproximationFragment;
import net.osmand.plus.measurementtool.GpxData;
@@ -125,8 +124,8 @@ import net.osmand.plus.routepreparationmenu.ChooseRouteFragment;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenuFragment;
import net.osmand.plus.routing.IRouteInformationListener;
-import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.RouteCalculationProgressCallback;
+import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper.TransportRouteCalculationProgressCallback;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab;
@@ -169,8 +168,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID;
-import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING;
-import static net.osmand.plus.activities.TrackActivity.TRACK_FILE_NAME;
public class MapActivity extends OsmandActionBarActivity implements DownloadEvents,
OnRequestPermissionsResultCallback, IRouteInformationListener, AMapPointUpdateListener,
@@ -1177,15 +1174,15 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
MapRouteInfoMenu.showLocationOnMap(this, latLonToShow.getLatitude(), latLonToShow.getLongitude());
} else if (toShow instanceof GPXFile) {
hideContextAndRouteInfoMenues();
+ GPXFile gpxFile = (GPXFile) toShow;
+ SelectedGpxFile selectedGpxFile;
+ if (gpxFile.showCurrentTrack) {
+ selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack();
+ } else {
+ selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFile.path);
+ }
- Bundle args = new Bundle();
- args.putString(TRACK_FILE_NAME, ((GPXFile) toShow).path);
- args.putBoolean(CURRENT_RECORDING, ((GPXFile) toShow).showCurrentTrack);
- args.putInt(ContextMenuFragment.MENU_STATE_KEY, MenuController.MenuState.HALF_SCREEN);
-
- TrackAppearanceFragment fragment = new TrackAppearanceFragment();
- fragment.setArguments(args);
- TrackAppearanceFragment.showInstance(this, fragment);
+ TrackAppearanceFragment.showInstance(this, selectedGpxFile);
} else if (toShow instanceof QuadRect) {
QuadRect qr = (QuadRect) toShow;
mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0);
diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java
index c2813551e9..3d6c3c15c9 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java
@@ -99,6 +99,7 @@ import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem;
import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.helpers.enums.SpeedConstants;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
+import net.osmand.plus.myplaces.SaveCurrentTrackTask;
import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
@@ -2192,6 +2193,23 @@ public class GpxUiHelper {
new SaveGpxAsyncTask(file, gpxFile, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
+ public static void saveAndShareCurrentGpx(@NonNull final OsmandApplication app, @NonNull final GPXFile gpxFile) {
+ SaveGpxListener saveGpxListener = new SaveGpxListener() {
+ @Override
+ public void gpxSavingStarted() {
+
+ }
+
+ @Override
+ public void gpxSavingFinished(Exception errorMessage) {
+ if (errorMessage == null) {
+ GpxUiHelper.shareGpx(app, new File(gpxFile.path));
+ }
+ }
+ };
+ new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
public static void saveAndShareGpxWithAppearance(@NonNull final Context context, @NonNull final GPXFile gpxFile) {
OsmandApplication app = (OsmandApplication) context.getApplicationContext();
GpxDataItem dataItem = getDataItem(app, gpxFile);
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java
index af83eff49a..8a86fbe134 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java
@@ -23,9 +23,7 @@ import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapcontextmenu.builders.SelectedGpxMenuBuilder;
-import net.osmand.plus.myplaces.SaveCurrentTrackTask;
import net.osmand.plus.settings.backend.OsmandSettings;
-import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
import net.osmand.plus.track.TrackMenuFragment;
import net.osmand.util.Algorithms;
@@ -77,7 +75,7 @@ public class SelectedGpxMenuController extends MenuController {
rightTitleButtonController.startIconId = R.drawable.ic_action_analyze_intervals;
}
- private static class OpenGpxDetailsTask extends AsyncTask {
+ public static class OpenGpxDetailsTask extends AsyncTask {
private OsmandApplication app;
@@ -87,7 +85,7 @@ public class SelectedGpxMenuController extends MenuController {
private ProgressDialog progressDialog;
private WeakReference activityRef;
- OpenGpxDetailsTask(SelectedGpxFile selectedGpxFile, WptPt selectedPoint, MapActivity mapActivity) {
+ public OpenGpxDetailsTask(SelectedGpxFile selectedGpxFile, WptPt selectedPoint, MapActivity mapActivity) {
app = mapActivity.getMyApplication();
this.activityRef = new WeakReference<>(mapActivity);
this.selectedGpxFile = selectedGpxFile;
@@ -217,7 +215,7 @@ public class SelectedGpxMenuController extends MenuController {
if (gpxFile != null) {
OsmandApplication app = mapActivity.getMyApplication();
if (Algorithms.isEmpty(gpxFile.path)) {
- saveAndShareCurrentGpx(app, gpxFile);
+ GpxUiHelper.saveAndShareCurrentGpx(app, gpxFile);
} else {
GpxUiHelper.saveAndShareGpxWithAppearance(app, gpxFile);
}
@@ -227,23 +225,6 @@ public class SelectedGpxMenuController extends MenuController {
}
}
- public void saveAndShareCurrentGpx(@NonNull final OsmandApplication app, @NonNull final GPXFile gpxFile) {
- SaveGpxListener saveGpxListener = new SaveGpxListener() {
- @Override
- public void gpxSavingStarted() {
-
- }
-
- @Override
- public void gpxSavingFinished(Exception errorMessage) {
- if (errorMessage == null) {
- GpxUiHelper.shareGpx(app, new File(gpxFile.path));
- }
- }
- };
- new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
public static class SelectedGpxPoint {
private final WptPt selectedPoint;
diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java
index 465f85b617..81d9ee9d72 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java
@@ -254,6 +254,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
@Override
public void onClick(View v) {
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
+ actionsListener.updateContent();
for (int i = 0; i < getCount(); i++) {
View view = getViewAtPosition(i);
updateJoinGapsInfo(view, i);
@@ -337,6 +338,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
@Override
public void onClick(View v) {
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
+ actionsListener.updateContent();
for (int i = 0; i < getCount(); i++) {
View view = getViewAtPosition(i);
updateJoinGapsInfo(view, i);
@@ -461,7 +463,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
if (!chartClicked) {
chartClicked = true;
if (selectedWpt != null) {
- actionsListener.onPointSelected(selectedWpt.lat, selectedWpt.lon);
+ actionsListener.onPointSelected(segment, selectedWpt.lat, selectedWpt.lon);
}
}
}
@@ -496,7 +498,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
WptPt wpt = getPoint(chart, h.getX());
selectedWpt = wpt;
if (chartClicked && wpt != null) {
- actionsListener.onPointSelected(wpt.lat, wpt.lon);
+ actionsListener.onPointSelected(segment, wpt.lat, wpt.lon);
}
}
@@ -565,7 +567,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
chart.highlightValue(h);
WptPt wpt = getPoint(chart, h.getX());
if (wpt != null) {
- actionsListener.onPointSelected(wpt.lat, wpt.lon);
+ actionsListener.onPointSelected(segment, wpt.lat, wpt.lon);
}
}
}
diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SegmentActionsListener.java b/OsmAnd/src/net/osmand/plus/myplaces/SegmentActionsListener.java
index d5ebc2235f..4033dedd7a 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/SegmentActionsListener.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/SegmentActionsListener.java
@@ -17,7 +17,7 @@ public interface SegmentActionsListener {
void scrollBy(int px);
- void onPointSelected(double lat, double lon);
+ void onPointSelected(TrkSegment segment, double lat, double lon);
void openSplitInterval(GpxDisplayItem gpxItem, TrkSegment trkSegment);
diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java
index 4a66e09d99..c10fa883ad 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java
@@ -284,7 +284,7 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
}
@Override
- public void onPointSelected(double lat, double lon) {
+ public void onPointSelected(TrkSegment segment, double lat, double lon) {
if (fragmentAdapter != null) {
fragmentAdapter.updateSelectedPoint(lat, lon);
}
diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java
index a9a3262216..f734b1c718 100644
--- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java
@@ -456,7 +456,7 @@ public class OsmEditingPlugin extends OsmandPlugin {
}
}
- public boolean sendGPXFiles(final FragmentActivity activity, AvailableGPXFragment fragment, final GpxInfo... info) {
+ public boolean sendGPXFiles(final FragmentActivity activity, Fragment fragment, final GpxInfo... info) {
String name = settings.USER_NAME.get();
String pwd = settings.USER_PASSWORD.get();
String authToken = settings.USER_ACCESS_TOKEN.get();
diff --git a/OsmAnd/src/net/osmand/plus/track/OptionsCard.java b/OsmAnd/src/net/osmand/plus/track/OptionsCard.java
new file mode 100644
index 0000000000..1ed533922c
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/track/OptionsCard.java
@@ -0,0 +1,355 @@
+package net.osmand.plus.track;
+
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+
+import net.osmand.AndroidUtils;
+import net.osmand.GPXUtilities.GPXFile;
+import net.osmand.plus.OsmandPlugin;
+import net.osmand.plus.R;
+import net.osmand.plus.UiUtilities;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
+import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescriptionDifHeight;
+import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem;
+import net.osmand.plus.helpers.FontCache;
+import net.osmand.plus.osmedit.OsmEditingPlugin;
+import net.osmand.plus.routepreparationmenu.cards.BaseCard;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import static net.osmand.plus.myplaces.TrackActivityFragmentAdapter.isGpxFileSelected;
+import static net.osmand.util.Algorithms.capitalizeFirstLetter;
+
+public class OptionsCard extends BaseCard {
+
+ public static final int SHOW_ON_MAP_BUTTON_INDEX = 0;
+ public static final int APPEARANCE_BUTTON_INDEX = 1;
+ public static final int DIRECTIONS_BUTTON_INDEX = 2;
+ public static final int JOIN_GAPS_BUTTON_INDEX = 3;
+ public static final int ANALYZE_ON_MAP_BUTTON_INDEX = 4;
+ public static final int ANALYZE_BY_INTERVALS_BUTTON_INDEX = 5;
+ public static final int SHARE_BUTTON_INDEX = 6;
+ public static final int UPLOAD_OSM_BUTTON_INDEX = 7;
+ public static final int EDIT_BUTTON_INDEX = 8;
+ public static final int RENAME_BUTTON_INDEX = 9;
+ public static final int CHANGE_FOLDER_BUTTON_INDEX = 10;
+ public static final int DELETE_BUTTON_INDEX = 11;
+
+ private TrackDisplayHelper displayHelper;
+ private GPXFile gpxFile;
+ private List items = new ArrayList<>();
+
+ public OptionsCard(@NonNull MapActivity mapActivity, TrackDisplayHelper displayHelper) {
+ super(mapActivity);
+ this.displayHelper = displayHelper;
+ this.gpxFile = displayHelper.getGpx();
+ }
+
+ @Override
+ public int getCardLayoutId() {
+ return R.layout.card_container;
+ }
+
+ @Override
+ protected void updateContent() {
+ ViewGroup itemsContainer = (ViewGroup) view;
+ itemsContainer.removeAllViews();
+ items.clear();
+
+ boolean fileAvailable = gpxFile.path != null && !gpxFile.showCurrentTrack;
+ items.add(createShowOnMapItem());
+ items.add(createAppearanceItem());
+ if (fileAvailable) {
+ items.add(createDirectionsItem());
+ }
+ items.add(createDividerItem());
+ items.add(createJoinGapsItem());
+ items.add(createAnalyzeOnMapItem());
+ items.add(createAnalyzeByIntervalsItem());
+
+ items.add(createDividerItem());
+ items.add(createShareItem());
+
+ if (fileAvailable) {
+ items.add(createUploadOsmItem());
+ items.add(createDividerItem());
+ items.add(createEditItem());
+ items.add(createRenameItem());
+ items.add(createChangeFolderItem());
+ items.add(createDividerItem());
+ items.add(createDeleteItem());
+ }
+ items.add(new DividerSpaceItem(mapActivity, AndroidUtils.dpToPx(app, 6)));
+
+ inflateItems();
+ }
+
+ private BaseBottomSheetItem createDividerItem() {
+ DividerItem dividerItem = new DividerItem(mapActivity);
+ int start = app.getResources().getDimensionPixelSize(R.dimen.measurement_tool_options_divider_margin_start);
+ int verticalMargin = AndroidUtils.dpToPx(app, 6);
+ dividerItem.setMargins(start, verticalMargin, 0, verticalMargin);
+
+ return dividerItem;
+ }
+
+ private BaseBottomSheetItem createShowOnMapItem() {
+
+ final Drawable showIcon = getActiveIcon(R.drawable.ic_action_view);
+ final Drawable hideIcon = getContentIcon(R.drawable.ic_action_hide);
+ boolean gpxFileSelected = isGpxFileSelected(app, gpxFile);
+
+ final BottomSheetItemWithCompoundButton[] showOnMapItem = new BottomSheetItemWithCompoundButton[1];
+ showOnMapItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
+ .setChecked(gpxFileSelected)
+ .setIcon(gpxFileSelected ? showIcon : hideIcon)
+ .setTitle(app.getString(R.string.shared_string_show_on_map))
+ .setLayoutId(R.layout.bottom_sheet_item_with_switch_pad_32)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ boolean checked = !showOnMapItem[0].isChecked();
+ showOnMapItem[0].setChecked(checked);
+ showOnMapItem[0].setIcon(checked ? showIcon : hideIcon);
+
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, SHOW_ON_MAP_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ return showOnMapItem[0];
+ }
+
+ private BaseBottomSheetItem createAppearanceItem() {
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(getActiveIcon(R.drawable.ic_action_appearance))
+ .setTitle(app.getString(R.string.shared_string_appearance))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, APPEARANCE_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createDirectionsItem() {
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(getActiveIcon(R.drawable.ic_action_gdirections_dark))
+ .setTitle(app.getString(R.string.get_directions))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, DIRECTIONS_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createJoinGapsItem() {
+ final Drawable joinGapsEnabledIcon = getActiveIcon(R.drawable.ic_action_join_segments);
+ final Drawable joinGapsDisabledIcon = getContentIcon(R.drawable.ic_action_join_segments);
+ boolean joinSegments = displayHelper.isJoinSegments();
+
+ final BottomSheetItemWithCompoundButton[] joinGapsItem = new BottomSheetItemWithCompoundButton[1];
+ joinGapsItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
+ .setChecked(joinSegments)
+ .setIcon(joinSegments ? joinGapsEnabledIcon : joinGapsDisabledIcon)
+ .setTitle(app.getString(R.string.gpx_join_gaps))
+ .setLayoutId(R.layout.bottom_sheet_item_with_switch_pad_32)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ boolean checked = !joinGapsItem[0].isChecked();
+ joinGapsItem[0].setChecked(checked);
+ joinGapsItem[0].setIcon(checked ? joinGapsEnabledIcon : joinGapsDisabledIcon);
+
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, JOIN_GAPS_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ return joinGapsItem[0];
+ }
+
+ private BaseBottomSheetItem createAnalyzeOnMapItem() {
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(getActiveIcon(R.drawable.ic_action_analyze_intervals))
+ .setTitle(app.getString(R.string.analyze_on_map))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, ANALYZE_ON_MAP_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createAnalyzeByIntervalsItem() {
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(getActiveIcon(R.drawable.ic_action_analyze_intervals))
+ .setTitle(app.getString(R.string.analyze_by_intervals))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, ANALYZE_BY_INTERVALS_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createShareItem() {
+ Drawable shareIcon = getActiveIcon(R.drawable.ic_action_gshare_dark);
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(AndroidUtils.getDrawableForDirection(app, shareIcon))
+ .setTitle(app.getString(R.string.shared_string_share))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, SHARE_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createUploadOsmItem() {
+ OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getEnabledPlugin(OsmEditingPlugin.class);
+ if (osmEditingPlugin != null) {
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(getActiveIcon(R.drawable.ic_action_export))
+ .setTitle(app.getString(R.string.upload_to_openstreetmap))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, UPLOAD_OSM_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+ return null;
+ }
+
+ private BaseBottomSheetItem createEditItem() {
+ Drawable editIcon = getActiveIcon(R.drawable.ic_action_edit_dark);
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(AndroidUtils.getDrawableForDirection(app, editIcon))
+ .setTitle(app.getString(R.string.edit_track))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, EDIT_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createRenameItem() {
+ Drawable renameIcon = getActiveIcon(R.drawable.ic_action_name_field);
+ return new SimpleBottomSheetItem.Builder()
+ .setIcon(AndroidUtils.getDrawableForDirection(app, renameIcon))
+ .setTitle(app.getString(R.string.rename_track))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, RENAME_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createChangeFolderItem() {
+ String folder = new File(gpxFile.path).getParentFile().getName();
+ Drawable changeFolderIcon = getActiveIcon(R.drawable.ic_action_folder_move);
+
+ return new BottomSheetItemWithDescriptionDifHeight.Builder()
+ .setMinHeight(app.getResources().getDimensionPixelSize(R.dimen.setting_list_item_group_height))
+ .setDescriptionColorId(nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light)
+ .setDescription(capitalizeFirstLetter(folder))
+ .setIcon(AndroidUtils.getDrawableForDirection(app, changeFolderIcon))
+ .setTitle(app.getString(R.string.change_folder))
+ .setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, CHANGE_FOLDER_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private BaseBottomSheetItem createDeleteItem() {
+ String delete = app.getString(R.string.shared_string_delete);
+ Typeface typeface = FontCache.getRobotoMedium(app);
+ return new SimpleBottomSheetItem.Builder()
+ .setTitleColorId(R.color.color_osm_edit_delete)
+ .setIcon(getColoredIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete))
+ .setTitle(UiUtilities.createCustomFontSpannable(typeface, delete, delete))
+ .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
+ .setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CardListener listener = getListener();
+ if (listener != null) {
+ listener.onCardButtonPressed(OptionsCard.this, DELETE_BUTTON_INDEX);
+ }
+ }
+ })
+ .create();
+ }
+
+ private void inflateItems() {
+ for (BaseBottomSheetItem item : items) {
+ item.inflate(mapActivity, (ViewGroup) view, nightMode);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java b/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java
index 3a6fce7271..b3921a6889 100644
--- a/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java
+++ b/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java
@@ -34,7 +34,7 @@ public class SegmentsCard extends BaseCard {
@Override
public int getCardLayoutId() {
- return R.layout.track_segments_container;
+ return R.layout.card_container;
}
@Override
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
index 66b2a5f5a2..43642bfe9c 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java
@@ -56,8 +56,6 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING;
-import static net.osmand.plus.activities.TrackActivity.TRACK_FILE_NAME;
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR;
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD;
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM;
@@ -121,6 +119,10 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
return trackDrawInfo;
}
+ public void setSelectedGpxFile(SelectedGpxFile selectedGpxFile) {
+ this.selectedGpxFile = selectedGpxFile;
+ }
+
@Override
public int getSupportedMenuStatesPortrait() {
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
@@ -132,40 +134,25 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
app = requireMyApplication();
gpxDbHelper = app.getGpxDbHelper();
- Bundle arguments = getArguments();
if (savedInstanceState != null) {
trackDrawInfo = new TrackDrawInfo(savedInstanceState);
- if (trackDrawInfo.isCurrentRecording()) {
- selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack();
- } else {
- selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(trackDrawInfo.getFilePath());
- }
if (!selectedGpxFile.isShowCurrentTrack()) {
gpxDataItem = gpxDbHelper.getItem(new File(trackDrawInfo.getFilePath()));
}
showStartFinishIconsInitialValue = savedInstanceState.getBoolean(SHOW_START_FINISH_ICONS_INITIAL_VALUE_KEY,
app.getSettings().SHOW_START_FINISH_ICONS.get());
- } else if (arguments != null) {
- String gpxFilePath = arguments.getString(TRACK_FILE_NAME);
- boolean currentRecording = arguments.getBoolean(CURRENT_RECORDING, false);
+ } else {
showStartFinishIconsInitialValue = app.getSettings().SHOW_START_FINISH_ICONS.get();
- if (gpxFilePath == null && !currentRecording) {
- log.error("Required extra '" + TRACK_FILE_NAME + "' is missing");
- dismiss();
- return;
- }
- if (currentRecording) {
+ if (selectedGpxFile.isShowCurrentTrack()) {
trackDrawInfo = new TrackDrawInfo(true);
trackDrawInfo.setColor(app.getSettings().CURRENT_TRACK_COLOR.get());
trackDrawInfo.setWidth(app.getSettings().CURRENT_TRACK_WIDTH.get());
trackDrawInfo.setShowArrows(app.getSettings().CURRENT_TRACK_SHOW_ARROWS.get());
trackDrawInfo.setShowStartFinish(app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.get());
- selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack();
} else {
- gpxDataItem = gpxDbHelper.getItem(new File(gpxFilePath));
+ gpxDataItem = gpxDbHelper.getItem(new File(selectedGpxFile.getGpxFile().path));
trackDrawInfo = new TrackDrawInfo(app, gpxDataItem, false);
- selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath);
}
updateTrackColor();
}
@@ -726,8 +713,12 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
return totalScreenHeight - frameTotalHeight;
}
- public static boolean showInstance(@NonNull MapActivity mapActivity, TrackAppearanceFragment fragment) {
+ public static boolean showInstance(@NonNull MapActivity mapActivity, @NonNull SelectedGpxFile selectedGpxFile) {
try {
+ TrackAppearanceFragment fragment = new TrackAppearanceFragment();
+ fragment.setSelectedGpxFile(selectedGpxFile);
+ fragment.setRetainInstance(true);
+
mapActivity.getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentContainer, fragment, fragment.getFragmentTag())
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDisplayHelper.java b/OsmAnd/src/net/osmand/plus/track/TrackDisplayHelper.java
index 5ab0a6740f..39ce84eedf 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackDisplayHelper.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackDisplayHelper.java
@@ -101,19 +101,7 @@ public class TrackDisplayHelper {
return new ArrayList<>();
}
if (gpxFile.modifiedTime != modifiedTime) {
- modifiedTime = gpxFile.modifiedTime;
- GpxSelectionHelper selectedGpxHelper = app.getSelectedGpxHelper();
- displayGroups = selectedGpxHelper.collectDisplayGroups(gpxFile);
- originalGroups.clear();
- for (GpxSelectionHelper.GpxDisplayGroup g : displayGroups) {
- originalGroups.add(g.cloneInstance());
- }
- if (file != null) {
- SelectedGpxFile sf = selectedGpxHelper.getSelectedFileByPath(gpxFile.path);
- if (sf != null && file != null && sf.getDisplayGroups(app) != null) {
- displayGroups = sf.getDisplayGroups(app);
- }
- }
+ updateDisplayGroups();
}
if (useDisplayGroups) {
return displayGroups;
@@ -122,6 +110,22 @@ public class TrackDisplayHelper {
}
}
+ public void updateDisplayGroups() {
+ modifiedTime = gpxFile.modifiedTime;
+ GpxSelectionHelper selectedGpxHelper = app.getSelectedGpxHelper();
+ displayGroups = selectedGpxHelper.collectDisplayGroups(gpxFile);
+ originalGroups.clear();
+ for (GpxDisplayGroup g : displayGroups) {
+ originalGroups.add(g.cloneInstance());
+ }
+ if (file != null) {
+ SelectedGpxFile sf = selectedGpxHelper.getSelectedFileByPath(gpxFile.path);
+ if (sf != null && file != null && sf.getDisplayGroups(app) != null) {
+ displayGroups = sf.getDisplayGroups(app);
+ }
+ }
+ }
+
@NonNull
public List getOriginalGroups(GpxDisplayItemType[] filterTypes) {
return filterGroups(false, filterTypes);
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
index 595c456858..794011f51e 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
@@ -5,12 +5,14 @@ import android.content.res.ColorStateList;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
@@ -25,36 +27,47 @@ import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import net.osmand.AndroidUtils;
+import net.osmand.FileUtils;
+import net.osmand.FileUtils.RenameCallback;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.Track;
import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.PlatformUtil;
+import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
-import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxDbHelper;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
+import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.activities.MapActivityActions;
import net.osmand.plus.base.ContextMenuFragment;
import net.osmand.plus.base.ContextMenuScrollFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
+import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController.OpenGpxDetailsTask;
+import net.osmand.plus.mapcontextmenu.other.TrackChartPoints;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.measurementtool.GpxData;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolFragment;
+import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
import net.osmand.plus.myplaces.GPXTabItemType;
+import net.osmand.plus.myplaces.MoveGpxFileBottomSheet;
+import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener;
import net.osmand.plus.myplaces.SegmentActionsListener;
import net.osmand.plus.myplaces.SplitSegmentDialogFragment;
import net.osmand.plus.myplaces.TrackActivityFragmentAdapter;
+import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
@@ -68,28 +81,46 @@ import java.util.List;
import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING;
import static net.osmand.plus.activities.TrackActivity.TRACK_FILE_NAME;
+import static net.osmand.plus.myplaces.TrackActivityFragmentAdapter.isGpxFileSelected;
+import static net.osmand.plus.track.OptionsCard.ANALYZE_BY_INTERVALS_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.ANALYZE_ON_MAP_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.APPEARANCE_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.CHANGE_FOLDER_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.DELETE_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.DIRECTIONS_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.EDIT_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.JOIN_GAPS_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.RENAME_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.SHARE_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.SHOW_ON_MAP_BUTTON_INDEX;
+import static net.osmand.plus.track.OptionsCard.UPLOAD_OSM_BUTTON_INDEX;
-public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener, SegmentActionsListener {
+public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
+ SegmentActionsListener, RenameCallback, OnTrackFileMoveListener {
public static final String TAG = TrackMenuFragment.class.getName();
private static final Log log = PlatformUtil.getLog(TrackMenuFragment.class);
private OsmandApplication app;
private TrackDisplayHelper displayHelper;
-
- private GpxDataItem gpxDataItem;
private SelectedGpxFile selectedGpxFile;
private View routeMenuTopShadowAll;
+ private TextView headerTitle;
+ private ImageView headerIcon;
private BottomNavigationView bottomNav;
private TrackMenuType menuType = TrackMenuType.TRACK;
private SegmentsCard segmentsCard;
+ private OptionsCard optionsCard;
+
+ private TrackChartPoints trackChartPoints;
private int menuTitleHeight;
public enum TrackMenuType {
TRACK(R.id.action_track, R.string.shared_string_gpx_tracks),
- POINTS(R.id.action_points, R.string.shared_string_gpx_points);
+ POINTS(R.id.action_points, R.string.shared_string_gpx_points),
+ OPTIONS(R.id.action_options, R.string.shared_string_options);
TrackMenuType(@DrawableRes int iconId, @StringRes int titleId) {
this.iconId = iconId;
@@ -140,26 +171,20 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
GpxDbHelper gpxDbHelper = app.getGpxDbHelper();
displayHelper = new TrackDisplayHelper(app);
- String gpxFilePath = "";
- boolean currentRecording = false;
Bundle arguments = getArguments();
- if (savedInstanceState != null) {
- gpxFilePath = savedInstanceState.getString(TRACK_FILE_NAME);
- currentRecording = savedInstanceState.getBoolean(CURRENT_RECORDING, false);
- } else if (arguments != null) {
- gpxFilePath = arguments.getString(TRACK_FILE_NAME);
- currentRecording = arguments.getBoolean(CURRENT_RECORDING, false);
+ if (arguments != null) {
+ String gpxFilePath = arguments.getString(TRACK_FILE_NAME);
+ boolean currentRecording = arguments.getBoolean(CURRENT_RECORDING, false);
+ if (currentRecording) {
+ selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack();
+ } else {
+ File file = new File(gpxFilePath);
+ displayHelper.setFile(file);
+ displayHelper.setGpxDataItem(gpxDbHelper.getItem(file));
+ selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath);
+ }
+ displayHelper.setGpx(selectedGpxFile.getGpxFile());
}
- if (currentRecording) {
- selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack();
- } else {
- File file = new File(gpxFilePath);
- displayHelper.setFile(file);
- gpxDataItem = gpxDbHelper.getItem(file);
- selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath);
- }
- displayHelper.setGpxDataItem(gpxDataItem);
- displayHelper.setGpx(selectedGpxFile.getGpxFile());
}
public GPXFile getGpx() {
@@ -172,14 +197,19 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
if (view != null) {
bottomNav = view.findViewById(R.id.bottom_navigation);
routeMenuTopShadowAll = view.findViewById(R.id.route_menu_top_shadow_all);
- TextView title = view.findViewById(R.id.title);
- String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
- title.setText(GpxUiHelper.getGpxTitle(fileName));
+ headerTitle = view.findViewById(R.id.title);
+ headerIcon = view.findViewById(R.id.icon_view);
if (isPortrait()) {
updateCardsLayout();
+ } else {
+ int widthNoShadow = getLandscapeNoShadowWidth();
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
+ params.gravity = Gravity.BOTTOM | Gravity.START;
+ bottomNav.setLayoutParams(params);
}
setupCards();
+ updateHeader();
setupButtons(view);
enterTrackAppearanceMode();
runLayoutListener();
@@ -187,18 +217,46 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
return view;
}
+ private void updateHeader() {
+ if (menuType == TrackMenuType.OPTIONS) {
+ headerTitle.setText(menuType.titleId);
+ AndroidUiHelper.updateVisibility(headerIcon, false);
+ } else {
+ String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
+ headerTitle.setText(GpxUiHelper.getGpxTitle(fileName));
+ AndroidUiHelper.updateVisibility(headerIcon, true);
+ }
+ }
+
private void setupCards() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
ViewGroup cardsContainer = getCardsContainer();
cardsContainer.removeAllViews();
if (menuType == TrackMenuType.TRACK) {
- if (segmentsCard != null) {
+ if (segmentsCard != null && segmentsCard.getView() != null) {
+ ViewGroup parent = (ViewGroup) segmentsCard.getView().getParent();
+ if (parent != null) {
+ parent.removeAllViews();
+ }
cardsContainer.addView(segmentsCard.getView());
} else {
segmentsCard = new SegmentsCard(mapActivity, displayHelper, this);
+ segmentsCard.setListener(this);
cardsContainer.addView(segmentsCard.build(mapActivity));
}
+ } else if (menuType == TrackMenuType.OPTIONS) {
+ if (optionsCard != null && optionsCard.getView() != null) {
+ ViewGroup parent = (ViewGroup) optionsCard.getView().getParent();
+ if (parent != null) {
+ parent.removeAllViews();
+ }
+ cardsContainer.addView(optionsCard.getView());
+ } else {
+ optionsCard = new OptionsCard(mapActivity, displayHelper);
+ optionsCard.setListener(this);
+ cardsContainer.addView(optionsCard.build(mapActivity));
+ }
}
}
}
@@ -239,6 +297,46 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
exitTrackAppearanceMode();
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ MapActivity mapActivity = getMapActivity();
+ if (mapActivity != null && trackChartPoints != null) {
+ mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ MapActivity mapActivity = getMapActivity();
+ if (mapActivity != null) {
+ mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(null);
+ }
+ }
+
+ @Override
+ public void renamedTo(File file) {
+ updateFile(file);
+ }
+
+ @Override
+ public void onFileMove(@NonNull File src, @NonNull File dest) {
+ File file = FileUtils.renameGpxFile(app, src, dest);
+ if (file != null) {
+ updateFile(file);
+ } else {
+ app.showToastMessage(R.string.file_can_not_be_renamed);
+ }
+ }
+
+ private void updateFile(File file) {
+ displayHelper.setFile(file);
+ displayHelper.updateDisplayGroups();
+ updateHeader();
+ updateContent();
+ }
+
private void enterTrackAppearanceMode() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
@@ -311,7 +409,104 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
@Override
public void onCardButtonPressed(@NonNull BaseCard card, int buttonIndex) {
+ MapActivity mapActivity = getMapActivity();
+ if (mapActivity == null) {
+ return;
+ }
+ if (card instanceof OptionsCard) {
+ final GPXFile gpxFile = getGpx();
+ if (buttonIndex == SHOW_ON_MAP_BUTTON_INDEX) {
+ boolean gpxFileSelected = !isGpxFileSelected(app, gpxFile);
+ app.getSelectedGpxHelper().selectGpxFile(gpxFile, gpxFileSelected, false);
+ mapActivity.refreshMap();
+ } else if (buttonIndex == APPEARANCE_BUTTON_INDEX) {
+ TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile);
+ } else if (buttonIndex == DIRECTIONS_BUTTON_INDEX) {
+ MapActivityActions mapActions = mapActivity.getMapActions();
+ if (app.getRoutingHelper().isFollowingMode()) {
+ mapActions.stopNavigationActionConfirm(null, new Runnable() {
+ @Override
+ public void run() {
+ MapActivity mapActivity = getMapActivity();
+ if (mapActivity != null) {
+ mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpxFile, null,
+ null, null, true, true, MenuState.HEADER_ONLY);
+ }
+ }
+ });
+ } else {
+ mapActions.stopNavigationWithoutConfirm();
+ mapActions.enterRoutePlanningModeGivenGpx(gpxFile, null, null,
+ null, true, true, MenuState.HEADER_ONLY);
+ }
+ dismiss();
+ }
+ if (buttonIndex == JOIN_GAPS_BUTTON_INDEX) {
+ displayHelper.setJoinSegments(!displayHelper.isJoinSegments());
+ mapActivity.refreshMap();
+ if (segmentsCard != null) {
+ segmentsCard.updateContent();
+ }
+ } else if (buttonIndex == ANALYZE_ON_MAP_BUTTON_INDEX) {
+ new OpenGpxDetailsTask(selectedGpxFile, null, mapActivity).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ dismiss();
+ } else if (buttonIndex == ANALYZE_BY_INTERVALS_BUTTON_INDEX) {
+ FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
+ TrkSegment segment = gpxFile.getGeneralSegment();
+ if (segment == null) {
+ List segments = gpxFile.getNonEmptyTrkSegments(false);
+ if (!Algorithms.isEmpty(segments)) {
+ segment = segments.get(0);
+ }
+ }
+ GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT};
+ List items = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes));
+ if (segment != null && !Algorithms.isEmpty(items)) {
+ SplitSegmentDialogFragment.showInstance(fragmentManager, displayHelper, items.get(0), segment);
+ }
+ } else if (buttonIndex == SHARE_BUTTON_INDEX) {
+ OsmandApplication app = mapActivity.getMyApplication();
+ if (gpxFile.showCurrentTrack) {
+ GpxUiHelper.saveAndShareCurrentGpx(app, gpxFile);
+ } else if (!Algorithms.isEmpty(gpxFile.path)) {
+ GpxUiHelper.saveAndShareGpxWithAppearance(app, gpxFile);
+ }
+ } else if (buttonIndex == UPLOAD_OSM_BUTTON_INDEX) {
+ OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getEnabledPlugin(OsmEditingPlugin.class);
+ if (osmEditingPlugin != null) {
+ GpxInfo gpxInfo = new GpxInfo();
+ gpxInfo.gpx = gpxFile;
+ gpxInfo.file = new File(gpxFile.path);
+ osmEditingPlugin.sendGPXFiles(mapActivity, this, gpxInfo);
+ }
+ } else if (buttonIndex == EDIT_BUTTON_INDEX) {
+ String fileName = Algorithms.getFileWithoutDirs(gpxFile.path);
+ MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), fileName);
+ dismiss();
+ } else if (buttonIndex == RENAME_BUTTON_INDEX) {
+ FileUtils.renameFile(mapActivity, new File(gpxFile.path), this, true);
+ } else if (buttonIndex == CHANGE_FOLDER_BUTTON_INDEX) {
+ FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
+ MoveGpxFileBottomSheet.showInstance(fragmentManager, this, gpxFile.path, true);
+ } else if (buttonIndex == DELETE_BUTTON_INDEX) {
+ String fileName = Algorithms.getFileWithoutDirs(gpxFile.path);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(UiUtilities.getThemedContext(mapActivity, isNightMode()));
+ builder.setTitle(getString(R.string.delete_confirmation_msg, fileName));
+ builder.setMessage(R.string.are_you_sure);
+ builder.setNegativeButton(R.string.shared_string_cancel, null).setPositiveButton(
+ R.string.shared_string_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (FileUtils.removeGpxFile(app, new File((gpxFile.path)))) {
+ dismiss();
+ }
+ }
+ });
+ builder.show();
+ }
+ }
}
@Override
@@ -378,6 +573,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
if (type.iconId == item.getItemId()) {
menuType = type;
setupCards();
+ updateHeader();
break;
}
}
@@ -391,6 +587,9 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
if (segmentsCard != null) {
segmentsCard.updateContent();
}
+ if (optionsCard != null) {
+ optionsCard.updateContent();
+ }
setupCards();
}
@@ -405,8 +604,19 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
}
@Override
- public void onPointSelected(double lat, double lon) {
-
+ public void onPointSelected(TrkSegment segment, double lat, double lon) {
+ if (trackChartPoints == null) {
+ trackChartPoints = new TrackChartPoints();
+ trackChartPoints.setGpx(getGpx());
+ }
+ MapActivity mapActivity = getMapActivity();
+ if (mapActivity != null) {
+ int segmentColor = segment != null ? segment.getColor(0) : 0;
+ trackChartPoints.setSegmentColor(segmentColor);
+ trackChartPoints.setHighlightedPoint(new LatLon(lat, lon));
+ mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
+ mapActivity.refreshMap();
+ }
}
@Override
@@ -551,10 +761,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
public void gpxSavingFinished(Exception errorMessage) {
if (selectedGpxFile != null) {
List groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT});
- if (groups != null) {
- selectedGpxFile.setDisplayGroups(groups, app);
- selectedGpxFile.processPoints(app);
- }
+ selectedGpxFile.setDisplayGroups(groups, app);
+ selectedGpxFile.processPoints(app);
}
updateContent();
}
@@ -582,6 +790,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
TrackMenuFragment fragment = new TrackMenuFragment();
fragment.setArguments(args);
+ fragment.setRetainInstance(true);
mapActivity.getSupportFragmentManager()
.beginTransaction()