Merge pull request #10655 from osmandapp/points_menu_gpx
Points GPX context menu
This commit is contained in:
commit
d224fdecaa
19 changed files with 1299 additions and 122 deletions
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/search_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:focusableInTouchMode="true"
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
android:paddingStart="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingEnd="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingBottom="@dimen/context_menu_direction_margin">
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingBottom="@dimen/context_menu_direction_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
@ -73,7 +73,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
tools:text="@string/amenity_type_finance" />
|
||||
tools:text="@string/amenity_type_finance" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -81,7 +81,7 @@
|
|||
android:id="@+id/icon_view"
|
||||
android:layout_width="@dimen/map_widget_icon"
|
||||
android:layout_height="@dimen/map_widget_icon"
|
||||
android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
|
||||
android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
|
||||
android:tint="?attr/default_icon_color"
|
||||
osmand:srcCompat="@drawable/ic_action_polygom_dark" />
|
||||
|
||||
|
@ -118,6 +118,79 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/context_menu_toolbar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/actionModeBackground"
|
||||
android:minHeight="@dimen/toolbar_height"
|
||||
android:padding="0dp"
|
||||
osmand:contentInsetEnd="0dp"
|
||||
osmand:contentInsetLeft="0dp"
|
||||
osmand:contentInsetRight="0dp"
|
||||
osmand:contentInsetStart="0dp"
|
||||
osmand:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/toolbar_height">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/close_button"
|
||||
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
|
||||
android:layout_width="@dimen/toolbar_height"
|
||||
android:layout_height="@dimen/toolbar_height"
|
||||
android:contentDescription="@string/access_shared_string_navigate_up"
|
||||
osmand:srcCompat="@drawable/ic_arrow_back" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/toolbar_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="2"
|
||||
android:textColor="?attr/app_bar_primary_item_color"
|
||||
android:textSize="@dimen/dialog_header_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="@string/routing_settings_2" />
|
||||
|
||||
<include
|
||||
layout="@layout/search_text_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/search_button"
|
||||
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
|
||||
android:layout_width="@dimen/toolbar_height"
|
||||
android:layout_height="@dimen/toolbar_height"
|
||||
android:contentDescription="@string/access_shared_string_navigate_up"
|
||||
android:visibility="gone"
|
||||
osmand:srcCompat="@drawable/ic_action_search_dark" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottom_navigation"
|
||||
android:layout_width="match_parent"
|
||||
|
|
21
OsmAnd/res/layout/track_points_card.xml
Normal file
21
OsmAnd/res/layout/track_points_card.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ExpandableListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginLeft="0dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginRight="0dp"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:drawSelectorOnTop="false"
|
||||
android:groupIndicator="@android:color/transparent" />
|
||||
|
||||
</LinearLayout>
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
-->
|
||||
|
||||
<string name="copy_to_map_favorites">Copy to favorites</string>
|
||||
<string name="copy_to_map_markers">Copy to map markers</string>
|
||||
<string name="delete_waypoints">Delete waypoints</string>
|
||||
<string name="context_menu_edit_descr">Edit description</string>
|
||||
<string name="context_menu_read_full">Read full</string>
|
||||
<string name="delete_online_routing_engine">Delete this online routing engine?</string>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.osmand;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -8,6 +9,8 @@ import androidx.fragment.app.Fragment;
|
|||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Metadata;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
@ -109,6 +112,8 @@ public class FileUtils {
|
|||
selected.getGpxFile().path = dest.getAbsolutePath();
|
||||
helper.updateSelectedGpxFile(selected);
|
||||
}
|
||||
RenameGpxAsyncTask renameGpxAsyncTask = new RenameGpxAsyncTask(app, dest);
|
||||
renameGpxAsyncTask.execute();
|
||||
return dest;
|
||||
}
|
||||
return null;
|
||||
|
@ -196,4 +201,34 @@ public class FileUtils {
|
|||
public interface RenameCallback {
|
||||
void renamedTo(File file);
|
||||
}
|
||||
|
||||
private static class RenameGpxAsyncTask extends AsyncTask<Void, Void, Exception> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private File file;
|
||||
|
||||
private RenameGpxAsyncTask(@NonNull OsmandApplication app, @NonNull File file) {
|
||||
this.app = app;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Exception doInBackground(Void... voids) {
|
||||
GpxSelectionHelper helper = app.getSelectedGpxHelper();
|
||||
SelectedGpxFile selected = helper.getSelectedFileByPath(file.getAbsolutePath());
|
||||
|
||||
GPXFile gpxFile;
|
||||
if (selected != null && selected.getGpxFile() != null) {
|
||||
gpxFile = selected.getGpxFile();
|
||||
} else {
|
||||
gpxFile = GPXUtilities.loadGPXFile(file);
|
||||
}
|
||||
if (gpxFile.metadata == null) {
|
||||
gpxFile.metadata = new Metadata();
|
||||
}
|
||||
gpxFile.metadata.name = Algorithms.getFileNameWithoutExtension(file.getName());
|
||||
|
||||
return GPXUtilities.writeGpxFile(file, gpxFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,10 +45,12 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class GpxSelectionHelper {
|
||||
|
||||
|
@ -60,6 +62,7 @@ public class GpxSelectionHelper {
|
|||
private static final String BACKUPMODIFIEDTIME = "backupTime";
|
||||
private static final String COLOR = "color";
|
||||
private static final String SELECTED_BY_USER = "selected_by_user";
|
||||
private static final String HIDDEN_GROUPS = "hidden_groups";
|
||||
|
||||
private OsmandApplication app;
|
||||
private SavingTrackHelper savingTrackHelper;
|
||||
|
@ -577,7 +580,10 @@ public class GpxSelectionHelper {
|
|||
} else if (obj.has(BACKUP)) {
|
||||
selectedGpxFilesBackUp.put(gpx, gpx.modifiedTime);
|
||||
} else {
|
||||
selectGpxFile(gpx, true, false, true, selectedByUser, false);
|
||||
SelectedGpxFile file = selectGpxFile(gpx, true, false, true, selectedByUser, false);
|
||||
if (obj.has(HIDDEN_GROUPS)) {
|
||||
readHiddenGroups(file, obj.getString(HIDDEN_GROUPS));
|
||||
}
|
||||
}
|
||||
gpx.addGeneralTrack();
|
||||
} else if (obj.has(CURRENT_TRACK)) {
|
||||
|
@ -598,6 +604,33 @@ public class GpxSelectionHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private String saveHiddenGroups(SelectedGpxFile selectedGpxFile) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
Iterator<String> it = selectedGpxFile.hiddenGroups.iterator();
|
||||
while (it.hasNext()) {
|
||||
String name = it.next();
|
||||
stringBuilder.append(name != null ? name : " ");
|
||||
if (it.hasNext()) {
|
||||
stringBuilder.append(",");
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public void readHiddenGroups(SelectedGpxFile selectedGpxFile, String text) {
|
||||
StringTokenizer toks = new StringTokenizer(text, ",");
|
||||
Set<String> res = new HashSet<>();
|
||||
while (toks.hasMoreTokens()) {
|
||||
String token = toks.nextToken();
|
||||
if (!Algorithms.isBlank(token)) {
|
||||
res.add(token);
|
||||
} else {
|
||||
res.add(null);
|
||||
}
|
||||
}
|
||||
selectedGpxFile.hiddenGroups = res;
|
||||
}
|
||||
|
||||
private int parseColor(String color) {
|
||||
try {
|
||||
return Algorithms.isEmpty(color) ? 0 : Algorithms.parseColor(color);
|
||||
|
@ -619,6 +652,7 @@ public class GpxSelectionHelper {
|
|||
if (s.gpxFile.getColor(0) != 0) {
|
||||
obj.put(COLOR, Algorithms.colorToString(s.gpxFile.getColor(0)));
|
||||
}
|
||||
obj.put(HIDDEN_GROUPS, saveHiddenGroups(s));
|
||||
}
|
||||
obj.put(SELECTED_BY_USER, s.selectedByUser);
|
||||
} catch (JSONException e) {
|
||||
|
@ -765,6 +799,7 @@ public class GpxSelectionHelper {
|
|||
private GPXFile gpxFile;
|
||||
private GPXTrackAnalysis trackAnalysis;
|
||||
|
||||
private Set<String> hiddenGroups = new HashSet<>();
|
||||
private List<TrkSegment> processedPointsToDisplay = new ArrayList<>();
|
||||
private List<GpxDisplayGroup> displayGroups;
|
||||
|
||||
|
@ -832,6 +867,18 @@ public class GpxSelectionHelper {
|
|||
return processedPointsToDisplay;
|
||||
}
|
||||
|
||||
public Set<String> getHiddenGroups() {
|
||||
return Collections.unmodifiableSet(hiddenGroups);
|
||||
}
|
||||
|
||||
public void addHiddenGroups(String group) {
|
||||
hiddenGroups.add(group);
|
||||
}
|
||||
|
||||
public void removeHiddenGroups(String group) {
|
||||
hiddenGroups.remove(group);
|
||||
}
|
||||
|
||||
public GPXFile getGpxFile() {
|
||||
return gpxFile;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,8 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment {
|
|||
file = new File(path);
|
||||
}
|
||||
selectedFileName = savedInstanceState.getString(SELECTED_FILE_NAME_KEY);
|
||||
} else {
|
||||
selectedFileName = Algorithms.getFileNameWithoutExtension(file);
|
||||
}
|
||||
items.add(new TitleItem(getString(R.string.shared_string_rename)));
|
||||
|
||||
|
@ -74,7 +76,7 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment {
|
|||
nameTextBox.setDefaultHintTextColor(colorStateList);
|
||||
|
||||
editText = view.findViewById(R.id.name_edit_text);
|
||||
editText.setText(selectedFileName != null ? selectedFileName : Algorithms.getFileNameWithoutExtension(file));
|
||||
editText.setText(selectedFileName);
|
||||
editText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
@ -127,12 +129,13 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment {
|
|||
File dest;
|
||||
int index = file.getName().lastIndexOf('.');
|
||||
String ext = index == -1 ? "" : file.getName().substring(index);
|
||||
String newName = Algorithms.getFileNameWithoutExtension(selectedFileName);
|
||||
if (SQLiteTileSource.EXT.equals(ext)) {
|
||||
dest = renameSQLiteFile(app, file, selectedFileName + ext, null);
|
||||
dest = renameSQLiteFile(app, file, newName + ext, null);
|
||||
} else if (IndexConstants.GPX_FILE_EXT.equals(ext)) {
|
||||
dest = renameGpxFile(app, file, selectedFileName + ext, false, null);
|
||||
dest = renameGpxFile(app, file, newName + ext, false, null);
|
||||
} else {
|
||||
dest = renameFile(app, file, selectedFileName + ext, false, null);
|
||||
dest = renameFile(app, file, newName + ext, false, null);
|
||||
}
|
||||
if (dest != null) {
|
||||
Fragment fragment = getTargetFragment();
|
||||
|
|
|
@ -15,14 +15,14 @@ import java.io.File;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.Set;
|
||||
|
||||
class DeletePointsTask extends AsyncTask<Void, Void, Void> {
|
||||
public class DeletePointsTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private GPXFile gpx;
|
||||
private Set<GpxDisplayItem> selectedItems;
|
||||
private WeakReference<OnPointsDeleteListener> listenerRef;
|
||||
|
||||
DeletePointsTask(OsmandApplication app, GPXFile gpxFile, Set<GpxDisplayItem> selectedItems, OnPointsDeleteListener listener) {
|
||||
public DeletePointsTask(OsmandApplication app, GPXFile gpxFile, Set<GpxDisplayItem> selectedItems, OnPointsDeleteListener listener) {
|
||||
this.app = app;
|
||||
this.gpx = gpxFile;
|
||||
this.selectedItems = selectedItems;
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package net.osmand.plus.myplaces;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
|
@ -17,56 +18,127 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.ListPopupWindow;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.data.FavouritePoint;
|
||||
import net.osmand.plus.FavouritesDbHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersHelper;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.EditFavoriteGroupDialogFragment.FavoriteColorAdapter;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.SavingTrackHelper;
|
||||
import net.osmand.plus.activities.TrackActivity;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersHelper;
|
||||
import net.osmand.plus.measurementtool.OptionsDividerItem;
|
||||
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.track.TrackMenuFragment;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.getCustomButtonView;
|
||||
import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.updateCustomButtonView;
|
||||
|
||||
public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment implements OnPointsDeleteListener {
|
||||
|
||||
public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment {
|
||||
public static final String TAG = EditTrackGroupDialogFragment.class.getSimpleName();
|
||||
|
||||
private OsmandApplication app;
|
||||
|
||||
private GpxDisplayGroup group;
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
final OsmandApplication app = getMyApplication();
|
||||
app = requiredMyApplication();
|
||||
if (group == null) {
|
||||
return;
|
||||
}
|
||||
items.add(new TitleItem(getCategoryName(app, group.getName())));
|
||||
|
||||
BaseBottomSheetItem editNameItem = new SimpleBottomSheetItem.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_edit_dark))
|
||||
.setTitle(getString(R.string.edit_name))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(group.getGpx().path);
|
||||
if (group.getType() == GpxDisplayItemType.TRACK_POINTS && selectedGpxFile != null) {
|
||||
items.add(createShowOnMapItem(selectedGpxFile));
|
||||
}
|
||||
items.add(createEditNameItem());
|
||||
items.add(new OptionsDividerItem(app));
|
||||
|
||||
// items.add(createCopyToMarkersItem());
|
||||
items.add(createCopyToFavoritesItem());
|
||||
items.add(new OptionsDividerItem(app));
|
||||
|
||||
items.add(createDeleteGroupItem());
|
||||
}
|
||||
|
||||
private BaseBottomSheetItem createShowOnMapItem(final SelectedGpxFile selectedGpxFile) {
|
||||
final String name = Algorithms.isEmpty(group.getName()) ? null : group.getName();
|
||||
boolean checked = !selectedGpxFile.getHiddenGroups().contains(name);
|
||||
final ApplicationMode mode = app.getSettings().getApplicationMode();
|
||||
final BottomSheetItemWithCompoundButton[] showOnMapItem = new BottomSheetItemWithCompoundButton[1];
|
||||
showOnMapItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setCompoundButtonColorId(mode.getIconColorInfo().getColor(nightMode))
|
||||
.setChecked(checked)
|
||||
.setTitle(getString(R.string.shared_string_show_on_map))
|
||||
.setCustomView(getCustomButtonView(app, mode, checked, nightMode))
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Activity activity = getActivity();
|
||||
boolean checked = !showOnMapItem[0].isChecked();
|
||||
if (checked) {
|
||||
selectedGpxFile.removeHiddenGroups(name);
|
||||
} else {
|
||||
selectedGpxFile.addHiddenGroups(name);
|
||||
}
|
||||
app.getSelectedGpxHelper().updateSelectedGpxFile(selectedGpxFile);
|
||||
|
||||
showOnMapItem[0].setChecked(checked);
|
||||
updateCustomButtonView(app, mode, v, checked, nightMode);
|
||||
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity instanceof MapActivity) {
|
||||
((MapActivity) activity).refreshMap();
|
||||
}
|
||||
}
|
||||
})
|
||||
.create();
|
||||
return showOnMapItem[0];
|
||||
}
|
||||
|
||||
private BaseBottomSheetItem createEditNameItem() {
|
||||
return new SimpleBottomSheetItem.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_name_field))
|
||||
.setTitle(getString(R.string.shared_string_rename))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
||||
b.setTitle(R.string.favorite_group_name);
|
||||
|
@ -86,11 +158,8 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
String name = nameEditText.getText().toString();
|
||||
boolean nameChanged = !Algorithms.objectEquals(group.getName(), name);
|
||||
if (nameChanged) {
|
||||
TrackActivity trackActivity = getTrackActivity();
|
||||
if (trackActivity != null) {
|
||||
new UpdateGpxCategoryTask(trackActivity, group, name)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
new UpdateGpxCategoryTask(activity, group, name)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
@ -100,20 +169,118 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
}
|
||||
})
|
||||
.create();
|
||||
items.add(editNameItem);
|
||||
}
|
||||
|
||||
private BaseBottomSheetItem createCopyToMarkersItem() {
|
||||
return new SimpleBottomSheetItem.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_copy))
|
||||
.setTitle(getString(R.string.copy_to_map_markers))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// MapMarkersHelper markersHelper = app.getMapMarkersHelper();
|
||||
// MapMarkersGroup markersGroup = markersHelper.getMarkersGroup(group);
|
||||
// if (markersGroup != null) {
|
||||
// markersHelper.removeMarkersGroup(markersGroup);
|
||||
// } else {
|
||||
// markersHelper.addOrEnableGroup(group);
|
||||
// }
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
|
||||
private BaseBottomSheetItem createCopyToFavoritesItem() {
|
||||
return new SimpleBottomSheetItem.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_copy))
|
||||
.setTitle(getString(R.string.copy_to_map_favorites))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
saveGroupToFavorites();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
|
||||
private void saveGroupToFavorites() {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
||||
final EditText editText = new EditText(activity);
|
||||
String name = group.getModifiableList().iterator().next().group.getName();
|
||||
if (name.indexOf('\n') > 0) {
|
||||
name = name.substring(0, name.indexOf('\n'));
|
||||
}
|
||||
editText.setText(name);
|
||||
int leftMargin = AndroidUtils.dpToPx(activity, 16f);
|
||||
int topMargin = AndroidUtils.dpToPx(activity, 8f);
|
||||
editText.setPadding(leftMargin, topMargin, leftMargin, topMargin);
|
||||
b.setTitle(R.string.save_as_favorites_points);
|
||||
b.setView(editText);
|
||||
b.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String category = editText.getText().toString();
|
||||
FavouritesDbHelper favouritesDbHelper = app.getFavorites();
|
||||
for (GpxDisplayItem item : group.getModifiableList()) {
|
||||
if (item.locationStart != null) {
|
||||
FavouritePoint fp = FavouritePoint.fromWpt(item.locationStart, app, category);
|
||||
if (!Algorithms.isEmpty(item.description)) {
|
||||
fp.setDescription(item.description);
|
||||
}
|
||||
favouritesDbHelper.addFavourite(fp, false);
|
||||
}
|
||||
}
|
||||
favouritesDbHelper.saveCurrentPointsIntoFile();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
b.show();
|
||||
}
|
||||
}
|
||||
|
||||
private BaseBottomSheetItem createDeleteGroupItem() {
|
||||
String delete = app.getString(R.string.shared_string_delete);
|
||||
Typeface typeface = FontCache.getRobotoMedium(app);
|
||||
return new SimpleBottomSheetItem.Builder()
|
||||
.setTitleColorId(R.color.color_osm_edit_delete)
|
||||
.setIcon(getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete))
|
||||
.setTitle(UiUtilities.createCustomFontSpannable(typeface, delete, delete))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||
.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
deleteGroupItems();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
|
||||
private void deleteGroupItems() {
|
||||
Set<GpxDisplayItem> items = new HashSet<>(group.getModifiableList());
|
||||
new DeletePointsTask(app, group.getGpx(), items, this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private BaseBottomSheetItem createChangeColorItem() {
|
||||
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
||||
final View changeColorView = View.inflate(new ContextThemeWrapper(getContext(), themeRes),
|
||||
R.layout.change_fav_color, null);
|
||||
((ImageView) changeColorView.findViewById(R.id.change_color_icon))
|
||||
.setImageDrawable(getContentIcon(R.drawable.ic_action_appearance));
|
||||
updateColorView((ImageView) changeColorView.findViewById(R.id.colorImage));
|
||||
BaseBottomSheetItem changeColorItem = new BaseBottomSheetItem.Builder()
|
||||
return new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(changeColorView)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Activity activity = getActivity();
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
final ListPopupWindow popup = new ListPopupWindow(activity);
|
||||
popup.setAnchorView(v);
|
||||
|
@ -135,11 +302,8 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
Integer color = colorAdapter.getItem(position);
|
||||
if (color != null) {
|
||||
if (color != group.getColor()) {
|
||||
TrackActivity trackActivity = getTrackActivity();
|
||||
if (trackActivity != null) {
|
||||
new UpdateGpxCategoryTask(trackActivity, group, color)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
new UpdateGpxCategoryTask(activity, group, color)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
popup.dismiss();
|
||||
|
@ -151,8 +315,6 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
}
|
||||
})
|
||||
.create();
|
||||
items.add(changeColorItem);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,15 +325,6 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TrackActivity getTrackActivity() {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null && activity instanceof TrackActivity) {
|
||||
return (TrackActivity) activity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getCategoryName(@NonNull Context ctx, String category) {
|
||||
return Algorithms.isEmpty(category) ? ctx.getString(R.string.shared_string_waypoints) : category;
|
||||
}
|
||||
|
@ -181,24 +334,38 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
if (color == 0) {
|
||||
colorImageView.setImageDrawable(getContentIcon(R.drawable.ic_action_circle));
|
||||
} else {
|
||||
colorImageView.setImageDrawable(getMyApplication().getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color));
|
||||
colorImageView.setImageDrawable(app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color));
|
||||
}
|
||||
}
|
||||
|
||||
public static void showInstance(FragmentManager fragmentManager, GpxDisplayGroup group) {
|
||||
EditTrackGroupDialogFragment f = (EditTrackGroupDialogFragment) fragmentManager
|
||||
.findFragmentByTag(EditTrackGroupDialogFragment.TAG);
|
||||
if (f == null ) {
|
||||
f = new EditTrackGroupDialogFragment();
|
||||
f.group = group;
|
||||
f.show(fragmentManager, EditTrackGroupDialogFragment.TAG);
|
||||
public static void showInstance(FragmentManager fragmentManager, GpxDisplayGroup group, Fragment target) {
|
||||
if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(TAG) == null) {
|
||||
EditTrackGroupDialogFragment fragment = new EditTrackGroupDialogFragment();
|
||||
fragment.group = group;
|
||||
fragment.setRetainInstance(true);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.show(fragmentManager, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointsDeletionStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointsDeleted() {
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof TrackMenuFragment) {
|
||||
((TrackMenuFragment) fragment).updateContent();
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private static class UpdateGpxCategoryTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private WeakReference<TrackActivity> activityRef;
|
||||
private WeakReference<FragmentActivity> activityRef;
|
||||
|
||||
private GpxDisplayGroup group;
|
||||
|
||||
|
@ -208,20 +375,20 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
private ProgressDialog progressDialog;
|
||||
private boolean wasUpdated = false;
|
||||
|
||||
private UpdateGpxCategoryTask(@NonNull TrackActivity activity, @NonNull GpxDisplayGroup group) {
|
||||
private UpdateGpxCategoryTask(@NonNull FragmentActivity activity, @NonNull GpxDisplayGroup group) {
|
||||
this.app = (OsmandApplication) activity.getApplication();
|
||||
activityRef = new WeakReference<>(activity);
|
||||
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
UpdateGpxCategoryTask(@NonNull TrackActivity activity, @NonNull GpxDisplayGroup group,
|
||||
UpdateGpxCategoryTask(@NonNull FragmentActivity activity, @NonNull GpxDisplayGroup group,
|
||||
@NonNull String newCategory) {
|
||||
this(activity, group);
|
||||
this.newCategory = newCategory;
|
||||
}
|
||||
|
||||
UpdateGpxCategoryTask(@NonNull TrackActivity activity, @NonNull GpxDisplayGroup group,
|
||||
UpdateGpxCategoryTask(@NonNull FragmentActivity activity, @NonNull GpxDisplayGroup group,
|
||||
@NonNull Integer newColor) {
|
||||
this(activity, group);
|
||||
this.newColor = newColor;
|
||||
|
@ -229,7 +396,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
TrackActivity activity = activityRef.get();
|
||||
FragmentActivity activity = activityRef.get();
|
||||
if (activity != null) {
|
||||
progressDialog = new ProgressDialog(activity);
|
||||
progressDialog.setTitle(EditTrackGroupDialogFragment.getCategoryName(app, group.getName()));
|
||||
|
@ -293,9 +460,15 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
|||
progressDialog.dismiss();
|
||||
}
|
||||
|
||||
TrackActivity activity = activityRef.get();
|
||||
if (activity != null) {
|
||||
activity.loadGpx();
|
||||
FragmentActivity activity = activityRef.get();
|
||||
if (activity instanceof TrackActivity) {
|
||||
((TrackActivity) activity).loadGpx();
|
||||
} else if (activity instanceof MapActivity) {
|
||||
MapActivity mapActivity = (MapActivity) activity;
|
||||
TrackMenuFragment fragment = mapActivity.getTrackMenuFragment();
|
||||
if (fragment != null) {
|
||||
fragment.updateContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1007,7 +1007,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
|
|||
public void onClick(View v) {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
EditTrackGroupDialogFragment.showInstance(activity.getSupportFragmentManager(), group);
|
||||
EditTrackGroupDialogFragment.showInstance(activity.getSupportFragmentManager(), group, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -122,14 +122,14 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
|
|||
return R.string.shared_string_close;
|
||||
}
|
||||
|
||||
protected static View getCustomButtonView(OsmandApplication app, ApplicationMode mode, boolean checked, boolean nightMode) {
|
||||
public static View getCustomButtonView(OsmandApplication app, ApplicationMode mode, boolean checked, boolean nightMode) {
|
||||
View customView = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_item_preference_switch, null);
|
||||
updateCustomButtonView(app, mode, customView, checked, nightMode);
|
||||
|
||||
return customView;
|
||||
}
|
||||
|
||||
protected static void updateCustomButtonView(OsmandApplication app, ApplicationMode mode, View customView, boolean checked, boolean nightMode) {
|
||||
public static void updateCustomButtonView(OsmandApplication app, ApplicationMode mode, View customView, boolean checked, boolean nightMode) {
|
||||
Context themedCtx = UiUtilities.getThemedContext(app, nightMode);
|
||||
View buttonView = customView.findViewById(R.id.button_container);
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ public class SegmentsCard extends BaseCard {
|
|||
|
||||
private TrackDisplayHelper displayHelper;
|
||||
private GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT};
|
||||
private SegmentGPXAdapter adapter;
|
||||
private SegmentActionsListener listener;
|
||||
|
||||
public SegmentsCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper,
|
||||
|
|
|
@ -112,10 +112,16 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMiddleStateKoef() {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInitialMenuState() {
|
||||
return MenuState.HALF_SCREEN;
|
||||
}
|
||||
|
||||
public TrackDrawInfo getTrackDrawInfo() {
|
||||
return trackDrawInfo;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
package net.osmand.plus.track;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
|
@ -17,10 +12,6 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
|||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.measurementtool.GpxData;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
@ -163,21 +154,4 @@ public class TrackDisplayHelper {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void addNewGpxData(Activity activity) {
|
||||
GPXFile gpxFile = getGpx();
|
||||
GpxData gpxData = new GpxData(gpxFile);
|
||||
WptPt pointToShow = gpxFile != null ? gpxFile.findPointToShow() : null;
|
||||
if (pointToShow != null) {
|
||||
LatLon location = new LatLon(pointToShow.getLatitude(), pointToShow.getLongitude());
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
|
||||
settings.getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_WPT, activity.getString(R.string.add_line)),
|
||||
false,
|
||||
gpxData
|
||||
);
|
||||
MapActivity.launchMapActivityMoveToTop(activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
package net.osmand.plus.track;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
@ -33,6 +39,7 @@ import net.osmand.GPXUtilities.TrkSegment;
|
|||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.GpxDbHelper;
|
||||
|
@ -61,6 +68,7 @@ import net.osmand.plus.measurementtool.GpxData;
|
|||
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
|
||||
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
|
||||
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet;
|
||||
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener;
|
||||
import net.osmand.plus.myplaces.SegmentActionsListener;
|
||||
|
@ -70,6 +78,7 @@ import net.osmand.plus.osmedit.OsmEditingPlugin;
|
|||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
||||
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
||||
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
|
||||
import net.osmand.plus.widgets.IconPopupMenu;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
@ -94,9 +103,12 @@ import static net.osmand.plus.track.OptionsCard.RENAME_BUTTON_INDEX;
|
|||
import static net.osmand.plus.track.OptionsCard.SHARE_BUTTON_INDEX;
|
||||
import static net.osmand.plus.track.OptionsCard.SHOW_ON_MAP_BUTTON_INDEX;
|
||||
import static net.osmand.plus.track.OptionsCard.UPLOAD_OSM_BUTTON_INDEX;
|
||||
import static net.osmand.plus.track.TrackPointsCard.ADD_WAYPOINT_INDEX;
|
||||
import static net.osmand.plus.track.TrackPointsCard.DELETE_WAYPOINTS_INDEX;
|
||||
|
||||
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
|
||||
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OsmAndLocationListener, OsmAndCompassListener {
|
||||
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OnPointsDeleteListener,
|
||||
OsmAndLocationListener, OsmAndCompassListener {
|
||||
|
||||
public static final String TAG = TrackMenuFragment.class.getName();
|
||||
private static final Log log = PlatformUtil.getLog(TrackMenuFragment.class);
|
||||
|
@ -105,37 +117,46 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
private TrackDisplayHelper displayHelper;
|
||||
private SelectedGpxFile selectedGpxFile;
|
||||
|
||||
private View routeMenuTopShadowAll;
|
||||
private TextView headerTitle;
|
||||
private ImageView headerIcon;
|
||||
private BottomNavigationView bottomNav;
|
||||
private TrackMenuType menuType = TrackMenuType.OVERVIEW;
|
||||
private SegmentsCard segmentsCard;
|
||||
private OptionsCard optionsCard;
|
||||
private DescriptionCard descriptionCard;
|
||||
private OverviewCard overviewCard;
|
||||
private TrackPointsCard pointsCard;
|
||||
|
||||
private TextView headerTitle;
|
||||
private ImageView headerIcon;
|
||||
private View toolbarContainer;
|
||||
private View searchContainer;
|
||||
private ImageView searchButton;
|
||||
private EditText searchEditText;
|
||||
private TextView toolbarTextView;
|
||||
private View routeMenuTopShadowAll;
|
||||
private BottomNavigationView bottomNav;
|
||||
|
||||
private String gpxTitle;
|
||||
private TrackChartPoints trackChartPoints;
|
||||
|
||||
private int menuTitleHeight;
|
||||
private String gpxTitle;
|
||||
private UpdateLocationViewCache updateLocationViewCache;
|
||||
private Location lastLocation = null;
|
||||
private Float heading;
|
||||
private Location lastLocation;
|
||||
private UpdateLocationViewCache updateLocationViewCache;
|
||||
private boolean locationUpdateStarted;
|
||||
|
||||
private int menuTitleHeight;
|
||||
private int toolbarHeightPx;
|
||||
|
||||
public enum TrackMenuType {
|
||||
OVERVIEW(R.id.action_overview, R.string.shared_string_overview),
|
||||
TRACK(R.id.action_track, R.string.shared_string_gpx_tracks),
|
||||
POINTS(R.id.action_points, R.string.shared_string_gpx_points),
|
||||
OPTIONS(R.id.action_options, R.string.shared_string_options);
|
||||
|
||||
TrackMenuType(@DrawableRes int iconId, @StringRes int titleId) {
|
||||
this.iconId = iconId;
|
||||
TrackMenuType(int menuItemId, @StringRes int titleId) {
|
||||
this.menuItemId = menuItemId;
|
||||
this.titleId = titleId;
|
||||
}
|
||||
|
||||
public final int iconId;
|
||||
public final int menuItemId;
|
||||
public final int titleId;
|
||||
}
|
||||
|
||||
|
@ -156,7 +177,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
|
||||
@Override
|
||||
public int getToolbarHeight() {
|
||||
return 0;
|
||||
return toolbarHeightPx;
|
||||
}
|
||||
|
||||
public float getMiddleStateKoef() {
|
||||
|
@ -183,6 +204,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
app = requireMyApplication();
|
||||
GpxDbHelper gpxDbHelper = app.getGpxDbHelper();
|
||||
displayHelper = new TrackDisplayHelper(app);
|
||||
updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache();
|
||||
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
|
@ -200,6 +222,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
|
||||
gpxTitle = GpxUiHelper.getGpxTitle(fileName);
|
||||
}
|
||||
toolbarHeightPx = getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar);
|
||||
}
|
||||
|
||||
public GPXFile getGpx() {
|
||||
|
@ -214,7 +237,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
routeMenuTopShadowAll = view.findViewById(R.id.route_menu_top_shadow_all);
|
||||
headerTitle = view.findViewById(R.id.title);
|
||||
headerIcon = view.findViewById(R.id.icon_view);
|
||||
updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache();
|
||||
toolbarContainer = view.findViewById(R.id.context_menu_toolbar_container);
|
||||
toolbarTextView = view.findViewById(R.id.toolbar_title);
|
||||
searchButton = view.findViewById(R.id.search_button);
|
||||
searchContainer = view.findViewById(R.id.search_container);
|
||||
|
||||
if (isPortrait()) {
|
||||
AndroidUiHelper.updateVisibility(getTopShadow(), true);
|
||||
|
@ -226,6 +252,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}
|
||||
|
||||
setupCards();
|
||||
setupToolbar();
|
||||
updateHeader();
|
||||
setupButtons(view);
|
||||
enterTrackAppearanceMode();
|
||||
|
@ -261,6 +288,74 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
boolean isOptions = menuType == TrackMenuType.OPTIONS;
|
||||
setHeaderTitle(isOptions ? app.getString(menuType.titleId) : gpxTitle, !isOptions);
|
||||
}
|
||||
if (menuType == TrackMenuType.POINTS) {
|
||||
AndroidUiHelper.updateVisibility(searchButton, true);
|
||||
} else {
|
||||
AndroidUiHelper.updateVisibility(toolbarTextView, true);
|
||||
AndroidUiHelper.updateVisibility(searchButton, false);
|
||||
AndroidUiHelper.updateVisibility(searchContainer, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
toolbarTextView.setText(gpxTitle);
|
||||
|
||||
ImageView closeButton = toolbarContainer.findViewById(R.id.close_button);
|
||||
closeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (menuType == TrackMenuType.POINTS) {
|
||||
AndroidUiHelper.updateVisibility(toolbarTextView, true);
|
||||
AndroidUiHelper.updateVisibility(searchButton, true);
|
||||
AndroidUiHelper.updateVisibility(searchContainer, false);
|
||||
}
|
||||
openMenuHeaderOnly();
|
||||
}
|
||||
});
|
||||
closeButton.setImageResource(AndroidUtils.getNavigationIconResId(toolbarContainer.getContext()));
|
||||
|
||||
searchButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
AndroidUiHelper.updateVisibility(searchContainer, true);
|
||||
AndroidUiHelper.updateVisibility(searchButton, false);
|
||||
AndroidUiHelper.updateVisibility(toolbarTextView, false);
|
||||
}
|
||||
});
|
||||
searchEditText = toolbarContainer.findViewById(R.id.searchEditText);
|
||||
searchEditText.setHint(R.string.search_poi_filter);
|
||||
searchEditText.addTextChangedListener(
|
||||
new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (pointsCard != null) {
|
||||
pointsCard.filter(s.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
ImageView clearButton = toolbarContainer.findViewById(R.id.clearButton);
|
||||
clearButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!Algorithms.isEmpty(searchEditText.getText())) {
|
||||
searchEditText.setText("");
|
||||
searchEditText.setSelection(0);
|
||||
}
|
||||
if (pointsCard != null) {
|
||||
pointsCard.updateContent();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupCards() {
|
||||
|
@ -296,13 +391,25 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
if (descriptionCard != null && descriptionCard.getView() != null) {
|
||||
ViewGroup parent = ((ViewGroup) descriptionCard.getView().getParent());
|
||||
if (parent != null) {
|
||||
cardsContainer.removeView(descriptionCard.getView());
|
||||
parent.removeView(descriptionCard.getView());
|
||||
}
|
||||
cardsContainer.addView(descriptionCard.getView());
|
||||
} else {
|
||||
descriptionCard = new DescriptionCard(getMapActivity(), displayHelper.getGpx());
|
||||
cardsContainer.addView(descriptionCard.build(mapActivity));
|
||||
}
|
||||
} else if (menuType == TrackMenuType.POINTS) {
|
||||
if (pointsCard != null && pointsCard.getView() != null) {
|
||||
ViewGroup parent = (ViewGroup) pointsCard.getView().getParent();
|
||||
if (parent != null) {
|
||||
parent.removeAllViews();
|
||||
}
|
||||
cardsContainer.addView(pointsCard.getView());
|
||||
} else {
|
||||
pointsCard = new TrackPointsCard(mapActivity, displayHelper);
|
||||
pointsCard.setListener(this);
|
||||
cardsContainer.addView(pointsCard.build(mapActivity));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -318,12 +425,14 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
protected void setViewY(int y, boolean animated, boolean adjustMapPos) {
|
||||
super.setViewY(y, animated, adjustMapPos);
|
||||
updateStatusBarColor();
|
||||
updateToolbar(y, animated);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateMainViewLayout(int posY) {
|
||||
super.updateMainViewLayout(posY);
|
||||
updateStatusBarColor();
|
||||
updateToolbar(posY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -484,7 +593,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
if (Build.VERSION.SDK_INT >= 23 && !nightMode) {
|
||||
view.setSystemUiVisibility(view.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
return nightMode ? R.color.divider_color_dark : R.color.divider_color_light;
|
||||
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= 23 && !nightMode) {
|
||||
view.setSystemUiVisibility(view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
|
@ -522,8 +631,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
if (mapActivity == null) {
|
||||
return;
|
||||
}
|
||||
final GPXFile gpxFile = getGpx();
|
||||
if (card instanceof OptionsCard || card instanceof OverviewCard) {
|
||||
final GPXFile gpxFile = getGpx();
|
||||
if (buttonIndex == SHOW_ON_MAP_BUTTON_INDEX) {
|
||||
boolean gpxFileSelected = !isGpxFileSelected(app, gpxFile);
|
||||
app.getSelectedGpxHelper().selectGpxFile(gpxFile, gpxFileSelected, false);
|
||||
|
@ -615,6 +724,25 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
});
|
||||
builder.show();
|
||||
}
|
||||
} else if (card instanceof TrackPointsCard) {
|
||||
if (buttonIndex == ADD_WAYPOINT_INDEX) {
|
||||
PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_WPT, app.getString(R.string.add_waypoint));
|
||||
QuadRect rect = displayHelper.getRect();
|
||||
NewGpxPoint newGpxPoint = new NewGpxPoint(gpxFile, pointDescription, rect);
|
||||
|
||||
mapActivity.getMapView().fitRectToMap(rect.left, rect.right, rect.top, rect.bottom,
|
||||
(int) rect.width(), (int) rect.height(), 0);
|
||||
mapActivity.getMapLayers().getContextMenuLayer().enterAddGpxPointMode(newGpxPoint);
|
||||
|
||||
hide();
|
||||
} else if (buttonIndex == DELETE_WAYPOINTS_INDEX) {
|
||||
TrackPointsCard pointsCard = (TrackPointsCard) card;
|
||||
if (pointsCard.isSelectionMode()) {
|
||||
pointsCard.deleteItemsAction();
|
||||
} else {
|
||||
pointsCard.setSelectionMode(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,6 +755,34 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
return y;
|
||||
}
|
||||
|
||||
public void updateToolbar(int y, boolean animated) {
|
||||
final MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
if (toolbarContainer != null && isPortrait()) {
|
||||
if (animated) {
|
||||
final float toolbarAlpha = getToolbarAlpha(y);
|
||||
if (toolbarAlpha > 0) {
|
||||
updateVisibility(toolbarContainer, true);
|
||||
}
|
||||
toolbarContainer.animate().alpha(toolbarAlpha)
|
||||
.setDuration(ContextMenuFragment.ANIMATION_DURATION)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
updateVisibility(toolbarContainer, toolbarAlpha);
|
||||
mapActivity.updateStatusBarColor();
|
||||
}
|
||||
})
|
||||
.start();
|
||||
} else {
|
||||
updateToolbarVisibility(toolbarContainer, y);
|
||||
mapActivity.updateStatusBarColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHeaderClick() {
|
||||
adjustMapPosition(getViewY());
|
||||
|
@ -664,7 +820,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
@Override
|
||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||
for (TrackMenuType type : TrackMenuType.values()) {
|
||||
if (type.iconId == item.getItemId()) {
|
||||
if (type.menuItemId == item.getItemId()) {
|
||||
menuType = type;
|
||||
setupCards();
|
||||
updateHeader();
|
||||
|
@ -687,6 +843,9 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
if (descriptionCard != null) {
|
||||
descriptionCard.updateContent();
|
||||
}
|
||||
if (pointsCard != null) {
|
||||
pointsCard.updateContent();
|
||||
}
|
||||
setupCards();
|
||||
}
|
||||
|
||||
|
@ -700,6 +859,18 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointsDeletionStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointsDeleted() {
|
||||
if (pointsCard != null) {
|
||||
pointsCard.onPointsDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointSelected(TrkSegment segment, double lat, double lon) {
|
||||
if (trackChartPoints == null) {
|
||||
|
@ -729,7 +900,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu();
|
||||
trackDetailsMenu.setGpxItem(gpxItem);
|
||||
trackDetailsMenu.show();
|
||||
close();
|
||||
hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -783,7 +954,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
private void editSegment(TrkSegment segment) {
|
||||
GPXFile gpxFile = getGpx();
|
||||
openPlanRoute(new GpxData(gpxFile));
|
||||
close();
|
||||
hide();
|
||||
}
|
||||
|
||||
public void openPlanRoute(GpxData gpxData) {
|
||||
|
@ -834,12 +1005,24 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void close() {
|
||||
private void hide() {
|
||||
try {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
|
||||
fragmentManager.beginTransaction().remove(this).commitAllowingStateLoss();
|
||||
fragmentManager.beginTransaction().hide(this).commit();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
try {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
|
||||
fragmentManager.beginTransaction().show(this).commit();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
|
@ -859,7 +1042,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
|
||||
mapActivity.getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, fragment, fragment.getFragmentTag())
|
||||
.replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(fragment.getFragmentTag())
|
||||
.commitAllowingStateLoss();
|
||||
return true;
|
||||
|
|
639
OsmAnd/src/net/osmand/plus/track/TrackPointsCard.java
Normal file
639
OsmAnd/src/net/osmand/plus/track/TrackPointsCard.java
Normal file
|
@ -0,0 +1,639 @@
|
|||
package net.osmand.plus.track;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.ExpandableListView.OnChildClickListener;
|
||||
import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Collator;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.OsmAndCollator;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
import net.osmand.plus.base.PointImageDrawable;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.myplaces.DeletePointsTask;
|
||||
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
|
||||
import net.osmand.plus.myplaces.EditTrackGroupDialogFragment;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class TrackPointsCard extends BaseCard implements OnChildClickListener, OnPointsDeleteListener {
|
||||
|
||||
public static final int ADD_WAYPOINT_INDEX = 0;
|
||||
public static final int DELETE_WAYPOINTS_INDEX = 1;
|
||||
|
||||
private final TrackDisplayHelper displayHelper;
|
||||
private final GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_POINTS, GpxDisplayItemType.TRACK_ROUTE_POINTS};
|
||||
|
||||
private final Set<Integer> selectedGroups = new LinkedHashSet<>();
|
||||
private final LinkedHashMap<GpxDisplayItemType, Set<GpxDisplayItem>> selectedItems = new LinkedHashMap<>();
|
||||
private boolean selectionMode;
|
||||
|
||||
private final PointGPXAdapter adapter;
|
||||
private ExpandableListView listView;
|
||||
|
||||
public TrackPointsCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper) {
|
||||
super(mapActivity);
|
||||
this.displayHelper = displayHelper;
|
||||
adapter = new PointGPXAdapter();
|
||||
}
|
||||
|
||||
public boolean isSelectionMode() {
|
||||
return selectionMode;
|
||||
}
|
||||
|
||||
public void setSelectionMode(boolean selectionMode) {
|
||||
this.selectionMode = selectionMode;
|
||||
adapter.notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardLayoutId() {
|
||||
return R.layout.track_points_card;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateContent() {
|
||||
listView = view.findViewById(android.R.id.list);
|
||||
listView.setOnChildClickListener(this);
|
||||
|
||||
adapter.setFilterResults(null);
|
||||
adapter.synchronizeGroups(getOriginalGroups());
|
||||
if (listView.getAdapter() == null) {
|
||||
listView.setAdapter(adapter);
|
||||
}
|
||||
if (!adapter.isEmpty() && listView.getFooterViewsCount() == 0) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode);
|
||||
listView.addFooterView(inflater.inflate(R.layout.list_shadow_footer, listView, false));
|
||||
addActions(inflater);
|
||||
}
|
||||
expandAllGroups();
|
||||
}
|
||||
|
||||
private void addActions(LayoutInflater inflater) {
|
||||
View view = inflater.inflate(R.layout.preference_category_with_descr, listView, false);
|
||||
TextView title = view.findViewById(android.R.id.title);
|
||||
title.setText(R.string.shared_string_actions);
|
||||
|
||||
AndroidUiHelper.updateVisibility(view.findViewById(android.R.id.icon), false);
|
||||
AndroidUiHelper.updateVisibility(view.findViewById(android.R.id.summary), false);
|
||||
listView.addFooterView(view);
|
||||
|
||||
addWaypointAction(inflater);
|
||||
deleteWaypointAction(inflater);
|
||||
}
|
||||
|
||||
private void addWaypointAction(LayoutInflater inflater) {
|
||||
View view = inflater.inflate(R.layout.preference_button, listView, false);
|
||||
TextView addWaypointTitle = view.findViewById(android.R.id.title);
|
||||
ImageView addWaypointIcon = view.findViewById(android.R.id.icon);
|
||||
|
||||
addWaypointTitle.setText(R.string.add_waypoint);
|
||||
addWaypointIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_name_field));
|
||||
|
||||
AndroidUiHelper.updateVisibility(view.findViewById(R.id.divider), true);
|
||||
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
CardListener listener = getListener();
|
||||
if (listener != null) {
|
||||
listener.onCardButtonPressed(TrackPointsCard.this, ADD_WAYPOINT_INDEX);
|
||||
}
|
||||
}
|
||||
});
|
||||
listView.addFooterView(view);
|
||||
}
|
||||
|
||||
private void deleteWaypointAction(LayoutInflater inflater) {
|
||||
View view = inflater.inflate(R.layout.preference_button, listView, false);
|
||||
TextView deleteWaypointsTitle = view.findViewById(android.R.id.title);
|
||||
ImageView deleteWaypointsIcon = view.findViewById(android.R.id.icon);
|
||||
|
||||
deleteWaypointsTitle.setText(R.string.delete_waypoints);
|
||||
deleteWaypointsIcon.setImageDrawable(getColoredIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete));
|
||||
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
CardListener listener = getListener();
|
||||
if (listener != null) {
|
||||
listener.onCardButtonPressed(TrackPointsCard.this, DELETE_WAYPOINTS_INDEX);
|
||||
}
|
||||
}
|
||||
});
|
||||
listView.addFooterView(view);
|
||||
}
|
||||
|
||||
private void expandAllGroups() {
|
||||
for (int i = 0; i < adapter.getGroupCount(); i++) {
|
||||
listView.expandGroup(i);
|
||||
}
|
||||
}
|
||||
|
||||
private List<GpxDisplayGroup> getOriginalGroups() {
|
||||
return displayHelper.getOriginalGroups(filterTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void deleteItemsAction() {
|
||||
int size = getSelectedItemsCount();
|
||||
if (size > 0) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mapActivity);
|
||||
b.setMessage(app.getString(R.string.points_delete_multiple, size));
|
||||
b.setPositiveButton(R.string.shared_string_delete, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
deleteItems();
|
||||
setSelectionMode(false);
|
||||
adapter.notifyDataSetInvalidated();
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
b.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteItems() {
|
||||
new DeletePointsTask(app, displayHelper.getGpx(), getSelectedItems(), this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private Set<GpxDisplayItem> getSelectedItems() {
|
||||
Set<GpxDisplayItem> result = new LinkedHashSet<>();
|
||||
for (Set<GpxDisplayItem> set : selectedItems.values()) {
|
||||
if (set != null) {
|
||||
result.addAll(set);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateSelectionMode() {
|
||||
int size = getSelectedItemsCount();
|
||||
app.showToastMessage(size + " " + app.getString(R.string.shared_string_selected_lowercase));
|
||||
}
|
||||
|
||||
private int getSelectedItemsCount() {
|
||||
int count = 0;
|
||||
for (Set<GpxDisplayItem> set : selectedItems.values()) {
|
||||
if (set != null) {
|
||||
count += set.size();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointsDeletionStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointsDeleted() {
|
||||
selectedItems.clear();
|
||||
selectedGroups.clear();
|
||||
adapter.synchronizeGroups(getOriginalGroups());
|
||||
}
|
||||
|
||||
public void filter(String text) {
|
||||
adapter.getFilter().filter(text);
|
||||
}
|
||||
|
||||
private class PointGPXAdapter extends OsmandBaseExpandableListAdapter implements Filterable {
|
||||
|
||||
private final List<GpxDisplayGroup> groups = new ArrayList<>();
|
||||
private final Map<GpxDisplayGroup, List<GpxDisplayItem>> itemGroups = new LinkedHashMap<>();
|
||||
private final Comparator<String> comparator;
|
||||
private Filter pointsFilter;
|
||||
private Set<?> filteredItems;
|
||||
|
||||
PointGPXAdapter() {
|
||||
final Collator collator = OsmAndCollator.primaryCollator();
|
||||
comparator = new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String s1, String s2) {
|
||||
return collator.compare(s1, s2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void synchronizeGroups(@NonNull List<GpxDisplayGroup> displayGroups) {
|
||||
groups.clear();
|
||||
itemGroups.clear();
|
||||
Set<?> filtered = filteredItems;
|
||||
Collections.sort(displayGroups, new Comparator<GpxDisplayGroup>() {
|
||||
@Override
|
||||
public int compare(GpxDisplayGroup g1, GpxDisplayGroup g2) {
|
||||
int i1 = g1.getType().ordinal();
|
||||
int i2 = g2.getType().ordinal();
|
||||
return i1 < i2 ? -1 : (i1 == i2 ? 0 : 1);
|
||||
}
|
||||
});
|
||||
List<GpxDisplayGroup> trackPointsGroups = new ArrayList<>();
|
||||
List<GpxDisplayGroup> routePointsGroups = new ArrayList<>();
|
||||
for (GpxDisplayGroup group : displayGroups) {
|
||||
if (group.getType() == GpxDisplayItemType.TRACK_POINTS) {
|
||||
trackPointsGroups.add(group);
|
||||
} else if (group.getType() == GpxDisplayItemType.TRACK_ROUTE_POINTS) {
|
||||
routePointsGroups.add(group);
|
||||
}
|
||||
}
|
||||
processDisplayGroups(trackPointsGroups, filtered);
|
||||
processDisplayGroups(routePointsGroups, filtered);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void processDisplayGroups(List<GpxDisplayGroup> displayGroups, Set<?> filteredItems) {
|
||||
for (int i = 0; i < displayGroups.size(); i++) {
|
||||
GpxDisplayGroup group = displayGroups.get(i);
|
||||
if (group.getModifiableList().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Map<String, List<GpxDisplayItem>> itemsMap = collectItemsByCategory(group, i);
|
||||
if (filteredItems != null) {
|
||||
itemsMap = filterItems(itemsMap, filteredItems);
|
||||
}
|
||||
if (!Algorithms.isEmpty(itemsMap)) {
|
||||
setCollectedItems(group, itemsMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<GpxDisplayItem>> collectItemsByCategory(GpxDisplayGroup group, int index) {
|
||||
Map<String, List<GpxDisplayItem>> itemsMap = new HashMap<>();
|
||||
|
||||
for (GpxDisplayItem item : group.getModifiableList()) {
|
||||
String category;
|
||||
if (item.locationStart != null) {
|
||||
if (group.getType() == GpxDisplayItemType.TRACK_POINTS) {
|
||||
category = item.locationStart.category;
|
||||
if (Algorithms.isEmpty(category)) {
|
||||
category = "";
|
||||
}
|
||||
} else {
|
||||
category = app.getString(R.string.route_points) + " " + (index + 1);
|
||||
}
|
||||
} else {
|
||||
category = "";
|
||||
}
|
||||
List<GpxDisplayItem> items = itemsMap.get(category);
|
||||
if (items == null) {
|
||||
items = new ArrayList<>();
|
||||
itemsMap.put(category, items);
|
||||
}
|
||||
items.add(item);
|
||||
}
|
||||
return itemsMap;
|
||||
}
|
||||
|
||||
private Map<String, List<GpxDisplayItem>> filterItems(Map<String, List<GpxDisplayItem>> itemsMap, Set<?> filteredItems) {
|
||||
Map<String, List<GpxDisplayItem>> itemsMapFiltered = new HashMap<>();
|
||||
for (Entry<String, List<GpxDisplayItem>> e : itemsMap.entrySet()) {
|
||||
String category = e.getKey();
|
||||
List<GpxDisplayItem> items = e.getValue();
|
||||
if (filteredItems.contains(category)) {
|
||||
itemsMapFiltered.put(category, items);
|
||||
} else {
|
||||
for (GpxDisplayItem i : items) {
|
||||
if (filteredItems.contains(i)) {
|
||||
List<GpxDisplayItem> itemsFiltered = itemsMapFiltered.get(category);
|
||||
if (itemsFiltered == null) {
|
||||
itemsFiltered = new ArrayList<>();
|
||||
itemsMapFiltered.put(category, itemsFiltered);
|
||||
}
|
||||
itemsFiltered.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return itemsMapFiltered;
|
||||
}
|
||||
|
||||
private void setCollectedItems(GpxDisplayGroup group, Map<String, List<GpxDisplayItem>> itemsMap) {
|
||||
List<String> categories = new ArrayList<>(itemsMap.keySet());
|
||||
Collections.sort(categories, comparator);
|
||||
for (String category : categories) {
|
||||
List<GpxDisplayItem> values = itemsMap.get(category);
|
||||
GpxDisplayGroup headerGroup = group.cloneInstance();
|
||||
headerGroup.setName(category);
|
||||
for (GpxDisplayItem i : values) {
|
||||
if (i.locationStart != null && i.locationStart.getColor() != 0) {
|
||||
headerGroup.setColor(i.locationStart.getColor(group.getColor()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<GpxDisplayItem> headerGroupItems = headerGroup.getModifiableList();
|
||||
headerGroupItems.clear();
|
||||
headerGroupItems.addAll(values);
|
||||
itemGroups.put(headerGroup, values);
|
||||
this.groups.add(headerGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return groups.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GpxDisplayGroup getGroup(int groupPosition) {
|
||||
return groups.get(groupPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int groupPosition) {
|
||||
return groupPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int groupPosition) {
|
||||
return itemGroups.get(groups.get(groupPosition)).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GpxDisplayItem getChild(int groupPosition, int childPosition) {
|
||||
return itemGroups.get(groups.get(groupPosition)).get(childPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return groupPosition * 10000 + childPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
final GpxDisplayGroup group = getGroup(groupPosition);
|
||||
View row = convertView;
|
||||
if (row == null) {
|
||||
LayoutInflater inflater = LayoutInflater.from(view.getContext());
|
||||
row = inflater.inflate(R.layout.wpt_list_item, parent, false);
|
||||
}
|
||||
|
||||
row.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (listView.isGroupExpanded(groupPosition)) {
|
||||
listView.collapseGroup(groupPosition);
|
||||
} else {
|
||||
listView.expandGroup(groupPosition);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
String categoryName = group.getName();
|
||||
if (TextUtils.isEmpty(categoryName)) {
|
||||
categoryName = app.getString(R.string.shared_string_gpx_points);
|
||||
}
|
||||
SpannableStringBuilder text = new SpannableStringBuilder(categoryName)
|
||||
.append(" – ")
|
||||
.append(String.valueOf(getChildrenCount(groupPosition)));
|
||||
text.setSpan(new ForegroundColorSpan(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.wikivoyage_primary_text_color)),
|
||||
0, categoryName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
text.setSpan(new ForegroundColorSpan(ContextCompat.getColor(app, R.color.wikivoyage_secondary_text)),
|
||||
categoryName.length() + 1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
TextView title = row.findViewById(R.id.label);
|
||||
title.setText(text);
|
||||
|
||||
ImageView icon = row.findViewById(R.id.icon);
|
||||
icon.setImageDrawable(getContentIcon(R.drawable.ic_action_folder));
|
||||
|
||||
boolean expanded = listView.isGroupExpanded(groupPosition);
|
||||
ImageView expandImage = row.findViewById(R.id.expand_image);
|
||||
expandImage.setImageDrawable(getContentIcon(expanded ? R.drawable.ic_action_arrow_up : R.drawable.ic_action_arrow_down));
|
||||
|
||||
final CheckBox checkBox = (CheckBox) row.findViewById(R.id.toggle_item);
|
||||
if (selectionMode) {
|
||||
checkBox.setChecked(selectedGroups.contains(groupPosition));
|
||||
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
List<GpxDisplayItem> items = itemGroups.get(group);
|
||||
setGroupSelection(items, groupPosition, checkBox.isChecked());
|
||||
adapter.notifyDataSetInvalidated();
|
||||
updateSelectionMode();
|
||||
}
|
||||
});
|
||||
AndroidUiHelper.updateVisibility(checkBox, true);
|
||||
} else {
|
||||
AndroidUiHelper.updateVisibility(checkBox, false);
|
||||
}
|
||||
|
||||
ImageView options = (ImageView) row.findViewById(R.id.options);
|
||||
options.setImageDrawable(getContentIcon(R.drawable.ic_overflow_menu_white));
|
||||
options.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
EditTrackGroupDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
group, mapActivity.getTrackMenuFragment());
|
||||
}
|
||||
});
|
||||
|
||||
AndroidUiHelper.updateVisibility(expandImage, true);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.divider), true);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.description), false);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.list_divider), false);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.group_divider), true);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
View row = convertView;
|
||||
if (row == null) {
|
||||
LayoutInflater inflater = LayoutInflater.from(view.getContext());
|
||||
row = inflater.inflate(R.layout.wpt_list_item, parent, false);
|
||||
}
|
||||
|
||||
final GpxDisplayGroup group = getGroup(groupPosition);
|
||||
final GpxDisplayItem gpxItem = getChild(groupPosition, childPosition);
|
||||
|
||||
TextView title = row.findViewById(R.id.label);
|
||||
title.setText(gpxItem.name);
|
||||
|
||||
TextView description = row.findViewById(R.id.description);
|
||||
if (!Algorithms.isEmpty(gpxItem.description)) {
|
||||
description.setText(gpxItem.description);
|
||||
AndroidUiHelper.updateVisibility(description, true);
|
||||
} else {
|
||||
AndroidUiHelper.updateVisibility(description, false);
|
||||
}
|
||||
|
||||
final CheckBox checkBox = (CheckBox) row.findViewById(R.id.toggle_item);
|
||||
if (selectionMode) {
|
||||
checkBox.setVisibility(View.VISIBLE);
|
||||
checkBox.setChecked(selectedItems.get(group.getType()) != null && selectedItems.get(group.getType()).contains(gpxItem));
|
||||
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (checkBox.isChecked()) {
|
||||
Set<GpxDisplayItem> set = selectedItems.get(group.getType());
|
||||
if (set != null) {
|
||||
set.add(gpxItem);
|
||||
} else {
|
||||
set = new LinkedHashSet<>();
|
||||
set.add(gpxItem);
|
||||
selectedItems.put(group.getType(), set);
|
||||
}
|
||||
} else {
|
||||
Set<GpxDisplayItem> set = selectedItems.get(group.getType());
|
||||
if (set != null) {
|
||||
set.remove(gpxItem);
|
||||
}
|
||||
}
|
||||
updateSelectionMode();
|
||||
}
|
||||
});
|
||||
AndroidUiHelper.updateVisibility(checkBox, true);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.icon), false);
|
||||
} else {
|
||||
ImageView icon = row.findViewById(R.id.icon);
|
||||
if (GpxDisplayItemType.TRACK_POINTS == group.getType()) {
|
||||
WptPt wpt = gpxItem.locationStart;
|
||||
int groupColor = wpt.getColor(group.getColor());
|
||||
if (groupColor == 0) {
|
||||
groupColor = ContextCompat.getColor(app, R.color.gpx_color_point);
|
||||
}
|
||||
icon.setImageDrawable(PointImageDrawable.getFromWpt(app, groupColor, false, wpt));
|
||||
} else {
|
||||
icon.setImageDrawable(getContentIcon(R.drawable.ic_action_marker_dark));
|
||||
}
|
||||
AndroidUiHelper.updateVisibility(icon, true);
|
||||
AndroidUiHelper.updateVisibility(checkBox, false);
|
||||
}
|
||||
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.divider), false);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.options), false);
|
||||
AndroidUiHelper.updateVisibility(row.findViewById(R.id.list_divider), true);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
private void setGroupSelection(List<GpxDisplayItem> items, int groupPosition, boolean select) {
|
||||
GpxDisplayGroup group = groups.get(groupPosition);
|
||||
if (select) {
|
||||
selectedGroups.add(groupPosition);
|
||||
if (items != null) {
|
||||
Set<GpxDisplayItem> set = selectedItems.get(group.getType());
|
||||
if (set != null) {
|
||||
set.addAll(items);
|
||||
} else {
|
||||
set = new LinkedHashSet<>(items);
|
||||
selectedItems.put(group.getType(), set);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
selectedGroups.remove(groupPosition);
|
||||
selectedItems.remove(group.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
if (pointsFilter == null) {
|
||||
pointsFilter = new PointsFilter();
|
||||
}
|
||||
return pointsFilter;
|
||||
}
|
||||
|
||||
public void setFilterResults(Set<?> values) {
|
||||
this.filteredItems = values;
|
||||
}
|
||||
}
|
||||
|
||||
public class PointsFilter extends Filter {
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
FilterResults results = new FilterResults();
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
results.values = null;
|
||||
results.count = 1;
|
||||
} else {
|
||||
Set<Object> filter = new HashSet<>();
|
||||
String cs = constraint.toString().toLowerCase();
|
||||
List<GpxDisplayGroup> groups = getOriginalGroups();
|
||||
if (groups != null) {
|
||||
for (GpxDisplayGroup g : groups) {
|
||||
for (GpxDisplayItem i : g.getModifiableList()) {
|
||||
if (i.name.toLowerCase().contains(cs)) {
|
||||
filter.add(i);
|
||||
} else if (i.locationStart != null && !TextUtils.isEmpty(i.locationStart.category)
|
||||
&& i.locationStart.category.toLowerCase().contains(cs)) {
|
||||
filter.add(i.locationStart.category);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
results.values = filter;
|
||||
results.count = filter.size();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
synchronized (adapter) {
|
||||
adapter.setFilterResults((Set<?>) results.values);
|
||||
List<GpxDisplayGroup> groups = getOriginalGroups();
|
||||
if (groups != null) {
|
||||
adapter.synchronizeGroups(groups);
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
expandAllGroups();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,19 +6,20 @@ import android.view.View;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.TrackActivity;
|
||||
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
||||
import net.osmand.plus.mapcontextmenu.editors.RtePtEditor;
|
||||
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor;
|
||||
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener;
|
||||
import net.osmand.plus.track.TrackMenuFragment;
|
||||
import net.osmand.plus.views.layers.ContextMenuLayer;
|
||||
|
||||
public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
||||
|
@ -73,7 +74,7 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
|||
public void onClick(View v) {
|
||||
hide();
|
||||
contextMenuLayer.cancelAddGpxPoint();
|
||||
openTrackActivity();
|
||||
onClose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -140,7 +141,16 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
|||
if (contextMenu.isVisible() && contextMenu.isClosable()) {
|
||||
contextMenu.close();
|
||||
}
|
||||
openTrackActivity();
|
||||
onClose();
|
||||
}
|
||||
|
||||
private void onClose() {
|
||||
TrackMenuFragment fragment = mapActivity.getTrackMenuFragment();
|
||||
if (fragment != null) {
|
||||
fragment.show();
|
||||
} else {
|
||||
openTrackActivity();
|
||||
}
|
||||
}
|
||||
|
||||
private void openTrackActivity() {
|
||||
|
|
|
@ -574,7 +574,6 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
|||
public void cancelAddGpxPoint() {
|
||||
cancelApplyingNewMarkerPosition = true;
|
||||
quitAddGpxPoint();
|
||||
activity.getContextMenu().show();
|
||||
applyingMarkerLatLon = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
for (WptPt wpt : getListStarPoints(g)) {
|
||||
if (wpt.lat >= latLonBounds.bottom && wpt.lat <= latLonBounds.top
|
||||
&& wpt.lon >= latLonBounds.left && wpt.lon <= latLonBounds.right
|
||||
&& wpt != contextMenuLayer.getMoveableObject()) {
|
||||
&& wpt != contextMenuLayer.getMoveableObject() && !isPointHidden(g, wpt)) {
|
||||
pointFileMap.put(wpt, g);
|
||||
MapMarker marker = null;
|
||||
if (synced) {
|
||||
|
@ -777,6 +777,14 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
return g.getGpxFile().getPoints();
|
||||
}
|
||||
|
||||
private boolean isPointHidden(SelectedGpxFile selectedGpxFile, WptPt point) {
|
||||
if (!Algorithms.isEmpty(selectedGpxFile.getHiddenGroups())) {
|
||||
return selectedGpxFile.getHiddenGroups().contains(point.category);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
|
||||
return (Math.abs(objx - ex) <= radius && Math.abs(objy - ey) <= radius);
|
||||
}
|
||||
|
@ -790,6 +798,9 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
List<WptPt> pts = getListStarPoints(g);
|
||||
// int fcolor = g.getColor() == 0 ? clr : g.getColor();
|
||||
for (WptPt n : pts) {
|
||||
if (isPointHidden(g, n)) {
|
||||
continue;
|
||||
}
|
||||
int x = (int) tb.getPixXFromLatLon(n.lat, n.lon);
|
||||
int y = (int) tb.getPixYFromLatLon(n.lat, n.lon);
|
||||
if (calculateBelongs(ex, ey, x, y, r)) {
|
||||
|
|
Loading…
Reference in a new issue