Merge pull request #9514 from osmandapp/plan_route_start
Plan route start
This commit is contained in:
commit
d72d210b3b
13 changed files with 773 additions and 94 deletions
35
OsmAnd/res/layout/bottom_sheet_item_simple_pad_32dp.xml
Normal file
35
OsmAnd/res/layout/bottom_sheet_item_simple_pad_32dp.xml
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/bottom_sheet_list_item_height"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin_large"
|
||||
android:layout_marginRight="@dimen/bottom_sheet_icon_margin_large"
|
||||
tools:src="@drawable/ic_action_info_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:textAppearance="@style/TextAppearance.ListItemTitle"
|
||||
tools:text="Title" />
|
||||
|
||||
</LinearLayout>
|
60
OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml
Normal file
60
OsmAnd/res/layout/bottom_sheet_plan_route_select_file.xml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
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:paddingTop="@dimen/bottom_sheet_title_padding_top"
|
||||
android:paddingBottom="@dimen/bottom_sheet_title_padding_bottom"
|
||||
android:text="@string/plan_route_open_existing_track"
|
||||
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="wrap_content"
|
||||
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:paddingTop="@dimen/bottom_sheet_title_padding_top"
|
||||
android:paddingBottom="@dimen/bottom_sheet_title_padding_bottom"
|
||||
android:text="@string/plan_route_select_track_file_for_open"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/folder_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal"
|
||||
tools:itemCount="3"
|
||||
tools:orientation="horizontal"
|
||||
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/point_editor_icon_category_item" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gpx_track_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:itemCount="1"
|
||||
tools:listitem="@layout/gpx_track_select_item">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
</LinearLayout>
|
40
OsmAnd/res/layout/bottom_sheet_plan_route_start.xml
Normal file
40
OsmAnd/res/layout/bottom_sheet_plan_route_start.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/bottom_sheet_title_padding_top"
|
||||
android:paddingBottom="@dimen/bottom_sheet_title_padding_bottom">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/last_edited"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/plan_route_last_edited"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gpx_track_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
tools:itemCount="1"
|
||||
tools:listitem="@layout/gpx_track_select_item">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
</LinearLayout>
|
|
@ -71,7 +71,7 @@
|
|||
android:layout_marginStart="@dimen/measurement_tool_text_button_padding"
|
||||
android:layout_toEndOf="@id/main_icon"
|
||||
android:layout_toRightOf="@id/main_icon"
|
||||
android:textAppearance="@style/TextAppearance.ListItemTitle"
|
||||
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
|
||||
tools:text="724 m,"/>
|
||||
|
||||
<TextView
|
||||
|
@ -81,8 +81,7 @@
|
|||
android:layout_marginTop="@dimen/measurement_tool_button_padding"
|
||||
android:layout_toEndOf="@id/measurement_distance_text_view"
|
||||
android:layout_toRightOf="@id/measurement_distance_text_view"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
|
||||
tools:text="points: 3"/>
|
||||
|
||||
<TextView
|
||||
|
@ -93,7 +92,7 @@
|
|||
android:layout_alignStart="@+id/measurement_distance_text_view"
|
||||
android:layout_alignLeft="@+id/measurement_distance_text_view"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_distance"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text=" – 700 m" />
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/settings_divider_margin_start"
|
||||
android:minHeight="@dimen/favorites_list_item_height"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
@ -29,9 +29,8 @@
|
|||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingBottom="@dimen/content_padding_small">
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
|
|
|
@ -268,6 +268,9 @@
|
|||
<dimen name="bottom_sheet_list_item_height">48dp</dimen>
|
||||
<dimen name="bottom_sheet_large_list_item_height">64dp</dimen>
|
||||
<dimen name="bottom_sheet_icon_margin">24dp</dimen>
|
||||
<dimen name="bottom_sheet_title_padding_top">10dp</dimen>
|
||||
<dimen name="bottom_sheet_title_padding_bottom">6dp</dimen>
|
||||
<dimen name="bottom_sheet_icon_margin_large">32dp</dimen>
|
||||
<dimen name="bottom_sheet_divider_margin_top">7dp</dimen>
|
||||
<dimen name="bottom_sheet_divider_margin_bottom">8dp</dimen>
|
||||
<dimen name="bottom_sheet_divider_margin_start">64dp</dimen>
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="shared_string_done">Done</string>
|
||||
<string name="plan_route_select_track_file_for_open">Select a track file for open.</string>
|
||||
<string name="plan_route_create_new_route">Create new route</string>
|
||||
<string name="plan_route_open_existing_track">Open existing track</string>
|
||||
<string name="plan_route_import_track">Import track</string>
|
||||
<string name="plan_route_last_edited">Last edited</string>
|
||||
<string name="track_coloring_solid">Solid</string>
|
||||
<string name="gpx_direction_arrows">Direction arrows</string>
|
||||
<string name="shared_string_custom">Custom</string>
|
||||
|
|
|
@ -41,8 +41,8 @@ import androidx.core.view.ViewCompat;
|
|||
import androidx.core.widget.TintableCompoundButton;
|
||||
|
||||
import com.google.android.material.slider.RangeSlider;
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar;
|
||||
import com.google.android.material.slider.Slider;
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.snackbar.SnackbarContentLayout;
|
||||
|
||||
|
@ -60,7 +60,6 @@ import org.apache.commons.logging.Log;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
|
||||
import static net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem;
|
||||
|
@ -184,7 +183,7 @@ public class UiUtilities {
|
|||
return tintDrawable(AppCompatResources.getDrawable(context, resId), color);
|
||||
}
|
||||
|
||||
public static Drawable tintDrawable(Drawable drawable, int color) {
|
||||
public static Drawable tintDrawable(Drawable drawable, @ColorInt int color) {
|
||||
Drawable coloredDrawable = null;
|
||||
if (drawable != null) {
|
||||
coloredDrawable = DrawableCompat.wrap(drawable);
|
||||
|
|
|
@ -15,11 +15,13 @@ import net.osmand.AndroidUtils;
|
|||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.GPXDatabase;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.GpxDbHelper;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -29,20 +31,27 @@ import java.util.List;
|
|||
|
||||
public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackViewHolder> {
|
||||
|
||||
private LayoutInflater themedInflater;
|
||||
private List<GpxUiHelper.GPXInfo> gpxInfoList;
|
||||
private OsmandApplication app;
|
||||
private LayoutInflater themedInflater;
|
||||
private UiUtilities iconsCache;
|
||||
private List<GPXInfo> gpxInfoList;
|
||||
private boolean showCurrentGpx;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
private UiUtilities iconsCache;
|
||||
|
||||
GpxTrackAdapter(Context ctx, List<GpxUiHelper.GPXInfo> gpxInfoList, boolean showCurrentGpx) {
|
||||
this.showCurrentGpx = showCurrentGpx;
|
||||
public GpxTrackAdapter(Context ctx, List<GPXInfo> gpxInfoList, boolean showCurrentGpx) {
|
||||
app = (OsmandApplication) ctx.getApplicationContext();
|
||||
boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
|
||||
themedInflater = UiUtilities.getInflater(ctx, nightMode);
|
||||
this.gpxInfoList = gpxInfoList;
|
||||
themedInflater = UiUtilities.getInflater(ctx, app.getDaynightHelper().isNightModeForMapControls());
|
||||
iconsCache = app.getUIUtilities();
|
||||
this.gpxInfoList = gpxInfoList;
|
||||
this.showCurrentGpx = showCurrentGpx;
|
||||
}
|
||||
|
||||
public void setGpxInfoList(List<GPXInfo> gpxInfoList) {
|
||||
this.gpxInfoList = gpxInfoList;
|
||||
}
|
||||
|
||||
public void setShowCurrentGpx(boolean showCurrentGpx) {
|
||||
this.showCurrentGpx = showCurrentGpx;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -67,15 +76,17 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
|||
holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
}
|
||||
final int adapterPosition = holder.getAdapterPosition();
|
||||
GpxUiHelper.GPXInfo info = gpxInfoList.get(adapterPosition);
|
||||
GPXDatabase.GpxDataItem dataItem = getDataItem(info);
|
||||
GPXInfo info = gpxInfoList.get(adapterPosition);
|
||||
GpxDataItem dataItem = getDataItem(info);
|
||||
String itemTitle = GpxUiHelper.getGpxTitle(info.getFileName());
|
||||
updateGpxInfoView(holder, itemTitle, info, dataItem, currentlyRecordingTrack, app);
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onItemClick(adapterPosition);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -84,8 +95,8 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
|||
return gpxInfoList.size();
|
||||
}
|
||||
|
||||
private void updateGpxInfoView(TrackViewHolder holder, String itemTitle, GpxUiHelper.GPXInfo info,
|
||||
GPXDatabase.GpxDataItem dataItem, boolean currentlyRecordingTrack,
|
||||
private void updateGpxInfoView(TrackViewHolder holder, String itemTitle, GPXInfo info,
|
||||
GpxDataItem dataItem, boolean currentlyRecordingTrack,
|
||||
OsmandApplication app) {
|
||||
holder.name.setText(itemTitle.replace("/", " • ").trim());
|
||||
GPXUtilities.GPXTrackAnalysis analysis = null;
|
||||
|
@ -121,7 +132,7 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
|||
}
|
||||
}
|
||||
|
||||
private GPXDatabase.GpxDataItem getDataItem(final GpxUiHelper.GPXInfo info) {
|
||||
private GpxDataItem getDataItem(final GPXInfo info) {
|
||||
GpxDbHelper.GpxDataItemCallback gpxDataItemCallback = new GpxDbHelper.GpxDataItemCallback() {
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
|
@ -129,7 +140,7 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onGpxDataItemReady(GPXDatabase.GpxDataItem item) {
|
||||
public void onGpxDataItemReady(GpxDataItem item) {
|
||||
if (item != null && gpxInfoList != null && info != null) {
|
||||
notifyItemChanged(gpxInfoList.indexOf(info));
|
||||
}
|
||||
|
@ -139,7 +150,7 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
|||
, gpxDataItemCallback);
|
||||
}
|
||||
|
||||
void setAdapterListener(OnItemClickListener onItemClickListener) {
|
||||
public void setAdapterListener(OnItemClickListener onItemClickListener) {
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import net.osmand.plus.activities.ActivityResultListener;
|
|||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.TrackActivity;
|
||||
import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||
import net.osmand.plus.settings.backend.SettingsHelper;
|
||||
import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener;
|
||||
|
@ -142,13 +143,17 @@ public class ImportHelper {
|
|||
}
|
||||
|
||||
public boolean handleGpxImport(final Uri contentUri, final boolean useImportDir) {
|
||||
return handleGpxImport(contentUri, useImportDir, true);
|
||||
}
|
||||
|
||||
public boolean handleGpxImport(final Uri contentUri, final boolean useImportDir, boolean showInDetailsActivity) {
|
||||
String name = getNameFromContentUri(app, contentUri);
|
||||
boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(contentUri.getPath()));
|
||||
if (!isOsmandSubdir && name != null) {
|
||||
String nameLC = name.toLowerCase();
|
||||
if (nameLC.endsWith(GPX_FILE_EXT)) {
|
||||
name = name.substring(0, name.length() - GPX_FILE_EXT.length()) + GPX_FILE_EXT;
|
||||
handleGpxImport(contentUri, name, true, useImportDir);
|
||||
handleGpxImport(contentUri, name, true, useImportDir, showInDetailsActivity);
|
||||
return true;
|
||||
} else if (nameLC.endsWith(KML_SUFFIX)) {
|
||||
name = name.substring(0, name.length() - KML_SUFFIX.length()) + KML_SUFFIX;
|
||||
|
@ -229,7 +234,8 @@ public class ImportHelper {
|
|||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void handleGpxImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir) {
|
||||
private void handleGpxImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir,
|
||||
final boolean showInDetailsActivity) {
|
||||
new AsyncTask<Void, Void, GPXFile>() {
|
||||
ProgressDialog progress = null;
|
||||
|
||||
|
@ -264,7 +270,7 @@ public class ImportHelper {
|
|||
if (AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
progress.dismiss();
|
||||
}
|
||||
handleResult(result, fileName, save, useImportDir, false);
|
||||
handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
@ -941,8 +947,13 @@ public class ImportHelper {
|
|||
executeImportTask(renderingImportTask);
|
||||
}
|
||||
|
||||
private void handleResult(GPXFile result, String name, boolean save,
|
||||
boolean useImportDir, boolean forceImportFavourites) {
|
||||
handleResult(result, name, save, useImportDir, forceImportFavourites, true);
|
||||
}
|
||||
|
||||
private void handleResult(final GPXFile result, final String name, final boolean save,
|
||||
final boolean useImportDir, boolean forceImportFavourites) {
|
||||
final boolean useImportDir, boolean forceImportFavourites, boolean showInDetailsActivity) {
|
||||
if (result != null) {
|
||||
if (result.error != null) {
|
||||
Toast.makeText(activity, result.error.getMessage(), Toast.LENGTH_LONG).show();
|
||||
|
@ -951,8 +962,9 @@ public class ImportHelper {
|
|||
}
|
||||
} else {
|
||||
if (save) {
|
||||
new SaveAsyncTask(result, name, useImportDir).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
new SaveAsyncTask(result, name, useImportDir, showInDetailsActivity)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else if (showInDetailsActivity) {
|
||||
showGpxInDetailsActivity(result);
|
||||
}
|
||||
if (gpxImportCompleteListener != null) {
|
||||
|
@ -1057,11 +1069,13 @@ public class ImportHelper {
|
|||
private final GPXFile result;
|
||||
private final String name;
|
||||
private final boolean useImportDir;
|
||||
private boolean showInDetailsActivity;
|
||||
|
||||
private SaveAsyncTask(GPXFile result, final String name, boolean useImportDir) {
|
||||
private SaveAsyncTask(GPXFile result, final String name, boolean useImportDir, boolean showInDetailsActivity) {
|
||||
this.result = result;
|
||||
this.name = name;
|
||||
this.useImportDir = useImportDir;
|
||||
this.showInDetailsActivity = showInDetailsActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1071,12 +1085,24 @@ public class ImportHelper {
|
|||
|
||||
@Override
|
||||
protected void onPostExecute(final String warning) {
|
||||
if(Algorithms.isEmpty(warning)) {
|
||||
if (Algorithms.isEmpty(warning)) {
|
||||
if (showInDetailsActivity) {
|
||||
showGpxInDetailsActivity(result);
|
||||
} else {
|
||||
showPlanRouteFragment();
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(activity, warning, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void showPlanRouteFragment() {
|
||||
MeasurementToolFragment fragment = (MeasurementToolFragment) activity.getSupportFragmentManager()
|
||||
.findFragmentByTag(MeasurementToolFragment.TAG);
|
||||
if (fragment != null && !fragment.isDetached() && !fragment.isRemoving()) {
|
||||
fragment.addNewGpxData(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MapActivity getMapActivity() {
|
||||
|
|
|
@ -50,6 +50,7 @@ import net.osmand.GPXUtilities.TrkSegment;
|
|||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
@ -79,6 +80,8 @@ import net.osmand.plus.views.MapControlsLayer;
|
|||
import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
|
||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory;
|
||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
|
||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
|
||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
|
@ -89,6 +92,8 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
||||
import static net.osmand.plus.measurementtool.SelectFileBottomSheet.SelectFileListener;
|
||||
import static net.osmand.plus.measurementtool.StartPlanRouteBottomSheet.StartPlanRouteListener;
|
||||
|
||||
|
||||
public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||
|
@ -117,6 +122,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
private boolean wasCollapseButtonVisible;
|
||||
private boolean progressBarVisible;
|
||||
private boolean pointsListOpened;
|
||||
private boolean planRouteMode = false;
|
||||
private Boolean saved;
|
||||
private boolean portrait;
|
||||
private boolean nightMode;
|
||||
|
@ -140,6 +146,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
this.initialPoint = initialPoint;
|
||||
}
|
||||
|
||||
public void setPlanRouteMode(boolean planRouteMode) {
|
||||
this.planRouteMode = planRouteMode;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -198,7 +208,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
hidePointsListFragment();
|
||||
}
|
||||
|
||||
editingCtx.getCommandManager().resetMeasurementLayer(measurementLayer);
|
||||
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
|
||||
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
|
||||
|
||||
|
@ -318,17 +327,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
editingCtx.getCommandManager().undo();
|
||||
if (editingCtx.getCommandManager().canUndo()) {
|
||||
enable(undoBtn);
|
||||
} else {
|
||||
disable(undoBtn);
|
||||
}
|
||||
updateUndoRedoButton(editingCtx.getCommandManager().canUndo(), undoBtn);
|
||||
hidePointsListIfNoPoints();
|
||||
if (editingCtx.getPointsCount() > 0) {
|
||||
enable(upDownBtn);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
enable(redoBtn);
|
||||
updateUndoRedoButton(true, redoBtn);
|
||||
updateText();
|
||||
}
|
||||
});
|
||||
|
@ -339,17 +344,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
editingCtx.getCommandManager().redo();
|
||||
if (editingCtx.getCommandManager().canRedo()) {
|
||||
enable(redoBtn);
|
||||
} else {
|
||||
disable(redoBtn);
|
||||
}
|
||||
updateUndoRedoButton(editingCtx.getCommandManager().canRedo(), redoBtn);
|
||||
hidePointsListIfNoPoints();
|
||||
if (editingCtx.getPointsCount() > 0) {
|
||||
enable(upDownBtn);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
enable(undoBtn);
|
||||
updateUndoRedoButton(true, undoBtn);
|
||||
updateText();
|
||||
}
|
||||
});
|
||||
|
@ -385,8 +386,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
String azimuthStr = OsmAndFormatter.getFormattedAzimuth(bearing, getMyApplication());
|
||||
distanceToCenterTv.setText(String.format("%1$s • %2$s", distStr, azimuthStr));
|
||||
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
|
||||
distanceToCenterTv, 12, 18, 2, TypedValue.COMPLEX_UNIT_SP
|
||||
);
|
||||
distanceToCenterTv, 14, 18, 2,
|
||||
TypedValue.COMPLEX_UNIT_SP);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -401,16 +402,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
});
|
||||
|
||||
if (!editingCtx.getCommandManager().canUndo()) {
|
||||
disable(undoBtn);
|
||||
updateUndoRedoButton(false, undoBtn);
|
||||
}
|
||||
if (!editingCtx.getCommandManager().canRedo()) {
|
||||
disable(redoBtn);
|
||||
updateUndoRedoButton(false, redoBtn);
|
||||
}
|
||||
if (editingCtx.getPointsCount() < 1) {
|
||||
disable(upDownBtn);
|
||||
}
|
||||
|
||||
toolBarController = new MeasurementToolBarController(newGpxData);
|
||||
toolBarController = new MeasurementToolBarController();
|
||||
if (editingCtx.getSelectedPointPosition() != -1) {
|
||||
int navigationIconResId = AndroidUtils.getNavigationIconResId(mapActivity);
|
||||
toolBarController.setBackBtnIconIds(navigationIconResId, navigationIconResId);
|
||||
|
@ -427,7 +428,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
toolBarController.setTitle(getString(R.string.edit_line));
|
||||
}
|
||||
} else {
|
||||
toolBarController.setTitle(getString(R.string.measurement_tool_action_bar));
|
||||
toolBarController.setTitle(getString(R.string.plan_route));
|
||||
}
|
||||
toolBarController.setOnBackButtonClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -451,7 +452,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
} else {
|
||||
if (newGpxData == null) {
|
||||
final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
String fileName = getSuggestedName(dir);
|
||||
String fileName = getSuggestedName(dir) + GPX_FILE_EXT;
|
||||
saveNewGpx(dir, fileName, true, SaveType.ROUTE_POINT, true);
|
||||
} else {
|
||||
addToGpx(mapActivity);
|
||||
|
@ -485,6 +486,17 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
pointsRv.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
pointsRv.setAdapter(adapter);
|
||||
|
||||
initMeasurementMode(newGpxData);
|
||||
|
||||
if (planRouteMode) {
|
||||
StartPlanRouteBottomSheet.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
createStartPlanRouteListener());
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initMeasurementMode(NewGpxData newGpxData) {
|
||||
editingCtx.getCommandManager().resetMeasurementLayer(getMapActivity().getMapLayers().getMeasurementToolLayer());
|
||||
enterMeasurementMode();
|
||||
|
||||
showSnapToRoadControls();
|
||||
|
@ -503,8 +515,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
if (saved == null) {
|
||||
saved = newGpxData != null && (newGpxData.getActionType() == ActionType.ADD_ROUTE_POINTS || newGpxData.getActionType() == ActionType.EDIT_SEGMENT);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -675,7 +685,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
if (pointsListOpened) {
|
||||
hidePointsList();
|
||||
}
|
||||
disable(redoBtn, upDownBtn);
|
||||
updateUndoRedoButton(false, redoBtn);
|
||||
disable(upDownBtn);
|
||||
updateText();
|
||||
saved = false;
|
||||
}
|
||||
|
@ -765,11 +776,77 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
};
|
||||
}
|
||||
|
||||
private StartPlanRouteListener createStartPlanRouteListener() {
|
||||
return new StartPlanRouteListener() {
|
||||
@Override
|
||||
public void openExistingTrackOnClick() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
SelectFileBottomSheet.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
createSelectFileListener());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openLastEditTrackOnClick(GPXFile gpxFile) {
|
||||
addNewGpxData(gpxFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissButtonOnClick() {
|
||||
quit(true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private SelectFileListener createSelectFileListener() {
|
||||
return new SelectFileListener() {
|
||||
@Override
|
||||
public void selectFileOnCLick(GPXFile gpxFile) {
|
||||
addNewGpxData(gpxFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissButtonOnClick() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
StartPlanRouteBottomSheet.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
createStartPlanRouteListener());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void addNewGpxData(GPXFile gpxFile) {
|
||||
QuadRect rect = gpxFile.getRect();
|
||||
TrkSegment segment = getTrkSegment(gpxFile);
|
||||
NewGpxData newGpxData = new NewGpxData(gpxFile, rect, ActionType.EDIT_SEGMENT, segment);
|
||||
editingCtx.setNewGpxData(newGpxData);
|
||||
initMeasurementMode(newGpxData);
|
||||
QuadRect qr = newGpxData.getRect();
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapView().fitRectToMap(qr.left, qr.right, qr.top, qr.bottom,
|
||||
(int) qr.width(), (int) qr.height(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
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 layer, int position) {
|
||||
editingCtx.getCommandManager().execute(new RemovePointCommand(layer, position));
|
||||
adapter.notifyDataSetChanged();
|
||||
enable(undoBtn);
|
||||
disable(redoBtn);
|
||||
updateUndoRedoButton(true, undoBtn);
|
||||
updateUndoRedoButton(false, redoBtn);
|
||||
updateText();
|
||||
saved = false;
|
||||
hidePointsListIfNoPoints();
|
||||
|
@ -831,7 +908,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
|
||||
editingCtx.getCommandManager().execute(new ReorderPointCommand(measurementLayer, fromPosition, toPosition));
|
||||
adapter.notifyDataSetChanged();
|
||||
disable(redoBtn);
|
||||
updateUndoRedoButton(false, redoBtn);
|
||||
updateText();
|
||||
mapActivity.refreshMap();
|
||||
saved = false;
|
||||
|
@ -1114,8 +1191,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
|
||||
private void doAddOrMovePointCommonStuff() {
|
||||
enable(undoBtn, upDownBtn);
|
||||
disable(redoBtn);
|
||||
enable(upDownBtn);
|
||||
updateUndoRedoButton(true, undoBtn);
|
||||
updateUndoRedoButton(false, redoBtn);
|
||||
updateText();
|
||||
adapter.notifyDataSetChanged();
|
||||
saved = false;
|
||||
|
@ -1486,6 +1564,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
}
|
||||
});
|
||||
snackbar.getView().<TextView>findViewById(com.google.android.material.R.id.snackbar_action)
|
||||
.setAllCaps(false);
|
||||
UiUtilities.setupSnackbar(snackbar, nightMode);
|
||||
snackbar.show();
|
||||
dismiss(mapActivity);
|
||||
|
@ -1502,19 +1582,25 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void enable(View... views) {
|
||||
for (View view : views) {
|
||||
private void updateUndoRedoButton(boolean enable, View view) {
|
||||
view.setEnabled(enable);
|
||||
int color = enable
|
||||
? nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light
|
||||
: nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light;
|
||||
ImageView imageView = ((ImageView) view);
|
||||
imageView.setImageDrawable(UiUtilities.tintDrawable(imageView.getDrawable(),
|
||||
ContextCompat.getColor(view.getContext(), color)));
|
||||
}
|
||||
|
||||
private void enable(View view) {
|
||||
view.setEnabled(true);
|
||||
view.setAlpha(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void disable(View... views) {
|
||||
for (View view : views) {
|
||||
private void disable(View view) {
|
||||
view.setEnabled(false);
|
||||
view.setAlpha(.5f);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateText() {
|
||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
|
@ -1534,11 +1620,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
toolBarController.setTitle(getSuggestedName(dir));
|
||||
toolBarController.setDescription(getString(R.string.plan_route));
|
||||
toolBarController.setSaveViewVisible(true);
|
||||
} else {
|
||||
toolBarController.setTitle(getString(R.string.measurement_tool_action_bar));
|
||||
toolBarController.setTitle(getString(R.string.plan_route));
|
||||
toolBarController.setDescription(null);
|
||||
toolBarController.setSaveViewVisible(false);
|
||||
}
|
||||
mapActivity.showTopToolbar(toolBarController);
|
||||
}
|
||||
|
@ -1699,7 +1783,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
} else {
|
||||
visibleSnapToRoadIcon(false);
|
||||
}
|
||||
if (editingCtx.getNewGpxData() != null) {
|
||||
if (editingCtx.getNewGpxData() != null && !planRouteMode) {
|
||||
GPXFile gpx = editingCtx.getNewGpxData().getGpxFile();
|
||||
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
|
||||
newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, gpx.path);
|
||||
|
@ -1726,7 +1810,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
|
||||
public static boolean showInstance(FragmentManager fragmentManager) {
|
||||
return showFragment(new MeasurementToolFragment(), fragmentManager);
|
||||
MeasurementToolFragment fragment = new MeasurementToolFragment();
|
||||
fragment.setPlanRouteMode(true);
|
||||
return showFragment(fragment, fragmentManager);
|
||||
}
|
||||
|
||||
private static boolean showFragment(MeasurementToolFragment fragment, FragmentManager fragmentManager) {
|
||||
|
@ -1743,29 +1829,44 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
|
||||
private class MeasurementToolBarController extends TopToolbarController {
|
||||
|
||||
MeasurementToolBarController(NewGpxData newGpxData) {
|
||||
super(MapInfoWidgetsFactory.TopToolbarControllerType.MEASUREMENT_TOOL);
|
||||
MeasurementToolBarController() {
|
||||
super(TopToolbarControllerType.MEASUREMENT_TOOL);
|
||||
setBackBtnIconClrIds(0, 0);
|
||||
setTitleTextClrIds(R.color.text_color_tab_active_light, R.color.text_color_tab_active_dark);
|
||||
setDescrTextClrIds(R.color.text_color_tab_active_light, R.color.text_color_tab_active_dark);
|
||||
setBgIds(R.drawable.gradient_toolbar, R.drawable.gradient_toolbar,
|
||||
R.drawable.gradient_toolbar, R.drawable.gradient_toolbar);
|
||||
setCloseBtnVisible(false);
|
||||
if (newGpxData != null) {
|
||||
setSaveViewVisible(true);
|
||||
}
|
||||
setSingleLineTitle(false);
|
||||
setSaveViewTextId(R.string.shared_string_done);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateToolbar(MapInfoWidgetsFactory.TopToolbarView view) {
|
||||
public void updateToolbar(TopToolbarView view) {
|
||||
super.updateToolbar(view);
|
||||
setupDoneButton(view);
|
||||
View shadow = view.getShadowView();
|
||||
if (shadow != null) {
|
||||
shadow.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupDoneButton(TopToolbarView view) {
|
||||
TextView done = view.getSaveView();
|
||||
Context ctx = done.getContext();
|
||||
done.setAllCaps(false);
|
||||
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) done.getLayoutParams();
|
||||
layoutParams.height = ctx.getResources().getDimensionPixelSize(R.dimen.measurement_tool_button_height);
|
||||
layoutParams.leftMargin = ctx.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_large);
|
||||
layoutParams.rightMargin = ctx.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_large);
|
||||
int paddingH = ctx.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_large);
|
||||
int paddingV = ctx.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_small);
|
||||
done.setPadding(paddingH, paddingV, paddingH, paddingV);
|
||||
AndroidUtils.setBackground(ctx, done, nightMode, R.drawable.dlg_btn_stroked_light,
|
||||
R.drawable.dlg_btn_stroked_dark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusBarColor(Context context, boolean night) {
|
||||
return NO_COLOR;
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
package net.osmand.plus.measurementtool;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.helpers.GpxTrackAdapter;
|
||||
import net.osmand.plus.helpers.GpxTrackAdapter.OnItemClickListener;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
|
||||
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
|
||||
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo;
|
||||
|
||||
public class SelectFileBottomSheet extends MenuBottomSheetDialogFragment {
|
||||
|
||||
public static final String TAG = SelectFileBottomSheet.class.getSimpleName();
|
||||
public static final int BOTTOM_SHEET_HEIGHT_DP = 427;
|
||||
|
||||
protected View mainView;
|
||||
protected GpxTrackAdapter adapter;
|
||||
private SelectFileListener listener;
|
||||
private Map<String, List<GPXInfo>> gpxInfoMap;
|
||||
|
||||
public void setListener(SelectFileListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
||||
Context context = requireContext();
|
||||
OsmandApplication app = requiredMyApplication();
|
||||
mainView = View.inflate(new ContextThemeWrapper(context, themeRes),
|
||||
R.layout.bottom_sheet_plan_route_select_file, null);
|
||||
final RecyclerView filesRecyclerView = mainView.findViewById(R.id.gpx_track_list);
|
||||
filesRecyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
|
||||
List<File> dirs = new ArrayList<>();
|
||||
final File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
collectDirs(gpxDir, dirs);
|
||||
List<String> dirItems = new ArrayList<>();
|
||||
for (File dir : dirs) {
|
||||
dirItems.add(dir.getName());
|
||||
}
|
||||
String allFilesFolder = context.getString(R.string.shared_string_all);
|
||||
dirItems.add(0, allFilesFolder);
|
||||
|
||||
final List<GPXInfo> allGpxList = getSortedGPXFilesInfo(gpxDir, null, false);
|
||||
gpxInfoMap = new HashMap<>();
|
||||
gpxInfoMap.put(allFilesFolder, allGpxList);
|
||||
for (GPXInfo gpxInfo : allGpxList) {
|
||||
String folderName = getFolderName(gpxInfo);
|
||||
List<GPXInfo> gpxList = gpxInfoMap.get(folderName);
|
||||
if (gpxList == null) {
|
||||
gpxList = new ArrayList<>();
|
||||
gpxInfoMap.put(folderName, gpxList);
|
||||
}
|
||||
gpxList.add(gpxInfo);
|
||||
}
|
||||
adapter = new GpxTrackAdapter(requireContext(), allGpxList, false);
|
||||
adapter.setAdapterListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(int position) {
|
||||
if (position != RecyclerView.NO_POSITION && position < allGpxList.size()) {
|
||||
String fileName = allGpxList.get(position).getFileName();
|
||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(new File(gpxDir, fileName));
|
||||
if (listener != null) {
|
||||
listener.selectFileOnCLick(gpxFile);
|
||||
}
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
filesRecyclerView.setAdapter(adapter);
|
||||
|
||||
final RecyclerView foldersRecyclerView = mainView.findViewById(R.id.folder_list);
|
||||
foldersRecyclerView.setLayoutManager(new LinearLayoutManager(context,
|
||||
RecyclerView.HORIZONTAL, false));
|
||||
final HorizontalSelectionAdapter folderAdapter = new HorizontalSelectionAdapter(app, nightMode);
|
||||
folderAdapter.setItems(dirItems);
|
||||
folderAdapter.setSelectedItem(allFilesFolder);
|
||||
foldersRecyclerView.setAdapter(folderAdapter);
|
||||
folderAdapter.setListener(new HorizontalSelectionAdapterListener() {
|
||||
@Override
|
||||
public void onItemSelected(String item) {
|
||||
List<GPXInfo> gpxInfoList = gpxInfoMap.get(item);
|
||||
adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList<GPXInfo>());
|
||||
adapter.notifyDataSetChanged();
|
||||
folderAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
items.add(new BaseBottomSheetItem.Builder().setCustomView(mainView).create());
|
||||
}
|
||||
|
||||
private String getFolderName(GPXInfo gpxInfo) {
|
||||
int fileNameStartIndex = gpxInfo.getFileName().lastIndexOf(File.separator);
|
||||
return fileNameStartIndex != -1
|
||||
? gpxInfo.getFileName().substring(0, fileNameStartIndex)
|
||||
: IndexConstants.GPX_INDEX_DIR.substring(0, IndexConstants.GPX_INDEX_DIR.length() - 1);
|
||||
}
|
||||
|
||||
private void collectDirs(File dir, List<File> dirs) {
|
||||
File[] listFiles = dir.listFiles();
|
||||
if (listFiles != null) {
|
||||
Arrays.sort(listFiles);
|
||||
for (File f : listFiles) {
|
||||
if (f.isDirectory()) {
|
||||
dirs.add(f);
|
||||
collectDirs(f, dirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getCustomHeight() {
|
||||
return AndroidUtils.dpToPx(mainView.getContext(), BOTTOM_SHEET_HEIGHT_DP);
|
||||
}
|
||||
|
||||
public static void showInstance(FragmentManager fragmentManager, SelectFileListener listener) {
|
||||
if (!fragmentManager.isStateSaved()) {
|
||||
SelectFileBottomSheet fragment = new SelectFileBottomSheet();
|
||||
fragment.setUsedOnMap(true);
|
||||
fragment.setRetainInstance(true);
|
||||
fragment.setListener(listener);
|
||||
fragment.show(fragmentManager, SelectFileBottomSheet.TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDismissButtonClickAction() {
|
||||
if (listener != null) {
|
||||
listener.dismissButtonOnClick();
|
||||
}
|
||||
}
|
||||
|
||||
interface SelectFileListener {
|
||||
|
||||
void selectFileOnCLick(GPXFile gpxFile);
|
||||
|
||||
void dismissButtonOnClick();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
package net.osmand.plus.measurementtool;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.helpers.GpxTrackAdapter;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
|
||||
import net.osmand.plus.helpers.ImportHelper;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.plus.helpers.GpxUiHelper.getSortedGPXFilesInfo;
|
||||
|
||||
public class StartPlanRouteBottomSheet extends MenuBottomSheetDialogFragment {
|
||||
|
||||
public static final String TAG = StartPlanRouteBottomSheet.class.getSimpleName();
|
||||
private static final Log LOG = PlatformUtil.getLog(StartPlanRouteBottomSheet.class);
|
||||
public static final int BOTTOM_SHEET_HEIGHT_DP = 427;
|
||||
private static final int OPEN_GPX_DOCUMENT_REQUEST = 1001;
|
||||
|
||||
protected View mainView;
|
||||
protected GpxTrackAdapter adapter;
|
||||
private StartPlanRouteListener listener;
|
||||
private ImportHelper importHelper;
|
||||
|
||||
public void setListener(StartPlanRouteListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
importHelper = new ImportHelper((AppCompatActivity) getActivity(), getMyApplication(), null);
|
||||
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
||||
mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes),
|
||||
R.layout.bottom_sheet_plan_route_start, null);
|
||||
|
||||
items.add(new TitleItem(getString(R.string.plan_route)));
|
||||
|
||||
BaseBottomSheetItem createNewRouteItem = new BottomSheetItemWithDescription.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_notification_track))
|
||||
.setTitle(getString(R.string.plan_route_create_new_route))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(createNewRouteItem);
|
||||
|
||||
BaseBottomSheetItem openExistingTrackItem = new BottomSheetItemWithDescription.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_folder))
|
||||
.setTitle(getString(R.string.plan_route_open_existing_track))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (listener != null) {
|
||||
listener.openExistingTrackOnClick();
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(openExistingTrackItem);
|
||||
|
||||
BaseBottomSheetItem importTrackItem = new BottomSheetItemWithDescription.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_phone))
|
||||
.setTitle(getString(R.string.plan_route_import_track))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
importTrack();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(importTrackItem);
|
||||
|
||||
items.add(new DividerHalfItem(getContext()));
|
||||
|
||||
final RecyclerView recyclerView = mainView.findViewById(R.id.gpx_track_list);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
OsmandApplication app = getMyApplication();
|
||||
if (app == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
List<GPXInfo> gpxList = getSortedGPXFilesInfo(gpxDir, null, false);
|
||||
Collections.sort(gpxList, new Comparator<GPXInfo>() {
|
||||
@Override
|
||||
public int compare(GPXInfo lhs, GPXInfo rhs) {
|
||||
return lhs.getLastModified() > rhs.getLastModified()
|
||||
? -1 : (lhs.getLastModified() == rhs.getLastModified() ? 0 : 1);
|
||||
}
|
||||
});
|
||||
final List<GPXInfo> gpxTopList = gpxList.subList(0, Math.min(5, gpxList.size()));
|
||||
adapter = new GpxTrackAdapter(requireContext(), gpxList, false);
|
||||
adapter.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(int position) {
|
||||
StartPlanRouteBottomSheet.this.onItemClick(position, gpxTopList);
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
items.add(new BaseBottomSheetItem.Builder().setCustomView(mainView).create());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getCustomHeight() {
|
||||
return AndroidUtils.dpToPx(mainView.getContext(), BOTTOM_SHEET_HEIGHT_DP);
|
||||
}
|
||||
|
||||
private void onItemClick(int position, List<GPXInfo> gpxInfoList) {
|
||||
if (position != RecyclerView.NO_POSITION && position < gpxInfoList.size()) {
|
||||
OsmandApplication app = requiredMyApplication();
|
||||
String fileName = gpxInfoList.get(position).getFileName();
|
||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), fileName));
|
||||
if (listener != null) {
|
||||
listener.openLastEditTrackOnClick(gpxFile);
|
||||
}
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void importTrack() {
|
||||
Intent intent = new Intent();
|
||||
String action;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
action = Intent.ACTION_OPEN_DOCUMENT;
|
||||
} else {
|
||||
action = Intent.ACTION_GET_CONTENT;
|
||||
}
|
||||
intent.setAction(action);
|
||||
intent.setType("*/*");
|
||||
try {
|
||||
startActivityForResult(intent, OPEN_GPX_DOCUMENT_REQUEST);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == OPEN_GPX_DOCUMENT_REQUEST && resultCode == Activity.RESULT_OK) {
|
||||
if (data != null) {
|
||||
Uri uri = data.getData();
|
||||
importHelper.setGpxImportCompleteListener(new ImportHelper.OnGpxImportCompleteListener() {
|
||||
@Override
|
||||
public void onComplete(boolean success) {
|
||||
finishImport(success);
|
||||
importHelper.setGpxImportCompleteListener(null);
|
||||
}
|
||||
});
|
||||
importHelper.handleGpxImport(uri, false, false);
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
void finishImport(boolean success) {
|
||||
if (success) {
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
public static void showInstance(FragmentManager fragmentManager, StartPlanRouteListener listener) {
|
||||
if (!fragmentManager.isStateSaved()) {
|
||||
StartPlanRouteBottomSheet fragment = new StartPlanRouteBottomSheet();
|
||||
fragment.setUsedOnMap(true);
|
||||
fragment.setRetainInstance(true);
|
||||
fragment.setListener(listener);
|
||||
fragment.show(fragmentManager, StartPlanRouteBottomSheet.TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDismissButtonClickAction() {
|
||||
if (listener != null) {
|
||||
listener.dismissButtonOnClick();
|
||||
}
|
||||
}
|
||||
|
||||
interface StartPlanRouteListener {
|
||||
|
||||
void openExistingTrackOnClick();
|
||||
|
||||
void openLastEditTrackOnClick(GPXFile gpxFile);
|
||||
|
||||
void dismissButtonOnClick();
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue