From 97c248dc98f85ccd775a64115e172a466774209a Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Fri, 10 Nov 2017 14:25:38 +0200 Subject: [PATCH 01/28] Add gpx menu --- ...eader.xml => add_markers_group_header.xml} | 0 ..._marker_add_group_bottom_sheet_dialog.xml} | 10 +- ...ouritesGroupBottomSheetDialogFragment.java | 67 +-------- ...MarkersGroupBottomSheetDialogFragment.java | 68 +++++---- ...dTracksGroupBottomSheetDialogFragment.java | 138 ++++++++++++++++++ .../mapmarkers/MapMarkersGroupsFragment.java | 42 +++--- ...MarkersGroupBottomSheetDialogFragment.java | 75 ++++++++++ .../adapters/FavouritesGroupsAdapter.java | 43 +----- .../mapmarkers/adapters/GroupsAdapter.java | 58 ++++++++ .../adapters/TracksGroupsAdapter.java | 43 ++++++ 10 files changed, 391 insertions(+), 153 deletions(-) rename OsmAnd/res/layout/{add_favourites_group_header.xml => add_markers_group_header.xml} (100%) rename OsmAnd/res/layout/{fragment_marker_add_favourites_group_bottom_sheet_dialog.xml => fragment_marker_add_group_bottom_sheet_dialog.xml} (81%) create mode 100644 OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/mapmarkers/SelectionMarkersGroupBottomSheetDialogFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/mapmarkers/adapters/GroupsAdapter.java create mode 100644 OsmAnd/src/net/osmand/plus/mapmarkers/adapters/TracksGroupsAdapter.java diff --git a/OsmAnd/res/layout/add_favourites_group_header.xml b/OsmAnd/res/layout/add_markers_group_header.xml similarity index 100% rename from OsmAnd/res/layout/add_favourites_group_header.xml rename to OsmAnd/res/layout/add_markers_group_header.xml diff --git a/OsmAnd/res/layout/fragment_marker_add_favourites_group_bottom_sheet_dialog.xml b/OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml similarity index 81% rename from OsmAnd/res/layout/fragment_marker_add_favourites_group_bottom_sheet_dialog.xml rename to OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml index 3dd4b75cb7..3e6b37668a 100644 --- a/OsmAnd/res/layout/fragment_marker_add_favourites_group_bottom_sheet_dialog.xml +++ b/OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml @@ -6,12 +6,20 @@ android:orientation="vertical"> + + favoriteGroups; - private MapMarkersHelper mapMarkersHelper; - - public void setListener(AddFavouriteGroupListener listener) { - this.listener = listener; - } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); favoriteGroups = getMyApplication().getFavorites().getFavoriteGroups(); - mapMarkersHelper = getMyApplication().getMapMarkersHelper(); } - @Nullable @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; - final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_add_favourites_group_bottom_sheet_dialog, container); - - final RecyclerView recyclerView = mainView.findViewById(R.id.favourites_group_recycler_view); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - final FavouritesGroupsAdapter adapter = new FavouritesGroupsAdapter(getContext(), favoriteGroups); - adapter.setAdapterListener(new FavouritesGroupsAdapter.FavouritesGroupsAdapterListener() { - @Override - public void onItemClick(View view) { - int position = recyclerView.getChildAdapterPosition(view); - if (position == RecyclerView.NO_POSITION) { - return; - } - FavoriteGroup group = favoriteGroups.get(position - 1); - MarkersSyncGroup markersSyncGroup = new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color); - mapMarkersHelper.addMarkersSyncGroup(markersSyncGroup); - mapMarkersHelper.syncGroup(markersSyncGroup); - if (listener != null) { - listener.onFavouriteGroupAdded(); - } - dismiss(); - } - }); - recyclerView.setAdapter(adapter); - - mainView.findViewById(R.id.close_row).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - dismiss(); - } - }); - - setupHeightAndBackground(mainView, R.id.favourites_group_recycler_view); - - return mainView; + public MarkersSyncGroup createMapMarkersSyncGroup(int position) { + FavoriteGroup group = favoriteGroups.get(position - 1); + return new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color); } - public interface AddFavouriteGroupListener { - void onFavouriteGroupAdded(); + @Override + public void createAdapter() { + adapter = new FavouritesGroupsAdapter(getContext(), favoriteGroups); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java index 738ccf1766..fb5324a303 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java @@ -2,57 +2,64 @@ package net.osmand.plus.mapmarkers; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; +import net.osmand.plus.MapMarkersHelper; +import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup; import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.mapmarkers.adapters.GroupsAdapter; -public class AddMarkersGroupBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { +public abstract class AddMarkersGroupBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { - public final static String TAG = "AddMarkersGroupBottomSheetDialogFragment"; + public static final String TAG = "AddMarkersGroupBottomSheetDialogFragment"; - private AddMarkersGroupFragmentListener listener; + private AddGroupListener listener; + protected View mainView; + protected GroupsAdapter adapter; + protected MapMarkersHelper mapMarkersHelper; - public void setListener(AddMarkersGroupFragmentListener listener) { + public void setListener(AddGroupListener listener) { this.listener = listener; } + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mapMarkersHelper = getMyApplication().getMapMarkersHelper(); + } + @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; - final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_add_markers_group_bottom_sheet_dialog, container); + mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_add_group_bottom_sheet_dialog, container); - if (nightMode) { - ((TextView) mainView.findViewById(R.id.add_group_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark)); - } - - ((ImageView) mainView.findViewById(R.id.favourites_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_fav_dark)); - ((ImageView) mainView.findViewById(R.id.waypoints_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_polygom_dark)); - - mainView.findViewById(R.id.favourites_row).setOnClickListener(new View.OnClickListener() { + final RecyclerView recyclerView = mainView.findViewById(R.id.groups_recycler_view); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + createAdapter(); + adapter.setAdapterListener(new GroupsAdapter.GroupsAdapterListener() { @Override - public void onClick(View view) { + public void onItemClick(View view) { + int position = recyclerView.getChildAdapterPosition(view); + if (position == RecyclerView.NO_POSITION) { + return; + } + MarkersSyncGroup group = createMapMarkersSyncGroup(position); + mapMarkersHelper.addMarkersSyncGroup(group); + mapMarkersHelper.syncGroup(group); if (listener != null) { - listener.favouritesOnClick(); - } - dismiss(); - } - }); - mainView.findViewById(R.id.waypoints_row).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (listener != null) { - listener.waypointsOnClick(); + listener.onGroupAdded(); } dismiss(); } }); + recyclerView.setAdapter(adapter); mainView.findViewById(R.id.close_row).setOnClickListener(new View.OnClickListener() { @Override @@ -61,15 +68,16 @@ public class AddMarkersGroupBottomSheetDialogFragment extends MenuBottomSheetDia } }); - setupHeightAndBackground(mainView, R.id.add_markers_group_scroll_view); + setupHeightAndBackground(mainView, R.id.groups_recycler_view); return mainView; } - interface AddMarkersGroupFragmentListener { + protected abstract void createAdapter(); - void favouritesOnClick(); + protected abstract MarkersSyncGroup createMapMarkersSyncGroup(int position); - void waypointsOnClick(); + public interface AddGroupListener { + void onGroupAdded(); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java new file mode 100644 index 0000000000..82859e338a --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -0,0 +1,138 @@ +package net.osmand.plus.mapmarkers; + +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.ProgressBar; + +import net.osmand.AndroidUtils; +import net.osmand.IndexConstants; +import net.osmand.plus.GPXDatabase; +import net.osmand.plus.GPXDatabase.GpxDataItem; +import net.osmand.plus.GPXUtilities; +import net.osmand.plus.GPXUtilities.GPXFile; +import net.osmand.plus.GPXUtilities.GPXTrackAnalysis; +import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.mapmarkers.adapters.TracksGroupsAdapter; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AddTracksGroupBottomSheetDialogFragment extends AddMarkersGroupBottomSheetDialogFragment { + + private ProcessGpxTask asyncProcessor; + private List gpxList = new ArrayList<>(); + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + asyncProcessor = new ProcessGpxTask(); + asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + @Override + public void createAdapter() { + adapter = new TracksGroupsAdapter(getContext(), gpxList); + } + + @Override + public MarkersSyncGroup createMapMarkersSyncGroup(int position) { + GpxDataItem gpxDataItem = gpxList.get(position - 1); + File gpx = gpxDataItem.getFile(); + return new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (asyncProcessor != null) { + asyncProcessor.cancel(false); + asyncProcessor = null; + } + } + + public class ProcessGpxTask extends AsyncTask { + + private OsmandApplication app = getMyApplication(); + private Map processedDataFiles = new HashMap<>(); + private GPXDatabase db = app.getGpxDatabase(); + private ProgressBar progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar);; + private RecyclerView recyclerView = (RecyclerView) mainView.findViewById(R.id.groups_recycler_view); + + ProcessGpxTask() { + List dataItems = db.getItems(); + for (GpxDataItem item : dataItems) { + processedDataFiles.put(item.getFile(), item); + } + } + + @Override + protected void onPreExecute() { + recyclerView.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + } + + @Override + protected Void doInBackground(Void... params) { + File gpxPath = app.getAppPath(IndexConstants.GPX_INDEX_DIR); + if (gpxPath.canRead()) { + processGPXFolder(gpxPath, ""); + } + return null; + } + + private File[] listFilesSorted(File dir) { + File[] listFiles = dir.listFiles(); + if (listFiles == null) { + return new File[0]; + } + Arrays.sort(listFiles); + return listFiles; + } + + private void processGPXFolder(File gpxPath, String gpxSubfolder) { + for (File gpxFile : listFilesSorted(gpxPath)) { + if (gpxFile.isDirectory()) { + String sub = gpxSubfolder.length() == 0 ? + gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName(); + processGPXFolder(gpxFile, sub); + } else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) { + GpxDataItem item = processedDataFiles.get(gpxFile); + if (item == null || item.getFileLastModifiedTime() != gpxFile.lastModified()) { + GPXFile f = GPXUtilities.loadGPXFile(app, gpxFile); + GPXTrackAnalysis analysis = f.getAnalysis(gpxFile.lastModified()); + if (item == null) { + item = new GpxDataItem(gpxFile, analysis); + db.add(item); + } else { + db.updateAnalysis(item, analysis); + } + } + processedDataFiles.put(gpxFile, item); + if (item.getAnalysis().wptPoints > 0) { + gpxList.add(item); + } + } + if (isCancelled()) { + break; + } + } + } + + @Override + protected void onPostExecute(Void aVoid) { + asyncProcessor = null; + adapter.notifyDataSetChanged(); + progressBar.setVisibility(View.GONE); + recyclerView.setVisibility(View.VISIBLE); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index f6d7b732f3..e537f0ac98 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -35,8 +35,7 @@ import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.dashboard.DashLocationFragment; import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder; import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter; -import net.osmand.plus.mapmarkers.AddMarkersGroupBottomSheetDialogFragment.AddMarkersGroupFragmentListener; -import net.osmand.plus.mapmarkers.AddFavouritesGroupBottomSheetDialogFragment.AddFavouriteGroupListener; +import net.osmand.plus.mapmarkers.SelectionMarkersGroupBottomSheetDialogFragment.AddMarkersGroupFragmentListener; import net.osmand.plus.widgets.EmptyStateRecyclerView; import net.osmand.util.MapUtils; @@ -62,13 +61,13 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL final boolean night = !mapActivity.getMyApplication().getSettings().isLightContent(); mainView = inflater.inflate(R.layout.fragment_map_markers_groups, container, false); - Fragment addMarkersGroupFragment = getChildFragmentManager().findFragmentByTag(AddMarkersGroupBottomSheetDialogFragment.TAG); - if (addMarkersGroupFragment != null) { - ((AddMarkersGroupBottomSheetDialogFragment) addMarkersGroupFragment).setListener(createAddMarkersGroupFragmentListener()); + Fragment selectionMarkersGroupFragment = getChildFragmentManager().findFragmentByTag(SelectionMarkersGroupBottomSheetDialogFragment.TAG); + if (selectionMarkersGroupFragment != null) { + ((SelectionMarkersGroupBottomSheetDialogFragment) selectionMarkersGroupFragment).setListener(createAddMarkersGroupFragmentListener()); } - Fragment addFavouritesGroupFragment = getChildFragmentManager().findFragmentByTag(AddFavouritesGroupBottomSheetDialogFragment.TAG); - if (addFavouritesGroupFragment != null) { - ((AddFavouritesGroupBottomSheetDialogFragment) addFavouritesGroupFragment).setListener(createAddFavouritesGroupListener()); + Fragment addGroupFragment = getChildFragmentManager().findFragmentByTag(AddMarkersGroupBottomSheetDialogFragment.TAG); + if (addGroupFragment != null) { + ((AddMarkersGroupBottomSheetDialogFragment) addGroupFragment).setListener(createAddGroupListener()); } final EmptyStateRecyclerView recyclerView = (EmptyStateRecyclerView) mainView.findViewById(R.id.list); @@ -279,23 +278,22 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL } private void openAddGroupMenu() { - AddMarkersGroupBottomSheetDialogFragment fragment = new AddMarkersGroupBottomSheetDialogFragment(); + SelectionMarkersGroupBottomSheetDialogFragment fragment = new SelectionMarkersGroupBottomSheetDialogFragment(); fragment.setListener(createAddMarkersGroupFragmentListener()); fragment.setUsedOnMap(false); + fragment.show(getChildFragmentManager(), SelectionMarkersGroupBottomSheetDialogFragment.TAG); + } + + private void openAddGroupMenu(AddMarkersGroupBottomSheetDialogFragment fragment) { + fragment.setListener(createAddGroupListener()); + fragment.setUsedOnMap(false); fragment.show(getChildFragmentManager(), AddMarkersGroupBottomSheetDialogFragment.TAG); } - private void openAddFavouritesGroupMenu() { - AddFavouritesGroupBottomSheetDialogFragment fragment = new AddFavouritesGroupBottomSheetDialogFragment(); - fragment.setListener(createAddFavouritesGroupListener()); - fragment.setUsedOnMap(false); - fragment.show(getChildFragmentManager(), AddFavouritesGroupBottomSheetDialogFragment.TAG); - } - - private AddFavouriteGroupListener createAddFavouritesGroupListener() { - return new AddFavouriteGroupListener() { + private AddMarkersGroupBottomSheetDialogFragment.AddGroupListener createAddGroupListener() { + return new AddMarkersGroupBottomSheetDialogFragment.AddGroupListener() { @Override - public void onFavouriteGroupAdded() { + public void onGroupAdded() { updateAdapter(); } }; @@ -305,12 +303,14 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL return new AddMarkersGroupFragmentListener() { @Override public void favouritesOnClick() { - openAddFavouritesGroupMenu(); + AddFavouritesGroupBottomSheetDialogFragment fragment = new AddFavouritesGroupBottomSheetDialogFragment(); + openAddGroupMenu(fragment); } @Override public void waypointsOnClick() { - + AddTracksGroupBottomSheetDialogFragment fragment = new AddTracksGroupBottomSheetDialogFragment(); + openAddGroupMenu(fragment); } }; } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/SelectionMarkersGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/SelectionMarkersGroupBottomSheetDialogFragment.java new file mode 100644 index 0000000000..720cb2068e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/SelectionMarkersGroupBottomSheetDialogFragment.java @@ -0,0 +1,75 @@ +package net.osmand.plus.mapmarkers; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import net.osmand.plus.R; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; + +public class SelectionMarkersGroupBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { + + public final static String TAG = "SelectionMarkersGroupBottomSheetDialogFragment"; + + private AddMarkersGroupFragmentListener listener; + + public void setListener(AddMarkersGroupFragmentListener listener) { + this.listener = listener; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; + final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_add_markers_group_bottom_sheet_dialog, container); + + if (nightMode) { + ((TextView) mainView.findViewById(R.id.add_group_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark)); + } + + ((ImageView) mainView.findViewById(R.id.favourites_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_fav_dark)); + ((ImageView) mainView.findViewById(R.id.waypoints_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_polygom_dark)); + + mainView.findViewById(R.id.favourites_row).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (listener != null) { + listener.favouritesOnClick(); + } + dismiss(); + } + }); + mainView.findViewById(R.id.waypoints_row).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (listener != null) { + listener.waypointsOnClick(); + } + dismiss(); + } + }); + + mainView.findViewById(R.id.close_row).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + + setupHeightAndBackground(mainView, R.id.add_markers_group_scroll_view); + + return mainView; + } + + interface AddMarkersGroupFragmentListener { + + void favouritesOnClick(); + + void waypointsOnClick(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/FavouritesGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/FavouritesGroupsAdapter.java index 1ae1f03948..99f6fe9827 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/FavouritesGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/FavouritesGroupsAdapter.java @@ -14,43 +14,13 @@ import net.osmand.plus.R; import java.util.List; -public class FavouritesGroupsAdapter extends RecyclerView.Adapter { +public class FavouritesGroupsAdapter extends GroupsAdapter { - private static final int TYPE_HEADER = 12; - private static final int TYPE_ITEM = 13; - - private FavouritesGroupsAdapterListener listener; - private OsmandApplication app; private List favoriteGroups; - private IconsCache iconsCache; public FavouritesGroupsAdapter(Context context, List favoriteGroups) { - this.app = (OsmandApplication) context.getApplicationContext(); + super(context); this.favoriteGroups = favoriteGroups; - this.iconsCache = app.getIconsCache(); - } - - public void setAdapterListener(FavouritesGroupsAdapterListener listener) { - this.listener = listener; - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if (viewType == TYPE_HEADER) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_favourites_group_header, parent, false); - return new MapMarkersGroupHeaderViewHolder(view); - } else { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.markers_group_view_holder, parent, false); - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (listener != null) { - listener.onItemClick(view); - } - } - }); - return new MapMarkersGroupViewHolder(view); - } } @Override @@ -69,11 +39,6 @@ public class FavouritesGroupsAdapter extends RecyclerView.Adapter { + + private static final int TYPE_HEADER = 12; + private static final int TYPE_ITEM = 13; + + private GroupsAdapterListener listener; + protected OsmandApplication app; + protected IconsCache iconsCache; + + public GroupsAdapter(Context context) { + this.app = (OsmandApplication) context.getApplicationContext(); + this.iconsCache = app.getIconsCache(); + } + + public void setAdapterListener(GroupsAdapterListener listener) { + this.listener = listener; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == TYPE_HEADER) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_markers_group_header, parent, false); + return new MapMarkersGroupHeaderViewHolder(view); + } else { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.markers_group_view_holder, parent, false); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (listener != null) { + listener.onItemClick(view); + } + } + }); + return new MapMarkersGroupViewHolder(view); + } + } + + @Override + public int getItemViewType(int position) { + return position == 0 ? TYPE_HEADER : TYPE_ITEM; + } + + public interface GroupsAdapterListener { + void onItemClick(View view); + } +} diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/TracksGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/TracksGroupsAdapter.java new file mode 100644 index 0000000000..cce88139e2 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/TracksGroupsAdapter.java @@ -0,0 +1,43 @@ +package net.osmand.plus.mapmarkers.adapters; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; + +import net.osmand.plus.GPXDatabase.GpxDataItem; +import net.osmand.plus.R; + +import java.util.List; + +public class TracksGroupsAdapter extends GroupsAdapter { + + private List gpxFiles; + + public TracksGroupsAdapter(Context context, List gpxFiles) { + super(context); + this.gpxFiles = gpxFiles; + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (holder instanceof MapMarkersGroupHeaderViewHolder) { + MapMarkersGroupHeaderViewHolder markersGroupHeaderViewHolder = (MapMarkersGroupHeaderViewHolder) holder; + markersGroupHeaderViewHolder.title.setText(app.getText(R.string.shared_string_tracks)); + markersGroupHeaderViewHolder.description.setText(app.getText(R.string.add_track_to_markers_descr)); + } else if (holder instanceof MapMarkersGroupViewHolder) { + GpxDataItem gpx = getItem(position); + MapMarkersGroupViewHolder markersGroupViewHolder = (MapMarkersGroupViewHolder) holder; + markersGroupViewHolder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark)); + markersGroupViewHolder.name.setText(gpx.getFile().getName().replace(".gpx", "").replace("/", " ").replace("_", " ")); + markersGroupViewHolder.numberCount.setText(String.valueOf(gpx.getAnalysis().wptPoints)); + } + } + + @Override + public int getItemCount() { + return gpxFiles.size() + 1; + } + + private GpxDataItem getItem(int position) { + return gpxFiles.get(position - 1); + } +} From 5b3e6ac21d4255c45a3e394f4ca67c03d34c4814 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Fri, 10 Nov 2017 16:55:10 +0200 Subject: [PATCH 02/28] Scroll to group --- .../src/net/osmand/plus/MapMarkersHelper.java | 2 ++ .../osmand/plus/activities/MapActivity.java | 13 ++++++---- .../mapmarkers/MapMarkersDialogFragment.java | 24 ++++++++----------- .../mapmarkers/MapMarkersGroupsFragment.java | 13 ++++++++++ .../adapters/MapMarkersGroupsAdapter.java | 9 +++++++ .../plus/myplaces/TrackPointFragment.java | 6 +++-- 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 04ae6aedf3..b3db8f4940 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -188,6 +188,8 @@ public class MapMarkersHelper { public static final int FAVORITES_TYPE = 0; public static final int GPX_TYPE = 1; + public static final String MARKERS_SYNC_GROUP_ID = "markers_sync_group_id"; + private String id; private String name; private int type; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index ed948cdbac..d58f920948 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -60,6 +60,7 @@ import net.osmand.plus.AppInitializer.AppInitializeListener; import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.ApplicationMode; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; +import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener; import net.osmand.plus.OnDismissDialogFragmentListener; @@ -711,7 +712,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven } } if (intent.hasExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS)) { - MapMarkersDialogFragment.showInstance(this, true); + Bundle openMapMarkersGroupsExtra = intent.getBundleExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS); + if (openMapMarkersGroupsExtra != null) { + MapMarkersDialogFragment.showInstance(this, openMapMarkersGroupsExtra.getString(MapMarkersHelper.MarkersSyncGroup.MARKERS_SYNC_GROUP_ID)); + } + setIntent(null); } } mapView.refreshMap(true); @@ -1456,7 +1461,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return mapLayers; } - public static void launchMapActivityMoveToTop(Context activity, String intentExtraActionName) { + public static void launchMapActivityMoveToTop(Context activity, String intentExtraActionName, Bundle intentExtraActionValue) { if (activity instanceof MapActivity) { if (((MapActivity) activity).getDashboard().isVisible()) { ((MapActivity) activity).getDashboard().hideDashboard(); @@ -1479,14 +1484,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven .getAppCustomization().getMapActivity()); newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP); if (intentExtraActionName != null) { - newIntent.putExtra(intentExtraActionName, true); + newIntent.putExtra(intentExtraActionName, intentExtraActionValue); } activity.startActivity(newIntent); } } public static void launchMapActivityMoveToTop(Context activity) { - launchMapActivityMoveToTop(activity, null); + launchMapActivityMoveToTop(activity, null, null); } public static void clearPrevActivityIntent() { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java index 196f255e33..eafaccf9ca 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java @@ -54,6 +54,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm private LockableViewPager viewPager; private boolean lightTheme; + private String groupIdToOpen; @Override public void onCreate(Bundle savedInstanceState) { @@ -67,11 +68,6 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { - Bundle args = getArguments(); - boolean openGroups = false; - if (args != null && args.getBoolean(OPEN_MAP_MARKERS_GROUPS)) { - openGroups = true; - } List fragments = getChildFragmentManager().getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { @@ -158,10 +154,10 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm bottomNav.setItemIconTintList(ContextCompat.getColorStateList(getContext(), R.color.bottom_navigation_color_selector_dark)); bottomNav.setItemTextColor(ContextCompat.getColorStateList(getContext(), R.color.bottom_navigation_color_selector_dark)); } - if (openGroups) { + if (groupIdToOpen != null) { activeFragment.stopLocationUpdate(); groupsFragment.startLocationUpdate(); - groupsFragment.updateAdapter(); + groupsFragment.setGroupIdToOpen(groupIdToOpen); viewPager.setCurrentItem(GROUPS_POSITION, false); } bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @@ -209,6 +205,10 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm return mainView; } + private void setGroupIdToOpen(String groupIdToOpen) { + this.groupIdToOpen = groupIdToOpen; + } + private void updateAdapters() { activeFragment.updateAdapter(); groupsFragment.updateAdapter(); @@ -387,20 +387,16 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm } public static boolean showInstance(@NonNull MapActivity mapActivity) { - return showInstance(mapActivity, false); + return showInstance(mapActivity, null); } - public static boolean showInstance(@NonNull MapActivity mapActivity, boolean openGroups) { + public static boolean showInstance(@NonNull MapActivity mapActivity, String groupIdToOpen) { try { if (mapActivity.isActivityDestroyed()) { return false; } MapMarkersDialogFragment fragment = new MapMarkersDialogFragment(); - if (openGroups) { - Bundle args = new Bundle(); - args.putBoolean(OPEN_MAP_MARKERS_GROUPS, true); - fragment.setArguments(args); - } + fragment.setGroupIdToOpen(groupIdToOpen); fragment.show(mapActivity.getSupportFragmentManager(), TAG); return true; } catch (RuntimeException e) { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index e537f0ac98..7eb5bbb3c5 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -53,6 +53,7 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL private Snackbar snackbar; private boolean compassUpdateAllowed = true; private View mainView; + private String groupIdToOpen; @Nullable @Override @@ -270,9 +271,21 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL openAddGroupMenu(); } }); + + if (groupIdToOpen != null) { + int groupHeaderPosition = adapter.getGroupHeaderPosition(groupIdToOpen); + if (groupHeaderPosition != -1) { + ((EmptyStateRecyclerView) mainView.findViewById(R.id.list)).scrollToPosition(groupHeaderPosition); + } + } + return mainView; } + void setGroupIdToOpen(String groupIdToOpen) { + this.groupIdToOpen = groupIdToOpen; + } + private void changeFabVisibilityIfNeeded() { mainView.findViewById(R.id.add_group_fab).setVisibility(adapter.getItemCount() > 0 ? View.VISIBLE : View.GONE); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 51c05146ad..46e7389bb0 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -147,6 +147,15 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter Date: Fri, 10 Nov 2017 18:10:13 +0200 Subject: [PATCH 03/28] Load markers from selected gpx files on start up --- .../src/net/osmand/plus/AppInitializer.java | 1 + .../src/net/osmand/plus/MapMarkersHelper.java | 54 +++++++++++++------ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 53fb922d9f..a5bf7e7e4c 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -519,6 +519,7 @@ public class AppInitializer implements IProgress { indexRegionsBoundaries(warnings); notifyEvent(InitEvents.INDEX_REGION_BOUNDARIES); app.selectedGpxHelper.loadGPXTracks(this); + app.mapMarkersHelper.loadMapMarkersFromSelectedGpx(); notifyEvent(InitEvents.LOAD_GPX_TRACKS); saveGPXTracks(); notifyEvent(InitEvents.SAVE_GPX_TRACKS); diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index b3db8f4940..66e1fa3402 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -5,6 +5,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; +import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; @@ -371,6 +372,10 @@ public class MapMarkersHelper { } public void syncGroup(MarkersSyncGroup group) { + syncGroup(group, true); + } + + public void syncGroup(MarkersSyncGroup group, boolean enabled) { if (!isGroupSynced(group.getId())) { return; } @@ -391,7 +396,7 @@ public class MapMarkersHelper { } for (FavouritePoint fp : favGroup.points) { - addNewMarkerIfNeeded(group, dbMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName()); + addNewMarkerIfNeeded(group, dbMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), enabled); } removeOldMarkersIfNeeded(dbMarkers); @@ -414,14 +419,14 @@ public class MapMarkersHelper { int defColor = ContextCompat.getColor(ctx, R.color.marker_red); for (WptPt pt : gpxPoints) { group.setColor(pt.getColor(defColor)); - addNewMarkerIfNeeded(group, dbMarkers, new LatLon(pt.lat, pt.lon), pt.name); + addNewMarkerIfNeeded(group, dbMarkers, new LatLon(pt.lat, pt.lon), pt.name, enabled); } removeOldMarkersIfNeeded(dbMarkers); } } - private void addNewMarkerIfNeeded(MarkersSyncGroup group, List markers, LatLon latLon, String name) { + private void addNewMarkerIfNeeded(MarkersSyncGroup group, List markers, LatLon latLon, String name, boolean enabled) { boolean exists = false; for (MapMarker marker : markers) { @@ -443,7 +448,7 @@ public class MapMarkersHelper { if (!exists) { addMarkers(Collections.singletonList(latLon), - Collections.singletonList(new PointDescription(POINT_TYPE_MAP_MARKER, name)), group); + Collections.singletonList(new PointDescription(POINT_TYPE_MAP_MARKER, name)), group, enabled); } } @@ -485,7 +490,7 @@ public class MapMarkersHelper { mapMarkers.addAll(markers); reorderActiveMarkersIfNeeded(); for (MapMarker marker : markers) { - addMarkerToGroup(marker); + addMarkerToGroup(marker, true); } refresh(); } @@ -501,7 +506,7 @@ public class MapMarkersHelper { mapMarkers.add(marker); reorderActiveMarkersIfNeeded(); } - addMarkerToGroup(marker); + addMarkerToGroup(marker, true); refresh(); } } @@ -748,14 +753,14 @@ public class MapMarkersHelper { } public void addMapMarker(LatLon point, PointDescription historyName) { - addMarkers(Collections.singletonList(point), Collections.singletonList(historyName), null); + addMarkers(Collections.singletonList(point), Collections.singletonList(historyName), null, true); } public void addMapMarkers(List points, List historyNames, @Nullable MarkersSyncGroup group) { - addMarkers(points, historyNames, group); + addMarkers(points, historyNames, group, true); } - private void addMarkers(List points, List historyNames, @Nullable MarkersSyncGroup group) { + private void addMarkers(List points, List historyNames, @Nullable MarkersSyncGroup group, boolean enabled) { if (points.size() > 0) { int colorIndex = -1; for (int i = 0; i < points.size(); i++) { @@ -792,8 +797,10 @@ public class MapMarkersHelper { marker.history = false; marker.nextKey = MapMarkersDbHelper.TAIL_NEXT_VALUE; markersDbHelper.addMarker(marker); - mapMarkers.add(0, marker); - addMarkerToGroup(marker); + if (enabled) { + mapMarkers.add(0, marker); + } + addMarkerToGroup(marker, enabled); reorderActiveMarkersIfNeeded(); lookupAddress(marker); } @@ -990,7 +997,7 @@ public class MapMarkersHelper { } } - private void addMarkerToGroup(MapMarker marker) { + private void addMarkerToGroup(MapMarker marker, boolean enabled) { if (marker != null) { MapMarkersGroup mapMarkersGroup = getMapMarkerGroupByName(marker.groupName); if (mapMarkersGroup != null) { @@ -1000,9 +1007,13 @@ public class MapMarkersHelper { sortMarkers(mapMarkersGroup.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); } } else { - MapMarkersGroup group = createMapMarkerGroup(marker); - group.getMarkers().add(marker); - createHeaderAndHistoryButtonInGroup(group); + mapMarkersGroup = createMapMarkerGroup(marker); + mapMarkersGroup.getMarkers().add(marker); + createHeaderAndHistoryButtonInGroup(mapMarkersGroup); + } + if (!enabled) { + mapMarkersGroup.setDisabled(true); + updateGroupDisabled(mapMarkersGroup, true); } } } @@ -1103,6 +1114,19 @@ public class MapMarkersHelper { } } + public void loadMapMarkersFromSelectedGpx() { + List selectedGpxFiles = ctx.getSelectedGpxHelper().getSelectedGPXFiles(); + for (SelectedGpxFile selectedGpxFile : selectedGpxFiles) { + GPXFile gpx = selectedGpxFile.getGpxFile(); + if (gpx.getPoints().size() > 0) { + File gpxFile = new File(gpx.path); + final MarkersSyncGroup syncGroup = new MarkersSyncGroup(gpxFile.getAbsolutePath(), AndroidUtils.trimExtension(gpxFile.getName()), MarkersSyncGroup.GPX_TYPE); + addMarkersSyncGroup(syncGroup); + syncGroup(syncGroup, false); + } + } + } + private void sortGroups() { if (mapMarkersGroups.size() > 0) { MapMarkersGroup noGroup = null; From 9a1f029b8125b879cac26feea8d820f03da99fe6 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 10:39:29 +0200 Subject: [PATCH 04/28] Optimize adding disabled groups --- .../src/net/osmand/plus/MapMarkersHelper.java | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 66e1fa3402..9b8fe56d31 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -489,9 +489,7 @@ public class MapMarkersHelper { markersDbHelper.addMarkers(markers); mapMarkers.addAll(markers); reorderActiveMarkersIfNeeded(); - for (MapMarker marker : markers) { - addMarkerToGroup(marker, true); - } + addMarkersToGroups(markers, true); refresh(); } } @@ -506,7 +504,7 @@ public class MapMarkersHelper { mapMarkers.add(marker); reorderActiveMarkersIfNeeded(); } - addMarkerToGroup(marker, true); + addMarkerToGroup(marker); refresh(); } } @@ -763,6 +761,7 @@ public class MapMarkersHelper { private void addMarkers(List points, List historyNames, @Nullable MarkersSyncGroup group, boolean enabled) { if (points.size() > 0) { int colorIndex = -1; + List mapMarkers = new ArrayList<>(); for (int i = 0; i < points.size(); i++) { LatLon point = points.get(i); PointDescription historyName = historyNames.get(i); @@ -800,10 +799,11 @@ public class MapMarkersHelper { if (enabled) { mapMarkers.add(0, marker); } - addMarkerToGroup(marker, enabled); + mapMarkers.add(marker); reorderActiveMarkersIfNeeded(); lookupAddress(marker); } + addMarkersToGroups(mapMarkers, enabled); } } @@ -997,7 +997,23 @@ public class MapMarkersHelper { } } - private void addMarkerToGroup(MapMarker marker, boolean enabled) { + private void addMarkersToGroups(List markers, boolean enabled) { + List groups = new ArrayList<>(); + for (int i = 0; i < markers.size(); i++) { + MapMarkersGroup group = addMarkerToGroup(markers.get(i)); + if (group != null && !groups.contains(group)) { + groups.add(group); + } + } + if (!enabled) { + for (MapMarkersGroup mapMarkersGroup : groups) { + mapMarkersGroup.setDisabled(true); + updateGroupDisabled(mapMarkersGroup, true); + } + } + } + + private MapMarkersGroup addMarkerToGroup(MapMarker marker) { if (marker != null) { MapMarkersGroup mapMarkersGroup = getMapMarkerGroupByName(marker.groupName); if (mapMarkersGroup != null) { @@ -1011,11 +1027,9 @@ public class MapMarkersHelper { mapMarkersGroup.getMarkers().add(marker); createHeaderAndHistoryButtonInGroup(mapMarkersGroup); } - if (!enabled) { - mapMarkersGroup.setDisabled(true); - updateGroupDisabled(mapMarkersGroup, true); - } + return mapMarkersGroup; } + return null; } private MapMarkersGroup createMapMarkerGroup(MapMarker marker) { From 6995b695e77f60a1c425c75ae67fa7682277e362 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 10:54:52 +0200 Subject: [PATCH 05/28] Do not show elements of disabled group --- OsmAnd/res/layout/map_marker_item_header.xml | 6 ++++ .../adapters/MapMarkerHeaderViewHolder.java | 2 ++ .../adapters/MapMarkersGroupsAdapter.java | 28 +++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/layout/map_marker_item_header.xml b/OsmAnd/res/layout/map_marker_item_header.xml index e6665ec2f7..e8184ea870 100644 --- a/OsmAnd/res/layout/map_marker_item_header.xml +++ b/OsmAnd/res/layout/map_marker_item_header.xml @@ -46,4 +46,10 @@ + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java index d8748a8786..9d71f5f943 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java @@ -15,6 +15,7 @@ public class MapMarkerHeaderViewHolder extends RecyclerView.ViewHolder { final View iconSpace; final TextView title; final SwitchCompat disableGroupSwitch; + final View bottomShadow; public MapMarkerHeaderViewHolder(View itemView) { super(itemView); @@ -22,5 +23,6 @@ public class MapMarkerHeaderViewHolder extends RecyclerView.ViewHolder { iconSpace = itemView.findViewById(R.id.icon_space); title = (TextView) itemView.findViewById(R.id.title); disableGroupSwitch = (SwitchCompat) itemView.findViewById(R.id.disable_group_switch); + bottomShadow = itemView.findViewById(R.id.bottom_shadow); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 46e7389bb0..736d60bfa4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -134,14 +134,29 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter objectsToAdd = new ArrayList<>(); if (showHideHistoryButton != null && showHideHistoryButton.isShowHistory()) { - items.addAll(group.getMarkers()); + objectsToAdd.addAll(group.getMarkers()); } else { - items.addAll(group.getActiveMarkers()); + objectsToAdd.addAll(group.getActiveMarkers()); } if (showHideHistoryButton != null) { - items.add(showHideHistoryButton); + objectsToAdd.add(showHideHistoryButton); + } + items.addAll(position, objectsToAdd); + } else { + items.removeAll(group.getActiveMarkers()); + if (showHideHistoryButton != null) { + items.remove(showHideHistoryButton); } } } @@ -401,13 +416,13 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter Date: Mon, 13 Nov 2017 11:16:25 +0200 Subject: [PATCH 06/28] Fix updating history adapter --- .../plus/mapmarkers/MapMarkersHistoryFragment.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java index ec12497499..ff55189a38 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java @@ -265,11 +265,21 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel @Override public void onMapMarkerChanged(MapMarker mapMarker) { - updateAdapter(); + app.runInUIThread(new Runnable() { + @Override + public void run() { + updateAdapter(); + } + }); } @Override public void onMapMarkersChanged() { - updateAdapter(); + app.runInUIThread(new Runnable() { + @Override + public void run() { + updateAdapter(); + } + }); } } From 1bbe877ec057b64bfd6b7ef31b797cb7960a38ce Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 11:26:24 +0200 Subject: [PATCH 07/28] Rename fragment --- .../AddFavouritesGroupBottomSheetDialogFragment.java | 2 +- ...t.java => AddGroupBottomSheetDialogFragment.java} | 4 ++-- .../AddTracksGroupBottomSheetDialogFragment.java | 2 +- .../plus/mapmarkers/MapMarkersGroupsFragment.java | 12 ++++++------ 4 files changed, 10 insertions(+), 10 deletions(-) rename OsmAnd/src/net/osmand/plus/mapmarkers/{AddMarkersGroupBottomSheetDialogFragment.java => AddGroupBottomSheetDialogFragment.java} (93%) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java index 3a60b751b1..a49639ca31 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java @@ -8,7 +8,7 @@ import net.osmand.plus.mapmarkers.adapters.FavouritesGroupsAdapter; import java.util.List; -public class AddFavouritesGroupBottomSheetDialogFragment extends AddMarkersGroupBottomSheetDialogFragment { +public class AddFavouritesGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment { private List favoriteGroups; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java similarity index 93% rename from OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java rename to OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java index fb5324a303..753b95e14d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddMarkersGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java @@ -15,9 +15,9 @@ import net.osmand.plus.R; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.mapmarkers.adapters.GroupsAdapter; -public abstract class AddMarkersGroupBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { +public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { - public static final String TAG = "AddMarkersGroupBottomSheetDialogFragment"; + public static final String TAG = "AddGroupBottomSheetDialogFragment"; private AddGroupListener listener; protected View mainView; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java index 82859e338a..c89706abc4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class AddTracksGroupBottomSheetDialogFragment extends AddMarkersGroupBottomSheetDialogFragment { +public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment { private ProcessGpxTask asyncProcessor; private List gpxList = new ArrayList<>(); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index 7eb5bbb3c5..1942861a26 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -66,9 +66,9 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL if (selectionMarkersGroupFragment != null) { ((SelectionMarkersGroupBottomSheetDialogFragment) selectionMarkersGroupFragment).setListener(createAddMarkersGroupFragmentListener()); } - Fragment addGroupFragment = getChildFragmentManager().findFragmentByTag(AddMarkersGroupBottomSheetDialogFragment.TAG); + Fragment addGroupFragment = getChildFragmentManager().findFragmentByTag(AddGroupBottomSheetDialogFragment.TAG); if (addGroupFragment != null) { - ((AddMarkersGroupBottomSheetDialogFragment) addGroupFragment).setListener(createAddGroupListener()); + ((AddGroupBottomSheetDialogFragment) addGroupFragment).setListener(createAddGroupListener()); } final EmptyStateRecyclerView recyclerView = (EmptyStateRecyclerView) mainView.findViewById(R.id.list); @@ -297,14 +297,14 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL fragment.show(getChildFragmentManager(), SelectionMarkersGroupBottomSheetDialogFragment.TAG); } - private void openAddGroupMenu(AddMarkersGroupBottomSheetDialogFragment fragment) { + private void openAddGroupMenu(AddGroupBottomSheetDialogFragment fragment) { fragment.setListener(createAddGroupListener()); fragment.setUsedOnMap(false); - fragment.show(getChildFragmentManager(), AddMarkersGroupBottomSheetDialogFragment.TAG); + fragment.show(getChildFragmentManager(), AddGroupBottomSheetDialogFragment.TAG); } - private AddMarkersGroupBottomSheetDialogFragment.AddGroupListener createAddGroupListener() { - return new AddMarkersGroupBottomSheetDialogFragment.AddGroupListener() { + private AddGroupBottomSheetDialogFragment.AddGroupListener createAddGroupListener() { + return new AddGroupBottomSheetDialogFragment.AddGroupListener() { @Override public void onGroupAdded() { updateAdapter(); From 8280a0ed06182e1faea02d2ea529cf03b7aaf438 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 12:01:28 +0200 Subject: [PATCH 08/28] Fix making next marker active after disabling group --- .../osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 736d60bfa4..142493c4ed 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -417,6 +417,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter Date: Mon, 13 Nov 2017 12:34:50 +0200 Subject: [PATCH 09/28] Fix adding markers --- OsmAnd/src/net/osmand/plus/MapMarkersHelper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 9b8fe56d31..0c1b63d07c 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -761,7 +761,7 @@ public class MapMarkersHelper { private void addMarkers(List points, List historyNames, @Nullable MarkersSyncGroup group, boolean enabled) { if (points.size() > 0) { int colorIndex = -1; - List mapMarkers = new ArrayList<>(); + List addedMarkers = new ArrayList<>(); for (int i = 0; i < points.size(); i++) { LatLon point = points.get(i); PointDescription historyName = historyNames.get(i); @@ -799,11 +799,11 @@ public class MapMarkersHelper { if (enabled) { mapMarkers.add(0, marker); } - mapMarkers.add(marker); + addedMarkers.add(marker); reorderActiveMarkersIfNeeded(); lookupAddress(marker); } - addMarkersToGroups(mapMarkers, enabled); + addMarkersToGroups(addedMarkers, enabled); } } From 5818d2369a0f7a0f3244dc9c6ba5bdd3e52543aa Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 13:07:51 +0200 Subject: [PATCH 10/28] Select gpx file on creating group --- .../AddGroupBottomSheetDialogFragment.java | 49 ++++++++++++++++--- ...dTracksGroupBottomSheetDialogFragment.java | 9 ++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java index 753b95e14d..84757059f4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java @@ -1,5 +1,6 @@ package net.osmand.plus.mapmarkers; +import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; @@ -8,6 +9,7 @@ import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ProgressBar; import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup; @@ -23,6 +25,7 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD protected View mainView; protected GroupsAdapter adapter; protected MapMarkersHelper mapMarkersHelper; + private CreateGpxGroupTask createGpxGroupTask; public void setListener(AddGroupListener listener) { this.listener = listener; @@ -50,13 +53,8 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD if (position == RecyclerView.NO_POSITION) { return; } - MarkersSyncGroup group = createMapMarkersSyncGroup(position); - mapMarkersHelper.addMarkersSyncGroup(group); - mapMarkersHelper.syncGroup(group); - if (listener != null) { - listener.onGroupAdded(); - } - dismiss(); + createGpxGroupTask = new CreateGpxGroupTask(); + createGpxGroupTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, position); } }); recyclerView.setAdapter(adapter); @@ -73,6 +71,15 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD return mainView; } + @Override + public void onDestroyView() { + super.onDestroyView(); + if (createGpxGroupTask != null) { + createGpxGroupTask.cancel(true); + createGpxGroupTask = null; + } + } + protected abstract void createAdapter(); protected abstract MarkersSyncGroup createMapMarkersSyncGroup(int position); @@ -80,4 +87,32 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD public interface AddGroupListener { void onGroupAdded(); } + + public class CreateGpxGroupTask extends AsyncTask { + + private ProgressBar progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar);; + private RecyclerView recyclerView = (RecyclerView) mainView.findViewById(R.id.groups_recycler_view); + + @Override + protected void onPreExecute() { + recyclerView.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + } + + @Override + protected MarkersSyncGroup doInBackground(Integer... integers) { + return createMapMarkersSyncGroup(integers[0]); + } + + @Override + protected void onPostExecute(MarkersSyncGroup group) { + createGpxGroupTask = null; + mapMarkersHelper.addMarkersSyncGroup(group); + mapMarkersHelper.syncGroup(group); + if (listener != null) { + listener.onGroupAdded(); + } + dismiss(); + } + } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java index c89706abc4..018a152170 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -14,6 +14,8 @@ import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.GPXTrackAnalysis; +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -30,10 +32,12 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet private ProcessGpxTask asyncProcessor; private List gpxList = new ArrayList<>(); + private GpxSelectionHelper gpxSelectionHelper; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); + gpxSelectionHelper = getMyApplication().getSelectedGpxHelper(); asyncProcessor = new ProcessGpxTask(); asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -47,6 +51,11 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet public MarkersSyncGroup createMapMarkersSyncGroup(int position) { GpxDataItem gpxDataItem = gpxList.get(position - 1); File gpx = gpxDataItem.getFile(); + SelectedGpxFile selectedGpxFile = gpxSelectionHelper.getSelectedFileByPath(gpx.getAbsolutePath()); + if (selectedGpxFile == null) { + GPXFile res = GPXUtilities.loadGPXFile(getContext(), gpx); + gpxSelectionHelper.selectGpxFile(res, true, false); + } return new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE); } From 2cf3c2c254658106915d40c48bdcc81e98006569 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 13:14:21 +0200 Subject: [PATCH 11/28] Fix creating groups in background --- .../src/net/osmand/plus/MapMarkersHelper.java | 24 +++++++++++++------ .../mapmarkers/MapMarkersHistoryFragment.java | 14 ++--------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 0c1b63d07c..fa16f8abef 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -888,16 +888,26 @@ public class MapMarkersHelper { listeners.remove(l); } - private void refreshMarker(MapMarker marker) { - for (MapMarkerChangedListener l : listeners) { - l.onMapMarkerChanged(marker); - } + private void refreshMarker(final MapMarker marker) { + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + for (MapMarkerChangedListener l : listeners) { + l.onMapMarkerChanged(marker); + } + } + }); } private void refreshMarkers() { - for (MapMarkerChangedListener l : listeners) { - l.onMapMarkersChanged(); - } + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + for (MapMarkerChangedListener l : listeners) { + l.onMapMarkersChanged(); + } + } + }); } public void refresh() { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java index ff55189a38..ec12497499 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java @@ -265,21 +265,11 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel @Override public void onMapMarkerChanged(MapMarker mapMarker) { - app.runInUIThread(new Runnable() { - @Override - public void run() { - updateAdapter(); - } - }); + updateAdapter(); } @Override public void onMapMarkersChanged() { - app.runInUIThread(new Runnable() { - @Override - public void run() { - updateAdapter(); - } - }); + updateAdapter(); } } From d74e3da288797ce2bc8c725729f5394cf1f28b0f Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 13:33:40 +0200 Subject: [PATCH 12/28] Show on map favourite group --- ...ddFavouritesGroupBottomSheetDialogFragment.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java index a49639ca31..a609a61ac3 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java @@ -2,30 +2,32 @@ package net.osmand.plus.mapmarkers; import android.os.Bundle; +import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup; import net.osmand.plus.mapmarkers.adapters.FavouritesGroupsAdapter; -import java.util.List; - public class AddFavouritesGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment { - private List favoriteGroups; + private FavouritesDbHelper favouritesDbHelper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - favoriteGroups = getMyApplication().getFavorites().getFavoriteGroups(); + favouritesDbHelper = getMyApplication().getFavorites(); } @Override public MarkersSyncGroup createMapMarkersSyncGroup(int position) { - FavoriteGroup group = favoriteGroups.get(position - 1); + FavoriteGroup group = favouritesDbHelper.getFavoriteGroups().get(position - 1); + if (!group.visible) { + favouritesDbHelper.editFavouriteGroup(group, group.name, group.color, true); + } return new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color); } @Override public void createAdapter() { - adapter = new FavouritesGroupsAdapter(getContext(), favoriteGroups); + adapter = new FavouritesGroupsAdapter(getContext(), favouritesDbHelper.getFavoriteGroups()); } } From d914e6fd591737f2e0d08ca327bd96e28a1411db Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 13:39:37 +0200 Subject: [PATCH 13/28] Fix concurrent modification exception --- OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java b/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java index cfb8acd1e1..81122ba850 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java @@ -313,12 +313,17 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi widgetsFactory.updateInfo(useFingerLocation ? fingerLocation : (myLoc == null ? tileBox.getCenterLatLon() : new LatLon(myLoc.getLatitude(), myLoc.getLongitude())), tileBox.getZoom()); OsmandSettings settings = map.getMyApplication().getSettings(); - int displayedWidgets = settings.DISPLAYED_MARKERS_WIDGETS_COUNT.get(); if (tileBox.getZoom() < 3 || !settings.USE_MAP_MARKERS.get()) { return; } + if (map.getMyApplication().isApplicationInitializing()) { + return; + } + + int displayedWidgets = settings.DISPLAYED_MARKERS_WIDGETS_COUNT.get(); + MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper(); for (MapMarker marker : markersHelper.getMapMarkers()) { From 3ec1ccfde4f06e5e67977561760c89e6f38392a9 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 14:17:28 +0200 Subject: [PATCH 14/28] Fix exception --- .../plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 142493c4ed..9752d2b3cb 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -410,8 +410,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter Date: Mon, 13 Nov 2017 15:47:47 +0200 Subject: [PATCH 15/28] Fix modifying list --- .../src/net/osmand/plus/MapMarkersHelper.java | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index fa16f8abef..ba314ee86e 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -269,7 +269,7 @@ public class MapMarkersHelper { mapMarkersHistory.clear(); List activeMarkers = markersDbHelper.getActiveMarkers(); - mapMarkers.addAll(activeMarkers); + addToMapMarkersList(activeMarkers); reorderActiveMarkersIfNeeded(); List markersHistory = markersDbHelper.getMarkersHistory(); @@ -281,6 +281,32 @@ public class MapMarkersHelper { } } + private void removeFromMapMarkersList(MapMarker marker) { + List copyList = new ArrayList<>(); + copyList.remove(marker); + mapMarkers = copyList; + } + + private void addToMapMarkersList(MapMarker marker) { + addToMapMarkersList(mapMarkers.size(), marker); + } + + private void addToMapMarkersList(int position, MapMarker marker) { + List copyList = new ArrayList<>(mapMarkers); + copyList.add(position, marker); + mapMarkers = copyList; + } + + private void addToMapMarkersList(List markers) { + addToMapMarkersList(mapMarkers.size(), markers); + } + + private void addToMapMarkersList(int position, List markers) { + List copyList = new ArrayList<>(); + copyList.addAll(position, markers); + mapMarkers = copyList; + } + public void reorderActiveMarkersIfNeeded() { if (!mapMarkers.isEmpty()) { if (mapMarkers.size() > 1) { @@ -458,7 +484,7 @@ public class MapMarkersHelper { for (MapMarker marker : markers) { if (!marker.history) { markersDbHelper.removeMarker(marker, false); - mapMarkers.remove(marker); + removeFromMapMarkersList(marker); removeMarkerFromGroup(marker); needRefresh = true; } @@ -474,7 +500,7 @@ public class MapMarkersHelper { if (marker != null) { cancelPointAddressRequests(marker.point); markersDbHelper.moveMarkerToHistory(marker); - mapMarkers.remove(marker); + removeFromMapMarkersList(marker); marker.history = true; marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE; mapMarkersHistory.add(marker); @@ -487,7 +513,7 @@ public class MapMarkersHelper { public void addMarkers(List markers) { if (markers != null) { markersDbHelper.addMarkers(markers); - mapMarkers.addAll(markers); + addToMapMarkersList(markers); reorderActiveMarkersIfNeeded(); addMarkersToGroups(markers, true); refresh(); @@ -501,7 +527,7 @@ public class MapMarkersHelper { mapMarkersHistory.add(marker); sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); } else { - mapMarkers.add(marker); + addToMapMarkersList(marker); reorderActiveMarkersIfNeeded(); } addMarkerToGroup(marker); @@ -514,7 +540,7 @@ public class MapMarkersHelper { markersDbHelper.restoreMapMarkerFromHistory(marker); mapMarkersHistory.remove(marker); marker.history = false; - mapMarkers.add(position, marker); + addToMapMarkersList(position, marker); reorderActiveMarkersIfNeeded(); sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); refresh(); @@ -527,7 +553,7 @@ public class MapMarkersHelper { markersDbHelper.restoreMapMarkerFromHistory(marker); mapMarkersHistory.remove(marker); marker.history = false; - mapMarkers.add(marker); + addToMapMarkersList(marker); } reorderActiveMarkersIfNeeded(); sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); @@ -543,7 +569,7 @@ public class MapMarkersHelper { if (history) { mapMarkersHistory.remove(marker); } else { - mapMarkers.remove(marker); + removeFromMapMarkersList(marker); } removeMarkerFromGroup(marker); refresh(); @@ -619,7 +645,7 @@ public class MapMarkersHelper { } mapMarkers.removeAll(markersToRemove); - mapMarkers.addAll(0, markers); + addToMapMarkersList(0, markers); reorderActiveMarkersIfNeeded(); ctx.getSettings().MAP_MARKERS_ORDER_BY_MODE.set(OsmandSettings.MapMarkersOrderByMode.CUSTOM); } @@ -725,9 +751,9 @@ public class MapMarkersHelper { } } else { if (disabled) { - mapMarkers.remove(marker); + removeFromMapMarkersList(marker); } else { - mapMarkers.add(marker); + addToMapMarkersList(marker); } } } @@ -797,7 +823,7 @@ public class MapMarkersHelper { marker.nextKey = MapMarkersDbHelper.TAIL_NEXT_VALUE; markersDbHelper.addMarker(marker); if (enabled) { - mapMarkers.add(0, marker); + addToMapMarkersList(0, marker); } addedMarkers.add(marker); reorderActiveMarkersIfNeeded(); @@ -819,8 +845,8 @@ public class MapMarkersHelper { public void moveMarkerToTop(MapMarker marker) { int i = mapMarkers.indexOf(marker); if (i != -1 && mapMarkers.size() > 1) { - mapMarkers.remove(i); - mapMarkers.add(0, marker); + removeFromMapMarkersList(marker); + addToMapMarkersList(0, marker); reorderActiveMarkersIfNeeded(); refresh(); } From a19ffdb884008bd945a6deeb5b016d98af04e2c2 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 16:00:24 +0200 Subject: [PATCH 16/28] Fix modifying markers list --- OsmAnd/src/net/osmand/plus/MapMarkersHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index ba314ee86e..59c36a629d 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -282,7 +282,7 @@ public class MapMarkersHelper { } private void removeFromMapMarkersList(MapMarker marker) { - List copyList = new ArrayList<>(); + List copyList = new ArrayList<>(mapMarkers); copyList.remove(marker); mapMarkers = copyList; } @@ -302,7 +302,7 @@ public class MapMarkersHelper { } private void addToMapMarkersList(int position, List markers) { - List copyList = new ArrayList<>(); + List copyList = new ArrayList<>(mapMarkers); copyList.addAll(position, markers); mapMarkers = copyList; } From 2582fe79728b54ca95dc4d6ec48ba70fe543e5a7 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 16:08:14 +0200 Subject: [PATCH 17/28] Revert drawing in markers layer --- OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java b/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java index 81122ba850..65e2b40e11 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java @@ -318,10 +318,6 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi return; } - if (map.getMyApplication().isApplicationInitializing()) { - return; - } - int displayedWidgets = settings.DISPLAYED_MARKERS_WIDGETS_COUNT.get(); MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper(); From eb8fc8440213bc1c856556bddbe4576d635bf1c5 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 16:11:27 +0200 Subject: [PATCH 18/28] Fix string --- OsmAnd/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index fc0f61819f..392b86ae8c 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,7 +11,7 @@ --> Appearance on the map Select track waypoints of which OsmAnd will add to markers - Select which favourite group you want to add to markers + Select which favourite group you want to add to markers. We show only tracks with waypoints Track waypoints Favourites group Add group From f4023816c6b7fbec3a060cec1a478e2ee020768c Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 16:42:38 +0200 Subject: [PATCH 19/28] Show text when loading tracks --- ...t_marker_add_group_bottom_sheet_dialog.xml | 24 +++++++++++++++---- OsmAnd/res/values/strings.xml | 1 + ...dTracksGroupBottomSheetDialogFragment.java | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml b/OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml index 3e6b37668a..51a0820240 100644 --- a/OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml +++ b/OsmAnd/res/layout/fragment_marker_add_group_bottom_sheet_dialog.xml @@ -1,5 +1,7 @@ + android:clipToPadding="false" + android:paddingBottom="@dimen/bottom_sheet_content_padding_small"/> + android:visibility="gone" + tools:visibility="visible"/> + + + Looking for tracks with waypoints Appearance on the map Select track waypoints of which OsmAnd will add to markers Select which favourite group you want to add to markers. We show only tracks with waypoints diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java index 018a152170..5609ab4b5e 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -6,6 +6,7 @@ import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ProgressBar; +import android.widget.TextView; import net.osmand.AndroidUtils; import net.osmand.IndexConstants; @@ -75,6 +76,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet private GPXDatabase db = app.getGpxDatabase(); private ProgressBar progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar);; private RecyclerView recyclerView = (RecyclerView) mainView.findViewById(R.id.groups_recycler_view); + private TextView lookingForTracksText = (TextView) mainView.findViewById(R.id.looking_for_tracks_text); ProcessGpxTask() { List dataItems = db.getItems(); @@ -87,6 +89,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet protected void onPreExecute() { recyclerView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); + lookingForTracksText.setVisibility(View.VISIBLE); } @Override @@ -141,6 +144,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet asyncProcessor = null; adapter.notifyDataSetChanged(); progressBar.setVisibility(View.GONE); + lookingForTracksText.setVisibility(View.GONE); recyclerView.setVisibility(View.VISIBLE); } } From 7ce58add2dfe30745f7eb51de1b6c5da04ab62ea Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Mon, 13 Nov 2017 18:06:13 +0200 Subject: [PATCH 20/28] Fix creating group when selecting gpx --- .../src/net/osmand/plus/AppInitializer.java | 1 - .../net/osmand/plus/GpxSelectionHelper.java | 21 ++++++++++++++++--- .../src/net/osmand/plus/MapMarkersHelper.java | 19 +++++------------ .../plus/mapmarkers/MapMarkersDbHelper.java | 20 +++++++++++++++++- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index a5bf7e7e4c..53fb922d9f 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -519,7 +519,6 @@ public class AppInitializer implements IProgress { indexRegionsBoundaries(warnings); notifyEvent(InitEvents.INDEX_REGION_BOUNDARIES); app.selectedGpxHelper.loadGPXTracks(this); - app.mapMarkersHelper.loadMapMarkersFromSelectedGpx(); notifyEvent(InitEvents.LOAD_GPX_TRACKS); saveGPXTracks(); notifyEvent(InitEvents.SAVE_GPX_TRACKS); diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index ad5f87f476..b26783cd1d 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -482,7 +482,7 @@ public class GpxSelectionHelper { selectedGPXFiles.remove(sf); } } - syncGpx(gpx); + syncGpx(gpx, true); return sf; } @@ -514,10 +514,25 @@ public class GpxSelectionHelper { } private void syncGpx(GPXFile gpxFile) { + syncGpx(gpxFile, false); + } + + private void syncGpx(GPXFile gpxFile, boolean createOrDeleteGroup) { File gpx = new File(gpxFile.path); if (gpx.exists()) { - app.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(gpx.getAbsolutePath(), - AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE)); + MapMarkersHelper mapMarkersHelper = app.getMapMarkersHelper(); + MarkersSyncGroup syncGroup = new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE); + boolean enabled = true; + if (createOrDeleteGroup) { + boolean show = getSelectedFileByPath(gpx.getAbsolutePath()) != null; + enabled = mapMarkersHelper.isGroupSynced(gpx.getAbsolutePath()); + if (show && !enabled) { + mapMarkersHelper.addMarkersSyncGroup(syncGroup); + } else if (!show && mapMarkersHelper.isGroupDisabled(gpx.getAbsolutePath())) { + mapMarkersHelper.removeMarkersSyncGroup(gpx.getAbsolutePath(), true); + } + } + mapMarkersHelper.syncGroup(syncGroup, enabled); } } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 59c36a629d..3b70e6e63d 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -390,6 +390,10 @@ public class MapMarkersHelper { return markersDbHelper.getGroup(id) != null; } + public boolean isGroupDisabled(String id) { + return markersDbHelper.isGroupDisabled(id); + } + public void syncAllGroups() { List groups = markersDbHelper.getAllGroups(); for (MarkersSyncGroup gr : groups) { @@ -721,7 +725,7 @@ public class MapMarkersHelper { if (removeActiveMarkers) { removeActiveMarkersFromSyncGroup(id); } - MapMarkersGroup group = getMapMarkerGroupByName(id); + MapMarkersGroup group = getMapMarkerGroupByKey(id); if (group != null) { mapMarkersGroups.remove(group); } @@ -1164,19 +1168,6 @@ public class MapMarkersHelper { } } - public void loadMapMarkersFromSelectedGpx() { - List selectedGpxFiles = ctx.getSelectedGpxHelper().getSelectedGPXFiles(); - for (SelectedGpxFile selectedGpxFile : selectedGpxFiles) { - GPXFile gpx = selectedGpxFile.getGpxFile(); - if (gpx.getPoints().size() > 0) { - File gpxFile = new File(gpx.path); - final MarkersSyncGroup syncGroup = new MarkersSyncGroup(gpxFile.getAbsolutePath(), AndroidUtils.trimExtension(gpxFile.getName()), MarkersSyncGroup.GPX_TYPE); - addMarkersSyncGroup(syncGroup); - syncGroup(syncGroup, false); - } - } - } - private void sortGroups() { if (mapMarkersGroups.size() > 0) { MapMarkersGroup noGroup = null; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java index c9547abd33..fdb2b315ef 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java @@ -87,7 +87,8 @@ public class MapMarkersDbHelper { private static final String GROUPS_TABLE_SELECT = "SELECT " + GROUPS_COL_ID + ", " + GROUPS_COL_NAME + ", " + - GROUPS_COL_TYPE + + GROUPS_COL_TYPE + ", " + + GROUPS_COL_DISABLED + " FROM " + GROUPS_TABLE_NAME; public static final String TAIL_NEXT_VALUE = "tail_next"; @@ -275,6 +276,23 @@ public class MapMarkersDbHelper { } } + public boolean isGroupDisabled(String id) { + boolean disabled = false; + SQLiteConnection db = openConnection(true); + if (db != null) { + try { + SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT + " WHERE " + GROUPS_COL_ID + " = ?", new String[]{id}); + if (query.moveToFirst()) { + disabled = query.getInt(3) == 1; + } + query.close(); + } finally { + db.close(); + } + } + return disabled; + } + public void removeDisabledGroups() { SQLiteConnection db = openConnection(false); if (db != null) { From 4efaccc61c4bd949447ef96ecc7bf5d14a3f0e01 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Tue, 14 Nov 2017 13:32:10 +0200 Subject: [PATCH 21/28] Fix changing lists and fix adapters --- .../src/net/osmand/plus/MapMarkersHelper.java | 105 +++++++++++++----- .../mapmarkers/MapMarkersActiveFragment.java | 1 + .../mapmarkers/MapMarkersGroupsFragment.java | 4 - .../mapmarkers/MapMarkersHistoryFragment.java | 3 - .../adapters/MapMarkersActiveAdapter.java | 42 +++---- .../adapters/MapMarkersGroupsAdapter.java | 69 +----------- .../adapters/MapMarkersHistoryAdapter.java | 6 +- 7 files changed, 102 insertions(+), 128 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 3b70e6e63d..0ca7cadce2 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -5,7 +5,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; -import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; @@ -24,7 +23,6 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -265,8 +263,8 @@ public class MapMarkersHelper { } private void loadMarkers() { - mapMarkers.clear(); - mapMarkersHistory.clear(); + mapMarkers = new LinkedList<>(); + mapMarkersHistory = new LinkedList<>(); List activeMarkers = markersDbHelper.getActiveMarkers(); addToMapMarkersList(activeMarkers); @@ -274,15 +272,21 @@ public class MapMarkersHelper { List markersHistory = markersDbHelper.getMarkersHistory(); sortMarkers(markersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); - mapMarkersHistory.addAll(markersHistory); + addToMapMarkersHistoryList(markersHistory); if (!ctx.isApplicationInitializing()) { lookupAddressAll(); } } + private void removeFromMapMarkersList(List markers) { + List copyList = new LinkedList<>(mapMarkers); + copyList.removeAll(markers); + mapMarkers = copyList; + } + private void removeFromMapMarkersList(MapMarker marker) { - List copyList = new ArrayList<>(mapMarkers); + List copyList = new LinkedList<>(mapMarkers); copyList.remove(marker); mapMarkers = copyList; } @@ -292,7 +296,7 @@ public class MapMarkersHelper { } private void addToMapMarkersList(int position, MapMarker marker) { - List copyList = new ArrayList<>(mapMarkers); + List copyList = new LinkedList<>(mapMarkers); copyList.add(position, marker); mapMarkers = copyList; } @@ -302,11 +306,53 @@ public class MapMarkersHelper { } private void addToMapMarkersList(int position, List markers) { - List copyList = new ArrayList<>(mapMarkers); + List copyList = new LinkedList<>(mapMarkers); copyList.addAll(position, markers); mapMarkers = copyList; } + private void removeFromMapMarkersHistoryList(MapMarker marker) { + List copyList = new LinkedList<>(mapMarkersHistory); + copyList.remove(marker); + mapMarkersHistory = copyList; + } + + private void addToMapMarkersHistoryList(MapMarker marker) { + addToMapMarkersHistoryList(mapMarkersHistory.size(), marker); + } + + private void addToMapMarkersHistoryList(int position, MapMarker marker) { + List copyList = new LinkedList<>(mapMarkersHistory); + copyList.add(position, marker); + mapMarkersHistory = copyList; + } + + private void addToMapMarkersHistoryList(int position, List markers) { + List copyList = new LinkedList<>(mapMarkersHistory); + copyList.addAll(position, markers); + mapMarkersHistory = copyList; + } + + private void addToMapMarkersHistoryList(List markers) { + addToMapMarkersHistoryList(mapMarkersHistory.size(), markers); + } + + private void removeFromGroupsList(MapMarkersGroup group) { + List copyList = new ArrayList<>(mapMarkersGroups); + copyList.remove(group); + mapMarkersGroups = copyList; + } + + private void addToGroupsList(int position, MapMarkersGroup group) { + List copyList = new ArrayList<>(mapMarkersGroups); + copyList.add(position, group); + mapMarkersGroups = copyList; + } + + private void addToGroupsList(MapMarkersGroup group) { + addToGroupsList(mapMarkersGroups.size(), group); + } + public void reorderActiveMarkersIfNeeded() { if (!mapMarkers.isEmpty()) { if (mapMarkers.size() > 1) { @@ -507,7 +553,7 @@ public class MapMarkersHelper { removeFromMapMarkersList(marker); marker.history = true; marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE; - mapMarkersHistory.add(marker); + addToMapMarkersHistoryList(marker); reorderActiveMarkersIfNeeded(); sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); refresh(); @@ -528,7 +574,7 @@ public class MapMarkersHelper { if (marker != null) { markersDbHelper.addMarker(marker); if (marker.history) { - mapMarkersHistory.add(marker); + addToMapMarkersHistoryList(marker); sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); } else { addToMapMarkersList(marker); @@ -542,7 +588,7 @@ public class MapMarkersHelper { public void restoreMarkerFromHistory(MapMarker marker, int position) { if (marker != null) { markersDbHelper.restoreMapMarkerFromHistory(marker); - mapMarkersHistory.remove(marker); + removeFromMapMarkersHistoryList(marker); marker.history = false; addToMapMarkersList(position, marker); reorderActiveMarkersIfNeeded(); @@ -555,7 +601,7 @@ public class MapMarkersHelper { if (markers != null) { for (MapMarker marker : markers) { markersDbHelper.restoreMapMarkerFromHistory(marker); - mapMarkersHistory.remove(marker); + removeFromMapMarkersHistoryList(marker); marker.history = false; addToMapMarkersList(marker); } @@ -571,7 +617,7 @@ public class MapMarkersHelper { boolean history = marker.history; markersDbHelper.removeMarker(marker, history); if (history) { - mapMarkersHistory.remove(marker); + removeFromMapMarkersHistoryList(marker); } else { removeFromMapMarkersList(marker); } @@ -648,7 +694,7 @@ public class MapMarkersHelper { return; } - mapMarkers.removeAll(markersToRemove); + removeFromMapMarkersList(markersToRemove); addToMapMarkersList(0, markers); reorderActiveMarkersIfNeeded(); ctx.getSettings().MAP_MARKERS_ORDER_BY_MODE.set(OsmandSettings.MapMarkersOrderByMode.CUSTOM); @@ -696,8 +742,8 @@ public class MapMarkersHelper { marker.history = true; marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE; } - mapMarkersHistory.addAll(mapMarkers); - mapMarkers.clear(); + addToMapMarkersHistoryList(mapMarkers); + mapMarkers = new LinkedList<>(); sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); updateGroups(); refresh(); @@ -706,7 +752,7 @@ public class MapMarkersHelper { public void removeMarkersHistory() { cancelAddressRequests(); markersDbHelper.clearAllMarkersHistory(); - mapMarkersHistory.clear(); + mapMarkersHistory = new LinkedList<>(); refresh(); removeHistoryMarkersFromGroups(); } @@ -727,7 +773,7 @@ public class MapMarkersHelper { } MapMarkersGroup group = getMapMarkerGroupByKey(id); if (group != null) { - mapMarkersGroups.remove(group); + removeFromGroupsList(group); } } } @@ -749,9 +795,9 @@ public class MapMarkersHelper { for (MapMarker marker : groupMarkers) { if (marker.history) { if (disabled) { - mapMarkersHistory.remove(marker); + removeFromMapMarkersHistoryList(marker); } else { - mapMarkersHistory.add(marker); + addToMapMarkersHistoryList(marker); } } else { if (disabled) { @@ -769,10 +815,12 @@ public class MapMarkersHelper { public void removeActiveMarkersFromSyncGroup(String syncGroupId) { if (syncGroupId != null) { markersDbHelper.removeActiveMarkersFromSyncGroup(syncGroupId); - for (Iterator iterator = mapMarkers.iterator(); iterator.hasNext(); ) { - String groupKey = iterator.next().groupKey; + List copyList = new LinkedList<>(mapMarkers); + for (int i = 0; i < copyList.size(); i++) { + MapMarker marker = copyList.get(i); + String groupKey = marker.groupKey; if (groupKey != null && groupKey.equals(syncGroupId)) { - iterator.remove(); + removeFromMapMarkersList(marker); } } reorderActiveMarkersIfNeeded(); @@ -1020,7 +1068,7 @@ public class MapMarkersHelper { public void updateGroup(MapMarkersGroup mapMarkersGroup) { if (mapMarkersGroup.getMarkers().size() == 0) { - mapMarkersGroups.remove(mapMarkersGroup); + removeFromGroupsList(mapMarkersGroup); return; } int historyMarkersCount = mapMarkersGroup.getHistoryMarkers().size(); @@ -1086,7 +1134,7 @@ public class MapMarkersHelper { group.setColor(MapMarker.getColorId(marker.colorIndex)); } group.setCreationDate(marker.creationDate); - mapMarkersGroups.add(group); + addToGroupsList(group); sortGroups(); return group; } @@ -1159,7 +1207,7 @@ public class MapMarkersHelper { } mapMarkersGroups = new ArrayList<>(groupsMap.values()); if (noGroup != null) { - mapMarkersGroups.add(noGroup); + addToGroupsList(noGroup); } sortGroups(); @@ -1175,7 +1223,8 @@ public class MapMarkersHelper { MapMarkersGroup group = mapMarkersGroups.get(i); if (group.getName() == null) { sortMarkers(group.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); - noGroup = mapMarkersGroups.remove(i); + removeFromGroupsList(group); + noGroup = group; } } Collections.sort(mapMarkersGroups, new Comparator() { @@ -1193,7 +1242,7 @@ public class MapMarkersHelper { } }); if (noGroup != null) { - mapMarkersGroups.add(0, noGroup); + addToGroupsList(0, noGroup); } } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java index 052b775314..497b276212 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java @@ -159,6 +159,7 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL void updateAdapter() { if (adapter != null) { + adapter.changeMarkers(); adapter.notifyDataSetChanged(); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index 5ced9460a9..333d05f833 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -185,10 +185,6 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL int snackbarStringRes; if (direction == ItemTouchHelper.RIGHT) { mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory((MapMarker) item); - MapMarkersHelper.MapMarkersGroup group = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkerGroupByName(marker.groupName); - if (group != null) { - mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group); - } snackbarStringRes = R.string.marker_moved_to_history; } else { mapActivity.getMyApplication().getMapMarkersHelper().removeMarker((MapMarker) item); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java index ec12497499..9aa7991009 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java @@ -158,7 +158,6 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel app.getMapMarkersHelper().removeMarker((MapMarker) item); snackbarStringRes = R.string.item_removed; } - adapter.notifyItemRemoved(pos); snackbar = Snackbar.make(viewHolder.itemView, snackbarStringRes, Snackbar.LENGTH_LONG) .setAction(R.string.shared_string_undo, new View.OnClickListener() { @Override @@ -231,7 +230,6 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel Object item = adapter.getItem(pos); if (item instanceof MapMarker) { app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0); - adapter.notifyItemRemoved(pos); } } @@ -240,7 +238,6 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel Object item = adapter.getItem(pos); if (item instanceof MapMarker) { app.getMapMarkersHelper().removeMarker((MapMarker) item); - adapter.notifyItemRemoved(pos); } } }; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java index 440dd65334..09073a656b 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java @@ -42,6 +42,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter 1) { - notifyItemChanged(1); - } else if (position == getItemCount()) { - notifyItemChanged(position - 1); - } + changeMarkers(); + notifyDataSetChanged(); snackbar = Snackbar.make(holder.itemView, mapActivity.getString(R.string.marker_moved_to_history), Snackbar.LENGTH_LONG) .setAction(R.string.shared_string_undo, new View.OnClickListener() { @Override public void onClick(View view) { mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, position); - notifyItemInserted(position); - if (showDirectionEnabled && position < 2 && getItemCount() > 2) { - notifyItemChanged(2); - } else if (position == getItemCount() - 1) { - notifyItemChanged(position - 1); - } + changeMarkers(); + notifyDataSetChanged(); } }); View snackBarView = snackbar.getView(); @@ -218,6 +211,10 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter 1) { - notifyItemChanged(1); - } else if (pos == getItemCount()) { - notifyItemChanged(pos - 1); - } + changeMarkers(); + notifyDataSetChanged(); snackbar = Snackbar.make(holder.itemView, R.string.marker_moved_to_history, Snackbar.LENGTH_LONG) .setAction(R.string.shared_string_undo, new View.OnClickListener() { @Override public void onClick(View view) { mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, pos); - notifyItemInserted(pos); - if (showDirectionEnabled && pos < 2 && getItemCount() > 2) { - notifyItemChanged(2); - } else if (pos == getItemCount() - 1) { - notifyItemChanged(pos - 1); - } + changeMarkers(); + notifyDataSetChanged(); } }); View snackBarView = snackbar.getView(); @@ -270,6 +259,11 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter(); app.getMapMarkersHelper().updateGroups(); List groups = app.getMapMarkersHelper().getMapMarkersGroups(); for (int i = 0; i < groups.size(); i++) { @@ -291,8 +291,6 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter historyMarkers = showHideHistoryButton.getMapMarkerGroup().getHistoryMarkers(); - int pos = holder.getAdapterPosition(); - if (showHistory) { - showHideHistoryButton.setShowHistory(false); - items.removeAll(historyMarkers); - } else { - showHideHistoryButton.setShowHistory(true); - items.addAll(pos, historyMarkers); - } + showHideHistoryButton.setShowHistory(!showHistory); + createDisplayGroups(); notifyDataSetChanged(); } }); @@ -509,24 +468,6 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter markers = group.getActiveMarkers(); - int index = -1; - for (MapMarker marker : markers) { - int markerIndex = items.indexOf(marker); - if (markerIndex > index) { - index = markerIndex; - } - } - if (index == -1) { - GroupHeader header = group.getGroupHeader(); - if (header != null) { - index = items.indexOf(group.getGroupHeader()); - } - } - return index; - } - public interface MapMarkersGroupsAdapterListener { void onItemClick(View view); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java index ec1745c90a..66293a8cfa 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java @@ -43,10 +43,8 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter(); List markersHistory = app.getMapMarkersHelper().getMapMarkersHistory(); - int previousHeader = -1; int monthsDisplayed = 0; @@ -151,14 +149,12 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter Date: Tue, 14 Nov 2017 14:17:07 +0200 Subject: [PATCH 22/28] Run group synchronization in background --- .../src/net/osmand/plus/MapMarkersHelper.java | 98 ++++++++++++------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 0ca7cadce2..67471ea0ec 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -1,6 +1,7 @@ package net.osmand.plus; import android.content.Context; +import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; @@ -27,6 +28,8 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER; @@ -41,6 +44,7 @@ public class MapMarkersHelper { private OsmandApplication ctx; private MapMarkersDbHelper markersDbHelper; private boolean startFromMyLocation; + private ExecutorService executorService = Executors.newSingleThreadExecutor(); private MarkersPlanRouteContext planRouteContext; @@ -455,50 +459,68 @@ public class MapMarkersHelper { if (!isGroupSynced(group.getId())) { return; } - List dbMarkers = markersDbHelper.getMarkersFromGroup(group); + SyncGroupTask syncGroupTask = new SyncGroupTask(group, enabled); + syncGroupTask.executeOnExecutor(executorService); + } - if (group.getType() == MarkersSyncGroup.FAVORITES_TYPE) { - FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName()); - if (favGroup == null) { - return; - } - if (!favGroup.visible) { - removeActiveMarkersFromSyncGroup(group.getId()); - removeActiveMarkersFromGroup(group.getId()); - return; - } - if (group.getColor() == -1) { - group.setColor(favGroup.color); - } + private class SyncGroupTask extends AsyncTask { - for (FavouritePoint fp : favGroup.points) { - addNewMarkerIfNeeded(group, dbMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), enabled); - } + private MarkersSyncGroup group; + private boolean enabled; - removeOldMarkersIfNeeded(dbMarkers); - } else if (group.getType() == MarkersSyncGroup.GPX_TYPE) { - GpxSelectionHelper gpxHelper = ctx.getSelectedGpxHelper(); - File file = new File(group.getId()); - if (!file.exists()) { - return; - } + SyncGroupTask(MarkersSyncGroup group, boolean enabled) { + this.group = group; + this.enabled = enabled; + } - SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(group.getId()); - GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile(); - if (gpx == null) { - removeActiveMarkersFromSyncGroup(group.getId()); - removeActiveMarkersFromGroup(group.getId()); - return; - } + @Override + protected Void doInBackground(Void... voids) { + List dbMarkers = markersDbHelper.getMarkersFromGroup(group); - List gpxPoints = new LinkedList<>(gpx.getPoints()); - int defColor = ContextCompat.getColor(ctx, R.color.marker_red); - for (WptPt pt : gpxPoints) { - group.setColor(pt.getColor(defColor)); - addNewMarkerIfNeeded(group, dbMarkers, new LatLon(pt.lat, pt.lon), pt.name, enabled); - } + if (group.getType() == MarkersSyncGroup.FAVORITES_TYPE) { + FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName()); + if (favGroup == null) { + return null; + } + if (!favGroup.visible) { + removeActiveMarkersFromSyncGroup(group.getId()); + removeActiveMarkersFromGroup(group.getId()); + return null; + } + if (group.getColor() == -1) { + group.setColor(favGroup.color); + } - removeOldMarkersIfNeeded(dbMarkers); + for (FavouritePoint fp : favGroup.points) { + addNewMarkerIfNeeded(group, dbMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), enabled); + } + + removeOldMarkersIfNeeded(dbMarkers); + } else if (group.getType() == MarkersSyncGroup.GPX_TYPE) { + GpxSelectionHelper gpxHelper = ctx.getSelectedGpxHelper(); + File file = new File(group.getId()); + if (!file.exists()) { + return null; + } + + SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(group.getId()); + GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile(); + if (gpx == null) { + removeActiveMarkersFromSyncGroup(group.getId()); + removeActiveMarkersFromGroup(group.getId()); + return null; + } + + List gpxPoints = new LinkedList<>(gpx.getPoints()); + int defColor = ContextCompat.getColor(ctx, R.color.marker_red); + for (WptPt pt : gpxPoints) { + group.setColor(pt.getColor(defColor)); + addNewMarkerIfNeeded(group, dbMarkers, new LatLon(pt.lat, pt.lon), pt.name, enabled); + } + + removeOldMarkersIfNeeded(dbMarkers); + } + return null; } } From 20f161f30b3959920a45481176f1f1ed5de38597 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Tue, 14 Nov 2017 16:51:49 +0200 Subject: [PATCH 23/28] Fix updating ui after group sync --- .../net/osmand/plus/GpxSelectionHelper.java | 14 ++-- .../src/net/osmand/plus/MapMarkersHelper.java | 53 +++++++++++---- .../AddGroupBottomSheetDialogFragment.java | 64 ++++++++----------- ...dTracksGroupBottomSheetDialogFragment.java | 5 +- .../mapmarkers/MapMarkersGroupsFragment.java | 1 + 5 files changed, 81 insertions(+), 56 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index b26783cd1d..b0f8848307 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -392,7 +392,7 @@ public class GpxSelectionHelper { public void setGpxFileToDisplay(GPXFile... gpxs) { // special case for gpx current route for (GPXFile gpx : gpxs) { - selectGpxFileImpl(gpx, true, false); + selectGpxFileImpl(gpx, true, false, true); } saveCurrentSelections(); } @@ -458,7 +458,7 @@ public class GpxSelectionHelper { app.getSettings().SELECTED_GPX.set(ar.toString()); } - private SelectedGpxFile selectGpxFileImpl(GPXFile gpx, boolean show, boolean notShowNavigationDialog) { + private SelectedGpxFile selectGpxFileImpl(GPXFile gpx, boolean show, boolean notShowNavigationDialog, boolean syncGroup) { boolean displayed; SelectedGpxFile sf; if (gpx != null && gpx.showCurrentTrack) { @@ -482,12 +482,18 @@ public class GpxSelectionHelper { selectedGPXFiles.remove(sf); } } - syncGpx(gpx, true); + if (syncGroup) { + syncGpx(gpx, true); + } return sf; } public SelectedGpxFile selectGpxFile(GPXFile gpx, boolean show, boolean notShowNavigationDialog) { - SelectedGpxFile sf = selectGpxFileImpl(gpx, show, notShowNavigationDialog); + return selectGpxFile(gpx, show, notShowNavigationDialog, true); + } + + public SelectedGpxFile selectGpxFile(GPXFile gpx, boolean show, boolean notShowNavigationDialog, boolean syncGroup) { + SelectedGpxFile sf = selectGpxFileImpl(gpx, show, notShowNavigationDialog, syncGroup); saveCurrentSelections(); return sf; } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 67471ea0ec..7e999213d7 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -54,6 +54,10 @@ public class MapMarkersHelper { void onMapMarkersChanged(); } + public interface OnGroupSyncedListener { + void onSyncDone(); + } + public static class MapMarker implements LocationPoint { private static int[] colors; @@ -452,14 +456,19 @@ public class MapMarkersHelper { } public void syncGroup(MarkersSyncGroup group) { - syncGroup(group, true); + syncGroup(group, true, null); } public void syncGroup(MarkersSyncGroup group, boolean enabled) { - if (!isGroupSynced(group.getId())) { - return; - } - SyncGroupTask syncGroupTask = new SyncGroupTask(group, enabled); + syncGroup(group, enabled, null); + } + + public void syncGroup(MarkersSyncGroup group, OnGroupSyncedListener groupSyncedListener) { + syncGroup(group, true, groupSyncedListener); + } + + private void syncGroup(MarkersSyncGroup group, boolean enabled, OnGroupSyncedListener groupSyncedListener) { + SyncGroupTask syncGroupTask = new SyncGroupTask(group, enabled, groupSyncedListener); syncGroupTask.executeOnExecutor(executorService); } @@ -467,25 +476,37 @@ public class MapMarkersHelper { private MarkersSyncGroup group; private boolean enabled; + private OnGroupSyncedListener listener; - SyncGroupTask(MarkersSyncGroup group, boolean enabled) { + SyncGroupTask(MarkersSyncGroup group, boolean enabled, OnGroupSyncedListener listener) { this.group = group; this.enabled = enabled; + this.listener = listener; } @Override protected Void doInBackground(Void... voids) { + runGroupSynchronization(); + onGroupSynced(); + return null; + } + + private void runGroupSynchronization() { + if (!isGroupSynced(group.getId())) { + return; + } + List dbMarkers = markersDbHelper.getMarkersFromGroup(group); if (group.getType() == MarkersSyncGroup.FAVORITES_TYPE) { FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName()); if (favGroup == null) { - return null; + return; } if (!favGroup.visible) { removeActiveMarkersFromSyncGroup(group.getId()); removeActiveMarkersFromGroup(group.getId()); - return null; + return; } if (group.getColor() == -1) { group.setColor(favGroup.color); @@ -500,7 +521,7 @@ public class MapMarkersHelper { GpxSelectionHelper gpxHelper = ctx.getSelectedGpxHelper(); File file = new File(group.getId()); if (!file.exists()) { - return null; + return; } SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(group.getId()); @@ -508,7 +529,7 @@ public class MapMarkersHelper { if (gpx == null) { removeActiveMarkersFromSyncGroup(group.getId()); removeActiveMarkersFromGroup(group.getId()); - return null; + return; } List gpxPoints = new LinkedList<>(gpx.getPoints()); @@ -520,7 +541,17 @@ public class MapMarkersHelper { removeOldMarkersIfNeeded(dbMarkers); } - return null; + } + + private void onGroupSynced() { + if (listener != null) { + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + listener.onSyncDone(); + } + }); + } } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java index 84757059f4..d2beab227d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java @@ -1,5 +1,6 @@ package net.osmand.plus.mapmarkers; +import android.app.Dialog; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; @@ -25,7 +26,6 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD protected View mainView; protected GroupsAdapter adapter; protected MapMarkersHelper mapMarkersHelper; - private CreateGpxGroupTask createGpxGroupTask; public void setListener(AddGroupListener listener) { this.listener = listener; @@ -43,6 +43,14 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_add_group_bottom_sheet_dialog, container); + setupHeightAndBackground(mainView, R.id.groups_recycler_view); + + return mainView; + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); final RecyclerView recyclerView = mainView.findViewById(R.id.groups_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); createAdapter(); @@ -53,8 +61,18 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD if (position == RecyclerView.NO_POSITION) { return; } - createGpxGroupTask = new CreateGpxGroupTask(); - createGpxGroupTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, position); + mainView.findViewById(R.id.groups_recycler_view).setVisibility(View.GONE); + mainView.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); + MarkersSyncGroup group = createMapMarkersSyncGroup(position); + mapMarkersHelper.addMarkersSyncGroup(group); + mapMarkersHelper.syncGroup(group, new MapMarkersHelper.OnGroupSyncedListener() { + @Override + public void onSyncDone() { + if (listener != null) { + listener.onGroupAdded(); + } + } + }); } }); recyclerView.setAdapter(adapter); @@ -65,19 +83,15 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD dismiss(); } }); - - setupHeightAndBackground(mainView, R.id.groups_recycler_view); - - return mainView; } @Override public void onDestroyView() { - super.onDestroyView(); - if (createGpxGroupTask != null) { - createGpxGroupTask.cancel(true); - createGpxGroupTask = null; + Dialog dialog = getDialog(); + if (dialog != null && getRetainInstance()) { + dialog.setDismissMessage(null); } + super.onDestroyView(); } protected abstract void createAdapter(); @@ -87,32 +101,4 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD public interface AddGroupListener { void onGroupAdded(); } - - public class CreateGpxGroupTask extends AsyncTask { - - private ProgressBar progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar);; - private RecyclerView recyclerView = (RecyclerView) mainView.findViewById(R.id.groups_recycler_view); - - @Override - protected void onPreExecute() { - recyclerView.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - } - - @Override - protected MarkersSyncGroup doInBackground(Integer... integers) { - return createMapMarkersSyncGroup(integers[0]); - } - - @Override - protected void onPostExecute(MarkersSyncGroup group) { - createGpxGroupTask = null; - mapMarkersHelper.addMarkersSyncGroup(group); - mapMarkersHelper.syncGroup(group); - if (listener != null) { - listener.onGroupAdded(); - } - dismiss(); - } - } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java index 5609ab4b5e..6ca9ae0a9d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -32,11 +32,12 @@ import java.util.Map; public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment { private ProcessGpxTask asyncProcessor; - private List gpxList = new ArrayList<>(); + private List gpxList; private GpxSelectionHelper gpxSelectionHelper; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + gpxList = new ArrayList<>(); super.onViewCreated(view, savedInstanceState); gpxSelectionHelper = getMyApplication().getSelectedGpxHelper(); asyncProcessor = new ProcessGpxTask(); @@ -55,7 +56,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet SelectedGpxFile selectedGpxFile = gpxSelectionHelper.getSelectedFileByPath(gpx.getAbsolutePath()); if (selectedGpxFile == null) { GPXFile res = GPXUtilities.loadGPXFile(getContext(), gpx); - gpxSelectionHelper.selectGpxFile(res, true, false); + gpxSelectionHelper.selectGpxFile(res, true, false, false); } return new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index 333d05f833..375ccd8d84 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -295,6 +295,7 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL private void openAddGroupMenu(AddGroupBottomSheetDialogFragment fragment) { fragment.setListener(createAddGroupListener()); fragment.setUsedOnMap(false); + fragment.setRetainInstance(true); fragment.show(getChildFragmentManager(), AddGroupBottomSheetDialogFragment.TAG); } From 6ddd566964d4422e13e27c6040cfc817dd0f5419 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Tue, 14 Nov 2017 17:14:08 +0200 Subject: [PATCH 24/28] Close menu after creating group --- .../plus/mapmarkers/AddGroupBottomSheetDialogFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java index d2beab227d..2ee0404e3d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java @@ -71,6 +71,7 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD if (listener != null) { listener.onGroupAdded(); } + dismiss(); } }); } From 138740ea73e3fb665c2e9b7963dc106ac0ad3bf8 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Thu, 16 Nov 2017 15:59:03 +0200 Subject: [PATCH 25/28] Change sync method (cherry picked from commit 8ef2ce4) --- .../src/net/osmand/plus/AppInitializer.java | 2 +- .../net/osmand/plus/FavouritesDbHelper.java | 16 +++++----- .../net/osmand/plus/GpxSelectionHelper.java | 2 +- .../src/net/osmand/plus/MapMarkersHelper.java | 31 +++++++++++-------- .../EditFavoriteGroupDialogFragment.java | 8 +---- .../activities/FavoritesTreeFragment.java | 2 +- .../editors/WptPtEditorFragment.java | 2 +- .../AddGroupBottomSheetDialogFragment.java | 4 +-- .../plus/myplaces/TrackPointFragment.java | 4 +-- .../src/net/osmand/plus/views/GPXLayer.java | 2 +- 10 files changed, 35 insertions(+), 38 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 53fb922d9f..b988c7523f 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -522,7 +522,7 @@ public class AppInitializer implements IProgress { notifyEvent(InitEvents.LOAD_GPX_TRACKS); saveGPXTracks(); notifyEvent(InitEvents.SAVE_GPX_TRACKS); - app.mapMarkersHelper.syncAllGroups(); + app.mapMarkersHelper.syncAllGroupsAsync(); // restore backuped favorites to normal file restoreBackupForFavoritesFiles(); notifyEvent(InitEvents.RESTORE_BACKUPS); diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index f05f4db730..47635fa5f9 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -124,7 +124,7 @@ public class FavouritesDbHelper { cachedFavoritePoints.remove(p); } for (FavoriteGroup gr : groupsToSync) { - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE)); + context.getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE)); } } if (groupsToDelete != null) { @@ -147,7 +147,7 @@ public class FavouritesDbHelper { FavoriteGroup group = flatGroups.get(p.getCategory()); if (group != null) { group.points.remove(p); - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE)); + context.getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE)); } cachedFavoritePoints.remove(p); } @@ -177,7 +177,7 @@ public class FavouritesDbHelper { sortAll(); saveCurrentPointsIntoFile(); } - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color)); + context.getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color)); return true; } @@ -272,7 +272,7 @@ public class FavouritesDbHelper { } sortAll(); saveCurrentPointsIntoFile(); - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(category, category, MarkersSyncGroup.FAVORITES_TYPE, p.getColor())); + context.getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(category, category, MarkersSyncGroup.FAVORITES_TYPE, p.getColor())); return true; } @@ -280,7 +280,7 @@ public class FavouritesDbHelper { p.setLatitude(lat); p.setLongitude(lon); saveCurrentPointsIntoFile(); - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(p.getCategory(), p.getCategory(), MarkersSyncGroup.FAVORITES_TYPE, p.getColor())); + context.getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(p.getCategory(), p.getCategory(), MarkersSyncGroup.FAVORITES_TYPE, p.getColor())); return true; } @@ -597,7 +597,7 @@ public class FavouritesDbHelper { for (FavouritePoint p : gr.points) { p.setColor(color); } - markersHelper.syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE, color)); + markersHelper.syncGroupAsync(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE, color)); } if (group.visible != visible) { FavoriteGroup gr = flatGroups.get(group.name); @@ -605,7 +605,7 @@ public class FavouritesDbHelper { for (FavouritePoint p : gr.points) { p.setVisible(visible); } - markersHelper.syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE, group.color)); + markersHelper.syncGroupAsync(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE, group.color)); } if (!group.name.equals(newName)) { FavoriteGroup gr = flatGroups.remove(group.name); @@ -627,7 +627,7 @@ public class FavouritesDbHelper { } MarkersSyncGroup syncGroup = new MarkersSyncGroup(renamedGroup.name, renamedGroup.name, MarkersSyncGroup.FAVORITES_TYPE, group.color); markersHelper.addMarkersSyncGroup(syncGroup); - markersHelper.syncGroup(syncGroup); + markersHelper.syncGroupAsync(syncGroup); } saveCurrentPointsIntoFile(); } diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index b0f8848307..3225081c2f 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -538,7 +538,7 @@ public class GpxSelectionHelper { mapMarkersHelper.removeMarkersSyncGroup(gpx.getAbsolutePath(), true); } } - mapMarkersHelper.syncGroup(syncGroup, enabled); + mapMarkersHelper.syncGroupAsync(syncGroup, enabled); } } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 7e999213d7..7336268266 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -448,28 +448,33 @@ public class MapMarkersHelper { return markersDbHelper.isGroupDisabled(id); } - public void syncAllGroups() { + public void syncAllGroupsAsync() { List groups = markersDbHelper.getAllGroups(); for (MarkersSyncGroup gr : groups) { - syncGroup(gr); + syncGroupAsync(gr); } } - public void syncGroup(MarkersSyncGroup group) { - syncGroup(group, true, null); + public void syncGroupAsync(MarkersSyncGroup group) { + syncGroupAsync(group, true, null); } - public void syncGroup(MarkersSyncGroup group, boolean enabled) { - syncGroup(group, enabled, null); + public void syncGroupAsync(MarkersSyncGroup group, boolean enabled) { + syncGroupAsync(group, enabled, null); } - public void syncGroup(MarkersSyncGroup group, OnGroupSyncedListener groupSyncedListener) { - syncGroup(group, true, groupSyncedListener); + public void syncGroupAsync(MarkersSyncGroup group, OnGroupSyncedListener groupSyncedListener) { + syncGroupAsync(group, true, groupSyncedListener); } - private void syncGroup(MarkersSyncGroup group, boolean enabled, OnGroupSyncedListener groupSyncedListener) { - SyncGroupTask syncGroupTask = new SyncGroupTask(group, enabled, groupSyncedListener); - syncGroupTask.executeOnExecutor(executorService); + private void syncGroupAsync(final MarkersSyncGroup group, final boolean enabled, final OnGroupSyncedListener groupSyncedListener) { + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + SyncGroupTask syncGroupTask = new SyncGroupTask(group, enabled, groupSyncedListener); + syncGroupTask.executeOnExecutor(executorService); + } + }); } private class SyncGroupTask extends AsyncTask { @@ -487,7 +492,6 @@ public class MapMarkersHelper { @Override protected Void doInBackground(Void... voids) { runGroupSynchronization(); - onGroupSynced(); return null; } @@ -543,7 +547,8 @@ public class MapMarkersHelper { } } - private void onGroupSynced() { + @Override + protected void onPostExecute(Void aVoid) { if (listener != null) { ctx.runInUIThread(new Runnable() { @Override diff --git a/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java index a2af444f0f..d543ce8405 100644 --- a/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java @@ -23,9 +23,6 @@ import android.widget.ImageView; import android.widget.TextView; import net.osmand.AndroidUtils; -import net.osmand.data.FavouritePoint; -import net.osmand.data.LatLon; -import net.osmand.data.PointDescription; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.IconsCache; @@ -37,9 +34,6 @@ import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.helpers.ColorDialogs; import net.osmand.util.Algorithms; -import java.util.ArrayList; -import java.util.List; - public class EditFavoriteGroupDialogFragment extends BottomSheetDialogFragment { public static final String TAG = "EditFavoriteGroupDialogFragment"; @@ -188,7 +182,7 @@ public class EditFavoriteGroupDialogFragment extends BottomSheetDialogFragment { @Override public void onClick(View v) { markersHelper.addMarkersSyncGroup(syncGroup); - markersHelper.syncGroup(syncGroup); + markersHelper.syncGroupAsync(syncGroup); dismiss(); MapActivity.launchMapActivityMoveToTop(getActivity()); } diff --git a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java index 3dd0cdb6ec..e1cdd641c7 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java @@ -412,7 +412,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment { new MarkersSyncGroup(favGr.name, favGr.name, MarkersSyncGroup.FAVORITES_TYPE, favGr.color); if (entry.getValue().size() == favGr.points.size()) { markersHelper.addMarkersSyncGroup(syncGr); - markersHelper.syncGroup(syncGr); + markersHelper.syncGroupAsync(syncGr); } else { for (FavouritePoint fp : entry.getValue()) { points.add(new LatLon(fp.getLatitude(), fp.getLongitude())); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java index 2732b20ee0..8b01132b2f 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java @@ -180,7 +180,7 @@ public class WptPtEditorFragment extends PointEditorFragment { private void syncGpx(GPXFile gpxFile) { File gpx = new File(gpxFile.path); if (gpx.exists()) { - getMyApplication().getMapMarkersHelper().syncGroup(new MarkersSyncGroup(gpx.getAbsolutePath(), + getMyApplication().getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE)); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java index 2ee0404e3d..286c987719 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java @@ -1,7 +1,6 @@ package net.osmand.plus.mapmarkers; import android.app.Dialog; -import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; @@ -10,7 +9,6 @@ import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ProgressBar; import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup; @@ -65,7 +63,7 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD mainView.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); MarkersSyncGroup group = createMapMarkersSyncGroup(position); mapMarkersHelper.addMarkersSyncGroup(group); - mapMarkersHelper.syncGroup(group, new MapMarkersHelper.OnGroupSyncedListener() { + mapMarkersHelper.syncGroupAsync(group, new MapMarkersHelper.OnGroupSyncedListener() { @Override public void onSyncDone() { if (listener != null) { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java index 49a429a041..30508ec02d 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java @@ -580,7 +580,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment { private void syncGpx(GPXFile gpxFile) { File gpx = new File(gpxFile.path); if (gpx.exists()) { - app.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(gpx.getAbsolutePath(), + app.getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE)); } } @@ -635,7 +635,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment { final MarkersSyncGroup syncGroup = new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE); markersHelper.addMarkersSyncGroup(syncGroup); - markersHelper.syncGroup(syncGroup); + markersHelper.syncGroupAsync(syncGroup); GPXFile gpxFile = getTrackActivity().getGpx(); if (gpxFile != null) { app.getSelectedGpxHelper().selectGpxFile(gpxFile, true, false); diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index 944d8f5e90..e5f4b73fc9 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -643,7 +643,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex private void syncGpx(GPXFile gpxFile) { File gpx = new File(gpxFile.path); if (gpx.exists()) { - view.getApplication().getMapMarkersHelper().syncGroup(new MarkersSyncGroup(gpx.getAbsolutePath(), + view.getApplication().getMapMarkersHelper().syncGroupAsync(new MarkersSyncGroup(gpx.getAbsolutePath(), AndroidUtils.trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE)); } } From ef2217c6676faf71472bc59fd1c216e703e2978a Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Thu, 16 Nov 2017 18:35:12 +0200 Subject: [PATCH 26/28] Refactor --- .../AddGroupBottomSheetDialogFragment.java | 20 +++++++++---------- ...dTracksGroupBottomSheetDialogFragment.java | 11 +++++++--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java index 286c987719..9366dab18e 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddGroupBottomSheetDialogFragment.java @@ -41,14 +41,6 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_add_group_bottom_sheet_dialog, container); - setupHeightAndBackground(mainView, R.id.groups_recycler_view); - - return mainView; - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); final RecyclerView recyclerView = mainView.findViewById(R.id.groups_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); createAdapter(); @@ -59,8 +51,7 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD if (position == RecyclerView.NO_POSITION) { return; } - mainView.findViewById(R.id.groups_recycler_view).setVisibility(View.GONE); - mainView.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); + showProgressBar(); MarkersSyncGroup group = createMapMarkersSyncGroup(position); mapMarkersHelper.addMarkersSyncGroup(group); mapMarkersHelper.syncGroupAsync(group, new MapMarkersHelper.OnGroupSyncedListener() { @@ -82,6 +73,10 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD dismiss(); } }); + + setupHeightAndBackground(mainView, R.id.groups_recycler_view); + + return mainView; } @Override @@ -93,6 +88,11 @@ public abstract class AddGroupBottomSheetDialogFragment extends MenuBottomSheetD super.onDestroyView(); } + private void showProgressBar() { + mainView.findViewById(R.id.groups_recycler_view).setVisibility(View.GONE); + mainView.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); + } + protected abstract void createAdapter(); protected abstract MarkersSyncGroup createMapMarkersSyncGroup(int position); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java index 6ca9ae0a9d..dbb762b02d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -36,16 +36,21 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet private GpxSelectionHelper gpxSelectionHelper; @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - gpxList = new ArrayList<>(); - super.onViewCreated(view, savedInstanceState); + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); gpxSelectionHelper = getMyApplication().getSelectedGpxHelper(); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); asyncProcessor = new ProcessGpxTask(); asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @Override public void createAdapter() { + gpxList = new ArrayList<>(); adapter = new TracksGroupsAdapter(getContext(), gpxList); } From 5e1b3e053c9fcebed8d9fba682d18c83dea3a817 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Fri, 17 Nov 2017 11:43:40 +0200 Subject: [PATCH 27/28] Reorder drawer items --- .../plus/activities/MapActivityActions.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index abebe76293..08c96f6330 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -720,16 +720,6 @@ public class MapActivityActions implements DialogProvider { }).createItem()); */ - optionsMenuHelper.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.measurement_tool, mapActivity) - .setIcon(R.drawable.ic_action_ruler) - .setListener(new ContextMenuAdapter.ItemClickListener() { - @Override - public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int position, boolean isChecked) { - MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager()); - return true; - } - }).createItem()); - optionsMenuHelper.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.configure_map, mapActivity) .setIcon(R.drawable.ic_action_layers_dark) .setListener(new ContextMenuAdapter.ItemClickListener() { @@ -778,16 +768,12 @@ public class MapActivityActions implements DialogProvider { }).createItem()); } - optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.prefs_plugins, mapActivity) - .setIcon(R.drawable.ic_extension_dark) - .setListener(new ItemClickListener() { + optionsMenuHelper.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.measurement_tool, mapActivity) + .setIcon(R.drawable.ic_action_ruler) + .setListener(new ContextMenuAdapter.ItemClickListener() { @Override - public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked) { - app.logEvent(mapActivity, "drawer_plugins_open"); - Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization() - .getPluginsActivity()); - newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - mapActivity.startActivity(newIntent); + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int position, boolean isChecked) { + MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager()); return true; } }).createItem()); @@ -804,6 +790,20 @@ public class MapActivityActions implements DialogProvider { } }).createItem()); + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.prefs_plugins, mapActivity) + .setIcon(R.drawable.ic_extension_dark) + .setListener(new ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked) { + app.logEvent(mapActivity, "drawer_plugins_open"); + Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization() + .getPluginsActivity()); + newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + mapActivity.startActivity(newIntent); + return true; + } + }).createItem()); + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.shared_string_settings, mapActivity) .setIcon(R.drawable.ic_action_settings) .setListener(new ContextMenuAdapter.ItemClickListener() { @@ -850,7 +850,7 @@ public class MapActivityActions implements DialogProvider { // Place divider between functionality and configuration related menu items int dividerItemIndex = -1; for (int i = 0; i < optionsMenuHelper.length(); i++) { - if (optionsMenuHelper.getItem(i).getTitleId() == R.string.configure_map) { + if (optionsMenuHelper.getItem(i).getTitleId() == R.string.layer_map_appearance) { dividerItemIndex = i; break; } From bc0b15d444d502a2124c6aef5df6b5a60dafe961 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Fri, 17 Nov 2017 12:20:58 +0200 Subject: [PATCH 28/28] Add Empty State images for OSM Edits and Notes. --- .../ic_empty_state_av_notes_day.webp | Bin 0 -> 5090 bytes .../ic_empty_state_av_notes_night.webp | Bin 0 -> 5314 bytes .../ic_empty_state_osm_edits_day.webp | Bin 0 -> 5650 bytes .../ic_empty_state_osm_edits_night.webp | Bin 0 -> 5864 bytes .../ic_empty_state_av_notes_day.webp | Bin 0 -> 3538 bytes .../ic_empty_state_av_notes_night.webp | Bin 0 -> 3382 bytes .../ic_empty_state_osm_edits_day.webp | Bin 0 -> 3922 bytes .../ic_empty_state_osm_edits_night.webp | Bin 0 -> 3834 bytes .../ic_empty_state_av_notes_day.webp | Bin 0 -> 6912 bytes .../ic_empty_state_av_notes_night.webp | Bin 0 -> 6924 bytes .../ic_empty_state_osm_edits_day.webp | Bin 0 -> 7638 bytes .../ic_empty_state_osm_edits_night.webp | Bin 0 -> 7698 bytes .../ic_empty_state_av_notes_day.webp | Bin 0 -> 14424 bytes .../ic_empty_state_av_notes_night.webp | Bin 0 -> 14790 bytes .../ic_empty_state_osm_edits_day.webp | Bin 0 -> 14992 bytes .../ic_empty_state_osm_edits_night.webp | Bin 0 -> 16726 bytes 16 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 OsmAnd/res/drawable-hdpi/ic_empty_state_av_notes_day.webp create mode 100644 OsmAnd/res/drawable-hdpi/ic_empty_state_av_notes_night.webp create mode 100644 OsmAnd/res/drawable-hdpi/ic_empty_state_osm_edits_day.webp create mode 100644 OsmAnd/res/drawable-hdpi/ic_empty_state_osm_edits_night.webp create mode 100644 OsmAnd/res/drawable-mdpi/ic_empty_state_av_notes_day.webp create mode 100644 OsmAnd/res/drawable-mdpi/ic_empty_state_av_notes_night.webp create mode 100644 OsmAnd/res/drawable-mdpi/ic_empty_state_osm_edits_day.webp create mode 100644 OsmAnd/res/drawable-mdpi/ic_empty_state_osm_edits_night.webp create mode 100644 OsmAnd/res/drawable-xhdpi/ic_empty_state_av_notes_day.webp create mode 100644 OsmAnd/res/drawable-xhdpi/ic_empty_state_av_notes_night.webp create mode 100644 OsmAnd/res/drawable-xhdpi/ic_empty_state_osm_edits_day.webp create mode 100644 OsmAnd/res/drawable-xhdpi/ic_empty_state_osm_edits_night.webp create mode 100644 OsmAnd/res/drawable-xxhdpi/ic_empty_state_av_notes_day.webp create mode 100644 OsmAnd/res/drawable-xxhdpi/ic_empty_state_av_notes_night.webp create mode 100644 OsmAnd/res/drawable-xxhdpi/ic_empty_state_osm_edits_day.webp create mode 100644 OsmAnd/res/drawable-xxhdpi/ic_empty_state_osm_edits_night.webp diff --git a/OsmAnd/res/drawable-hdpi/ic_empty_state_av_notes_day.webp b/OsmAnd/res/drawable-hdpi/ic_empty_state_av_notes_day.webp new file mode 100644 index 0000000000000000000000000000000000000000..551b6f0ef77bf39cb15ccea3bb5f0779e4317349 GIT binary patch literal 5090 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 Edx0VEz5oCK literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-hdpi/ic_empty_state_av_notes_night.webp b/OsmAnd/res/drawable-hdpi/ic_empty_state_av_notes_night.webp new file mode 100644 index 0000000000000000000000000000000000000000..6f265d57f8f8f9dd5105d4caf0bdeb6ac155f91b GIT binary patch literal 5314 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 literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-hdpi/ic_empty_state_osm_edits_night.webp b/OsmAnd/res/drawable-hdpi/ic_empty_state_osm_edits_night.webp new file mode 100644 index 0000000000000000000000000000000000000000..bcefe20c207d69177f16f7f746bd653df599408d GIT binary patch literal 5864 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 literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-mdpi/ic_empty_state_av_notes_day.webp b/OsmAnd/res/drawable-mdpi/ic_empty_state_av_notes_day.webp new file mode 100644 index 0000000000000000000000000000000000000000..66eac11d7a3b9bda57fb2586e6f426ac403e5d1f GIT binary patch literal 3538 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 Me(|^F#Y^i100TP5&Hw-a literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-mdpi/ic_empty_state_av_notes_night.webp b/OsmAnd/res/drawable-mdpi/ic_empty_state_av_notes_night.webp new file mode 100644 index 0000000000000000000000000000000000000000..198b2559cf4667527ce7a4f08b7b5ec488866387 GIT binary patch literal 3382 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 literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-mdpi/ic_empty_state_osm_edits_night.webp b/OsmAnd/res/drawable-mdpi/ic_empty_state_osm_edits_night.webp new file mode 100644 index 0000000000000000000000000000000000000000..2b179ecd540521bc62a453b8097b3fa141c139d0 GIT binary patch literal 3834 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 literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-xhdpi/ic_empty_state_av_notes_day.webp b/OsmAnd/res/drawable-xhdpi/ic_empty_state_av_notes_day.webp new file mode 100644 index 0000000000000000000000000000000000000000..1499879b5a5a3b5698ffbbe069aefded82f5361a GIT binary patch literal 6912 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 GM!N)qS~ws8 literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-xhdpi/ic_empty_state_av_notes_night.webp b/OsmAnd/res/drawable-xhdpi/ic_empty_state_av_notes_night.webp new file mode 100644 index 0000000000000000000000000000000000000000..01e7f61f026c54650cc52c135fb67cdc197b0977 GIT binary patch literal 6924 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 M71*Av_R?Gc0QqX(761SM literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-xxhdpi/ic_empty_state_av_notes_day.webp b/OsmAnd/res/drawable-xxhdpi/ic_empty_state_av_notes_day.webp new file mode 100644 index 0000000000000000000000000000000000000000..52383453a5e3171368cc3e349c0475bf395e6bbb GIT binary patch literal 14424 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 literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-xxhdpi/ic_empty_state_av_notes_night.webp b/OsmAnd/res/drawable-xxhdpi/ic_empty_state_av_notes_night.webp new file mode 100644 index 0000000000000000000000000000000000000000..7acf169e60d2d486aaf2fdfbcb46a0e0c6aec4b8 GIT binary patch literal 14790 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 literal 0 HcmV?d00001