This commit is contained in:
max-klaus 2019-11-09 12:37:48 +03:00
parent 0d6ad28309
commit a314f06e87
6 changed files with 260 additions and 102 deletions

View file

@ -3,54 +3,85 @@
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/bg_color"
android:orientation="vertical">
<TextView
android:id="@+id/saved_track_name_string"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/content_padding"
tools:text="Track 2019-02-26 12-52 saved"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"/>
<LinearLayout
android:orientation="horizontal"
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/content_padding_small">
android:padding="@dimen/content_padding"
android:text="@string/track_saved"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_medium" />
<Button
android:id="@+id/open_track_button"
android:background="?attr/dlg_btn_secondary"
<net.osmand.plus.widgets.OsmandTextFieldBoxes
android:id="@+id/name_text_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingBottom="@dimen/content_padding_small"
osmand:hasClearButton="true"
osmand:labelText="@string/gpx_file_name">
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="text"
android:maxLines="1" />
</net.osmand.plus.widgets.OsmandTextFieldBoxes>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="@dimen/bottom_sheet_cancel_button_height_small"
android:layout_weight="1"
android:text="@string/shared_string_open_track"
android:textColor="?attr/dlg_btn_secondary_text"
android:textSize="@dimen/default_desc_text_size"
android:textAllCaps="false"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
/>
<Button
android:id="@+id/show_on_map_button"
android:background="?attr/dlg_btn_primary"
android:layout_width="0dp"
android:layout_height="@dimen/bottom_sheet_cancel_button_height_small"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="@dimen/content_padding"
android:text="@string/shared_string_show_on_map"
android:textAllCaps="false"
android:textColor="?attr/dlg_btn_primary_text"
android:textSize="@dimen/default_desc_text_size"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
/>
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size" />
<android.support.v7.widget.SwitchCompat
android:id="@+id/btn_show_on_map"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:checked="true"
android:padding="@dimen/content_padding" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="@dimen/content_padding"
android:paddingTop="@dimen/content_padding_small"
android:paddingRight="@dimen/content_padding"
android:paddingBottom="@dimen/content_padding_small">
<include
android:id="@+id/open_track_button"
layout="@layout/bottom_sheet_dialog_button" />
<View
android:id="@+id/buttons_divider"
android:layout_width="@dimen/content_padding"
android:layout_height="match_parent" />
<include
android:id="@+id/close_button"
layout="@layout/bottom_sheet_dialog_button" />
</LinearLayout>
</LinearLayout>

View file

@ -11,6 +11,8 @@
Thx - Hardy
-->
<string name="track_saved">Track saved</string>
<string name="empty_filename">File name is empty</string>
<string name="default_speed_dialog_msg">Used to estimate arrival time for unknown type of roads and to limit speed for all roads (could change the route)</string>
<string name="rendering_value_white_name">White</string>
<string name="swap_two_places">Swap %1$s and %2$s</string>

View file

