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_marginStart="@dimen/measurement_tool_text_button_padding"
|
||||||
android:layout_toEndOf="@id/main_icon"
|
android:layout_toEndOf="@id/main_icon"
|
||||||
android:layout_toRightOf="@id/main_icon"
|
android:layout_toRightOf="@id/main_icon"
|
||||||
android:textAppearance="@style/TextAppearance.ListItemTitle"
|
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
|
||||||
tools:text="724 m,"/>
|
tools:text="724 m,"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -81,8 +81,7 @@
|
||||||
android:layout_marginTop="@dimen/measurement_tool_button_padding"
|
android:layout_marginTop="@dimen/measurement_tool_button_padding"
|
||||||
android:layout_toEndOf="@id/measurement_distance_text_view"
|
android:layout_toEndOf="@id/measurement_distance_text_view"
|
||||||
android:layout_toRightOf="@id/measurement_distance_text_view"
|
android:layout_toRightOf="@id/measurement_distance_text_view"
|
||||||
android:textColor="?android:textColorSecondary"
|
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
|
||||||
android:textSize="@dimen/default_list_text_size"
|
|
||||||
tools:text="points: 3"/>
|
tools:text="points: 3"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -93,7 +92,7 @@
|
||||||
android:layout_alignStart="@+id/measurement_distance_text_view"
|
android:layout_alignStart="@+id/measurement_distance_text_view"
|
||||||
android:layout_alignLeft="@+id/measurement_distance_text_view"
|
android:layout_alignLeft="@+id/measurement_distance_text_view"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="@color/color_distance"
|
android:textColor="?android:textColorSecondary"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
tools:text=" – 700 m" />
|
tools:text=" – 700 m" />
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="@dimen/settings_divider_margin_start"
|
android:minHeight="@dimen/favorites_list_item_height"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
@ -29,9 +29,8 @@
|
||||||
android:layout_marginEnd="@dimen/list_content_padding"
|
android:layout_marginEnd="@dimen/list_content_padding"
|
||||||
android:layout_marginRight="@dimen/list_content_padding"
|
android:layout_marginRight="@dimen/list_content_padding"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:paddingTop="@dimen/content_padding_small"
|
android:orientation="vertical">
|
||||||
android:paddingBottom="@dimen/content_padding_small">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/name"
|
android:id="@+id/name"
|
||||||
|
|
|
@ -268,6 +268,9 @@
|
||||||
<dimen name="bottom_sheet_list_item_height">48dp</dimen>
|
<dimen name="bottom_sheet_list_item_height">48dp</dimen>
|
||||||
<dimen name="bottom_sheet_large_list_item_height">64dp</dimen>
|
<dimen name="bottom_sheet_large_list_item_height">64dp</dimen>
|
||||||
<dimen name="bottom_sheet_icon_margin">24dp</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_top">7dp</dimen>
|
||||||
<dimen name="bottom_sheet_divider_margin_bottom">8dp</dimen>
|
<dimen name="bottom_sheet_divider_margin_bottom">8dp</dimen>
|
||||||
<dimen name="bottom_sheet_divider_margin_start">64dp</dimen>
|
<dimen name="bottom_sheet_divider_margin_start">64dp</dimen>
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
Thx - Hardy
|
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="track_coloring_solid">Solid</string>
|
||||||
<string name="gpx_direction_arrows">Direction arrows</string>
|
<string name="gpx_direction_arrows">Direction arrows</string>
|
||||||
<string name="shared_string_custom">Custom</string>
|
<string name="shared_string_custom">Custom</string>
|
||||||
|
|
|
@ -41,8 +41,8 @@ import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.widget.TintableCompoundButton;
|
import androidx.core.widget.TintableCompoundButton;
|
||||||
|
|
||||||
import com.google.android.material.slider.RangeSlider;
|
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.slider.Slider;
|
||||||
|
import com.google.android.material.snackbar.BaseTransientBottomBar;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.android.material.snackbar.SnackbarContentLayout;
|
import com.google.android.material.snackbar.SnackbarContentLayout;
|
||||||
|
|
||||||
|
@ -60,7 +60,6 @@ import org.apache.commons.logging.Log;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
|
|
||||||
import static net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem;
|
import static net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem;
|
||||||
|
@ -184,7 +183,7 @@ public class UiUtilities {
|
||||||
return tintDrawable(AppCompatResources.getDrawable(context, resId), color);
|
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;
|
Drawable coloredDrawable = null;
|
||||||
if (drawable != null) {
|
if (drawable != null) {
|
||||||
coloredDrawable = DrawableCompat.wrap(drawable);
|
coloredDrawable = DrawableCompat.wrap(drawable);
|
||||||
|
|
|
@ -15,11 +15,13 @@ import net.osmand.AndroidUtils;
|
||||||
import net.osmand.GPXUtilities;
|
import net.osmand.GPXUtilities;
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.plus.GPXDatabase;
|
import net.osmand.plus.GPXDatabase;
|
||||||
|
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||||
import net.osmand.plus.GpxDbHelper;
|
import net.osmand.plus.GpxDbHelper;
|
||||||
import net.osmand.plus.OsmAndFormatter;
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.UiUtilities;
|
import net.osmand.plus.UiUtilities;
|
||||||
|
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -29,20 +31,27 @@ import java.util.List;
|
||||||
|
|
||||||
public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackViewHolder> {
|
public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackViewHolder> {
|
||||||
|
|
||||||
private LayoutInflater themedInflater;
|
|
||||||
private List<GpxUiHelper.GPXInfo> gpxInfoList;
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
|
private LayoutInflater themedInflater;
|
||||||
|
private UiUtilities iconsCache;
|
||||||
|
private List<GPXInfo> gpxInfoList;
|
||||||
private boolean showCurrentGpx;
|
private boolean showCurrentGpx;
|
||||||
private OnItemClickListener onItemClickListener;
|
private OnItemClickListener onItemClickListener;
|
||||||
private UiUtilities iconsCache;
|
|
||||||
|
|
||||||
GpxTrackAdapter(Context ctx, List<GpxUiHelper.GPXInfo> gpxInfoList, boolean showCurrentGpx) {
|
public GpxTrackAdapter(Context ctx, List<GPXInfo> gpxInfoList, boolean showCurrentGpx) {
|
||||||
this.showCurrentGpx = showCurrentGpx;
|
|
||||||
app = (OsmandApplication) ctx.getApplicationContext();
|
app = (OsmandApplication) ctx.getApplicationContext();
|
||||||
boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
|
themedInflater = UiUtilities.getInflater(ctx, app.getDaynightHelper().isNightModeForMapControls());
|
||||||
themedInflater = UiUtilities.getInflater(ctx, nightMode);
|
|
||||||
this.gpxInfoList = gpxInfoList;
|
|
||||||
iconsCache = app.getUIUtilities();
|
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
|
@NonNull
|
||||||
|
@ -67,15 +76,17 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
||||||
holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||||
}
|
}
|
||||||
final int adapterPosition = holder.getAdapterPosition();
|
final int adapterPosition = holder.getAdapterPosition();
|
||||||
GpxUiHelper.GPXInfo info = gpxInfoList.get(adapterPosition);
|
GPXInfo info = gpxInfoList.get(adapterPosition);
|
||||||
GPXDatabase.GpxDataItem dataItem = getDataItem(info);
|
GpxDataItem dataItem = getDataItem(info);
|
||||||
String itemTitle = GpxUiHelper.getGpxTitle(info.getFileName());
|
String itemTitle = GpxUiHelper.getGpxTitle(info.getFileName());
|
||||||
updateGpxInfoView(holder, itemTitle, info, dataItem, currentlyRecordingTrack, app);
|
updateGpxInfoView(holder, itemTitle, info, dataItem, currentlyRecordingTrack, app);
|
||||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
if (onItemClickListener != null) {
|
||||||
onItemClickListener.onItemClick(adapterPosition);
|
onItemClickListener.onItemClick(adapterPosition);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +95,8 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
||||||
return gpxInfoList.size();
|
return gpxInfoList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateGpxInfoView(TrackViewHolder holder, String itemTitle, GpxUiHelper.GPXInfo info,
|
private void updateGpxInfoView(TrackViewHolder holder, String itemTitle, GPXInfo info,
|
||||||
GPXDatabase.GpxDataItem dataItem, boolean currentlyRecordingTrack,
|
GpxDataItem dataItem, boolean currentlyRecordingTrack,
|
||||||
OsmandApplication app) {
|
OsmandApplication app) {
|
||||||
holder.name.setText(itemTitle.replace("/", " • ").trim());
|
holder.name.setText(itemTitle.replace("/", " • ").trim());
|
||||||
GPXUtilities.GPXTrackAnalysis analysis = null;
|
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() {
|
GpxDbHelper.GpxDataItemCallback gpxDataItemCallback = new GpxDbHelper.GpxDataItemCallback() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
|
@ -129,7 +140,7 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGpxDataItemReady(GPXDatabase.GpxDataItem item) {
|
public void onGpxDataItemReady(GpxDataItem item) {
|
||||||
if (item != null && gpxInfoList != null && info != null) {
|
if (item != null && gpxInfoList != null && info != null) {
|
||||||
notifyItemChanged(gpxInfoList.indexOf(info));
|
notifyItemChanged(gpxInfoList.indexOf(info));
|
||||||
}
|
}
|
||||||
|
@ -139,7 +150,7 @@ public class GpxTrackAdapter extends RecyclerView.Adapter<GpxTrackAdapter.TrackV
|
||||||
, gpxDataItemCallback);
|
, gpxDataItemCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAdapterListener(OnItemClickListener onItemClickListener) {
|
public void setAdapterListener(OnItemClickListener onItemClickListener) {
|
||||||
this.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.MapActivity;
|
||||||
import net.osmand.plus.activities.TrackActivity;
|
import net.osmand.plus.activities.TrackActivity;
|
||||||
import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment;
|
import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||||
import net.osmand.plus.settings.backend.SettingsHelper;
|
import net.osmand.plus.settings.backend.SettingsHelper;
|
||||||
import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener;
|
import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener;
|
||||||
|
@ -142,13 +143,17 @@ public class ImportHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean handleGpxImport(final Uri contentUri, final boolean useImportDir) {
|
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);
|
String name = getNameFromContentUri(app, contentUri);
|
||||||
boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(contentUri.getPath()));
|
boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(contentUri.getPath()));
|
||||||
if (!isOsmandSubdir && name != null) {
|
if (!isOsmandSubdir && name != null) {
|
||||||
String nameLC = name.toLowerCase();
|
String nameLC = name.toLowerCase();
|
||||||
if (nameLC.endsWith(GPX_FILE_EXT)) {
|
if (nameLC.endsWith(GPX_FILE_EXT)) {
|
||||||
name = name.substring(0, name.length() - GPX_FILE_EXT.length()) + 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;
|
return true;
|
||||||
} else if (nameLC.endsWith(KML_SUFFIX)) {
|
} else if (nameLC.endsWith(KML_SUFFIX)) {
|
||||||
name = name.substring(0, name.length() - KML_SUFFIX.length()) + KML_SUFFIX;
|
name = name.substring(0, name.length() - KML_SUFFIX.length()) + KML_SUFFIX;
|
||||||
|
@ -229,7 +234,8 @@ public class ImportHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@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>() {
|
new AsyncTask<Void, Void, GPXFile>() {
|
||||||
ProgressDialog progress = null;
|
ProgressDialog progress = null;
|
||||||
|
|
||||||
|
@ -264,7 +270,7 @@ public class ImportHelper {
|
||||||
if (AndroidUtils.isActivityNotDestroyed(activity)) {
|
if (AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||||
progress.dismiss();
|
progress.dismiss();
|
||||||
}
|
}
|
||||||
handleResult(result, fileName, save, useImportDir, false);
|
handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity);
|
||||||
}
|
}
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
@ -941,8 +947,13 @@ public class ImportHelper {
|
||||||
executeImportTask(renderingImportTask);
|
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,
|
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 != null) {
|
||||||
if (result.error != null) {
|
if (result.error != null) {
|
||||||
Toast.makeText(activity, result.error.getMessage(), Toast.LENGTH_LONG).show();
|
Toast.makeText(activity, result.error.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
@ -951,8 +962,9 @@ public class ImportHelper {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (save) {
|
if (save) {
|
||||||
new SaveAsyncTask(result, name, useImportDir).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
new SaveAsyncTask(result, name, useImportDir, showInDetailsActivity)
|
||||||
} else {
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
} else if (showInDetailsActivity) {
|
||||||
showGpxInDetailsActivity(result);
|
showGpxInDetailsActivity(result);
|
||||||
}
|
}
|
||||||
if (gpxImportCompleteListener != null) {
|
if (gpxImportCompleteListener != null) {
|
||||||
|
@ -1057,11 +1069,13 @@ public class ImportHelper {
|
||||||
private final GPXFile result;
|
private final GPXFile result;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final boolean useImportDir;
|
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.result = result;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.useImportDir = useImportDir;
|
this.useImportDir = useImportDir;
|
||||||
|
this.showInDetailsActivity = showInDetailsActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1072,11 +1086,23 @@ public class ImportHelper {
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(final String warning) {
|
protected void onPostExecute(final String warning) {
|
||||||
if (Algorithms.isEmpty(warning)) {
|
if (Algorithms.isEmpty(warning)) {
|
||||||
|
if (showInDetailsActivity) {
|
||||||
showGpxInDetailsActivity(result);
|
showGpxInDetailsActivity(result);
|
||||||
|
} else {
|
||||||
|
showPlanRouteFragment();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(activity, warning, Toast.LENGTH_LONG).show();
|
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() {
|
private MapActivity getMapActivity() {
|
||||||
|
|
|
@ -50,6 +50,7 @@ import net.osmand.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||||
import net.osmand.plus.OsmAndFormatter;
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
import net.osmand.plus.OsmandApplication;
|
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.controls.ReorderItemTouchHelperCallback;
|
||||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory;
|
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory;
|
||||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
|
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.io.File;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
@ -89,6 +92,8 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
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 {
|
public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
|
@ -117,6 +122,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
private boolean wasCollapseButtonVisible;
|
private boolean wasCollapseButtonVisible;
|
||||||
private boolean progressBarVisible;
|
private boolean progressBarVisible;
|
||||||
private boolean pointsListOpened;
|
private boolean pointsListOpened;
|
||||||
|
private boolean planRouteMode = false;
|
||||||
private Boolean saved;
|
private Boolean saved;
|
||||||
private boolean portrait;
|
private boolean portrait;
|
||||||
private boolean nightMode;
|
private boolean nightMode;
|
||||||
|
@ -140,6 +146,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
this.initialPoint = initialPoint;
|
this.initialPoint = initialPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlanRouteMode(boolean planRouteMode) {
|
||||||
|
this.planRouteMode = planRouteMode;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
@ -198,7 +208,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
hidePointsListFragment();
|
hidePointsListFragment();
|
||||||
}
|
}
|
||||||
|
|
||||||
editingCtx.getCommandManager().resetMeasurementLayer(measurementLayer);
|
|
||||||
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
|
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
|
||||||
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
|
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
|
||||||
|
|
||||||
|
@ -318,17 +327,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
editingCtx.getCommandManager().undo();
|
editingCtx.getCommandManager().undo();
|
||||||
if (editingCtx.getCommandManager().canUndo()) {
|
updateUndoRedoButton(editingCtx.getCommandManager().canUndo(), undoBtn);
|
||||||
enable(undoBtn);
|
|
||||||
} else {
|
|
||||||
disable(undoBtn);
|
|
||||||
}
|
|
||||||
hidePointsListIfNoPoints();
|
hidePointsListIfNoPoints();
|
||||||
if (editingCtx.getPointsCount() > 0) {
|
if (editingCtx.getPointsCount() > 0) {
|
||||||
enable(upDownBtn);
|
enable(upDownBtn);
|
||||||
}
|
}
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
enable(redoBtn);
|
updateUndoRedoButton(true, redoBtn);
|
||||||
updateText();
|
updateText();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -339,17 +344,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
editingCtx.getCommandManager().redo();
|
editingCtx.getCommandManager().redo();
|
||||||
if (editingCtx.getCommandManager().canRedo()) {
|
updateUndoRedoButton(editingCtx.getCommandManager().canRedo(), redoBtn);
|
||||||
enable(redoBtn);
|
|
||||||
} else {
|
|
||||||
disable(redoBtn);
|
|
||||||
}
|
|
||||||
hidePointsListIfNoPoints();
|
hidePointsListIfNoPoints();
|
||||||
if (editingCtx.getPointsCount() > 0) {
|
if (editingCtx.getPointsCount() > 0) {
|
||||||
enable(upDownBtn);
|
enable(upDownBtn);
|
||||||
}
|
}
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
enable(undoBtn);
|
updateUndoRedoButton(true, undoBtn);
|
||||||
updateText();
|
updateText();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -385,8 +386,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
String azimuthStr = OsmAndFormatter.getFormattedAzimuth(bearing, getMyApplication());
|
String azimuthStr = OsmAndFormatter.getFormattedAzimuth(bearing, getMyApplication());
|
||||||
distanceToCenterTv.setText(String.format("%1$s • %2$s", distStr, azimuthStr));
|
distanceToCenterTv.setText(String.format("%1$s • %2$s", distStr, azimuthStr));
|
||||||
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
|
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()) {
|
if (!editingCtx.getCommandManager().canUndo()) {
|
||||||
disable(undoBtn);
|
updateUndoRedoButton(false, undoBtn);
|
||||||
}
|
}
|
||||||
if (!editingCtx.getCommandManager().canRedo()) {
|
if (!editingCtx.getCommandManager().canRedo()) {
|
||||||
disable(redoBtn);
|
updateUndoRedoButton(false, redoBtn);
|
||||||
}
|
}
|
||||||
if (editingCtx.getPointsCount() < 1) {
|
if (editingCtx.getPointsCount() < 1) {
|
||||||
disable(upDownBtn);
|
disable(upDownBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
toolBarController = new MeasurementToolBarController(newGpxData);
|
toolBarController = new MeasurementToolBarController();
|
||||||
if (editingCtx.getSelectedPointPosition() != -1) {
|
if (editingCtx.getSelectedPointPosition() != -1) {
|
||||||
int navigationIconResId = AndroidUtils.getNavigationIconResId(mapActivity);
|
int navigationIconResId = AndroidUtils.getNavigationIconResId(mapActivity);
|
||||||
toolBarController.setBackBtnIconIds(navigationIconResId, navigationIconResId);
|
toolBarController.setBackBtnIconIds(navigationIconResId, navigationIconResId);
|
||||||
|
@ -427,7 +428,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
toolBarController.setTitle(getString(R.string.edit_line));
|
toolBarController.setTitle(getString(R.string.edit_line));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toolBarController.setTitle(getString(R.string.measurement_tool_action_bar));
|
toolBarController.setTitle(getString(R.string.plan_route));
|
||||||
}
|
}
|
||||||
toolBarController.setOnBackButtonClickListener(new View.OnClickListener() {
|
toolBarController.setOnBackButtonClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -451,7 +452,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
} else {
|
} else {
|
||||||
if (newGpxData == null) {
|
if (newGpxData == null) {
|
||||||
final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR);
|
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);
|
saveNewGpx(dir, fileName, true, SaveType.ROUTE_POINT, true);
|
||||||
} else {
|
} else {
|
||||||
addToGpx(mapActivity);
|
addToGpx(mapActivity);
|
||||||
|
@ -485,6 +486,17 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
pointsRv.setLayoutManager(new LinearLayoutManager(getContext()));
|
pointsRv.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
pointsRv.setAdapter(adapter);
|
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();
|
enterMeasurementMode();
|
||||||
|
|
||||||
showSnapToRoadControls();
|
showSnapToRoadControls();
|
||||||
|
@ -503,8 +515,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
if (saved == null) {
|
if (saved == null) {
|
||||||
saved = newGpxData != null && (newGpxData.getActionType() == ActionType.ADD_ROUTE_POINTS || newGpxData.getActionType() == ActionType.EDIT_SEGMENT);
|
saved = newGpxData != null && (newGpxData.getActionType() == ActionType.ADD_ROUTE_POINTS || newGpxData.getActionType() == ActionType.EDIT_SEGMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -675,7 +685,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
if (pointsListOpened) {
|
if (pointsListOpened) {
|
||||||
hidePointsList();
|
hidePointsList();
|
||||||
}
|
}
|
||||||
disable(redoBtn, upDownBtn);
|
updateUndoRedoButton(false, redoBtn);
|
||||||
|
disable(upDownBtn);
|
||||||
updateText();
|
updateText();
|
||||||
saved = false;
|
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) {
|
private void removePoint(MeasurementToolLayer layer, int position) {
|
||||||
editingCtx.getCommandManager().execute(new RemovePointCommand(layer, position));
|
editingCtx.getCommandManager().execute(new RemovePointCommand(layer, position));
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
enable(undoBtn);
|
updateUndoRedoButton(true, undoBtn);
|
||||||
disable(redoBtn);
|
updateUndoRedoButton(false, redoBtn);
|
||||||
updateText();
|
updateText();
|
||||||
saved = false;
|
saved = false;
|
||||||
hidePointsListIfNoPoints();
|
hidePointsListIfNoPoints();
|
||||||
|
@ -831,7 +908,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
|
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
|
||||||
editingCtx.getCommandManager().execute(new ReorderPointCommand(measurementLayer, fromPosition, toPosition));
|
editingCtx.getCommandManager().execute(new ReorderPointCommand(measurementLayer, fromPosition, toPosition));
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
disable(redoBtn);
|
updateUndoRedoButton(false, redoBtn);
|
||||||
updateText();
|
updateText();
|
||||||
mapActivity.refreshMap();
|
mapActivity.refreshMap();
|
||||||
saved = false;
|
saved = false;
|
||||||
|
@ -1114,8 +1191,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doAddOrMovePointCommonStuff() {
|
private void doAddOrMovePointCommonStuff() {
|
||||||
enable(undoBtn, upDownBtn);
|
enable(upDownBtn);
|
||||||
disable(redoBtn);
|
updateUndoRedoButton(true, undoBtn);
|
||||||
|
updateUndoRedoButton(false, redoBtn);
|
||||||
updateText();
|
updateText();
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
saved = false;
|
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);
|
UiUtilities.setupSnackbar(snackbar, nightMode);
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
dismiss(mapActivity);
|
dismiss(mapActivity);
|
||||||
|
@ -1502,19 +1582,25 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enable(View... views) {
|
private void updateUndoRedoButton(boolean enable, View view) {
|
||||||
for (View view : views) {
|
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.setEnabled(true);
|
||||||
view.setAlpha(1);
|
view.setAlpha(1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void disable(View... views) {
|
private void disable(View view) {
|
||||||
for (View view : views) {
|
|
||||||
view.setEnabled(false);
|
view.setEnabled(false);
|
||||||
view.setAlpha(.5f);
|
view.setAlpha(.5f);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void updateText() {
|
private void updateText() {
|
||||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||||
|
@ -1534,11 +1620,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR);
|
final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||||
toolBarController.setTitle(getSuggestedName(dir));
|
toolBarController.setTitle(getSuggestedName(dir));
|
||||||
toolBarController.setDescription(getString(R.string.plan_route));
|
toolBarController.setDescription(getString(R.string.plan_route));
|
||||||
toolBarController.setSaveViewVisible(true);
|
|
||||||
} else {
|
} else {
|
||||||
toolBarController.setTitle(getString(R.string.measurement_tool_action_bar));
|
toolBarController.setTitle(getString(R.string.plan_route));
|
||||||
toolBarController.setDescription(null);
|
toolBarController.setDescription(null);
|
||||||
toolBarController.setSaveViewVisible(false);
|
|
||||||
}
|
}
|
||||||
mapActivity.showTopToolbar(toolBarController);
|
mapActivity.showTopToolbar(toolBarController);
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1783,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
} else {
|
} else {
|
||||||
visibleSnapToRoadIcon(false);
|
visibleSnapToRoadIcon(false);
|
||||||
}
|
}
|
||||||
if (editingCtx.getNewGpxData() != null) {
|
if (editingCtx.getNewGpxData() != null && !planRouteMode) {
|
||||||
GPXFile gpx = editingCtx.getNewGpxData().getGpxFile();
|
GPXFile gpx = editingCtx.getNewGpxData().getGpxFile();
|
||||||
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
|
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
|
||||||
newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, gpx.path);
|
newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, gpx.path);
|
||||||
|
@ -1726,7 +1810,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean showInstance(FragmentManager fragmentManager) {
|
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) {
|
private static boolean showFragment(MeasurementToolFragment fragment, FragmentManager fragmentManager) {
|
||||||
|
@ -1743,29 +1829,44 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||||
|
|
||||||
private class MeasurementToolBarController extends TopToolbarController {
|
private class MeasurementToolBarController extends TopToolbarController {
|
||||||
|
|
||||||
MeasurementToolBarController(NewGpxData newGpxData) {
|
MeasurementToolBarController() {
|
||||||
super(MapInfoWidgetsFactory.TopToolbarControllerType.MEASUREMENT_TOOL);
|
super(TopToolbarControllerType.MEASUREMENT_TOOL);
|
||||||
setBackBtnIconClrIds(0, 0);
|
setBackBtnIconClrIds(0, 0);
|
||||||
setTitleTextClrIds(R.color.text_color_tab_active_light, R.color.text_color_tab_active_dark);
|
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);
|
setDescrTextClrIds(R.color.text_color_tab_active_light, R.color.text_color_tab_active_dark);
|
||||||
setBgIds(R.drawable.gradient_toolbar, R.drawable.gradient_toolbar,
|
setBgIds(R.drawable.gradient_toolbar, R.drawable.gradient_toolbar,
|
||||||
R.drawable.gradient_toolbar, R.drawable.gradient_toolbar);
|
R.drawable.gradient_toolbar, R.drawable.gradient_toolbar);
|
||||||
setCloseBtnVisible(false);
|
setCloseBtnVisible(false);
|
||||||
if (newGpxData != null) {
|
|
||||||
setSaveViewVisible(true);
|
setSaveViewVisible(true);
|
||||||
}
|
|
||||||
setSingleLineTitle(false);
|
setSingleLineTitle(false);
|
||||||
|
setSaveViewTextId(R.string.shared_string_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateToolbar(MapInfoWidgetsFactory.TopToolbarView view) {
|
public void updateToolbar(TopToolbarView view) {
|
||||||
super.updateToolbar(view);
|
super.updateToolbar(view);
|
||||||
|
setupDoneButton(view);
|
||||||
View shadow = view.getShadowView();
|
View shadow = view.getShadowView();
|
||||||
if (shadow != null) {
|
if (shadow != null) {
|
||||||
shadow.setVisibility(View.GONE);
|
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
|
@Override
|
||||||
public int getStatusBarColor(Context context, boolean night) {
|
public int getStatusBarColor(Context context, boolean night) {
|
||||||
return NO_COLOR;
|
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