diff --git a/OsmAnd/res/layout/enough_space_warning_card.xml b/OsmAnd/res/layout/enough_space_warning_card.xml
new file mode 100644
index 0000000000..a39076eb99
--- /dev/null
+++ b/OsmAnd/res/layout/enough_space_warning_card.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/fragment_import.xml b/OsmAnd/res/layout/fragment_import.xml
index e9852ea58d..ef83bba63d 100644
--- a/OsmAnd/res/layout/fragment_import.xml
+++ b/OsmAnd/res/layout/fragment_import.xml
@@ -21,46 +21,49 @@
+ android:paddingBottom="@dimen/bottom_sheet_title_padding_bottom"
+ android:visibility="invisible"
+ tools:visibility="visible">
@@ -78,26 +82,32 @@
android:layout_height="match_parent" />
diff --git a/OsmAnd/res/layout/list_item_description_header.xml b/OsmAnd/res/layout/list_item_description_header.xml
index f27db51731..9ff915193d 100644
--- a/OsmAnd/res/layout/list_item_description_header.xml
+++ b/OsmAnd/res/layout/list_item_description_header.xml
@@ -10,15 +10,25 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
+ android:lineSpacingMultiplier="@dimen/line_spacing_multiplier_description"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/list_header_settings_top_margin"
android:paddingEnd="@dimen/content_padding"
- android:lineSpacingMultiplier="@dimen/line_spacing_multiplier_description"
android:paddingBottom="@dimen/list_header_settings_top_margin"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/select_data_to_import" />
-
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/profile_data_list_item_group.xml b/OsmAnd/res/layout/profile_data_list_item_group.xml
index 6cf421ff8a..99bb29511b 100644
--- a/OsmAnd/res/layout/profile_data_list_item_group.xml
+++ b/OsmAnd/res/layout/profile_data_list_item_group.xml
@@ -14,12 +14,12 @@
@@ -48,16 +48,20 @@
android:id="@+id/title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:letterSpacing="@dimen/text_button_letter_spacing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
+ osmand:lineHeight="@dimen/default_title_line_height"
tools:text="Quick actions" />
@@ -66,8 +70,8 @@
android:id="@+id/vertical_divider"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:layout_marginTop="@dimen/content_padding"
- android:layout_marginBottom="@dimen/content_padding"
+ android:layout_marginTop="@dimen/setting_profile_item_switch_margin"
+ android:layout_marginBottom="@dimen/setting_profile_item_switch_margin"
android:background="?attr/list_divider" />
23sp
15sp15sp
+ 24sp
+ 20sp13sp13sp
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 9dee5100fe..6b382d13af 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,10 +11,15 @@
Thx - Hardy
-->
+ There is not enough space
+ OsmAnd is needed %1$s to export a file. Your device only has %2$s free. You can free up space on the device, or skip some items from export.Needed for importSelect the data to be exported to the file.Approximate file sizeResources
+ Motorboat
+ Kayak
+ Search historyI already have an accountCreate new accountPhotos are provided by open data project OpenPlaceReviews.org. In order to upload your photos you need to sign up on website.
@@ -23,10 +28,10 @@
You can log in using the safe OAuth method or use your login and password.Comment OSM NoteClose OSM Note
- Trackable means that the trace will not show up in any public listings but trackpoints from it will still be available through the public GPS API with timestamps. Other users will only be able to download processed trackpoints from your trace which can\'t be associated with you directly.
- Identifiable means that the trace will be shown publicly in Your GPS traces and in public GPS trace listings, i.e. other users will be able to download the raw trace and associate it with your username. Data served via the trackpoints API will reference your original trace page. Timestamps of the trace points are available through the public GPS API.
- Private means that the trace will not show up in any public listings, but trackpoints from it will still be available through the public GPS API without timestamps but will not be chronologically ordered.
- Public means that the trace will be shown publicly in Your GPS traces and in public GPS trace listings. Data served via the API does not reference your trace page. Timestamps of the trace points are not available through the public GPS API, and the points are not chronologically ordered. However, other users are still able to download the raw trace from the public trace list and any timestamps contained within.
+ \"Trackable\" means the trace does not show up in any public listings, but processed trackpoints with timestamps from it (that can\'t be associated with you directly) do through downloads from the public GPS API.
+ \"Identifiable\" means that the trace will be shown publicly in Your GPS traces and in public GPS trace listings, i.e. other users will be able to download the raw trace and associate it with your username. Public timestamped tracepoint data from the GPS API served via the trackpoints API will reference your original trace page.
+ \"Private\" means the trace does not show up in any public listings, but trackpoints from it in unchronological order are available through the public GPS API without timestamps.
+ \"Public\" means the trace is shown publicly in your GPS traces and in public GPS trace listings, and in the public trace list with timestamps in raw form. Data served via the API does not reference your trace page. Tracepoint timestamps are not available through the public GPS API, and tracepoints are not chronologically ordered.Enter tags separated by comma.Send GPX file to OpenStreetMapMarkers history
@@ -78,13 +83,13 @@
Payment will be charged to your AppGallery account at the confirmation of purchase.\n\nSubscription automatically renews unless it is canceled before the renewal date. Your account will be charged for renewal period (month/three month/year) only on the renewal date.\n\nYou can manage and cancel your subscriptions by going to your AppGallery settings.Subscription charged per selected period. Cancel it on AppGallery at any time.Thank you for purchasing \'Contour lines\'
- Start/finish icons
+ Start and finish iconsName: A – ZName: Z – ALast modified
• Updated "Plan a route" function: allows using different navigation types per segment and the inclusion of tracks\n\n
- • New "Appearance" menu for tracks: select color, thickness, display direction arrows, start/finish icons\n\n
+ • New "Appearance" menu for tracks: select color, thickness, display direction arrows, start and finish icons\n\n
• Improved visibility of bicycle nodes.\n\n
• Tracks are now tappable, have context menu with basic info.\n\n
• Improved "Search" algorithms\n\n
@@ -104,11 +109,11 @@
System defaultResume trip recordingPause trip recording
- Specify the logging interval for the general track recording (enabled via the Trip recording widget on the map).
+ Specify the logging interval for the general track recording (turned on via the \'Trip recording\' widget on the map).Will pause track logging when the app is killed (via recent apps). (OsmAnd background indication disappears from the Android notification bar.)REC%s track files selected
- File name
+ FilenameOnly the route line will be saved, the waypoints will be deleted.Simplified trackChange route type after
@@ -270,11 +275,11 @@
The action button switches between selected profiles.Back to editingRestore default items order
- Add / Edit Favorite
+ Add or edit favoriteParking positions
- Create / Edit POI
+ Create or edit POIButton showing or hiding public transport on the map.
- Show/hide public transport
+ Show or hide public transportShow public transportHide public transport
@@ -376,7 +381,7 @@
A button to show or hide terrain layer on the map.Show terrainHide terrain
- Show / hide terrain
+ Show or hide terrainSlopes%1$s of %2$sThe route will be recalculated if the distance from the route to the current location is more than selected value.
@@ -561,7 +566,7 @@
Clear %1$s?RevertTrack saved
- File name is empty
+ Empty filenameEstimates arrival time for unknown road types, and limits speed for all roads (may affect routing)WhiteSwap %1$s and %2$s
@@ -1173,7 +1178,7 @@
Adds initial stopMove destination up, and create itShow closed notes
- Show/hide OSM notes on the map.
+ Show or hide OSM notes on the map.GPX - suitable for export to JOSM or other OSM editors.OSC - suitable for export to OSM.GPX file
@@ -1335,7 +1340,7 @@
Save the points either as route points or as a line.Select navigation profilePlease add at least one point.
- GPX file name:
+ GPX filename:Show on map after savingBrowse the map and add pointsMeasure distance
@@ -3826,7 +3831,7 @@
Number of contributorsNumber of editsReport for
- File name contains illegal character
+ Illegal character in filenameQuick actionAction %dScreen %d
@@ -3948,9 +3953,9 @@
No cobblestone or settAvoids cobblestone and settAdd at least one item to the list in the \'Quick action\' settings
- Alpine/downhill ski
+ Alpine and downhill skiingSlopes for alpine or downhill skiing and access to ski lifts.
- Cross country/nordic ski
+ Cross country and nordic skiingTrails for nordic or cross-country skiing.Ski touringRoutes for ski touring.
diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java
index 40ea9cfb98..af0d934083 100644
--- a/OsmAnd/src/net/osmand/AndroidUtils.java
+++ b/OsmAnd/src/net/osmand/AndroidUtils.java
@@ -788,6 +788,14 @@ public class AndroidUtils {
return result;
}
+ public static long getAvailableSpace(@Nullable File dir) {
+ if (dir != null && dir.canRead()) {
+ StatFs fs = new StatFs(dir.getAbsolutePath());
+ return fs.getAvailableBlocksLong() * fs.getBlockSize();
+ }
+ return -1;
+ }
+
public static float getFreeSpaceGb(File dir) {
if (dir.canRead()) {
StatFs fs = new StatFs(dir.getAbsolutePath());
diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadActivity.java b/OsmAnd/src/net/osmand/plus/download/DownloadActivity.java
index 3ebd06b4b4..52bb44bf5f 100644
--- a/OsmAnd/src/net/osmand/plus/download/DownloadActivity.java
+++ b/OsmAnd/src/net/osmand/plus/download/DownloadActivity.java
@@ -22,7 +22,6 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Space;
import android.widget.TextView;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -36,7 +35,6 @@ import androidx.fragment.app.FragmentActivity;
import androidx.viewpager.widget.ViewPager;
import net.osmand.AndroidUtils;
-import net.osmand.IProgress;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibilityAssistant;
@@ -45,7 +43,6 @@ import net.osmand.data.PointDescription;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
-import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.LocalIndexInfo;
@@ -64,6 +61,8 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
+import net.osmand.plus.settings.backend.OsmandSettings;
+import net.osmand.plus.download.ReloadIndexesTask.ReloadIndexesListener;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import net.osmand.util.Algorithms;
@@ -389,8 +388,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
return !Version.isPaidVersion(application)
|| application.getSettings().SHOULD_SHOW_FREE_VERSION_BANNER.get();
}
-
-
+
public static class FreeVersionBanner {
private final View freeVersionBanner;
private final View freeVersionBannerTitle;
@@ -441,7 +439,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
freeVersionBanner.setVisibility(View.VISIBLE);
downloadsLeftProgressBar.setMax(DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS);
freeVersionDescriptionTextView.setText(ctx.getString(R.string.free_version_message,
- DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS +"" ));
+ DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS + ""));
LinearLayout marksLinearLayout = (LinearLayout) freeVersionBanner.findViewById(R.id.marksLinearLayout);
Space spaceView = new Space(ctx);
@@ -493,6 +491,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
freeVersionBannerTitle.setVisibility(View.VISIBLE);
}
}
+
private void updateAvailableDownloads() {
int activeTasks = ctx.getDownloadThread().getCountedDownloads();
OsmandSettings settings = ctx.getMyApplication().getSettings();
@@ -570,36 +569,26 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
}
}
- @SuppressLint("StaticFieldLeak")
public void reloadLocalIndexes() {
- AsyncTask> task = new AsyncTask>() {
+ final OsmandApplication app = (OsmandApplication) getApplication();
+ ReloadIndexesTask reloadIndexesTask = new ReloadIndexesTask(app, new ReloadIndexesListener() {
@Override
- protected void onPreExecute() {
- super.onPreExecute();
+ public void reloadIndexesStarted() {
setSupportProgressBarIndeterminateVisibility(true);
}
@Override
- protected List doInBackground(Void... params) {
- return getMyApplication().getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS,
- new ArrayList()
- );
- }
-
- @Override
- protected void onPostExecute(List warnings) {
+ public void reloadIndexesFinished(List warnings) {
setSupportProgressBarIndeterminateVisibility(false);
- if (!warnings.isEmpty()) {
- Toast.makeText(DownloadActivity.this, AndroidUtils.formatWarnings(warnings).toString(), Toast.LENGTH_LONG).show();
+ if (!Algorithms.isEmpty(warnings)) {
+ app.showToastMessage(AndroidUtils.formatWarnings(warnings).toString());
}
newDownloadIndexes();
}
- };
- task.executeOnExecutor(singleThreadExecutor);
+ });
+ reloadIndexesTask.executeOnExecutor(singleThreadExecutor);
}
-
-
public void setDownloadItem(WorldRegion region, String targetFileName) {
if (downloadItem == null) {
downloadItem = region;
@@ -666,8 +655,8 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
int percent = 0;
if (dir.canRead()) {
StatFs fs = new StatFs(dir.getAbsolutePath());
- size = AndroidUtils.formatSize(activity, ((long)fs.getAvailableBlocks()) * fs.getBlockSize());
- percent = 100 - (int)((long)fs.getAvailableBlocks() * 100 / fs.getBlockCount());
+ size = AndroidUtils.formatSize(activity, ((long) fs.getAvailableBlocks()) * fs.getBlockSize());
+ percent = 100 - (int) ((long) fs.getAvailableBlocks() * 100 / fs.getBlockCount());
}
sizeProgress.setIndeterminate(false);
sizeProgress.setProgress(percent);
diff --git a/OsmAnd/src/net/osmand/plus/download/ReloadIndexesTask.java b/OsmAnd/src/net/osmand/plus/download/ReloadIndexesTask.java
new file mode 100644
index 0000000000..873d73b671
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/download/ReloadIndexesTask.java
@@ -0,0 +1,49 @@
+package net.osmand.plus.download;
+
+import android.os.AsyncTask;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import net.osmand.IProgress;
+import net.osmand.plus.OsmandApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ReloadIndexesTask extends AsyncTask> {
+
+ private final OsmandApplication app;
+ private final ReloadIndexesListener listener;
+
+ public ReloadIndexesTask(@NonNull OsmandApplication app, @Nullable ReloadIndexesListener listener) {
+ this.app = app;
+ this.listener = listener;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ if (listener != null) {
+ listener.reloadIndexesStarted();
+ }
+ }
+
+ @Override
+ protected List doInBackground(Void... params) {
+ return app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList());
+ }
+
+ @Override
+ protected void onPostExecute(List warnings) {
+ if (listener != null) {
+ listener.reloadIndexesFinished(warnings);
+ }
+ }
+
+ public interface ReloadIndexesListener {
+
+ void reloadIndexesStarted();
+
+ void reloadIndexesFinished(List warnings);
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java b/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java
index 10e392d0cc..bf86c42ee6 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java
@@ -7,23 +7,24 @@ import net.osmand.plus.R;
public enum ExportSettingsType {
PROFILE(R.string.shared_string_profiles, R.drawable.ic_action_manage_profiles),
+ GLOBAL(R.string.general_settings_2, R.drawable.ic_action_settings),
QUICK_ACTIONS(R.string.configure_screen_quick_action, R.drawable.ic_quick_action),
POI_TYPES(R.string.poi_dialog_poi_type, R.drawable.ic_action_info_dark),
- MAP_SOURCES(R.string.quick_action_map_source_title, R.drawable.ic_map),
- CUSTOM_RENDER_STYLE(R.string.shared_string_rendering_style, R.drawable.ic_action_map_style),
- CUSTOM_ROUTING(R.string.shared_string_routing, R.drawable.ic_action_route_distance),
+ SEARCH_HISTORY(R.string.shared_string_search_history, R.drawable.ic_action_history),
AVOID_ROADS(R.string.avoid_road, R.drawable.ic_action_alert),
+ FAVORITES(R.string.shared_string_favorites, R.drawable.ic_action_favorite),
TRACKS(R.string.shared_string_tracks, R.drawable.ic_action_route_distance),
- MULTIMEDIA_NOTES(R.string.audionotes_plugin_name, R.drawable.ic_action_photo_dark),
- GLOBAL(R.string.general_settings_2, R.drawable.ic_action_settings),
OSM_NOTES(R.string.osm_notes, R.drawable.ic_action_openstreetmap_logo),
OSM_EDITS(R.string.osm_edits, R.drawable.ic_action_openstreetmap_logo),
- OFFLINE_MAPS(R.string.shared_string_maps, R.drawable.ic_map),
- FAVORITES(R.string.shared_string_favorites, R.drawable.ic_action_favorite),
- TTS_VOICE(R.string.local_indexes_cat_tts, R.drawable.ic_action_volume_up),
- VOICE(R.string.local_indexes_cat_voice, R.drawable.ic_action_volume_up),
+ MULTIMEDIA_NOTES(R.string.audionotes_plugin_name, R.drawable.ic_grouped_by_type),
ACTIVE_MARKERS(R.string.map_markers, R.drawable.ic_action_flag),
- HISTORY_MARKERS(R.string.markers_history, R.drawable.ic_action_flag);
+ HISTORY_MARKERS(R.string.markers_history, R.drawable.ic_action_flag),
+ CUSTOM_RENDER_STYLE(R.string.shared_string_rendering_style, R.drawable.ic_action_map_style),
+ CUSTOM_ROUTING(R.string.shared_string_routing, R.drawable.ic_action_route_distance),
+ MAP_SOURCES(R.string.quick_action_map_source_title, R.drawable.ic_map),
+ OFFLINE_MAPS(R.string.shared_string_maps, R.drawable.ic_map),
+ TTS_VOICE(R.string.local_indexes_cat_tts, R.drawable.ic_action_volume_up),
+ VOICE(R.string.local_indexes_cat_voice, R.drawable.ic_action_volume_up);
@StringRes
private final int titleId;
@@ -46,7 +47,8 @@ public enum ExportSettingsType {
}
public boolean isSettingsCategory() {
- return this == PROFILE || this == GLOBAL || this == QUICK_ACTIONS || this == POI_TYPES;
+ return this == PROFILE || this == GLOBAL || this == QUICK_ACTIONS || this == POI_TYPES
+ || this == SEARCH_HISTORY || this == AVOID_ROADS;
}
public boolean isMyPlacesCategory() {
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java
index 3a0cbe8a61..910ac66ab3 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java
@@ -29,6 +29,8 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
+import net.osmand.plus.helpers.SearchHistoryHelper;
+import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.osmedit.OpenstreetmapPoint;
@@ -504,12 +506,15 @@ public class SettingsHelper {
List resourcesItems = getResourcesItems();
if (!settingsItems.isEmpty()) {
+ sortExportSettingsObjects(settingsItems);
dataList.put(ExportSettingsCategory.SETTINGS, settingsItems);
}
if (!myPlacesItems.isEmpty()) {
+ sortExportSettingsObjects(myPlacesItems);
dataList.put(ExportSettingsCategory.MY_PLACES, myPlacesItems);
}
if (!resourcesItems.isEmpty()) {
+ sortExportSettingsObjects(resourcesItems);
dataList.put(ExportSettingsCategory.RESOURCES, resourcesItems);
}
@@ -537,7 +542,14 @@ public class SettingsHelper {
if (!poiList.isEmpty()) {
settingsItems.add(new ExportDataObject(ExportSettingsType.POI_TYPES, poiList));
}
-
+ List historyEntries = SearchHistoryHelper.getInstance(app).getHistoryEntries(false);
+ if (!historyEntries.isEmpty()) {
+ settingsItems.add(new ExportDataObject(ExportSettingsType.SEARCH_HISTORY, historyEntries));
+ }
+ Map impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
+ if (!impassableRoads.isEmpty()) {
+ settingsItems.add(new ExportDataObject(ExportSettingsType.AVOID_ROADS, new ArrayList<>(impassableRoads.values())));
+ }
return settingsItems;
}
@@ -653,10 +665,6 @@ public class SettingsHelper {
if (!files.isEmpty()) {
resourcesItems.add(new ExportDataObject(ExportSettingsType.VOICE, files));
}
- Map impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
- if (!impassableRoads.isEmpty()) {
- resourcesItems.add(new ExportDataObject(ExportSettingsType.AVOID_ROADS, new ArrayList<>(impassableRoads.values())));
- }
return resourcesItems;
}
@@ -699,6 +707,7 @@ public class SettingsHelper {
List osmEditsPointList = new ArrayList<>();
List markersGroups = new ArrayList<>();
List markersHistoryGroups = new ArrayList<>();
+ List historyEntries = new ArrayList<>();
for (Object object : data) {
if (object instanceof QuickAction) {
@@ -730,6 +739,8 @@ public class SettingsHelper {
} else if (ExportSettingsType.HISTORY_MARKERS.name().equals(markersGroup.getId())) {
markersHistoryGroups.add((MapMarkersGroup) object);
}
+ } else if (object instanceof HistoryEntry) {
+ historyEntries.add((HistoryEntry) object);
}
}
if (!quickActions.isEmpty()) {
@@ -775,6 +786,9 @@ public class SettingsHelper {
}
settingsItems.add(new HistoryMarkersSettingsItem(app, mapMarkers));
}
+ if (!historyEntries.isEmpty()) {
+ settingsItems.add(new SearchHistorySettingsItem(app, historyEntries));
+ }
return settingsItems;
}
@@ -797,12 +811,15 @@ public class SettingsHelper {
}
}
if (!settingsItems.isEmpty()) {
+ sortExportSettingsObjects(settingsItems);
exportMap.put(ExportSettingsCategory.SETTINGS, settingsItems);
}
if (!myPlacesItems.isEmpty()) {
+ sortExportSettingsObjects(myPlacesItems);
exportMap.put(ExportSettingsCategory.MY_PLACES, myPlacesItems);
}
if (!resourcesItems.isEmpty()) {
+ sortExportSettingsObjects(resourcesItems);
exportMap.put(ExportSettingsCategory.RESOURCES, resourcesItems);
}
@@ -829,6 +846,7 @@ public class SettingsHelper {
List favoriteGroups = new ArrayList<>();
List markersGroups = new ArrayList<>();
List markersHistoryGroups = new ArrayList<>();
+ List historyEntries = new ArrayList<>();
for (SettingsItem item : settingsItems) {
switch (item.getType()) {
@@ -916,6 +934,10 @@ public class SettingsHelper {
HistoryMarkersSettingsItem historyMarkersSettingsItem = (HistoryMarkersSettingsItem) item;
markersHistoryGroups.add(historyMarkersSettingsItem.getMarkersGroup());
break;
+ case SEARCH_HISTORY:
+ SearchHistorySettingsItem searchHistorySettingsItem = (SearchHistorySettingsItem) item;
+ historyEntries.addAll(searchHistorySettingsItem.getItems());
+ break;
default:
break;
}
@@ -972,9 +994,12 @@ public class SettingsHelper {
if (!markersGroups.isEmpty()) {
settingsToOperate.put(ExportSettingsType.ACTIVE_MARKERS, markersGroups);
}
- if (!markersGroups.isEmpty()) {
+ if (!markersHistoryGroups.isEmpty()) {
settingsToOperate.put(ExportSettingsType.HISTORY_MARKERS, markersHistoryGroups);
}
+ if (!historyEntries.isEmpty()) {
+ settingsToOperate.put(ExportSettingsType.SEARCH_HISTORY, historyEntries);
+ }
return settingsToOperate;
}
@@ -991,4 +1016,15 @@ public class SettingsHelper {
}
});
}
+
+ private static void sortExportSettingsObjects(List items) {
+ Collections.sort(items, new Comparator() {
+ @Override
+ public int compare(ExportDataObject lhs, ExportDataObject rhs) {
+ int order1 = lhs.getType().ordinal();
+ int order2 = rhs.getType().ordinal();
+ return (order1 < order2) ? -1 : ((order1 == order2) ? 0 : 1);
+ }
+ });
+ }
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportDataObject.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportDataObject.java
index 11cb9a79b6..e8ede12a77 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportDataObject.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportDataObject.java
@@ -1,5 +1,7 @@
package net.osmand.plus.settings.fragments;
+import androidx.annotation.NonNull;
+
import net.osmand.plus.settings.backend.ExportSettingsType;
import java.util.List;
@@ -9,7 +11,7 @@ public class ExportDataObject {
private ExportSettingsType type;
private List> items;
- public ExportDataObject(ExportSettingsType type, List> items) {
+ public ExportDataObject(@NonNull ExportSettingsType type, @NonNull List> items) {
this.type = type;
this.items = items;
}
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java
index 24df2f294f..2643b5230d 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportImportSettingsAdapter.java
@@ -4,6 +4,8 @@ import android.content.res.ColorStateList;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -11,16 +13,33 @@ import androidx.core.content.ContextCompat;
import androidx.core.widget.CompoundButtonCompat;
import net.osmand.AndroidUtils;
+import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
+import net.osmand.map.ITileSource;
+import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
-import net.osmand.plus.helpers.AndroidUiHelper;
-import net.osmand.plus.helpers.FontCache;
-import net.osmand.plus.settings.backend.ExportSettingsCategory;
+import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
+import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
+import net.osmand.plus.helpers.FileNameTranslationHelper;
+import net.osmand.plus.helpers.GpxUiHelper;
+import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
+import net.osmand.plus.osmedit.OpenstreetmapPoint;
+import net.osmand.plus.osmedit.OsmEditingPlugin;
+import net.osmand.plus.osmedit.OsmNotesPoint;
+import net.osmand.plus.poi.PoiUIFilter;
+import net.osmand.plus.profiles.ProfileIconColors;
+import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
+import net.osmand.plus.quickaction.QuickAction;
+import net.osmand.plus.render.RenderingIcons;
+import net.osmand.plus.settings.backend.ApplicationMode;
+import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.backup.FileSettingsItem;
+import net.osmand.plus.settings.backend.backup.GlobalSettingsItem;
+import net.osmand.util.Algorithms;
import net.osmand.view.ThreeStateCheckbox;
import org.apache.commons.logging.Log;
@@ -29,10 +48,11 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import static net.osmand.plus.settings.backend.ExportSettingsType.OFFLINE_MAPS;
+import static net.osmand.plus.settings.backend.backup.FileSettingsItem.FileSubtype;
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
import static net.osmand.view.ThreeStateCheckbox.State.MISC;
import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
@@ -40,94 +60,91 @@ import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
private static final Log LOG = PlatformUtil.getLog(ExportImportSettingsAdapter.class.getName());
+ private OsmandApplication app;
+ private UiUtilities uiUtilities;
+ private List super Object> data;
+ private Map> itemsMap;
+ private List itemsTypes;
+ private boolean nightMode;
+ private boolean importState;
+ private int activeColorRes;
+ private int secondaryColorRes;
- private final OsmandApplication app;
- private final UiUtilities uiUtilities;
-
- private List itemsTypes = new ArrayList<>();
- private Map> selectedItemsMap = new HashMap<>();
- private Map> itemsMap = new LinkedHashMap<>();
-
- private final OnItemSelectedListener listener;
-
- private final LayoutInflater themedInflater;
-
- private final boolean nightMode;
- private final int activeColorRes;
- private final int secondaryColorRes;
-
- ExportImportSettingsAdapter(OsmandApplication app, OnItemSelectedListener listener, boolean nightMode) {
+ ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode, boolean importState) {
this.app = app;
- this.listener = listener;
this.nightMode = nightMode;
+ this.importState = importState;
+ this.itemsMap = new HashMap<>();
+ this.itemsTypes = new ArrayList<>();
+ this.data = new ArrayList<>();
uiUtilities = app.getUIUtilities();
- themedInflater = UiUtilities.getInflater(app, nightMode);
- activeColorRes = nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light;
- secondaryColorRes = nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light;
+ activeColorRes = nightMode
+ ? R.color.icon_color_active_dark
+ : R.color.icon_color_active_light;
+ secondaryColorRes = nightMode
+ ? R.color.icon_color_secondary_dark
+ : R.color.icon_color_secondary_light;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View group = convertView;
if (group == null) {
- group = themedInflater.inflate(R.layout.profile_data_list_item_group, parent, false);
+ LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
+ group = inflater.inflate(R.layout.profile_data_list_item_group, parent, false);
}
- final ExportSettingsCategory category = itemsTypes.get(groupPosition);
- final List items = itemsMap.get(category);
- String title = app.getString(category.getTitleId());
+ boolean isLastGroup = groupPosition == getGroupCount() - 1;
+ final ExportSettingsType type = itemsTypes.get(groupPosition);
+
TextView titleTv = group.findViewById(R.id.title_tv);
- titleTv.setText(UiUtilities.createCustomFontSpannable(FontCache.getRobotoMedium(app), title, title));
-
TextView subTextTv = group.findViewById(R.id.sub_text_tv);
- subTextTv.setText(getCategoryDescr(category));
-
- int selectedTypes = 0;
- for (int i = 0; i < items.size(); i++) {
- ExportDataObject object = items.get(i);
- if (selectedItemsMap.containsKey(object.getType())) {
- selectedTypes++;
- }
- }
final ThreeStateCheckbox checkBox = group.findViewById(R.id.check_box);
- if (selectedTypes == 0) {
- checkBox.setState(UNCHECKED);
+ FrameLayout checkBoxContainer = group.findViewById(R.id.check_box_container);
+ ImageView expandIv = group.findViewById(R.id.explist_indicator);
+ View lineDivider = group.findViewById(R.id.divider);
+ View cardTopDivider = group.findViewById(R.id.card_top_divider);
+ View cardBottomDivider = group.findViewById(R.id.card_bottom_divider);
+
+ titleTv.setText(getGroupTitle(type));
+ lineDivider.setVisibility(importState || isExpanded || isLastGroup ? View.GONE : View.VISIBLE);
+ cardTopDivider.setVisibility(importState ? View.VISIBLE : View.GONE);
+ cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE);
+
+ final List> listItems = itemsMap.get(type);
+ subTextTv.setText(getSelectedItemsAmount(listItems, type));
+
+ if (data.containsAll(listItems)) {
+ checkBox.setState(CHECKED);
} else {
- checkBox.setState(selectedTypes == items.size() ? CHECKED : MISC);
+ boolean contains = false;
+ for (Object object : listItems) {
+ if (data.contains(object)) {
+ contains = true;
+ break;
+ }
+ }
+ checkBox.setState(contains ? MISC : UNCHECKED);
}
int checkBoxColor = checkBox.getState() == UNCHECKED ? secondaryColorRes : activeColorRes;
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, checkBoxColor)));
-
- group.findViewById(R.id.check_box_container).setOnClickListener(new View.OnClickListener() {
+ checkBoxContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
checkBox.performClick();
- boolean selected = checkBox.getState() == CHECKED;
- if (selected) {
- for (ExportDataObject object : items) {
- if (!selectedItemsMap.containsKey(object.getType())) {
- selectedItemsMap.put(object.getType(), (List