diff --git a/OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml b/OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml
new file mode 100644
index 0000000000..07406ae2c7
--- /dev/null
+++ b/OsmAnd/res/drawable/ic_action_sort_by_name_ascending.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml b/OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml
new file mode 100644
index 0000000000..04cd095335
--- /dev/null
+++ b/OsmAnd/res/drawable/ic_action_sort_by_name_descending.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/values/styles.xml b/OsmAnd/res/values/styles.xml
index 35f24529e1..e52dbdfd56 100644
--- a/OsmAnd/res/values/styles.xml
+++ b/OsmAnd/res/values/styles.xml
@@ -551,11 +551,11 @@
- @null
-
-
diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java b/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java
index 01caa18083..00bb1e218b 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/GpxTrackAdapter.java
@@ -34,14 +34,17 @@ public class GpxTrackAdapter extends RecyclerView.Adapter gpxInfoList;
- private boolean showCurrentGpx;
private OnItemClickListener onItemClickListener;
- public GpxTrackAdapter(Context ctx, List gpxInfoList, boolean showCurrentGpx) {
+ private boolean showFolderName;
+ private boolean showCurrentGpx;
+
+ public GpxTrackAdapter(Context ctx, List gpxInfoList, boolean showCurrentGpx, boolean showFolderName) {
app = (OsmandApplication) ctx.getApplicationContext();
themedInflater = UiUtilities.getInflater(ctx, app.getDaynightHelper().isNightModeForMapControls());
iconsCache = app.getUIUtilities();
this.gpxInfoList = gpxInfoList;
+ this.showFolderName = showFolderName;
this.showCurrentGpx = showCurrentGpx;
}
@@ -57,6 +60,10 @@ public class GpxTrackAdapter extends RecyclerView.Adapter ind * 2 + 1) {
pt.ele = pf[ind * 2 + 1];
+
}
pt.lat = l.getLatitude();
pt.lon = l.getLongitude();
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java
index c82bc1e9d5..2bb0c2e7c5 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java
@@ -64,6 +64,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
private Map> gpxInfoMap;
private Mode fragmentMode;
private String selectedFolder;
+ private String allFilesFolder;
public void setFragmentMode(Mode fragmentMode) {
this.fragmentMode = fragmentMode;
@@ -91,7 +92,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
final File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
collectDirs(gpxDir, dirs);
List dirItems = new ArrayList<>();
- String allFilesFolder = context.getString(R.string.shared_string_all);
+ allFilesFolder = context.getString(R.string.shared_string_all);
if (savedInstanceState == null) {
selectedFolder = allFilesFolder;
}
@@ -116,7 +117,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
gpxList.add(gpxInfo);
}
- adapter = new GpxTrackAdapter(requireContext(), allGpxList, isShowCurrentGpx());
+ adapter = new GpxTrackAdapter(requireContext(), allGpxList, isShowCurrentGpx(), showFoldersName());
adapter.setAdapterListener(new OnItemClickListener() {
@Override
public void onItemClick(int position) {
@@ -157,11 +158,16 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
private void updateFileList(String folderName, HorizontalSelectionAdapter folderAdapter) {
List gpxInfoList = gpxInfoMap.get(folderName);
+ adapter.setShowFolderName(showFoldersName());
adapter.setGpxInfoList(gpxInfoList != null ? gpxInfoList : new ArrayList());
adapter.notifyDataSetChanged();
folderAdapter.notifyDataSetChanged();
}
+ private boolean showFoldersName() {
+ return allFilesFolder.equals(selectedFolder);
+ }
+
private boolean isShowCurrentGpx() {
return fragmentMode == Mode.ADD_TO_TRACK;
}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java
index 666fe4f0a6..b81b015f32 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java
@@ -128,7 +128,7 @@ public class StartPlanRouteBottomSheet extends BottomSheetBehaviourDialogFragmen
}
});
final List gpxTopList = gpxList.subList(0, Math.min(5, gpxList.size()));
- adapter = new GpxTrackAdapter(requireContext(), gpxTopList, false);
+ adapter = new GpxTrackAdapter(requireContext(), gpxTopList, false, true);
adapter.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
index 6e862b5d4b..8432080bc8 100644
--- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
+++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java
@@ -37,6 +37,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
+import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@@ -102,7 +103,11 @@ import java.util.regex.Pattern;
import static net.osmand.plus.GpxSelectionHelper.CURRENT_TRACK;
import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB;
import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID;
-import static net.osmand.util.Algorithms.*;
+import static net.osmand.util.Algorithms.capitalizeFirstLetter;
+import static net.osmand.util.Algorithms.collectDirs;
+import static net.osmand.util.Algorithms.formatDuration;
+import static net.osmand.util.Algorithms.objectEquals;
+import static net.osmand.util.Algorithms.removeAllFiles;
public class AvailableGPXFragment extends OsmandExpandableListFragment implements
FavoritesFragmentStateHolder {
@@ -129,6 +134,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
private boolean importing = false;
private View emptyView;
private GpxSelectionHelper.SelectGpxTaskListener gpxTaskListener;
+ private boolean sortByName;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -157,6 +163,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
public void onAttach(Context activity) {
super.onAttach(activity);
this.app = (OsmandApplication) getActivity().getApplication();
+ sortByName = app.getSettings().SORT_TRACKS_BY_NAME.get();
final Collator collator = Collator.getInstance();
collator.setStrength(Collator.SECONDARY);
currentRecording = new GpxInfo(getMyApplication().getSavingTrackHelper().getCurrentGpx(), getString(R.string.shared_string_currently_recording_track));
@@ -495,6 +502,8 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
addTrack();
}else if (itemId == R.string.coordinate_input) {
openCoordinatesInput();
+ } else if (itemId == R.string.shared_string_sort) {
+ updateTracksSort();
}
return true;
}
@@ -512,6 +521,8 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
.setIcon(R.drawable.ic_action_delete_dark).setListener(listener).createItem());
optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.shared_string_refresh, getActivity())
.setIcon(R.drawable.ic_action_refresh_dark).setListener(listener).createItem());
+ optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.shared_string_sort, getActivity())
+ .setIcon(getSortIconId(!sortByName)).setListener(listener).createItem());
OsmandPlugin.onOptionsMenuActivity(getActivity(), this, optionsMenuAdapter);
for (int j = 0; j < optionsMenuAdapter.length(); j++) {
final MenuItem item;
@@ -536,6 +547,11 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
}
}
+ @DrawableRes
+ private int getSortIconId(boolean sortByName) {
+ return sortByName ? R.drawable.ic_action_sort_by_name : R.drawable.ic_action_list_sort;
+ }
+
public void doAction(int actionResId) {
if (actionResId == R.string.shared_string_delete) {
operationTask = new DeleteGpxTask();
@@ -555,6 +571,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
ContextMenuItem contextMenuItem = optionsMenuAdapter.getItem(i);
if (itemId == contextMenuItem.getTitleId()) {
contextMenuItem.getItemClickListener().onContextMenuClick(null, itemId, i, false, null);
+ if (itemId == R.string.shared_string_sort) {
+ item.setIcon(getSortIconId(!sortByName));
+ }
return true;
}
}
@@ -565,6 +584,12 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
((FavoritesActivity) getActivity()).addTrack();
}
+ private void updateTracksSort() {
+ sortByName = !sortByName;
+ app.getSettings().SORT_TRACKS_BY_NAME.set(sortByName);
+ reloadTracks();
+ }
+
private void openCoordinatesInput() {
CoordinateInputDialogFragment fragment = new CoordinateInputDialogFragment();
fragment.setRetainInstance(true);
@@ -948,11 +973,15 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
Arrays.sort(listFiles, new Comparator() {
@Override
public int compare(File f1, File f2) {
- // here we could guess date from file name '2017-08-30 ...' - first part date
- if (f1.lastModified() == f2.lastModified()) {
+ if (sortByName) {
return -f1.getName().compareTo(f2.getName());
+ } else {
+ // here we could guess date from file name '2017-08-30 ...' - first part date
+ if (f1.lastModified() == f2.lastModified()) {
+ return -f1.getName().compareTo(f2.getName());
+ }
+ return -Long.compare(f1.lastModified(), f2.lastModified());
}
- return -Long.compare(f1.lastModified(), f2.lastModified());
}
});
return listFiles;
@@ -969,8 +998,9 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
}
private void loadGPXFolder(File mapPath, List result, LoadGpxTask loadTask, List progress,
- String gpxSubfolder) {
- for (File gpxFile : listFilesSorted(mapPath)) {
+ String gpxSubfolder) {
+ File[] listFiles = listFilesSorted(mapPath);
+ for (File gpxFile : listFiles) {
if (gpxFile.isDirectory()) {
String sub = gpxSubfolder.length() == 0 ? gpxFile.getName() : gpxSubfolder + "/"
+ gpxFile.getName();
@@ -985,7 +1015,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
loadTask.loadFile(progress.toArray(new GpxInfo[progress.size()]));
progress.clear();
}
-
}
}
}
@@ -993,7 +1022,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
public List getResult() {
return result;
}
-
}
protected class GpxIndexesAdapter extends OsmandBaseExpandableListAdapter implements Filterable {
@@ -1050,7 +1078,16 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
Collections.sort(selected, new Comparator() {
@Override
public int compare(GpxInfo i1, GpxInfo i2) {
- return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+ if (sortByName) {
+ return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+ } else {
+ long time1 = i1.file.lastModified();
+ long time2 = i2.file.lastModified();
+ if (time1 == time2) {
+ return i1.getName().toLowerCase().compareTo(i2.getName().toLowerCase());
+ }
+ return -Long.compare(time1, time2);
+ }
}
});
}
@@ -1112,7 +1149,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
data.get(category.get(found)).add(info);
}
- // disable sort
public void sort() {
Collections.sort(category, new Comparator() {
@Override
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
index 3357e4f2fa..94770e0135 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
@@ -23,6 +23,8 @@ public class TracksToFollowCard extends BaseCard {
private List gpxInfoList;
private String selectedCategory;
+ private String defaultCategory;
+ private String visibleCategory;
private GpxTrackAdapter tracksAdapter;
@@ -30,6 +32,8 @@ public class TracksToFollowCard extends BaseCard {
super(mapActivity);
this.gpxInfoList = gpxInfoList;
this.selectedCategory = selectedCategory;
+ defaultCategory = app.getString(R.string.shared_string_all);
+ visibleCategory = app.getString(R.string.shared_string_visible);
gpxInfoCategories = getGpxInfoCategories();
}
@@ -62,7 +66,7 @@ public class TracksToFollowCard extends BaseCard {
filesRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
filesRecyclerView.setNestedScrollingEnabled(false);
- tracksAdapter = new GpxTrackAdapter(view.getContext(), gpxInfoList, false);
+ tracksAdapter = new GpxTrackAdapter(view.getContext(), gpxInfoList, false, showFoldersName());
tracksAdapter.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
@@ -88,6 +92,7 @@ public class TracksToFollowCard extends BaseCard {
public void onItemSelected(String item) {
selectedCategory = item;
List items = gpxInfoCategories.get(item);
+ tracksAdapter.setShowFolderName(showFoldersName());
tracksAdapter.setGpxInfoList(items != null ? items : new ArrayList());
tracksAdapter.notifyDataSetChanged();
@@ -101,17 +106,19 @@ public class TracksToFollowCard extends BaseCard {
selectionAdapter.notifyDataSetChanged();
}
+ private boolean showFoldersName() {
+ return defaultCategory.equals(selectedCategory) || visibleCategory.equals(selectedCategory);
+ }
+
private Map> getGpxInfoCategories() {
- String all = app.getString(R.string.shared_string_all);
- String visible = app.getString(R.string.shared_string_visible);
Map> gpxInfoCategories = new LinkedHashMap<>();
- gpxInfoCategories.put(visible, new ArrayList());
- gpxInfoCategories.put(all, new ArrayList());
+ gpxInfoCategories.put(visibleCategory, new ArrayList());
+ gpxInfoCategories.put(defaultCategory, new ArrayList());
for (GPXInfo info : gpxInfoList) {
if (info.isSelected()) {
- addGpxInfoCategory(gpxInfoCategories, info, visible);
+ addGpxInfoCategory(gpxInfoCategories, info, visibleCategory);
}
if (!Algorithms.isEmpty(info.getFileName())) {
File file = new File(info.getFileName());
@@ -120,7 +127,7 @@ public class TracksToFollowCard extends BaseCard {
addGpxInfoCategory(gpxInfoCategories, info, dirName);
}
}
- addGpxInfoCategory(gpxInfoCategories, info, all);
+ addGpxInfoCategory(gpxInfoCategories, info, defaultCategory);
}
return gpxInfoCategories;
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
index 4baca18a19..a860d4c65c 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
@@ -3936,6 +3936,9 @@ public class OsmandSettings {
public final CommonPreference FAVORITES_TAB =
new IntPreference("FAVORITES_TAB", 0).makeGlobal().cache();
+ public final CommonPreference SORT_TRACKS_BY_NAME
+ = new BooleanPreference("sort_tracks_by_name", true).makeGlobal().cache();
+
public final CommonPreference OSMAND_THEME =
new IntPreference("osmand_theme", OSMAND_LIGHT_THEME) {
@Override