Replace 'rename' to 'undo' after done button

This commit is contained in:
max-klaus 2020-09-22 14:37:52 +03:00
parent 1cc690ecf5
commit fdea007118
3 changed files with 207 additions and 88 deletions

View file

@ -9,6 +9,7 @@ import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import net.osmand.plus.GpxSelectionHelper;
@ -19,6 +20,7 @@ import net.osmand.plus.SQLiteTileSource;
import net.osmand.util.Algorithms;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.regex.Pattern;
@ -121,33 +123,54 @@ public class FileUtils {
return null;
}
public static File renameGpxFile(OsmandApplication ctx, File source, String newName, boolean dirAllowed,
RenameCallback callback) {
File dest = checkRenamePossibility(ctx, source, newName, dirAllowed);
public static File renameGpxFile(@NonNull OsmandApplication app, @NonNull File source,
@NonNull String newName, boolean dirAllowed, @Nullable RenameCallback callback) {
File dest = checkRenamePossibility(app, source, newName, dirAllowed);
if (dest == null) {
return null;
}
File res = renameGpxFile(app, source, dest);
if (res != null) {
if (callback != null) {
callback.renamedTo(res);
}
} else {
Toast.makeText(app, R.string.file_can_not_be_renamed, Toast.LENGTH_LONG).show();
}
return res;
}
public static File renameGpxFile(@NonNull OsmandApplication app, @NonNull File src, @NonNull File dest) {
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
if (source.renameTo(dest)) {
GpxSelectionHelper helper = ctx.getSelectedGpxHelper();
SelectedGpxFile selected = helper.getSelectedFileByPath(source.getAbsolutePath());
ctx.getGpxDbHelper().rename(source, dest);
if (src.renameTo(dest)) {
GpxSelectionHelper helper = app.getSelectedGpxHelper();
SelectedGpxFile selected = helper.getSelectedFileByPath(src.getAbsolutePath());
app.getGpxDbHelper().rename(src, dest);
if (selected != null && selected.getGpxFile() != null) {
selected.getGpxFile().path = dest.getAbsolutePath();
helper.updateSelectedGpxFile(selected);
}
if (callback != null) {
callback.renamedTo(dest);
}
return dest;
} else {
Toast.makeText(ctx, R.string.file_can_not_be_renamed, Toast.LENGTH_LONG).show();
}
return null;
}
public static boolean removeGpxFile(@NonNull OsmandApplication app, @NonNull File file) {
if (file.exists()) {
GpxSelectionHelper helper = app.getSelectedGpxHelper();
SelectedGpxFile selected = helper.getSelectedFileByPath(file.getAbsolutePath());
file.delete();
app.getGpxDbHelper().remove(file);
if (selected != null && selected.getGpxFile() != null) {
helper.selectGpxFile(selected.getGpxFile(), false, false);
}
return true;
}
return false;
}
public static File checkRenamePossibility(OsmandApplication ctx, File source, String newName, boolean dirAllowed) {
if (Algorithms.isEmpty(newName)) {
Toast.makeText(ctx, R.string.empty_filename, Toast.LENGTH_LONG).show();
@ -178,6 +201,23 @@ public class FileUtils {
return uniqueFileName;
}
public static File backupFile(@NonNull OsmandApplication app, @NonNull File src) {
if (!src.exists()) {
return null;
}
File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
if (!tempDir.exists()) {
tempDir.mkdirs();
}
File dest = new File(tempDir, src.getName());
try {
Algorithms.fileCopy(src, dest);
} catch (IOException e) {
return null;
}
return dest;
}
public interface RenameCallback {
void renamedTo(File file);
}

View file

@ -25,6 +25,13 @@ public class GpxData {
this.trkSegment = trkSegment;
}
public GpxData(GPXFile gpxFile, GpxData gpxData) {
this.gpxFile = gpxFile;
this.rect = gpxData.rect;
this.actionType = gpxData.actionType;
this.trkSegment = gpxData.trkSegment;
}
public GPXFile getGpxFile() {
return gpxFile;
}

View file

@ -136,9 +136,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private boolean wasCollapseButtonVisible;
private boolean progressBarVisible;
private boolean pointsListOpened;
private boolean planRouteMode = false;
private boolean directionMode = false;
private boolean followTrackMode = false;
private static final int PLAN_ROUTE_MODE = 0x1;
private static final int DIRECTION_MODE = 0x2;
private static final int FOLLOW_TRACK_MODE = 0x4;
private static final int UNDO_MODE = 0x8;
private int modes = 0x0;
private boolean approximationApplied = false;
private boolean portrait;
private boolean nightMode;
@ -167,16 +171,30 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
this.initialPoint = initialPoint;
}
private void setPlanRouteMode(boolean planRouteMode) {
this.planRouteMode = planRouteMode;
private void setMode(int mode, boolean on) {
int modes = this.modes;
if (on) {
modes |= mode;
} else {
modes &= ~mode;
}
this.modes = modes;
}
private void setDirectionMode(boolean directionMode) {
this.directionMode = directionMode;
private boolean isPlanRouteMode() {
return (this.modes & PLAN_ROUTE_MODE) == PLAN_ROUTE_MODE;
}
private void setFollowTrackMode(boolean followTrackMode) {
this.followTrackMode = followTrackMode;
private boolean isDirectionMode() {
return (this.modes & DIRECTION_MODE) == DIRECTION_MODE;
}
private boolean isFollowTrackMode() {
return (this.modes & FOLLOW_TRACK_MODE) == FOLLOW_TRACK_MODE;
}
private boolean isUndoMode() {
return (this.modes & UNDO_MODE) == UNDO_MODE;
}
@Override
@ -446,7 +464,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
toolBarController.setOnSaveViewClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (followTrackMode) {
if (isFollowTrackMode()) {
startTrackNavigation();
} else {
saveChanges(FinalSaveAction.SHOW_SNACK_BAR_AND_CLOSE, false);
@ -495,7 +513,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
public boolean isInEditMode() {
return !planRouteMode && !editingCtx.isNewData() && !directionMode && !followTrackMode;
return !isPlanRouteMode() && !editingCtx.isNewData() && !isDirectionMode() && !isFollowTrackMode();
}
public void setFileName(String fileName) {
@ -519,11 +537,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
enterMeasurementMode();
updateSnapToRoadControls();
if (gpxData != null) {
List<WptPt> points = gpxData.getGpxFile().getRoutePoints();
if (!points.isEmpty()) {
ApplicationMode snapToRoadAppMode = ApplicationMode.valueOfStringKey(points.get(points.size() - 1).getProfileType(), null);
if (snapToRoadAppMode != null) {
setAppMode(snapToRoadAppMode);
if (!isUndoMode()) {
List<WptPt> points = gpxData.getGpxFile().getRoutePoints();
if (!points.isEmpty()) {
ApplicationMode snapToRoadAppMode = ApplicationMode.valueOfStringKey(points.get(points.size() - 1).getProfileType(), null);
if (snapToRoadAppMode != null) {
setAppMode(snapToRoadAppMode);
}
}
}
ActionType actionType = gpxData.getActionType();
@ -533,6 +553,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
displaySegmentPoints();
}
}
setMode(UNDO_MODE, false);
}
}
@ -678,7 +699,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
switch (resultCode) {
case SnapTrackWarningFragment.CANCEL_RESULT_CODE:
toolBarController.setSaveViewVisible(true);
directionMode = false;
setMode(DIRECTION_MODE, false);
exitApproximationMode();
updateToolbar();
break;
@ -744,7 +765,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
targetPointsHelper.clearAllPoints(false);
mapActions.enterRoutePlanningModeGivenGpx(gpx, appMode, null, null, true, true, MenuState.HEADER_ONLY);
} else {
directionMode = true;
setMode(DIRECTION_MODE, true);
enterApproximationMode(mapActivity);
}
}
@ -760,7 +781,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (mapActivity != null) {
OsmandApplication app = mapActivity.getMyApplication();
if (app.getRoutingHelper().isFollowingMode()) {
if (followTrackMode) {
if (isFollowTrackMode()) {
mapActivity.getMapActions().setGPXRouteParams(gpx);
app.getTargetPointsHelper().updateRouteAndRefresh(true);
app.getRoutingHelper().recalculateRouteDueToSettingsChange();
@ -1026,20 +1047,29 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
public void addNewGpxData(GPXFile gpxFile) {
QuadRect rect = gpxFile.getRect();
TrkSegment segment = gpxFile.getNonEmptyTrkSegment();
ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
GpxData gpxData = new GpxData(gpxFile, rect, actionType, segment);
editingCtx.setGpxData(gpxData);
GpxData gpxData = setupGpxData(gpxFile);
initMeasurementMode(gpxData);
QuadRect qr = gpxData.getRect();
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
if (mapActivity != null && gpxData != null) {
QuadRect qr = gpxData.getRect();
mapActivity.getMapView().fitRectToMap(qr.left, qr.right, qr.top, qr.bottom,
(int) qr.width(), (int) qr.height(), 0);
}
}
@Nullable
private GpxData setupGpxData(@Nullable GPXFile gpxFile) {
GpxData gpxData = null;
if (gpxFile != null) {
QuadRect rect = gpxFile.getRect();
TrkSegment segment = gpxFile.getNonEmptyTrkSegment();
ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
gpxData = new GpxData(gpxFile, rect, actionType, segment);
}
editingCtx.setGpxData(gpxData);
return gpxData;
}
private void removePoint(MeasurementToolLayer measurementLayer, int position) {
if (measurementLayer != null) {
editingCtx.getCommandManager().execute(new RemovePointCommand(measurementLayer, position));
@ -1172,7 +1202,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (gpx != null) {
List<WptPt> points = gpx.getRoutePoints();
if (measurementLayer != null) {
editingCtx.addPoints(points);
if (!isUndoMode()) {
editingCtx.addPoints(points);
}
adapter.notifyDataSetChanged();
updateDistancePointsText();
}
@ -1182,7 +1214,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void displaySegmentPoints() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
editingCtx.addPoints();
if (!isUndoMode()) {
editingCtx.addPoints();
}
adapter.notifyDataSetChanged();
updateDistancePointsText();
}
@ -1510,7 +1544,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
new AsyncTask<Void, Void, Exception>() {
private ProgressDialog progressDialog;
private File toSave;
private File backupFile;
private File outFile;
private GPXFile savedGpxFile;
@Override
@ -1535,7 +1570,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
TrkSegment after = editingCtx.getAfterTrkSegmentLine();
if (gpxFile == null) {
toSave = new File(dir, fileName);
outFile = new File(dir, fileName);
String trackName = fileName.substring(0, fileName.length() - GPX_FILE_EXT.length());
GPXFile gpx = new GPXFile(Version.getFullVersion(app));
if (measurementLayer != null) {
@ -1561,19 +1596,20 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
gpx.addRoutePoints(points);
}
}
Exception res = GPXUtilities.writeGpxFile(toSave, gpx);
gpx.path = toSave.getAbsolutePath();
Exception res = GPXUtilities.writeGpxFile(outFile, gpx);
gpx.path = outFile.getAbsolutePath();
savedGpxFile = gpx;
if (showOnMap) {
app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
showGpxOnMap(app, gpx, true);
}
return res;
} else {
GPXFile gpx = gpxFile;
toSave = new File(gpx.path);
String trackName = Algorithms.getFileNameWithoutExtension(toSave);
outFile = new File(gpx.path);
backupFile = FileUtils.backupFile(app, outFile);
String trackName = Algorithms.getFileNameWithoutExtension(outFile);
if (measurementLayer != null) {
if (planRouteMode) {
if (isPlanRouteMode()) {
if (saveType == SaveType.LINE) {
TrkSegment segment = new TrkSegment();
if (editingCtx.hasRoute()) {
@ -1635,21 +1671,25 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
Exception res = null;
if (!gpx.showCurrentTrack) {
res = GPXUtilities.writeGpxFile(toSave, gpx);
res = GPXUtilities.writeGpxFile(outFile, gpx);
}
savedGpxFile = gpx;
if (showOnMap) {
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
if (sf != null) {
if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) {
sf.processPoints(getMyApplication());
}
}
showGpxOnMap(app, gpx, false);
}
return res;
}
}
private void showGpxOnMap(OsmandApplication app, GPXFile gpx, boolean isNewGpx) {
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
if (sf != null && !isNewGpx) {
if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) {
sf.processPoints(getMyApplication());
}
}
}
@Override
protected void onPostExecute(Exception warning) {
onGpxSaved(warning);
@ -1665,7 +1705,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
mapActivity.refreshMap();
if (warning == null) {
editingCtx.setChangesSaved();
if (editingCtx.isNewData() && savedGpxFile != null) {
QuadRect rect = savedGpxFile.getRect();
TrkSegment segment = savedGpxFile.getNonEmptyTrkSegment();
@ -1674,30 +1713,66 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateToolbar();
}
if (isInEditMode()) {
editingCtx.setChangesSaved();
dismiss(mapActivity);
} else {
switch (finalSaveAction) {
case SHOW_SNACK_BAR_AND_CLOSE:
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
snackbar = Snackbar.make(mapActivity.getLayout(),
MessageFormat.format(getString(R.string.gpx_saved_sucessfully), toSave.getName()),
MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getName()),
Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_rename, getRenameListener(mapActivityRef));
.setAction(R.string.shared_string_undo, new OnClickListener() {
@Override
public void onClick(View view) {
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
if (outFile != null) {
OsmandApplication app = mapActivity.getMyApplication();
FileUtils.removeGpxFile(app, outFile);
if (backupFile != null) {
FileUtils.renameGpxFile(app, backupFile, outFile);
GPXFile gpx = GPXUtilities.loadGPXFile(outFile);
setupGpxData(gpx);
if (showOnMap) {
showGpxOnMap(app, gpx, false);
}
} else {
setupGpxData(null);
}
}
setMode(UNDO_MODE, true);
MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(),
editingCtx, modes);
}
}
})
.addCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar transientBottomBar, int event) {
if (event != DISMISS_EVENT_ACTION) {
editingCtx.setChangesSaved();
}
super.onDismissed(transientBottomBar, event);
}
});
snackbar.getView().<TextView>findViewById(com.google.android.material.R.id.snackbar_action)
.setAllCaps(false);
UiUtilities.setupSnackbar(snackbar, nightMode);
snackbar.show();
dismiss(mapActivity);
dismiss(mapActivity, false);
break;
case SHOW_IS_SAVED_FRAGMENT:
editingCtx.setChangesSaved();
SavedTrackBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
toSave.getAbsolutePath());
outFile.getAbsolutePath());
dismiss(mapActivity);
break;
case SHOW_TOAST:
editingCtx.setChangesSaved();
if (!savedGpxFile.showCurrentTrack) {
Toast.makeText(mapActivity,
MessageFormat.format(getString(R.string.gpx_saved_sucessfully), toSave.getAbsolutePath()),
MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getAbsolutePath()),
Toast.LENGTH_LONG).show();
}
}
@ -1706,22 +1781,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
Toast.makeText(mapActivity, warning.getMessage(), Toast.LENGTH_LONG).show();
}
}
private OnClickListener getRenameListener(final WeakReference<MapActivity> mapActivityRef) {
return new OnClickListener() {
@Override
public void onClick(View view) {
MapActivity mapActivity = mapActivityRef.get();
String parentFolder = toSave.getParentFile().getName();
if (GPX_INDEX_DIR.equals(parentFolder + File.separator)) {
parentFolder = null;
}
SaveAsNewTrackBottomSheetDialogFragment.showInstance(
mapActivity.getSupportFragmentManager(), null, parentFolder,
AndroidUtils.trimExtension(toSave.getName()), false, showOnMap);
}
};
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -1859,7 +1918,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
cancelAddPointBeforeOrAfterMode();
return;
}
if (followTrackMode) {
if (isFollowTrackMode()) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
mapActivity.getMapLayers().getMapControlsLayer().showRouteInfoControlDialog();
@ -1886,9 +1945,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
private void dismiss(MapActivity mapActivity) {
private void dismiss(@NonNull MapActivity mapActivity) {
dismiss(mapActivity, true);
}
private void dismiss(@NonNull MapActivity mapActivity, boolean clearContext) {
try {
editingCtx.clearSegments();
if (clearContext) {
editingCtx.clearSegments();
}
if (pointsListOpened) {
hidePointsList();
}
@ -1914,21 +1979,21 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public static boolean showInstance(FragmentManager fragmentManager, LatLon initialPoint) {
MeasurementToolFragment fragment = new MeasurementToolFragment();
fragment.setInitialPoint(initialPoint);
fragment.setPlanRouteMode(true);
fragment.setMode(PLAN_ROUTE_MODE, true);
return showFragment(fragment, fragmentManager);
}
public static boolean showInstance(FragmentManager fragmentManager, String fileName) {
MeasurementToolFragment fragment = new MeasurementToolFragment();
fragment.setFileName(fileName);
fragment.setPlanRouteMode(true);
fragment.setMode(PLAN_ROUTE_MODE, true);
return showFragment(fragment, fragmentManager);
}
public static boolean showInstance(FragmentManager fragmentManager, GPXFile gpxFile) {
MeasurementToolFragment fragment = new MeasurementToolFragment();
fragment.addNewGpxData(gpxFile);
fragment.setPlanRouteMode(true);
fragment.setMode(PLAN_ROUTE_MODE, true);
return showFragment(fragment, fragmentManager);
}
@ -1936,7 +2001,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
boolean followTrackMode) {
MeasurementToolFragment fragment = new MeasurementToolFragment();
fragment.setEditingCtx(editingCtx);
fragment.setFollowTrackMode(followTrackMode);
fragment.setMode(FOLLOW_TRACK_MODE, followTrackMode);
return showFragment(fragment, fragmentManager);
}
@ -1948,7 +2013,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public static boolean showInstance(FragmentManager fragmentManager) {
MeasurementToolFragment fragment = new MeasurementToolFragment();
fragment.setPlanRouteMode(true);
fragment.setMode(PLAN_ROUTE_MODE, true);
return showFragment(fragment, fragmentManager);
}
private static boolean showInstance(FragmentManager fragmentManager, MeasurementEditingContext editingCtx, int modes) {
MeasurementToolFragment fragment = new MeasurementToolFragment();
fragment.setEditingCtx(editingCtx);
fragment.modes = modes;
return showFragment(fragment, fragmentManager);
}
@ -2033,8 +2105,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
exitApproximationMode();
doAddOrMovePointCommonStuff();
updateSnapToRoadControls();
if (directionMode || followTrackMode) {
directionMode = false;
if (isDirectionMode() || isFollowTrackMode()) {
setMode(DIRECTION_MODE, false);
startTrackNavigation();
}
}
@ -2062,7 +2134,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public void onCancelGpxApproximation() {
editingCtx.getCommandManager().undo();
exitApproximationMode();
directionMode = false;
setMode(DIRECTION_MODE, false);
updateSnapToRoadControls();
updateToolbar();
}