@ -39,6 +39,7 @@ import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.resources.IncrementalChangesManager;
import net.osmand.util.Algorithms;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Typeface;
@ -299,31 +300,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
new View.OnClickListener() {
@Override
public void onClick(View v) {
String newName = editText.getText().toString() + ext;
if (ILLEGAL_FILE_NAME_CHARACTERS.matcher(newName).find()) {
Toast.makeText(a, R.string.file_name_containes_illegal_char,
Toast.LENGTH_LONG).show();
return;
OsmandApplication app = (OsmandApplication) a.getApplication();
if (renameGpxFile(app, f, editText.getText().toString() + ext, callback) != null) {
alertDialog.dismiss();
}
File dest = new File(f.getParentFile(), newName);
if (dest.exists()) {
Toast.makeText(a, R.string.file_with_name_already_exists,
Toast.LENGTH_LONG).show();
return;
} else {
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
if (f.renameTo(dest)) {
if (callback != null) {
callback.renamedTo(dest);
}
} else {
Toast.makeText(a, R.string.file_can_not_be_renamed,
Toast.LENGTH_LONG).show();
}
}
alertDialog.dismiss();
}
});
}
@ -332,6 +312,35 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
}
}
public static File renameGpxFile(OsmandApplication ctx, File source, String newName, RenameCallback callback) {
if (Algorithms.isEmpty(newName)) {
Toast.makeText(ctx, R.string.empty_filename, Toast.LENGTH_LONG).show();
return null;
}
if (ILLEGAL_FILE_NAME_CHARACTERS.matcher(newName).find()) {
Toast.makeText(ctx, R.string.file_name_containes_illegal_char, Toast.LENGTH_LONG).show();
return null;
}
File dest = new File(source.getParentFile(), newName);
if (dest.exists()) {
Toast.makeText(ctx, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show();
} else {
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
if (source.renameTo(dest)) {
ctx.getGpxDbHelper().rename(source, dest);
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 class LoadLocalIndexTask extends AsyncTask<Void, LocalIndexInfo, List<LocalIndexInfo>>
implements AbstractLoadLocalIndexTask {

View file

@ -1,89 +1,206 @@
package net.osmand.plus.monitoring;
import android.graphics.Typeface;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.ContextThemeWrapper;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.SwitchCompat;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.view.inputmethod.EditorInfo;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import java.io.File;
import net.osmand.AndroidUtils;
import android.widget.Toast;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.DialogButtonType;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment;
import net.osmand.plus.myplaces.AvailableGPXFragment;
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.widgets.OsmandTextFieldBoxes;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.download.ui.LocalIndexesFragment.ILLEGAL_FILE_NAME_CHARACTERS;
public class OnSaveCurrentTrackFragment extends BottomSheetDialogFragment {
public static final String TAG = "OnSaveCurrentTrackBottomSheetFragment";
public static final String SAVED_TRACK_KEY = "saved_track_filename";
public static final String SAVED_TRACKS_KEY = "saved_track_filename";
private boolean showOnMap = true;
private boolean openTrack = false;
private File file;
private String savedGpxName = "";
private String newGpxName = "";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final OsmandApplication app = requiredMyApplication();
Bundle args = getArguments();
String savedGpxName = "";
if (args != null && args.containsKey(SAVED_TRACK_KEY)) {
savedGpxName = args.getString(SAVED_TRACK_KEY, "");
if (args != null && args.containsKey(SAVED_TRACKS_KEY)) {
ArrayList<String> savedGpxNames = args.getStringArrayList(SAVED_TRACKS_KEY);
if (savedGpxNames != null && savedGpxNames.size() > 0) {
savedGpxName = savedGpxNames.get(savedGpxNames.size() - 1);
newGpxName = savedGpxName;
}
} else {
dismiss();
}
final File f = new File (app.getAppCustomization().getTracksDir(), savedGpxName + ".gpx");
final boolean nightMode = !app.getSettings().isLightContent();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
View mainView = View
.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_on_save_current_track, container);
TextView tv = mainView.findViewById(R.id.saved_track_name_string);
Button openTrackBtn = mainView.findViewById(R.id.open_track_button);
Button showOnMapBtn = mainView.findViewById(R.id.show_on_map_button);
Context ctx = requireContext();
file = new File(app.getAppCustomization().getTracksDir(), savedGpxName + ".gpx");
final boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
final int textPrimaryColor = nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light;
View mainView = UiUtilities.getInflater(ctx, nightMode).inflate(R.layout.fragment_on_save_current_track, container);
tv.setText(AndroidUtils.getStyledString(app.getString(R.string.shared_string_track_is_saved), savedGpxName, Typeface.BOLD));
OsmandTextFieldBoxes textBox = (OsmandTextFieldBoxes) mainView.findViewById(R.id.name_text_box);
if (nightMode) {
textBox.setPrimaryColor(ContextCompat.getColor(app, R.color.active_color_primary_dark));
}
final EditText nameEditText = (EditText) mainView.findViewById(R.id.name_edit_text);
nameEditText.setText(savedGpxName);
nameEditText.setTextColor(ContextCompat.getColor(ctx, textPrimaryColor));
textBox.activate(true);
nameEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
newGpxName = s.toString();
}
@Override
public void afterTextChanged(Editable s) {
Editable text = nameEditText.getText();
if (text.length() >= 1) {
if (ILLEGAL_FILE_NAME_CHARACTERS.matcher(text).find()) {
nameEditText.setError(app.getString(R.string.file_name_containes_illegal_char));
}
}
}
});
nameEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
doRename(false);
return true;
}
return false;
}
});
SwitchCompat showOnMapButton = (SwitchCompat) mainView.findViewById(R.id.btn_show_on_map);
showOnMapButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
showOnMap = isChecked;
}
});
View openTrackBtn = mainView.findViewById(R.id.open_track_button);
UiUtilities.setupDialogButton(nightMode, openTrackBtn, DialogButtonType.SECONDARY, R.string.shared_string_open_track);
final View showOnMapBtn = mainView.findViewById(R.id.close_button);
UiUtilities.setupDialogButton(nightMode, showOnMapBtn, DialogButtonType.SECONDARY, R.string.shared_string_close);
openTrackBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
AvailableGPXFragment.openTrack(getActivity(), f);
dismiss();
doRename(true);
}
});
showOnMapBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
GpxInfo gpxInfo = new GpxInfo();
gpxInfo.setGpx(GPXUtilities.loadGPXFile(f));
if (gpxInfo.gpx != null) {
OsmandSettings settings = app.getSettings();
WptPt loc = gpxInfo.gpx.findPointToShow();
if (loc != null) {
settings.setMapLocationToShow(loc.lat, loc.lon, settings.getLastKnownMapZoom());
app.getSelectedGpxHelper().setGpxFileToDisplay(gpxInfo.gpx);
}
}
dismiss();
doRename(false);
}
});
return mainView;
}
public static void showInstance(FragmentManager fragmentManager, String filename) {
private void doRename(boolean openTrack) {
file = renameGpxFile();
if (file != null) {
this.openTrack = openTrack;
dismiss();
}
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (file != null) {
if (showOnMap) {
showOnMap(file, !openTrack);
}
if (openTrack) {
AvailableGPXFragment.openTrack(getActivity(), file);
}
}
}
private File renameGpxFile() {
OsmandApplication app = requiredMyApplication();
File savedFile = new File(app.getAppCustomization().getTracksDir(), savedGpxName + ".gpx");
if (savedGpxName.equalsIgnoreCase(newGpxName)) {
return savedFile;
}
return LocalIndexesFragment.renameGpxFile(app, savedFile, newGpxName + ".gpx", null);
}
private void showOnMap(File f, boolean animated) {
OsmandApplication app = requiredMyApplication();
GpxInfo gpxInfo = new GpxInfo();
gpxInfo.setGpx(GPXUtilities.loadGPXFile(f));
if (gpxInfo.gpx != null) {
WptPt loc = gpxInfo.gpx.findPointToShow();
if (loc != null) {
app.getSelectedGpxHelper().setGpxFileToDisplay(gpxInfo.gpx);
FragmentActivity activity = getActivity();
if (activity instanceof MapActivity) {
MapActivity mapActivity = (MapActivity) activity;
if (animated) {
OsmandMapTileView mapView = mapActivity.getMapView();
mapView.getAnimatedDraggingThread().startMoving(loc.lat, loc.lon, mapView.getZoom(), true);
mapView.refreshMap();
} else {
mapActivity.setMapLocation(loc.lat, loc.lon);
}
}
}
}
}
public static void showInstance(FragmentManager fragmentManager, List<String> filenames) {
OnSaveCurrentTrackFragment f = new OnSaveCurrentTrackFragment();
Bundle b = new Bundle();
b.putString(SAVED_TRACK_KEY, filename);
b.putStringArrayList(SAVED_TRACKS_KEY, new ArrayList<>(filenames));
f.setArguments(b);
f.show(fragmentManager, TAG);
}

View file

@ -380,7 +380,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
if (activityRef != null && !Algorithms.isEmpty(result.getFilenames())) {
final Activity a = activityRef.get();
if (a instanceof FragmentActivity && !a.isFinishing()) {
OnSaveCurrentTrackFragment.showInstance(((FragmentActivity) a).getSupportFragmentManager(), result.getFilenames().get(0));
OnSaveCurrentTrackFragment.showInstance(((FragmentActivity) a).getSupportFragmentManager(), result.getFilenames());
}
}

View file

@ -1459,7 +1459,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
LocalIndexesFragment.renameFile(getActivity(), gpxInfo.file, new RenameCallback() {
@Override
public void renamedTo(File file) {
app.getGpxDbHelper().rename(gpxInfo.file, file);
asyncLoader = new LoadGpxTask();
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
}