diff --git a/OsmAnd/res/animator/appbar_always_elevated.xml b/OsmAnd/res/animator/appbar_always_elevated.xml
new file mode 100644
index 0000000000..c8378c1c29
--- /dev/null
+++ b/OsmAnd/res/animator/appbar_always_elevated.xml
@@ -0,0 +1,10 @@
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_checkbox_56dp.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_checkbox_56dp.xml
index 34e329d8a3..65fc03610c 100644
--- a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_checkbox_56dp.xml
+++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_checkbox_56dp.xml
@@ -33,7 +33,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
- android:maxLines="1"
+ android:maxLines="2"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="Some title"/>
diff --git a/OsmAnd/res/layout/enough_space_warning_card.xml b/OsmAnd/res/layout/enough_space_warning_card.xml
index a39076eb99..d572d20366 100644
--- a/OsmAnd/res/layout/enough_space_warning_card.xml
+++ b/OsmAnd/res/layout/enough_space_warning_card.xml
@@ -36,6 +36,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:letterSpacing="@dimen/text_button_letter_spacing"
+ android:paddingBottom="@dimen/measurement_tool_menu_title_padding_bottom"
android:text="@string/export_not_enough_space"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
diff --git a/OsmAnd/res/layout/fragment_import.xml b/OsmAnd/res/layout/fragment_import.xml
index 30f518cbfc..eb2cbc7f79 100644
--- a/OsmAnd/res/layout/fragment_import.xml
+++ b/OsmAnd/res/layout/fragment_import.xml
@@ -23,16 +23,22 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
- android:background="?attr/bg_color"
- android:gravity="center"
- android:minHeight="@dimen/bottom_sheet_title_height"
android:orientation="vertical">
+
+
+ android:background="@android:color/transparent"
+ android:stateListAnimator="@animator/appbar_always_elevated">
diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml
index c1addc1349..f91581adf6 100644
--- a/OsmAnd/res/values/sizes.xml
+++ b/OsmAnd/res/values/sizes.xml
@@ -397,6 +397,7 @@
42dp
128dp
164dp
+ 68dp
6dp
12dp
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 72fb10e393..9da2ac6d86 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,7 @@
Thx - Hardy
-->
+ %1$s * %2$s
OsmAnd shows photos from several sources:\nOpenPlaceReviews - POI photos;\nMapillary - street-level imagery;\nWeb / Wikimedia - POI photos specified in OpenStreetMap data.
Use dev.openstreetmap.org
Switch to use "dev.openstreetmap.org" instead of "openstreetmap.org" to testing uploading OSM Note / POI / GPX.
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java b/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java
index bf86c42ee6..13135c0821 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/ExportSettingsType.java
@@ -10,7 +10,6 @@ public enum ExportSettingsType {
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),
- 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),
@@ -19,6 +18,7 @@ public enum ExportSettingsType {
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),
+ SEARCH_HISTORY(R.string.shared_string_search_history, R.drawable.ic_action_history),
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),
@@ -48,12 +48,13 @@ public enum ExportSettingsType {
public boolean isSettingsCategory() {
return this == PROFILE || this == GLOBAL || this == QUICK_ACTIONS || this == POI_TYPES
- || this == SEARCH_HISTORY || this == AVOID_ROADS;
+ || this == AVOID_ROADS;
}
public boolean isMyPlacesCategory() {
return this == FAVORITES || this == TRACKS || this == OSM_EDITS || this == OSM_NOTES
- || this == MULTIMEDIA_NOTES || this == ACTIVE_MARKERS || this == HISTORY_MARKERS;
+ || this == MULTIMEDIA_NOTES || this == ACTIVE_MARKERS || this == HISTORY_MARKERS
+ || this == SEARCH_HISTORY;
}
public boolean isResourcesCategory() {
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/FileSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/FileSettingsItem.java
index 563a04fc75..493e49fa07 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/FileSettingsItem.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/FileSettingsItem.java
@@ -19,6 +19,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FileSettingsItem extends StreamSettingsItem {
@@ -131,6 +132,7 @@ public class FileSettingsItem extends StreamSettingsItem {
private final File appPath;
protected FileSubtype subtype;
private long size;
+ private long lastModified;
public FileSettingsItem(@NonNull OsmandApplication app, @NonNull File file) throws IllegalArgumentException {
super(app, file.getPath().replace(app.getAppPath(null).getPath(), ""));
@@ -222,6 +224,14 @@ public class FileSettingsItem extends StreamSettingsItem {
this.size = size;
}
+ public long getLastModified() {
+ return lastModified;
+ }
+
+ public void setLastModified(long lastModified) {
+ this.lastModified = lastModified;
+ }
+
@NonNull
public File getFile() {
return file;
@@ -292,6 +302,9 @@ public class FileSettingsItem extends StreamSettingsItem {
} finally {
Algorithms.closeStream(output);
}
+ if (lastModified != -1) {
+ dest.setLastModified(lastModified);
+ }
}
};
}
@@ -306,7 +319,14 @@ public class FileSettingsItem extends StreamSettingsItem {
warnings.add(app.getString(R.string.settings_item_read_error, file.getName()));
SettingsHelper.LOG.error("Failed to set input stream from file: " + file.getName(), e);
}
- return super.getWriter();
+ return new StreamSettingsItemWriter(this) {
+ @Override
+ public ZipEntry createNewEntry(String fileName) {
+ ZipEntry entry = super.createNewEntry(fileName);
+ entry.setTime(file.lastModified());
+ return entry;
+ }
+ };
} else {
return new StreamSettingsItemWriter(this) {
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 4553cf805f..babb91a140 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java
@@ -539,10 +539,6 @@ public class SettingsHelper {
if (!poiList.isEmpty()) {
settingsItems.put(ExportSettingsType.POI_TYPES, poiList);
}
- List historyEntries = SearchHistoryHelper.getInstance(app).getHistoryEntries(false);
- if (!historyEntries.isEmpty()) {
- settingsItems.put(ExportSettingsType.SEARCH_HISTORY, historyEntries);
- }
Map impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
if (!impassableRoads.isEmpty()) {
settingsItems.put(ExportSettingsType.AVOID_ROADS, new ArrayList<>(impassableRoads.values()));
@@ -611,6 +607,10 @@ public class SettingsHelper {
markersGroup.setMarkers(markersHistory);
myPlacesItems.put(ExportSettingsType.HISTORY_MARKERS, Collections.singletonList(markersGroup));
}
+ List historyEntries = SearchHistoryHelper.getInstance(app).getHistoryEntries(false);
+ if (!historyEntries.isEmpty()) {
+ myPlacesItems.put(ExportSettingsType.SEARCH_HISTORY, historyEntries);
+ }
return myPlacesItems;
}
@@ -829,10 +829,10 @@ public class SettingsHelper {
List routingFilesList = new ArrayList<>();
List renderFilesList = new ArrayList<>();
List multimediaFilesList = new ArrayList<>();
- List tracksFilesList = new ArrayList<>();
List ttsVoiceFilesList = new ArrayList<>();
List voiceFilesList = new ArrayList<>();
List mapFilesList = new ArrayList<>();
+ List tracksFilesList = new ArrayList<>();
List avoidRoads = new ArrayList<>();
List globalSettingsItems = new ArrayList<>();
List notesPointList = new ArrayList<>();
@@ -856,7 +856,7 @@ public class SettingsHelper {
} else if (fileItem.getSubtype() == FileSubtype.MULTIMEDIA_NOTES) {
multimediaFilesList.add(fileItem.getFile());
} else if (fileItem.getSubtype() == FileSubtype.GPX) {
- tracksFilesList.add(fileItem.getFile());
+ tracksFilesList.add(fileItem);
} else if (fileItem.getSubtype().isMap()) {
mapFilesList.add(fileItem);
} else if (fileItem.getSubtype() == FileSubtype.TTS_VOICE) {
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsImporter.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsImporter.java
index 7f72761066..66c40d03cc 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsImporter.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsImporter.java
@@ -60,7 +60,7 @@ class SettingsImporter {
try {
SettingsItemsFactory itemsFactory = new SettingsItemsFactory(app, itemsJson);
List settingsItemList = itemsFactory.getItems();
- getFilesSize(file, settingsItemList);
+ updateFilesInfo(file, settingsItemList);
items.addAll(settingsItemList);
} catch (IllegalArgumentException e) {
SettingsHelper.LOG.error("Error parsing items: " + itemsJson, e);
@@ -81,7 +81,7 @@ class SettingsImporter {
return items;
}
- private void getFilesSize(@NonNull File file, List settingsItemList) throws IOException {
+ private void updateFilesInfo(@NonNull File file, List settingsItemList) throws IOException {
ZipFile zipfile = new ZipFile(file.getPath());
Enumeration extends ZipEntry> zipEnum = zipfile.entries();
while (zipEnum.hasMoreElements()) {
@@ -90,7 +90,9 @@ class SettingsImporter {
for (SettingsItem settingsItem : settingsItemList) {
if (settingsItem instanceof FileSettingsItem
&& zipEntry.getName().equals(settingsItem.getFileName())) {
- ((FileSettingsItem) settingsItem).setSize(size);
+ FileSettingsItem fileSettingsItem = (FileSettingsItem) settingsItem;
+ fileSettingsItem.setSize(size);
+ fileSettingsItem.setLastModified(zipEntry.getTime());
break;
}
}
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsItemWriter.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsItemWriter.java
index 090767a493..65863f0e90 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsItemWriter.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsItemWriter.java
@@ -22,9 +22,13 @@ public abstract class SettingsItemWriter {
public abstract boolean writeToStream(@NonNull OutputStream outputStream) throws IOException;
public void writeEntry(String fileName, @NonNull ZipOutputStream zos) throws IOException {
- ZipEntry entry = new ZipEntry(fileName);
+ ZipEntry entry = createNewEntry(fileName);
zos.putNextEntry(entry);
writeToStream(zos);
zos.closeEntry();
}
+
+ public ZipEntry createNewEntry(String fileName) {
+ return new ZipEntry(fileName);
+ }
}
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsListFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsListFragment.java
index d95b6cffea..86b7389f6e 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsListFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsListFragment.java
@@ -2,15 +2,14 @@ package net.osmand.plus.settings.fragments;
import android.content.Context;
import android.content.DialogInterface;
-import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
+import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@@ -31,6 +30,7 @@ import net.osmand.plus.settings.backend.ExportSettingsCategory;
import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.fragments.ExportSettingsAdapter.OnItemSelectedListener;
import net.osmand.plus.widgets.TextViewEx;
+import net.osmand.util.Algorithms;
import java.io.File;
import java.util.ArrayList;
@@ -60,6 +60,7 @@ public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implem
protected ExpandableListView expandableList;
protected ExportSettingsAdapter adapter;
+ protected boolean exportMode;
protected boolean nightMode;
private boolean wasDrawerDisabled;
@@ -73,6 +74,17 @@ public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implem
super.onCreate(savedInstanceState);
app = requireMyApplication();
nightMode = !app.getSettings().isLightContent();
+
+ requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
+ @Override
+ public void handleOnBackPressed() {
+ if (hasSelectedData()) {
+ showExitDialog();
+ } else {
+ dismissFragment();
+ }
+ }
+ });
}
@Nullable
@@ -101,26 +113,15 @@ public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implem
continueBtn = root.findViewById(R.id.continue_button);
UiUtilities.setupDialogButton(nightMode, continueBtn, DialogButtonType.PRIMARY, getString(R.string.shared_string_continue));
- continueBtn.setOnClickListener(new View.OnClickListener() {
+ root.findViewById(R.id.continue_button_container).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- onContinueButtonClickAction();
- }
- });
-
- ViewTreeObserver treeObserver = buttonsContainer.getViewTreeObserver();
- treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- if (buttonsContainer != null) {
- ViewTreeObserver vts = buttonsContainer.getViewTreeObserver();
- int height = buttonsContainer.getMeasuredHeight();
- expandableList.setPadding(0, 0, 0, height);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- vts.removeOnGlobalLayoutListener(this);
- } else {
- vts.removeGlobalOnLayoutListener(this);
+ if (expandableList.getHeaderViewsCount() <= 1) {
+ if (hasSelectedData()) {
+ onContinueButtonClickAction();
}
+ } else {
+ expandableList.smoothScrollToPosition(0);
}
}
});
@@ -185,7 +186,11 @@ public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implem
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- showExitDialog();
+ if (hasSelectedData()) {
+ showExitDialog();
+ } else {
+ dismissFragment();
+ }
}
});
}
@@ -204,16 +209,25 @@ public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implem
continueBtn.setEnabled(false);
} else {
updateWarningHeaderVisibility(false);
- continueBtn.setEnabled(adapter.hasSelectedData());
+ continueBtn.setEnabled(hasSelectedData());
}
itemsSizeContainer.setVisibility(View.VISIBLE);
} else {
updateWarningHeaderVisibility(false);
itemsSizeContainer.setVisibility(View.INVISIBLE);
- continueBtn.setEnabled(adapter.hasSelectedData());
+ continueBtn.setEnabled(hasSelectedData());
}
}
+ public boolean hasSelectedData() {
+ for (List> items : selectedItemsMap.values()) {
+ if (!Algorithms.isEmpty(items)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void updateWarningHeaderVisibility(boolean visible) {
if (visible) {
if (expandableList.getHeaderViewsCount() < 2) {
@@ -255,13 +269,24 @@ public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implem
updateAvailableSpace();
}
+ protected List