Export UI first screen initial commit
This commit is contained in:
parent
21ccac8d78
commit
058c7414f5
15 changed files with 996 additions and 941 deletions
|
@ -32,34 +32,46 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/file_size_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1">
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/bottom_sheet_title_padding_bottom"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/bottom_sheet_title_padding_bottom">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/select_button"
|
||||
android:id="@+id/file_size"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start|center_vertical"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding_small"
|
||||
android:text="@string/shared_string_select_all"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Select all" />
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="567 MB" />
|
||||
|
||||
</FrameLayout>
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/file_size_descr"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start|center_vertical"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:text="@string/approximate_file_size"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="@dimen/content_padding"
|
||||
|
@ -68,6 +80,10 @@
|
|||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/content_padding_half"
|
||||
android:layout_marginTop="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
android:layout_marginBottom="@dimen/content_padding_half"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/dlg_btn_primary">
|
||||
|
||||
|
@ -79,8 +95,6 @@
|
|||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding_small"
|
||||
android:text="@string/shared_string_continue"
|
||||
android:textColor="?attr/dlg_btn_primary_text"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -95,8 +109,8 @@
|
|||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
|
@ -104,24 +118,24 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/toolbar_height_expanded"
|
||||
android:background="?attr/actionModeBackground"
|
||||
osmand:collapsedTitleTextAppearance="@style/AppBarTitle"
|
||||
osmand:expandedTitleGravity="start|bottom"
|
||||
osmand:expandedTitleMarginBottom="@dimen/content_padding_small"
|
||||
osmand:expandedTitleMarginEnd="@dimen/content_padding"
|
||||
osmand:expandedTitleMarginStart="@dimen/content_padding"
|
||||
osmand:collapsedTitleTextAppearance="@style/AppBarTitle"
|
||||
osmand:expandedTitleGravity="start|bottom"
|
||||
osmand:expandedTitleTextAppearance="@style/AppBarTitle"
|
||||
osmand:layout_scrollFlags="scroll|exitUntilCollapsed">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
osmand:titleMarginEnd="0dp"
|
||||
osmand:titleMarginStart="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/toolbar_height"
|
||||
android:minHeight="@dimen/toolbar_height"
|
||||
osmand:layout_collapseMode="pin"
|
||||
osmand:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed"
|
||||
osmand:title="@string/shared_string_import">
|
||||
osmand:title="@string/shared_string_import"
|
||||
osmand:titleMarginEnd="0dp"
|
||||
osmand:titleMarginStart="0dp">
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
|
@ -132,8 +146,8 @@
|
|||
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="5dp"
|
||||
android:visibility="gone"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"
|
||||
osmand:mpb_progressStyle="horizontal"
|
||||
osmand:mpb_setBothDrawables="true"
|
||||
osmand:mpb_useIntrinsicPadding="false"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -22,7 +22,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp"
|
||||
android:minHeight="@dimen/setting_list_item_large_height"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
|
@ -72,11 +72,11 @@
|
|||
|
||||
<FrameLayout
|
||||
android:id="@+id/check_box_container"
|
||||
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
|
||||
android:layout_width="@dimen/acceptable_touch_radius"
|
||||
android:layout_height="@dimen/acceptable_touch_radius"
|
||||
android:layout_marginEnd="@dimen/text_margin_small"
|
||||
android:layout_marginRight="@dimen/text_margin_small"
|
||||
android:background="?attr/selectableItemBackgroundBorderless">
|
||||
android:layout_marginRight="@dimen/text_margin_small">
|
||||
|
||||
<net.osmand.view.ThreeStateCheckbox
|
||||
android:id="@+id/check_box"
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="file_size_needed_for_import">Needed for import</string>
|
||||
<string name="select_data_to_export">Select the data to be exported to the file.</string>
|
||||
<string name="approximate_file_size">Approximate file size</string>
|
||||
<string name="shared_string_resources">Resources</string>
|
||||
<string name="register_opr_have_account">I already have an account</string>
|
||||
<string name="register_opr_create_new_account">Create new account</string>
|
||||
<string name="register_on_openplacereviews_desc">Photos are provided by open data project OpenPlaceReviews.org. In order to upload your photos you need to sign up on website.</string>
|
||||
|
|
|
@ -2312,7 +2312,7 @@ public class OsmandAidlApi {
|
|||
File exportDir = app.getSettings().getExternalStorageDirectory();
|
||||
String fileName = appMode.toHumanString();
|
||||
SettingsHelper settingsHelper = app.getSettingsHelper();
|
||||
settingsItems.addAll(settingsHelper.getFilteredSettingsItems(settingsHelper.getAdditionalData(false), settingsTypes));
|
||||
settingsItems.addAll(settingsHelper.getFilteredSettingsItems(settingsTypes, false));
|
||||
settingsHelper.exportSettings(exportDir, fileName, null, settingsItems, true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package net.osmand.plus.settings.backend;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public enum ExportSettingsCategory {
|
||||
SETTINGS(R.string.shared_string_settings),
|
||||
MY_PLACES(R.string.shared_string_my_places),
|
||||
RESOURCES(R.string.shared_string_resources);
|
||||
|
||||
@StringRes
|
||||
private final int titleId;
|
||||
|
||||
ExportSettingsCategory(@StringRes int titleId) {
|
||||
this.titleId = titleId;
|
||||
}
|
||||
|
||||
public int getTitleId() {
|
||||
return titleId;
|
||||
}
|
||||
}
|
|
@ -1,22 +1,61 @@
|
|||
package net.osmand.plus.settings.backend;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public enum ExportSettingsType {
|
||||
PROFILE,
|
||||
QUICK_ACTIONS,
|
||||
POI_TYPES,
|
||||
MAP_SOURCES,
|
||||
CUSTOM_RENDER_STYLE,
|
||||
CUSTOM_ROUTING,
|
||||
AVOID_ROADS,
|
||||
TRACKS,
|
||||
MULTIMEDIA_NOTES,
|
||||
GLOBAL,
|
||||
OSM_NOTES,
|
||||
OSM_EDITS,
|
||||
OFFLINE_MAPS,
|
||||
FAVORITES,
|
||||
TTS_VOICE,
|
||||
VOICE,
|
||||
ACTIVE_MARKERS,
|
||||
HISTORY_MARKERS
|
||||
}
|
||||
PROFILE(R.string.shared_string_profiles, R.drawable.ic_action_manage_profiles),
|
||||
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),
|
||||
AVOID_ROADS(R.string.avoid_road, R.drawable.ic_action_alert),
|
||||
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),
|
||||
ACTIVE_MARKERS(R.string.map_markers, R.drawable.ic_action_flag),
|
||||
HISTORY_MARKERS(R.string.markers_history, R.drawable.ic_action_flag);
|
||||
|
||||
@StringRes
|
||||
private final int titleId;
|
||||
@DrawableRes
|
||||
private final int drawableRes;
|
||||
|
||||
ExportSettingsType(@StringRes int titleId, @DrawableRes int drawableRes) {
|
||||
this.titleId = titleId;
|
||||
this.drawableRes = drawableRes;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
public int getTitleId() {
|
||||
return titleId;
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
public int getIconRes() {
|
||||
return drawableRes;
|
||||
}
|
||||
|
||||
public boolean isSettingsCategory() {
|
||||
return this == PROFILE || this == GLOBAL || this == QUICK_ACTIONS || this == POI_TYPES;
|
||||
}
|
||||
|
||||
public boolean isMyPlacesCategory() {
|
||||
return this == FAVORITES || this == TRACKS || this == OSM_EDITS || this == OSM_NOTES
|
||||
|| this == MULTIMEDIA_NOTES || this == ACTIVE_MARKERS || this == HISTORY_MARKERS;
|
||||
}
|
||||
|
||||
public boolean isResourcesCategory() {
|
||||
return this == CUSTOM_RENDER_STYLE || this == CUSTOM_ROUTING || this == MAP_SOURCES
|
||||
|| this == OFFLINE_MAPS || this == VOICE || this == TTS_VOICE;
|
||||
}
|
||||
}
|
|
@ -39,7 +39,9 @@ import net.osmand.plus.quickaction.QuickAction;
|
|||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsCategory;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
import net.osmand.plus.settings.fragments.ExportDataObject;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -52,6 +54,7 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -465,6 +468,17 @@ public class SettingsHelper {
|
|||
exportSettings(fileDir, fileName, listener, new ArrayList<>(Arrays.asList(items)), exportItemsFiles);
|
||||
}
|
||||
|
||||
public List<SettingsItem> getFilteredSettingsItems(List<ExportSettingsType> settingsTypes, boolean globalExport) {
|
||||
Map<ExportSettingsCategory, List<ExportDataObject>> dataList = getAdditionalData(globalExport);
|
||||
Map<ExportSettingsType, List<?>> typesMap = new HashMap<>();
|
||||
for (List<ExportDataObject> objects : dataList.values()) {
|
||||
for (ExportDataObject exportObject : objects) {
|
||||
typesMap.put(exportObject.getType(), exportObject.getItems());
|
||||
}
|
||||
}
|
||||
return getFilteredSettingsItems(typesMap, settingsTypes);
|
||||
}
|
||||
|
||||
public List<SettingsItem> getFilteredSettingsItems(Map<ExportSettingsType, List<?>> additionalData,
|
||||
List<ExportSettingsType> settingsTypes) {
|
||||
List<SettingsItem> settingsItems = new ArrayList<>();
|
||||
|
@ -482,20 +496,129 @@ public class SettingsHelper {
|
|||
return settingsItems;
|
||||
}
|
||||
|
||||
public Map<ExportSettingsType, List<?>> getAdditionalData(boolean globalExport) {
|
||||
Map<ExportSettingsType, List<?>> dataList = new HashMap<>();
|
||||
public Map<ExportSettingsCategory, List<ExportDataObject>> getAdditionalData(boolean globalExport) {
|
||||
Map<ExportSettingsCategory, List<ExportDataObject>> dataList = new LinkedHashMap<>();
|
||||
|
||||
List<ExportDataObject> settingsItems = getSettingsItems(globalExport);
|
||||
List<ExportDataObject> myPlacesItems = getMyPlacesItems();
|
||||
List<ExportDataObject> resourcesItems = getResourcesItems();
|
||||
|
||||
if (!settingsItems.isEmpty()) {
|
||||
dataList.put(ExportSettingsCategory.SETTINGS, settingsItems);
|
||||
}
|
||||
if (!myPlacesItems.isEmpty()) {
|
||||
dataList.put(ExportSettingsCategory.MY_PLACES, myPlacesItems);
|
||||
}
|
||||
if (!resourcesItems.isEmpty()) {
|
||||
dataList.put(ExportSettingsCategory.RESOURCES, resourcesItems);
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
private List<ExportDataObject> getSettingsItems(boolean globalExport) {
|
||||
List<ExportDataObject> settingsItems = new ArrayList<>();
|
||||
|
||||
if (globalExport) {
|
||||
List<ApplicationModeBean> appModeBeans = new ArrayList<>();
|
||||
for (ApplicationMode mode : ApplicationMode.allPossibleValues()) {
|
||||
appModeBeans.add(mode.toModeBean());
|
||||
}
|
||||
settingsItems.add(new ExportDataObject(ExportSettingsType.PROFILE, appModeBeans));
|
||||
}
|
||||
settingsItems.add(new ExportDataObject(ExportSettingsType.GLOBAL, Collections.singletonList(new GlobalSettingsItem(app.getSettings()))));
|
||||
|
||||
QuickActionRegistry registry = app.getQuickActionRegistry();
|
||||
List<QuickAction> actionsList = registry.getQuickActions();
|
||||
if (!actionsList.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.QUICK_ACTIONS, actionsList);
|
||||
settingsItems.add(new ExportDataObject(ExportSettingsType.QUICK_ACTIONS, actionsList));
|
||||
}
|
||||
|
||||
List<PoiUIFilter> poiList = app.getPoiFilters().getUserDefinedPoiFilters(false);
|
||||
if (!poiList.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.POI_TYPES, poiList);
|
||||
settingsItems.add(new ExportDataObject(ExportSettingsType.POI_TYPES, poiList));
|
||||
}
|
||||
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
private List<ExportDataObject> getMyPlacesItems() {
|
||||
List<ExportDataObject> myPlacesItems = new ArrayList<>();
|
||||
|
||||
List<FavoriteGroup> favoriteGroups = app.getFavorites().getFavoriteGroups();
|
||||
if (!favoriteGroups.isEmpty()) {
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.FAVORITES, favoriteGroups));
|
||||
}
|
||||
File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
List<GPXInfo> gpxInfoList = GpxUiHelper.getSortedGPXFilesInfo(gpxDir, null, true);
|
||||
if (!gpxInfoList.isEmpty()) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (GPXInfo gpxInfo : gpxInfoList) {
|
||||
File file = new File(gpxInfo.getFileName());
|
||||
if (file.exists()) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (!files.isEmpty()) {
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.TRACKS, files));
|
||||
}
|
||||
}
|
||||
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
|
||||
if (osmEditingPlugin != null) {
|
||||
List<OsmNotesPoint> notesPointList = osmEditingPlugin.getDBBug().getOsmbugsPoints();
|
||||
if (!notesPointList.isEmpty()) {
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.OSM_NOTES, notesPointList));
|
||||
}
|
||||
List<OpenstreetmapPoint> editsPointList = osmEditingPlugin.getDBPOI().getOpenstreetmapPoints();
|
||||
if (!editsPointList.isEmpty()) {
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.OSM_EDITS, editsPointList));
|
||||
}
|
||||
}
|
||||
AudioVideoNotesPlugin plugin = OsmandPlugin.getPlugin(AudioVideoNotesPlugin.class);
|
||||
if (plugin != null) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (Recording rec : plugin.getAllRecordings()) {
|
||||
File file = rec.getFile();
|
||||
if (file != null && file.exists()) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (!files.isEmpty()) {
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.MULTIMEDIA_NOTES, files));
|
||||
}
|
||||
}
|
||||
List<MapMarker> mapMarkers = app.getMapMarkersHelper().getMapMarkersFromDefaultGroups(false);
|
||||
if (!mapMarkers.isEmpty()) {
|
||||
String name = app.getString(R.string.map_markers);
|
||||
String groupId = ExportSettingsType.ACTIVE_MARKERS.name();
|
||||
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
|
||||
markersGroup.setMarkers(mapMarkers);
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.ACTIVE_MARKERS, Collections.singletonList(markersGroup)));
|
||||
}
|
||||
List<MapMarker> markersHistory = app.getMapMarkersHelper().getMapMarkersFromDefaultGroups(true);
|
||||
if (!markersHistory.isEmpty()) {
|
||||
String name = app.getString(R.string.shared_string_history);
|
||||
String groupId = ExportSettingsType.HISTORY_MARKERS.name();
|
||||
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
|
||||
markersGroup.setMarkers(markersHistory);
|
||||
myPlacesItems.add(new ExportDataObject(ExportSettingsType.HISTORY_MARKERS, Collections.singletonList(markersGroup)));
|
||||
}
|
||||
return myPlacesItems;
|
||||
}
|
||||
|
||||
private List<ExportDataObject> getResourcesItems() {
|
||||
List<ExportDataObject> resourcesItems = new ArrayList<>();
|
||||
|
||||
Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers();
|
||||
if (!externalRenderers.isEmpty()) {
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.CUSTOM_RENDER_STYLE, new ArrayList<>(externalRenderers.values())));
|
||||
}
|
||||
File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR);
|
||||
if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) {
|
||||
File[] fl = routingProfilesFolder.listFiles();
|
||||
if (fl != null && fl.length > 0) {
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.CUSTOM_ROUTING, Arrays.asList(fl)));
|
||||
}
|
||||
}
|
||||
List<ITileSource> iTileSources = new ArrayList<>();
|
||||
Set<String> tileSourceNames = app.getSettings().getTileSourceEntries(true).keySet();
|
||||
for (String name : tileSourceNames) {
|
||||
|
@ -513,107 +636,29 @@ public class SettingsHelper {
|
|||
}
|
||||
}
|
||||
if (!iTileSources.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.MAP_SOURCES, iTileSources);
|
||||
}
|
||||
|
||||
Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers();
|
||||
if (!externalRenderers.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.CUSTOM_RENDER_STYLE, new ArrayList<>(externalRenderers.values()));
|
||||
}
|
||||
|
||||
File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR);
|
||||
if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) {
|
||||
File[] fl = routingProfilesFolder.listFiles();
|
||||
if (fl != null && fl.length > 0) {
|
||||
dataList.put(ExportSettingsType.CUSTOM_ROUTING, Arrays.asList(fl));
|
||||
}
|
||||
}
|
||||
|
||||
Map<LatLon, AvoidRoadInfo> impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
|
||||
if (!impassableRoads.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.AVOID_ROADS, new ArrayList<>(impassableRoads.values()));
|
||||
}
|
||||
AudioVideoNotesPlugin plugin = OsmandPlugin.getPlugin(AudioVideoNotesPlugin.class);
|
||||
if (plugin != null) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (Recording rec : plugin.getAllRecordings()) {
|
||||
File file = rec.getFile();
|
||||
if (file != null && file.exists()) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (!files.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.MULTIMEDIA_NOTES, files);
|
||||
}
|
||||
}
|
||||
File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
List<GPXInfo> gpxInfoList = GpxUiHelper.getSortedGPXFilesInfo(gpxDir, null, true);
|
||||
if (!gpxInfoList.isEmpty()) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (GPXInfo gpxInfo : gpxInfoList) {
|
||||
File file = new File(gpxInfo.getFileName());
|
||||
if (file.exists()) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (!files.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.TRACKS, files);
|
||||
}
|
||||
}
|
||||
if (globalExport) {
|
||||
List<ApplicationModeBean> appModeBeans = new ArrayList<>();
|
||||
for (ApplicationMode mode : ApplicationMode.allPossibleValues()) {
|
||||
appModeBeans.add(mode.toModeBean());
|
||||
}
|
||||
dataList.put(ExportSettingsType.PROFILE, appModeBeans);
|
||||
}
|
||||
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
|
||||
if (osmEditingPlugin != null) {
|
||||
List<OsmNotesPoint> notesPointList = osmEditingPlugin.getDBBug().getOsmbugsPoints();
|
||||
if (!notesPointList.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.OSM_NOTES, notesPointList);
|
||||
}
|
||||
List<OpenstreetmapPoint> editsPointList = osmEditingPlugin.getDBPOI().getOpenstreetmapPoints();
|
||||
if (!editsPointList.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.OSM_EDITS, editsPointList);
|
||||
}
|
||||
}
|
||||
List<FavoriteGroup> favoriteGroups = app.getFavorites().getFavoriteGroups();
|
||||
if (!favoriteGroups.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.FAVORITES, favoriteGroups);
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.MAP_SOURCES, iTileSources));
|
||||
}
|
||||
List<LocalIndexInfo> localIndexInfoList = getLocalIndexData();
|
||||
List<File> files = getFilesByType(localIndexInfoList, LocalIndexType.MAP_DATA, LocalIndexType.TILES_DATA,
|
||||
LocalIndexType.SRTM_DATA, LocalIndexType.WIKI_DATA);
|
||||
if (!files.isEmpty()) {
|
||||
sortLocalFiles(files);
|
||||
dataList.put(ExportSettingsType.OFFLINE_MAPS, files);
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.OFFLINE_MAPS, files));
|
||||
}
|
||||
files = getFilesByType(localIndexInfoList, LocalIndexType.TTS_VOICE_DATA);
|
||||
if (!files.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.TTS_VOICE, files);
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.TTS_VOICE, files));
|
||||
}
|
||||
files = getFilesByType(localIndexInfoList, LocalIndexType.VOICE_DATA);
|
||||
if (!files.isEmpty()) {
|
||||
dataList.put(ExportSettingsType.VOICE, files);
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.VOICE, files));
|
||||
}
|
||||
List<MapMarker> mapMarkers = app.getMapMarkersHelper().getMapMarkersFromDefaultGroups(false);
|
||||
if (!mapMarkers.isEmpty()) {
|
||||
String name = app.getString(R.string.map_markers);
|
||||
String groupId = ExportSettingsType.ACTIVE_MARKERS.name();
|
||||
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
|
||||
markersGroup.setMarkers(mapMarkers);
|
||||
dataList.put(ExportSettingsType.ACTIVE_MARKERS, Collections.singletonList(markersGroup));
|
||||
Map<LatLon, AvoidRoadInfo> impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
|
||||
if (!impassableRoads.isEmpty()) {
|
||||
resourcesItems.add(new ExportDataObject(ExportSettingsType.AVOID_ROADS, new ArrayList<>(impassableRoads.values())));
|
||||
}
|
||||
List<MapMarker> markersHistory = app.getMapMarkersHelper().getMapMarkersFromDefaultGroups(true);
|
||||
if (!markersHistory.isEmpty()) {
|
||||
String name = app.getString(R.string.shared_string_history);
|
||||
String groupId = ExportSettingsType.HISTORY_MARKERS.name();
|
||||
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
|
||||
markersGroup.setMarkers(markersHistory);
|
||||
dataList.put(ExportSettingsType.HISTORY_MARKERS, Collections.singletonList(markersGroup));
|
||||
}
|
||||
return dataList;
|
||||
|
||||
return resourcesItems;
|
||||
}
|
||||
|
||||
private List<LocalIndexInfo> getLocalIndexData() {
|
||||
|
@ -733,6 +778,37 @@ public class SettingsHelper {
|
|||
return settingsItems;
|
||||
}
|
||||
|
||||
public static Map<ExportSettingsCategory, List<ExportDataObject>> getSettingsToOperateByCategory(List<SettingsItem> items, boolean importComplete) {
|
||||
Map<ExportSettingsCategory, List<ExportDataObject>> exportMap = new LinkedHashMap<>();
|
||||
Map<ExportSettingsType, List<?>> settingsToOperate = getSettingsToOperate(items, importComplete);
|
||||
|
||||
List<ExportDataObject> settingsItems = new ArrayList<>();
|
||||
List<ExportDataObject> myPlacesItems = new ArrayList<>();
|
||||
List<ExportDataObject> resourcesItems = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<ExportSettingsType, List<?>> entry : settingsToOperate.entrySet()) {
|
||||
ExportSettingsType type = entry.getKey();
|
||||
if (type.isSettingsCategory()) {
|
||||
settingsItems.add(new ExportDataObject(type, entry.getValue()));
|
||||
} else if (type.isMyPlacesCategory()) {
|
||||
myPlacesItems.add(new ExportDataObject(type, entry.getValue()));
|
||||
} else if (type.isResourcesCategory()) {
|
||||
resourcesItems.add(new ExportDataObject(type, entry.getValue()));
|
||||
}
|
||||
}
|
||||
if (!settingsItems.isEmpty()) {
|
||||
exportMap.put(ExportSettingsCategory.SETTINGS, settingsItems);
|
||||
}
|
||||
if (!myPlacesItems.isEmpty()) {
|
||||
exportMap.put(ExportSettingsCategory.MY_PLACES, myPlacesItems);
|
||||
}
|
||||
if (!resourcesItems.isEmpty()) {
|
||||
exportMap.put(ExportSettingsCategory.RESOURCES, resourcesItems);
|
||||
}
|
||||
|
||||
return exportMap;
|
||||
}
|
||||
|
||||
public static Map<ExportSettingsType, List<?>> getSettingsToOperate(List<SettingsItem> settingsItems, boolean importComplete) {
|
||||
Map<ExportSettingsType, List<?>> settingsToOperate = new HashMap<>();
|
||||
List<ApplicationModeBean> profiles = new ArrayList<>();
|
||||
|
|
|
@ -31,12 +31,9 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsCollectListener;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
|
@ -44,6 +41,9 @@ import net.osmand.plus.helpers.FontCache;
|
|||
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
|
||||
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet;
|
||||
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet.CopyAppModePrefsListener;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsCollectListener;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItem;
|
||||
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet;
|
||||
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet.ResetAppModePrefsListener;
|
||||
|
@ -433,10 +433,7 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
|
|||
} else if (EXPORT_PROFILE.equals(prefId)) {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
if (fragmentManager != null) {
|
||||
ExportProfileBottomSheet.showInstance(
|
||||
fragmentManager,
|
||||
this,
|
||||
getSelectedAppMode(), false);
|
||||
ExportSettingsFragment.showInstance(fragmentManager, getSelectedAppMode(), false);
|
||||
}
|
||||
} else if (DELETE_PROFILE.equals(prefId)) {
|
||||
onDeleteProfileClick();
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ExportDataObject {
|
||||
|
||||
private ExportSettingsType type;
|
||||
private List<?> items;
|
||||
|
||||
public ExportDataObject(ExportSettingsType type, List<?> items) {
|
||||
this.type = type;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public ExportSettingsType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<?> getItems() {
|
||||
return items;
|
||||
}
|
||||
}
|
|
@ -4,8 +4,6 @@ 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;
|
||||
|
||||
|
@ -13,32 +11,16 @@ 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.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.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.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsCategory;
|
||||
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;
|
||||
|
@ -47,11 +29,10 @@ 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;
|
||||
|
@ -59,91 +40,94 @@ 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<ExportSettingsType, List<?>> itemsMap;
|
||||
private List<ExportSettingsType> itemsTypes;
|
||||
private boolean nightMode;
|
||||
private boolean importState;
|
||||
private int activeColorRes;
|
||||
private int secondaryColorRes;
|
||||
|
||||
ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode, boolean importState) {
|
||||
private final OsmandApplication app;
|
||||
private final UiUtilities uiUtilities;
|
||||
|
||||
private List<ExportSettingsCategory> itemsTypes = new ArrayList<>();
|
||||
private Map<ExportSettingsType, List<Object>> selectedItemsMap = new HashMap<>();
|
||||
private Map<ExportSettingsCategory, List<ExportDataObject>> 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) {
|
||||
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();
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
View group = convertView;
|
||||
if (group == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
group = inflater.inflate(R.layout.profile_data_list_item_group, parent, false);
|
||||
group = themedInflater.inflate(R.layout.profile_data_list_item_group, parent, false);
|
||||
}
|
||||
final ExportSettingsCategory category = itemsTypes.get(groupPosition);
|
||||
final List<ExportDataObject> items = itemsMap.get(category);
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
final ExportSettingsType type = itemsTypes.get(groupPosition);
|
||||
|
||||
String title = app.getString(category.getTitleId());
|
||||
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);
|
||||
final ThreeStateCheckbox checkBox = group.findViewById(R.id.check_box);
|
||||
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);
|
||||
subTextTv.setText(getCategoryDescr(category));
|
||||
|
||||
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 {
|
||||
boolean contains = false;
|
||||
for (Object object : listItems) {
|
||||
if (data.contains(object)) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
int selectedTypes = 0;
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ExportDataObject object = items.get(i);
|
||||
if (selectedItemsMap.containsKey(object.getType())) {
|
||||
selectedTypes++;
|
||||
}
|
||||
checkBox.setState(contains ? MISC : UNCHECKED);
|
||||
}
|
||||
final ThreeStateCheckbox checkBox = group.findViewById(R.id.check_box);
|
||||
if (selectedTypes == 0) {
|
||||
checkBox.setState(UNCHECKED);
|
||||
} else {
|
||||
checkBox.setState(selectedTypes == items.size() ? CHECKED : MISC);
|
||||
}
|
||||
int checkBoxColor = checkBox.getState() == UNCHECKED ? secondaryColorRes : activeColorRes;
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, checkBoxColor)));
|
||||
checkBoxContainer.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
group.findViewById(R.id.check_box_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
checkBox.performClick();
|
||||
if (checkBox.getState() == CHECKED) {
|
||||
for (Object object : listItems) {
|
||||
if (!data.contains(object)) {
|
||||
data.add(object);
|
||||
boolean selected = checkBox.getState() == CHECKED;
|
||||
if (selected) {
|
||||
for (ExportDataObject object : items) {
|
||||
if (!selectedItemsMap.containsKey(object.getType())) {
|
||||
selectedItemsMap.put(object.getType(), (List<Object>) object.getItems());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
data.removeAll(listItems);
|
||||
for (ExportDataObject object : items) {
|
||||
selectedItemsMap.remove(object.getType());
|
||||
}
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onCategorySelected(category, selected);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
|
||||
adjustIndicator(app, groupPosition, isExpanded, group, nightMode);
|
||||
AndroidUiHelper.updateVisibility(group.findViewById(R.id.divider), isExpanded);
|
||||
AndroidUiHelper.updateVisibility(group.findViewById(R.id.card_top_divider), true);
|
||||
AndroidUiHelper.updateVisibility(group.findViewById(R.id.vertical_divider), false);
|
||||
AndroidUiHelper.updateVisibility(group.findViewById(R.id.card_bottom_divider), !isExpanded);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
|
@ -151,168 +135,57 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
|||
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
View child = convertView;
|
||||
if (child == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false);
|
||||
child = themedInflater.inflate(R.layout.profile_data_list_item_group, parent, false);
|
||||
}
|
||||
final Object currentItem = itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
|
||||
final ExportDataObject currentItem = itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
|
||||
List<Object> selectedItems = selectedItemsMap.get(currentItem.getType());
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
boolean itemSelected = data.contains(currentItem);
|
||||
final ExportSettingsType type = itemsTypes.get(groupPosition);
|
||||
TextView titleTv = child.findViewById(R.id.title_tv);
|
||||
titleTv.setText(currentItem.getType().getTitleId());
|
||||
|
||||
TextView title = child.findViewById(R.id.title_tv);
|
||||
TextView subText = child.findViewById(R.id.sub_title_tv);
|
||||
subText.setVisibility(View.GONE);
|
||||
final CheckBox checkBox = child.findViewById(R.id.check_box);
|
||||
ImageView icon = child.findViewById(R.id.icon);
|
||||
View lineDivider = child.findViewById(R.id.divider);
|
||||
View cardBottomDivider = child.findViewById(R.id.card_bottom_divider);
|
||||
TextView subTextTv = child.findViewById(R.id.sub_text_tv);
|
||||
subTextTv.setText(getSelectedTypeDescr(currentItem));
|
||||
|
||||
lineDivider.setVisibility(!importState && isLastChild && !isLastGroup ? View.VISIBLE : View.GONE);
|
||||
cardBottomDivider.setVisibility(importState && isLastChild ? View.VISIBLE : View.GONE);
|
||||
int checkBoxColor = itemSelected ? activeColorRes : secondaryColorRes;
|
||||
ImageView icon = child.findViewById(R.id.explist_indicator);
|
||||
setupIcon(icon, currentItem.getType().getIconRes(), selectedItems != null);
|
||||
|
||||
final ThreeStateCheckbox checkBox = child.findViewById(R.id.check_box);
|
||||
if (selectedItems == null) {
|
||||
checkBox.setState(UNCHECKED);
|
||||
} else if (selectedItems.containsAll(currentItem.getItems())) {
|
||||
checkBox.setState(CHECKED);
|
||||
} else {
|
||||
boolean contains = false;
|
||||
for (Object object : currentItem.getItems()) {
|
||||
if (selectedItems.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)));
|
||||
|
||||
checkBox.setChecked(itemSelected);
|
||||
checkBox.setClickable(false);
|
||||
child.setOnClickListener(new View.OnClickListener() {
|
||||
child.findViewById(R.id.check_box_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (data.contains(currentItem)) {
|
||||
data.remove(currentItem);
|
||||
checkBox.performClick();
|
||||
boolean selected = checkBox.getState() == CHECKED;
|
||||
if (selected) {
|
||||
selectedItemsMap.put(currentItem.getType(), (List<Object>) currentItem.getItems());
|
||||
} else {
|
||||
data.add(currentItem);
|
||||
selectedItemsMap.remove(currentItem.getType());
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onTypeSelected(currentItem.getType(), selected);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
|
||||
switch (type) {
|
||||
case PROFILE:
|
||||
ApplicationModeBean modeBean = (ApplicationModeBean) currentItem;
|
||||
String profileName = modeBean.userProfileName;
|
||||
if (Algorithms.isEmpty(profileName)) {
|
||||
ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
|
||||
profileName = app.getString(appMode.getNameKeyResource());
|
||||
}
|
||||
title.setText(profileName);
|
||||
String routingProfile = "";
|
||||
String routingProfileValue = modeBean.routingProfile;
|
||||
if (!routingProfileValue.isEmpty()) {
|
||||
try {
|
||||
routingProfile = app.getString(RoutingProfilesResources.valueOf(routingProfileValue.toUpperCase()).getStringRes());
|
||||
routingProfile = Algorithms.capitalizeFirstLetterAndLowercase(routingProfile);
|
||||
} catch (IllegalArgumentException e) {
|
||||
routingProfile = Algorithms.capitalizeFirstLetterAndLowercase(routingProfileValue);
|
||||
LOG.error("Error trying to get routing resource for " + routingProfileValue + "\n" + e);
|
||||
}
|
||||
}
|
||||
if (!Algorithms.isEmpty(routingProfile)) {
|
||||
subText.setText(String.format(
|
||||
app.getString(R.string.ltr_or_rtl_combine_via_colon),
|
||||
app.getString(R.string.nav_type_hint),
|
||||
routingProfile));
|
||||
subText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
int profileIconRes = AndroidUtils.getDrawableId(app, modeBean.iconName);
|
||||
ProfileIconColors iconColor = modeBean.iconColor;
|
||||
icon.setImageDrawable(uiUtilities.getIcon(profileIconRes, iconColor.getColor(nightMode)));
|
||||
break;
|
||||
case QUICK_ACTIONS:
|
||||
title.setText(((QuickAction) currentItem).getName(app.getApplicationContext()));
|
||||
setupIcon(icon, ((QuickAction) currentItem).getIconRes(), itemSelected);
|
||||
break;
|
||||
case POI_TYPES:
|
||||
title.setText(((PoiUIFilter) currentItem).getName());
|
||||
int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId());
|
||||
setupIcon(icon, iconRes != 0 ? iconRes : R.drawable.ic_action_user, itemSelected);
|
||||
break;
|
||||
case MAP_SOURCES:
|
||||
title.setText(((ITileSource) currentItem).getName());
|
||||
setupIcon(icon, R.drawable.ic_map, itemSelected);
|
||||
break;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
String renderName = ((File) currentItem).getName();
|
||||
renderName = renderName.replace('_', ' ').replaceAll(IndexConstants.RENDERER_INDEX_EXT, "");
|
||||
title.setText(renderName);
|
||||
setupIcon(icon, R.drawable.ic_action_map_style, itemSelected);
|
||||
break;
|
||||
case CUSTOM_ROUTING:
|
||||
String routingName = ((File) currentItem).getName();
|
||||
routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
|
||||
title.setText(routingName);
|
||||
setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected);
|
||||
break;
|
||||
case AVOID_ROADS:
|
||||
AvoidRoadInfo avoidRoadInfo = (AvoidRoadInfo) currentItem;
|
||||
title.setText(avoidRoadInfo.name);
|
||||
setupIcon(icon, R.drawable.ic_action_alert, itemSelected);
|
||||
break;
|
||||
case MULTIMEDIA_NOTES:
|
||||
File file = (File) currentItem;
|
||||
title.setText(file.getName());
|
||||
int iconId = AudioVideoNotesPlugin.getIconIdForRecordingFile(file);
|
||||
if (iconId == -1) {
|
||||
iconId = R.drawable.ic_action_photo_dark;
|
||||
}
|
||||
setupIcon(icon, iconId, itemSelected);
|
||||
break;
|
||||
case TRACKS:
|
||||
String fileName = ((File) currentItem).getName();
|
||||
title.setText(GpxUiHelper.getGpxTitle(fileName));
|
||||
setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected);
|
||||
break;
|
||||
case GLOBAL:
|
||||
String name = ((GlobalSettingsItem) currentItem).getPublicName(app);
|
||||
title.setText(name);
|
||||
setupIcon(icon, R.drawable.ic_action_settings, itemSelected);
|
||||
break;
|
||||
case OSM_NOTES:
|
||||
title.setText(((OsmNotesPoint) currentItem).getText());
|
||||
setupIcon(icon, R.drawable.ic_action_osm_note_add, itemSelected);
|
||||
break;
|
||||
case OSM_EDITS:
|
||||
title.setText(OsmEditingPlugin.getTitle((OpenstreetmapPoint) currentItem, app));
|
||||
setupIcon(icon, R.drawable.ic_action_info_dark, itemSelected);
|
||||
break;
|
||||
case OFFLINE_MAPS:
|
||||
long size;
|
||||
if (currentItem instanceof FileSettingsItem) {
|
||||
FileSettingsItem currentFileItem = (FileSettingsItem) currentItem;
|
||||
file = currentFileItem.getFile();
|
||||
size = currentFileItem.getSize();
|
||||
} else {
|
||||
file = (File) currentItem;
|
||||
size = file.length();
|
||||
}
|
||||
title.setText(FileNameTranslationHelper.getFileNameWithRegion(app, file.getName()));
|
||||
FileSubtype subtype = FileSubtype.getSubtypeByPath(app, file.getPath());
|
||||
setupIcon(icon, subtype.getIconId(), itemSelected);
|
||||
subText.setText(AndroidUtils.formatSize(app, size));
|
||||
subText.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case FAVORITES:
|
||||
FavoriteGroup favoriteGroup = (FavoriteGroup) currentItem;
|
||||
title.setText(favoriteGroup.getDisplayName(app));
|
||||
setupIcon(icon, R.drawable.ic_action_favorite, itemSelected);
|
||||
break;
|
||||
case TTS_VOICE:
|
||||
case VOICE:
|
||||
file = (File) currentItem;
|
||||
title.setText(FileNameTranslationHelper.getFileNameWithRegion(app, file.getName()));
|
||||
setupIcon(icon, R.drawable.ic_action_volume_up, itemSelected);
|
||||
break;
|
||||
case ACTIVE_MARKERS:
|
||||
title.setText(R.string.map_markers);
|
||||
setupIcon(icon, R.drawable.ic_action_flag, itemSelected);
|
||||
break;
|
||||
case HISTORY_MARKERS:
|
||||
title.setText(R.string.markers_history);
|
||||
setupIcon(icon, R.drawable.ic_action_flag, itemSelected);
|
||||
break;
|
||||
default:
|
||||
return child;
|
||||
}
|
||||
AndroidUiHelper.updateVisibility(child.findViewById(R.id.card_bottom_divider), isLastChild);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
@ -356,78 +229,16 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
|||
return true;
|
||||
}
|
||||
|
||||
private String getSelectedItemsAmount(List<?> listItems, ExportSettingsType type) {
|
||||
int amount = 0;
|
||||
long amountSize = 0;
|
||||
for (Object item : listItems) {
|
||||
if (data.contains(item)) {
|
||||
amount++;
|
||||
if (type == OFFLINE_MAPS) {
|
||||
if (item instanceof FileSettingsItem) {
|
||||
amountSize += ((FileSettingsItem) item).getSize();
|
||||
} else {
|
||||
amountSize += ((File) item).length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String itemsOf = app.getString(R.string.n_items_of_z, String.valueOf(amount), String.valueOf(listItems.size()));
|
||||
return amountSize == 0 ? itemsOf : app.getString(R.string.ltr_or_rtl_combine_via_bold_point, itemsOf,
|
||||
AndroidUtils.formatSize(app, amountSize));
|
||||
}
|
||||
|
||||
private int getGroupTitle(ExportSettingsType type) {
|
||||
switch (type) {
|
||||
case PROFILE:
|
||||
return R.string.shared_string_profiles;
|
||||
case QUICK_ACTIONS:
|
||||
return R.string.configure_screen_quick_action;
|
||||
case POI_TYPES:
|
||||
return R.string.poi_dialog_poi_type;
|
||||
case MAP_SOURCES:
|
||||
return R.string.quick_action_map_source_title;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
return R.string.shared_string_rendering_style;
|
||||
case CUSTOM_ROUTING:
|
||||
return R.string.shared_string_routing;
|
||||
case AVOID_ROADS:
|
||||
return R.string.avoid_road;
|
||||
case TRACKS:
|
||||
return R.string.shared_string_tracks;
|
||||
case MULTIMEDIA_NOTES:
|
||||
return R.string.audionotes_plugin_name;
|
||||
case GLOBAL:
|
||||
return R.string.general_settings_2;
|
||||
case OSM_NOTES:
|
||||
return R.string.osm_notes;
|
||||
case OSM_EDITS:
|
||||
return R.string.osm_edits;
|
||||
case OFFLINE_MAPS:
|
||||
return R.string.shared_string_maps;
|
||||
case FAVORITES:
|
||||
return R.string.shared_string_favorites;
|
||||
case TTS_VOICE:
|
||||
return R.string.local_indexes_cat_tts;
|
||||
case VOICE:
|
||||
return R.string.local_indexes_cat_voice;
|
||||
case ACTIVE_MARKERS:
|
||||
return R.string.map_markers;
|
||||
case HISTORY_MARKERS:
|
||||
return R.string.markers_history;
|
||||
default:
|
||||
return R.string.access_empty_list;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupIcon(ImageView icon, int iconRes, boolean itemSelected) {
|
||||
if (itemSelected) {
|
||||
icon.setImageDrawable(uiUtilities.getIcon(iconRes, activeColorRes));
|
||||
int colorRes = nightMode ? R.color.icon_color_active_dark : R.color.icon_color_osmand_light;
|
||||
icon.setImageDrawable(uiUtilities.getIcon(iconRes, colorRes));
|
||||
} else {
|
||||
icon.setImageDrawable(uiUtilities.getIcon(iconRes, nightMode));
|
||||
icon.setImageDrawable(uiUtilities.getIcon(iconRes, secondaryColorRes));
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSettingsList(Map<ExportSettingsType, List<?>> itemsMap) {
|
||||
public void updateSettingsList(Map<ExportSettingsCategory, List<ExportDataObject>> itemsMap) {
|
||||
this.itemsMap = itemsMap;
|
||||
this.itemsTypes = new ArrayList<>(itemsMap.keySet());
|
||||
Collections.sort(itemsTypes);
|
||||
|
@ -440,17 +251,90 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void selectAll(boolean selectAll) {
|
||||
data.clear();
|
||||
if (selectAll) {
|
||||
for (List<?> values : itemsMap.values()) {
|
||||
data.addAll(values);
|
||||
}
|
||||
public List<? super Object> getData() {
|
||||
List<Object> selectedItems = new ArrayList<>();
|
||||
for (List<?> items : selectedItemsMap.values()) {
|
||||
selectedItems.addAll(items);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
return selectedItems;
|
||||
}
|
||||
|
||||
List<? super Object> getData() {
|
||||
return this.data;
|
||||
private String getCategoryDescr(ExportSettingsCategory category) {
|
||||
long itemsSize = 0;
|
||||
int selectedTypes = 0;
|
||||
List<ExportDataObject> items = itemsMap.get(category);
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ExportDataObject object = items.get(i);
|
||||
if (selectedItemsMap.containsKey(object.getType())) {
|
||||
selectedTypes++;
|
||||
itemsSize += calculateItemsSize(object.getItems());
|
||||
}
|
||||
}
|
||||
|
||||
String description;
|
||||
if (selectedTypes == 0) {
|
||||
description = app.getString(R.string.shared_string_none);
|
||||
} else if (selectedTypes == items.size()) {
|
||||
description = app.getString(R.string.shared_string_all);
|
||||
} else {
|
||||
description = app.getString(R.string.ltr_or_rtl_combine_via_slash, String.valueOf(selectedTypes), String.valueOf(items.size()));
|
||||
}
|
||||
String formattedSize = AndroidUtils.formatSize(app, itemsSize);
|
||||
return itemsSize == 0 ? description : app.getString(R.string.ltr_or_rtl_combine_via_comma, description, formattedSize);
|
||||
}
|
||||
|
||||
public static long calculateItemsSize(List<?> items) {
|
||||
long itemsSize = 0;
|
||||
for (Object item : items) {
|
||||
if (item instanceof FileSettingsItem) {
|
||||
itemsSize += ((FileSettingsItem) item).getSize();
|
||||
} else if (item instanceof File) {
|
||||
itemsSize += ((File) item).length();
|
||||
}
|
||||
}
|
||||
return itemsSize;
|
||||
}
|
||||
|
||||
private String getSelectedTypeDescr(ExportDataObject dataObject) {
|
||||
long itemsSize = 0;
|
||||
int selectedTypes = 0;
|
||||
|
||||
List<?> items = dataObject.getItems();
|
||||
List<Object> selectedItems = selectedItemsMap.get(dataObject.getType());
|
||||
if (selectedItems != null) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Object object = items.get(i);
|
||||
if (selectedItems.contains(object)) {
|
||||
selectedTypes++;
|
||||
if (object instanceof FileSettingsItem) {
|
||||
itemsSize += ((FileSettingsItem) object).getSize();
|
||||
} else if (object instanceof File) {
|
||||
itemsSize += ((File) object).length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String description;
|
||||
if (selectedTypes == 0) {
|
||||
description = app.getString(R.string.shared_string_none);
|
||||
} else if (selectedTypes == items.size()) {
|
||||
description = app.getString(R.string.shared_string_all);
|
||||
if (itemsSize == 0) {
|
||||
description = app.getString(R.string.ltr_or_rtl_combine_via_comma, description, String.valueOf(items.size()));
|
||||
}
|
||||
} else {
|
||||
description = app.getString(R.string.ltr_or_rtl_combine_via_slash, String.valueOf(selectedTypes), String.valueOf(items.size()));
|
||||
}
|
||||
String formattedSize = AndroidUtils.formatSize(app, itemsSize);
|
||||
return itemsSize == 0 ? description : app.getString(R.string.ltr_or_rtl_combine_via_comma, description, formattedSize);
|
||||
}
|
||||
|
||||
interface OnItemSelectedListener {
|
||||
|
||||
void onCategorySelected(ExportSettingsCategory type, boolean selected);
|
||||
|
||||
void onTypeSelected(ExportSettingsType type, boolean selected);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,429 +0,0 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.FileUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
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.plus.settings.backend.backup.ProfileSettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsExportListener;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItem;
|
||||
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
|
||||
|
||||
public static final String TAG = ExportProfileBottomSheet.class.getSimpleName();
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ExportProfileBottomSheet.class);
|
||||
|
||||
private static final String GLOBAL_EXPORT_KEY = "global_export_key";
|
||||
private static final String EXPORT_START_TIME_KEY = "export_start_time_key";
|
||||
private static final String EXPORTING_PROFILE_KEY = "exporting_profile_key";
|
||||
private static final String INCLUDE_ADDITIONAL_DATA_KEY = "include_additional_data_key";
|
||||
private static final String INCLUDE_GLOBAL_SETTINGS_KEY = "include_global_settings_key";
|
||||
private static final String PROGRESS_MAX_KEY = "progress_max_key";
|
||||
private static final String PROGRESS_VALUE_KEY = "progress_value_key";
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yy", Locale.US);
|
||||
|
||||
private OsmandApplication app;
|
||||
private Map<ExportSettingsType, List<?>> dataList = new HashMap<>();
|
||||
private ExportImportSettingsAdapter adapter;
|
||||
|
||||
private SettingsExportListener exportListener;
|
||||
private ProgressDialog progress;
|
||||
private int progressMax;
|
||||
private int progressValue;
|
||||
|
||||
private long exportStartTime;
|
||||
|
||||
private boolean globalExport = false;
|
||||
private boolean exportingProfile = false;
|
||||
private boolean includeAdditionalData = false;
|
||||
private boolean includeGlobalSettings = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requiredMyApplication();
|
||||
if (savedInstanceState != null) {
|
||||
globalExport = savedInstanceState.getBoolean(GLOBAL_EXPORT_KEY);
|
||||
exportingProfile = savedInstanceState.getBoolean(EXPORTING_PROFILE_KEY);
|
||||
includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY);
|
||||
includeGlobalSettings = savedInstanceState.getBoolean(INCLUDE_GLOBAL_SETTINGS_KEY);
|
||||
exportStartTime = savedInstanceState.getLong(EXPORT_START_TIME_KEY);
|
||||
progressMax = savedInstanceState.getInt(PROGRESS_MAX_KEY);
|
||||
progressValue = savedInstanceState.getInt(PROGRESS_VALUE_KEY);
|
||||
}
|
||||
dataList = app.getSettingsHelper().getAdditionalData(globalExport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(GLOBAL_EXPORT_KEY, globalExport);
|
||||
outState.putBoolean(EXPORTING_PROFILE_KEY, exportingProfile);
|
||||
outState.putBoolean(INCLUDE_ADDITIONAL_DATA_KEY, includeAdditionalData);
|
||||
outState.putBoolean(INCLUDE_GLOBAL_SETTINGS_KEY, includeGlobalSettings);
|
||||
outState.putLong(EXPORT_START_TIME_KEY, exportStartTime);
|
||||
outState.putInt(PROGRESS_MAX_KEY, progress.getMax());
|
||||
outState.putInt(PROGRESS_VALUE_KEY, progress.getProgress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
final Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
if (globalExport) {
|
||||
items.add(new TitleItem(getString(R.string.shared_string_export)));
|
||||
|
||||
final BottomSheetItemWithCompoundButton[] globalSettingsItem = new BottomSheetItemWithCompoundButton[1];
|
||||
globalSettingsItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setChecked(includeGlobalSettings)
|
||||
.setTitle(getString(R.string.general_settings_2))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
boolean checked = !globalSettingsItem[0].isChecked();
|
||||
globalSettingsItem[0].setChecked(checked);
|
||||
includeGlobalSettings = checked;
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(globalSettingsItem[0]);
|
||||
} else {
|
||||
items.add(new TitleItem(getString(R.string.export_profile)));
|
||||
ApplicationMode profile = getAppMode();
|
||||
int profileColor = profile.getIconColorInfo().getColor(nightMode);
|
||||
int colorNoAlpha = ContextCompat.getColor(context, profileColor);
|
||||
|
||||
Drawable backgroundIcon = UiUtilities.getColoredSelectableDrawable(context, colorNoAlpha, 0.3f);
|
||||
Drawable[] layers = {new ColorDrawable(UiUtilities.getColorWithAlpha(colorNoAlpha, 0.10f)), backgroundIcon};
|
||||
|
||||
BaseBottomSheetItem profileItem = new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setChecked(true)
|
||||
.setCompoundButtonColorId(profileColor)
|
||||
.setButtonTintList(ColorStateList.valueOf(getResolvedColor(profileColor)))
|
||||
.setDescription(BaseSettingsFragment.getAppModeDescription(context, profile))
|
||||
.setIcon(getIcon(profile.getIconRes(), profileColor))
|
||||
.setTitle(profile.toHumanString())
|
||||
.setBackground(new LayerDrawable(layers))
|
||||
.setLayoutId(R.layout.preference_profile_item_with_radio_btn)
|
||||
.create();
|
||||
items.add(profileItem);
|
||||
}
|
||||
setupAdditionalItems();
|
||||
}
|
||||
|
||||
private void setupAdditionalItems() {
|
||||
if (!dataList.isEmpty()) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
View additionalDataView = inflater.inflate(R.layout.bottom_sheet_item_additional_data, null);
|
||||
ExpandableListView listView = additionalDataView.findViewById(R.id.list);
|
||||
adapter = new ExportImportSettingsAdapter(app, nightMode, false);
|
||||
|
||||
View listHeader = inflater.inflate(R.layout.item_header_export_expand_list, null);
|
||||
final View topSwitchDivider = listHeader.findViewById(R.id.topSwitchDivider);
|
||||
final View bottomSwitchDivider = listHeader.findViewById(R.id.bottomSwitchDivider);
|
||||
final SwitchCompat switchItem = listHeader.findViewById(R.id.switchItem);
|
||||
switchItem.setTextColor(getResources().getColor(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light));
|
||||
switchItem.setChecked(includeAdditionalData);
|
||||
switchItem.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
includeAdditionalData = !includeAdditionalData;
|
||||
topSwitchDivider.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE);
|
||||
bottomSwitchDivider.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE);
|
||||
if (includeAdditionalData) {
|
||||
adapter.updateSettingsList(app.getSettingsHelper().getAdditionalData(globalExport));
|
||||
adapter.selectAll(true);
|
||||
} else {
|
||||
adapter.selectAll(false);
|
||||
adapter.clearSettingsList();
|
||||
}
|
||||
updateSwitch(switchItem);
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
});
|
||||
listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
|
||||
@Override
|
||||
public void onGroupExpand(int i) {
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
});
|
||||
|
||||
updateSwitch(switchItem);
|
||||
listView.addHeaderView(listHeader);
|
||||
listView.setAdapter(adapter);
|
||||
final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
|
||||
.setCustomView(additionalDataView)
|
||||
.create();
|
||||
items.add(titleItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSwitch(View view) {
|
||||
if (includeAdditionalData) {
|
||||
UiUtilities.setMargins(view, 0, 0, 0, 0);
|
||||
view.setPadding(AndroidUtils.dpToPx(app, 32), 0, AndroidUtils.dpToPx(app, 32), 0);
|
||||
} else {
|
||||
UiUtilities.setMargins(view, AndroidUtils.dpToPx(app, 16), 0, AndroidUtils.dpToPx(app, 16), 0);
|
||||
view.setPadding(AndroidUtils.dpToPx(app, 16), 0, AndroidUtils.dpToPx(app, 16), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRightBottomButtonTextId() {
|
||||
return R.string.shared_string_export;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRightBottomButtonClick() {
|
||||
prepareFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useScrollableItemsContainer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useExpandableList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
checkExportingFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (exportingProfile) {
|
||||
File file = getExportFile();
|
||||
app.getSettingsHelper().updateExportListener(file, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void setGlobalExport(boolean globalExport) {
|
||||
this.globalExport = globalExport;
|
||||
}
|
||||
|
||||
private List<SettingsItem> prepareSettingsItemsForExport() {
|
||||
List<SettingsItem> settingsItems = new ArrayList<>();
|
||||
if (!globalExport) {
|
||||
settingsItems.add(new ProfileSettingsItem(app, getAppMode()));
|
||||
}
|
||||
if (includeGlobalSettings) {
|
||||
settingsItems.add(new GlobalSettingsItem(app.getSettings()));
|
||||
}
|
||||
if (includeAdditionalData) {
|
||||
settingsItems.addAll(app.getSettingsHelper().prepareAdditionalSettingsItems(adapter.getData()));
|
||||
}
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
private void prepareFile() {
|
||||
if (app != null) {
|
||||
exportingProfile = true;
|
||||
exportStartTime = System.currentTimeMillis();
|
||||
showExportProgressDialog();
|
||||
File tempDir = FileUtils.getTempDir(app);
|
||||
String fileName = getFileName();
|
||||
List<SettingsItem> items = prepareSettingsItemsForExport();
|
||||
progress.setMax(getMaxProgress(items));
|
||||
app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), items, true);
|
||||
}
|
||||
}
|
||||
|
||||
private int getMaxProgress(List<SettingsItem> items) {
|
||||
long maxProgress = 0;
|
||||
for (SettingsItem item : items) {
|
||||
if (item instanceof FileSettingsItem) {
|
||||
maxProgress += ((FileSettingsItem) item).getSize();
|
||||
}
|
||||
}
|
||||
return (int) maxProgress / (1 << 20);
|
||||
}
|
||||
|
||||
private String getFileName() {
|
||||
if (globalExport) {
|
||||
if (exportStartTime == 0) {
|
||||
exportStartTime = System.currentTimeMillis();
|
||||
}
|
||||
return "Export_" + DATE_FORMAT.format(new Date(exportStartTime));
|
||||
} else {
|
||||
return getAppMode().toHumanString();
|
||||
}
|
||||
}
|
||||
|
||||
private void showExportProgressDialog() {
|
||||
Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
if (progress != null) {
|
||||
progress.dismiss();
|
||||
}
|
||||
progress = new ProgressDialog(context);
|
||||
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
progress.setCancelable(true);
|
||||
progress.setTitle(app.getString(R.string.shared_string_export));
|
||||
progress.setMessage(app.getString(R.string.shared_string_preparing));
|
||||
progress.setButton(DialogInterface.BUTTON_NEGATIVE, app.getString(R.string.shared_string_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
cancelExport();
|
||||
}
|
||||
});
|
||||
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
cancelExport();
|
||||
}
|
||||
});
|
||||
progress.show();
|
||||
}
|
||||
|
||||
private void cancelExport() {
|
||||
app.getSettingsHelper().cancelExportForFile(getExportFile());
|
||||
progress.dismiss();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private SettingsExportListener getSettingsExportListener() {
|
||||
if (exportListener == null) {
|
||||
exportListener = new SettingsExportListener() {
|
||||
|
||||
@Override
|
||||
public void onSettingsExportFinished(@NonNull File file, boolean succeed) {
|
||||
dismissExportProgressDialog();
|
||||
exportingProfile = false;
|
||||
if (succeed) {
|
||||
shareProfile(file);
|
||||
} else {
|
||||
app.showToastMessage(R.string.export_profile_failed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsExportProgressUpdate(int value) {
|
||||
progress.setProgress(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
return exportListener;
|
||||
}
|
||||
|
||||
private void checkExportingFile() {
|
||||
if (exportingProfile) {
|
||||
File file = getExportFile();
|
||||
boolean fileExporting = app.getSettingsHelper().isFileExporting(file);
|
||||
if (fileExporting) {
|
||||
showExportProgressDialog();
|
||||
progress.setMax(progressMax);
|
||||
progress.setProgress(progressValue);
|
||||
app.getSettingsHelper().updateExportListener(file, getSettingsExportListener());
|
||||
} else if (file.exists()) {
|
||||
dismissExportProgressDialog();
|
||||
shareProfile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dismissExportProgressDialog() {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (progress != null && activity != null && AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
progress.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private File getExportFile() {
|
||||
File tempDir = FileUtils.getTempDir(app);
|
||||
String fileName = getFileName();
|
||||
return new File(tempDir, fileName + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
|
||||
}
|
||||
|
||||
private void shareProfile(@NonNull File file) {
|
||||
try {
|
||||
final Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_SUBJECT, file.getName());
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), file));
|
||||
sendIntent.setType("*/*");
|
||||
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(sendIntent);
|
||||
dismiss();
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(requireContext(), R.string.export_profile_failed, Toast.LENGTH_SHORT).show();
|
||||
LOG.error("Share profile error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull FragmentManager fragmentManager,
|
||||
Fragment target, @NonNull ApplicationMode appMode,
|
||||
boolean globalExport) {
|
||||
try {
|
||||
ExportProfileBottomSheet fragment = new ExportProfileBottomSheet();
|
||||
fragment.setAppMode(appMode);
|
||||
fragment.setGlobalExport(globalExport);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.show(fragmentManager, TAG);
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,405 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
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 android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.FileUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsCategory;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
import net.osmand.plus.settings.backend.backup.FileSettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsExportListener;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItem;
|
||||
import net.osmand.plus.settings.fragments.ExportImportSettingsAdapter.OnItemSelectedListener;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.plus.settings.fragments.BaseSettingsFragment.APP_MODE_KEY;
|
||||
|
||||
public class ExportSettingsFragment extends BaseOsmAndFragment implements OnItemSelectedListener {
|
||||
|
||||
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
|
||||
public static final Log LOG = PlatformUtil.getLog(ImportSettingsFragment.class.getSimpleName());
|
||||
|
||||
private static final String EXPORT_SETTINGS_TAG = "import_settings_tag";
|
||||
private static final String GLOBAL_EXPORT_KEY = "global_export_key";
|
||||
private static final String EXPORT_START_TIME_KEY = "export_start_time_key";
|
||||
private static final String EXPORTING_STARTED_KEY = "exporting_started_key";
|
||||
private static final String INCLUDE_ADDITIONAL_DATA_KEY = "include_additional_data_key";
|
||||
private static final String INCLUDE_GLOBAL_SETTINGS_KEY = "include_global_settings_key";
|
||||
private static final String PROGRESS_MAX_KEY = "progress_max_key";
|
||||
private static final String PROGRESS_VALUE_KEY = "progress_value_key";
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yy", Locale.US);
|
||||
|
||||
private OsmandApplication app;
|
||||
private Map<ExportSettingsCategory, List<ExportDataObject>> dataList;
|
||||
|
||||
private ProgressDialog progress;
|
||||
private ApplicationMode appMode;
|
||||
private SettingsExportListener exportListener;
|
||||
|
||||
private TextViewEx fileSize;
|
||||
private LinearLayout buttonsContainer;
|
||||
private ExpandableListView expandableList;
|
||||
private ExportImportSettingsAdapter adapter;
|
||||
|
||||
private int progressMax;
|
||||
private int progressValue;
|
||||
|
||||
private long exportStartTime;
|
||||
|
||||
private boolean nightMode;
|
||||
private boolean globalExport;
|
||||
private boolean exportingStarted;
|
||||
|
||||
@Override
|
||||
public int getStatusBarColorId() {
|
||||
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requireMyApplication();
|
||||
nightMode = !app.getSettings().isLightContent();
|
||||
if (savedInstanceState != null) {
|
||||
appMode = ApplicationMode.valueOfStringKey(savedInstanceState.getString(APP_MODE_KEY), null);
|
||||
globalExport = savedInstanceState.getBoolean(GLOBAL_EXPORT_KEY);
|
||||
exportingStarted = savedInstanceState.getBoolean(EXPORTING_STARTED_KEY);
|
||||
exportStartTime = savedInstanceState.getLong(EXPORT_START_TIME_KEY);
|
||||
progressMax = savedInstanceState.getInt(PROGRESS_MAX_KEY);
|
||||
progressValue = savedInstanceState.getInt(PROGRESS_VALUE_KEY);
|
||||
}
|
||||
dataList = app.getSettingsHelper().getAdditionalData(globalExport);
|
||||
|
||||
requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
showExitDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(app, nightMode);
|
||||
View root = themedInflater.inflate(R.layout.fragment_import, container, false);
|
||||
AndroidUtils.addStatusBarPadding21v(app, root);
|
||||
|
||||
fileSize = root.findViewById(R.id.file_size);
|
||||
expandableList = root.findViewById(R.id.list);
|
||||
buttonsContainer = root.findViewById(R.id.buttons_container);
|
||||
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
setupToolbar(toolbar);
|
||||
ViewCompat.setNestedScrollingEnabled(expandableList, true);
|
||||
View header = themedInflater.inflate(R.layout.list_item_description_header, null);
|
||||
expandableList.addHeaderView(header);
|
||||
|
||||
TextViewEx continueBtn = root.findViewById(R.id.continue_button);
|
||||
continueBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
prepareFile();
|
||||
}
|
||||
});
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
adapter = new ExportImportSettingsAdapter(app, this, nightMode);
|
||||
adapter.updateSettingsList(dataList);
|
||||
expandableList.setAdapter(adapter);
|
||||
|
||||
CollapsingToolbarLayout toolbarLayout = root.findViewById(R.id.toolbar_layout);
|
||||
toolbarLayout.setTitle(getString(R.string.shared_string_export));
|
||||
TextView description = header.findViewById(R.id.description);
|
||||
description.setText(R.string.select_data_to_export);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(GLOBAL_EXPORT_KEY, globalExport);
|
||||
outState.putBoolean(EXPORTING_STARTED_KEY, exportingStarted);
|
||||
outState.putLong(EXPORT_START_TIME_KEY, exportStartTime);
|
||||
outState.putString(APP_MODE_KEY, appMode.getStringKey());
|
||||
if (progress != null) {
|
||||
outState.putInt(PROGRESS_MAX_KEY, progress.getMax());
|
||||
outState.putInt(PROGRESS_VALUE_KEY, progress.getProgress());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
checkExportingFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (exportingStarted) {
|
||||
File file = getExportFile();
|
||||
app.getSettingsHelper().updateExportListener(file, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void dismissFragment() {
|
||||
FragmentManager fm = getFragmentManager();
|
||||
if (fm != null && !fm.isStateSaved()) {
|
||||
getFragmentManager().popBackStack(EXPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void showExitDialog() {
|
||||
Context themedContext = UiUtilities.getThemedContext(getActivity(), nightMode);
|
||||
AlertDialog.Builder dismissDialog = new AlertDialog.Builder(themedContext);
|
||||
dismissDialog.setTitle(getString(R.string.shared_string_dismiss));
|
||||
dismissDialog.setMessage(getString(R.string.exit_without_saving));
|
||||
dismissDialog.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismissFragment();
|
||||
}
|
||||
});
|
||||
dismissDialog.show();
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
int color = ContextCompat.getColor(app, nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light);
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_action_close, color));
|
||||
toolbar.setNavigationContentDescription(R.string.shared_string_close);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showExitDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateFileSize() {
|
||||
long itemsSize = ExportImportSettingsAdapter.calculateItemsSize(adapter.getData());
|
||||
String size = itemsSize != 0 ? AndroidUtils.formatSize(app, itemsSize) : "";
|
||||
fileSize.setText(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategorySelected(ExportSettingsCategory type, boolean selected) {
|
||||
updateFileSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTypeSelected(ExportSettingsType type, boolean selected) {
|
||||
updateFileSize();
|
||||
}
|
||||
|
||||
private void prepareFile() {
|
||||
if (app != null) {
|
||||
exportingStarted = true;
|
||||
exportStartTime = System.currentTimeMillis();
|
||||
showExportProgressDialog();
|
||||
File tempDir = FileUtils.getTempDir(app);
|
||||
String fileName = getFileName();
|
||||
List<SettingsItem> items = app.getSettingsHelper().prepareAdditionalSettingsItems(adapter.getData());
|
||||
progress.setMax(getMaxProgress(items));
|
||||
app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), items, true);
|
||||
}
|
||||
}
|
||||
|
||||
private int getMaxProgress(List<SettingsItem> items) {
|
||||
long maxProgress = 0;
|
||||
for (SettingsItem item : items) {
|
||||
if (item instanceof FileSettingsItem) {
|
||||
maxProgress += ((FileSettingsItem) item).getSize();
|
||||
}
|
||||
}
|
||||
return (int) maxProgress / (1 << 20);
|
||||
}
|
||||
|
||||
private String getFileName() {
|
||||
if (globalExport) {
|
||||
if (exportStartTime == 0) {
|
||||
exportStartTime = System.currentTimeMillis();
|
||||
}
|
||||
return "Export_" + DATE_FORMAT.format(new Date(exportStartTime));
|
||||
} else {
|
||||
return appMode.toHumanString();
|
||||
}
|
||||
}
|
||||
|
||||
private void showExportProgressDialog() {
|
||||
Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
if (progress != null) {
|
||||
progress.dismiss();
|
||||
}
|
||||
progress = new ProgressDialog(context);
|
||||
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
progress.setCancelable(true);
|
||||
progress.setTitle(app.getString(R.string.shared_string_export));
|
||||
progress.setMessage(app.getString(R.string.shared_string_preparing));
|
||||
progress.setButton(DialogInterface.BUTTON_NEGATIVE, app.getString(R.string.shared_string_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
cancelExport();
|
||||
}
|
||||
});
|
||||
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
cancelExport();
|
||||
}
|
||||
});
|
||||
progress.show();
|
||||
}
|
||||
|
||||
private void cancelExport() {
|
||||
app.getSettingsHelper().cancelExportForFile(getExportFile());
|
||||
progress.dismiss();
|
||||
dismissFragment();
|
||||
}
|
||||
|
||||
private SettingsExportListener getSettingsExportListener() {
|
||||
if (exportListener == null) {
|
||||
exportListener = new SettingsExportListener() {
|
||||
|
||||
@Override
|
||||
public void onSettingsExportFinished(@NonNull File file, boolean succeed) {
|
||||
dismissExportProgressDialog();
|
||||
exportingStarted = false;
|
||||
if (succeed) {
|
||||
shareProfile(file);
|
||||
} else {
|
||||
app.showToastMessage(R.string.export_profile_failed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsExportProgressUpdate(int value) {
|
||||
progress.setProgress(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
return exportListener;
|
||||
}
|
||||
|
||||
private void checkExportingFile() {
|
||||
if (exportingStarted) {
|
||||
File file = getExportFile();
|
||||
boolean fileExporting = app.getSettingsHelper().isFileExporting(file);
|
||||
if (fileExporting) {
|
||||
showExportProgressDialog();
|
||||
progress.setMax(progressMax);
|
||||
progress.setProgress(progressValue);
|
||||
app.getSettingsHelper().updateExportListener(file, getSettingsExportListener());
|
||||
} else if (file.exists()) {
|
||||
dismissExportProgressDialog();
|
||||
shareProfile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dismissExportProgressDialog() {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (progress != null && activity != null && AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
progress.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private File getExportFile() {
|
||||
File tempDir = FileUtils.getTempDir(app);
|
||||
String fileName = getFileName();
|
||||
return new File(tempDir, fileName + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
|
||||
}
|
||||
|
||||
private void shareProfile(@NonNull File file) {
|
||||
try {
|
||||
final Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_SUBJECT, file.getName());
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), file));
|
||||
sendIntent.setType("*/*");
|
||||
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(sendIntent);
|
||||
dismissFragment();
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(requireContext(), R.string.export_profile_failed, Toast.LENGTH_SHORT).show();
|
||||
LOG.error("Share profile error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull FragmentManager fragmentManager, @NonNull ApplicationMode appMode, boolean globalExport) {
|
||||
try {
|
||||
ExportSettingsFragment fragment = new ExportSettingsFragment();
|
||||
fragment.appMode = appMode;
|
||||
fragment.globalExport = globalExport;
|
||||
fragmentManager.beginTransaction().
|
||||
replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(EXPORT_SETTINGS_TAG)
|
||||
.commitAllowingStateLoss();
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,13 +22,13 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||
|
@ -48,6 +48,7 @@ import net.osmand.plus.osmedit.OsmNotesPoint;
|
|||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsCategory;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
import net.osmand.plus.settings.backend.backup.AvoidRoadsSettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.FavoritesSettingsItem;
|
||||
|
@ -66,38 +67,44 @@ import net.osmand.plus.settings.backend.backup.SettingsHelper.ImportAsyncTask;
|
|||
import net.osmand.plus.settings.backend.backup.SettingsHelper.ImportType;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItemType;
|
||||
import net.osmand.plus.settings.fragments.ExportImportSettingsAdapter.OnItemSelectedListener;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ImportSettingsFragment extends BaseOsmAndFragment {
|
||||
public class ImportSettingsFragment extends BaseOsmAndFragment implements OnItemSelectedListener {
|
||||
|
||||
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
|
||||
public static final Log LOG = PlatformUtil.getLog(ImportSettingsFragment.class.getSimpleName());
|
||||
|
||||
protected static final String IMPORT_SETTINGS_TAG = "import_settings_tag";
|
||||
private static final String DUPLICATES_START_TIME_KEY = "duplicates_start_time";
|
||||
private static final long MIN_DELAY_TIME_MS = 500;
|
||||
static final String IMPORT_SETTINGS_TAG = "import_settings_tag";
|
||||
|
||||
private OsmandApplication app;
|
||||
|
||||
private File file;
|
||||
private SettingsHelper settingsHelper;
|
||||
private List<SettingsItem> settingsItems;
|
||||
private Map<ExportSettingsCategory, List<ExportDataObject>> dataList;
|
||||
|
||||
private ExportImportSettingsAdapter adapter;
|
||||
private ExpandableListView expandableList;
|
||||
private TextViewEx selectBtn;
|
||||
private TextView description;
|
||||
private List<SettingsItem> settingsItems;
|
||||
private File file;
|
||||
private boolean allSelected;
|
||||
private boolean nightMode;
|
||||
private LinearLayout buttonsContainer;
|
||||
private ProgressBar progressBar;
|
||||
private TextViewEx fileSize;
|
||||
private TextViewEx fileSizeDescr;
|
||||
private CollapsingToolbarLayout toolbarLayout;
|
||||
private SettingsHelper settingsHelper;
|
||||
|
||||
private boolean nightMode;
|
||||
private long duplicateStartTime;
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fm, @NonNull List<SettingsItem> settingsItems, @NonNull File file) {
|
||||
|
@ -134,11 +141,13 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
View root = inflater.inflate(R.layout.fragment_import, container, false);
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
TextViewEx continueBtn = root.findViewById(R.id.continue_button);
|
||||
fileSize = root.findViewById(R.id.file_size);
|
||||
toolbarLayout = root.findViewById(R.id.toolbar_layout);
|
||||
selectBtn = root.findViewById(R.id.select_button);
|
||||
expandableList = root.findViewById(R.id.list);
|
||||
buttonsContainer = root.findViewById(R.id.buttons_container);
|
||||
progressBar = root.findViewById(R.id.progress_bar);
|
||||
fileSizeDescr = root.findViewById(R.id.file_size_descr);
|
||||
fileSizeDescr.setText(R.string.file_size_needed_for_import);
|
||||
setupToolbar(toolbar);
|
||||
ViewCompat.setNestedScrollingEnabled(expandableList, true);
|
||||
View header = inflater.inflate(R.layout.list_item_description_header, null);
|
||||
|
@ -155,14 +164,6 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
}
|
||||
});
|
||||
selectBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
allSelected = !allSelected;
|
||||
selectBtn.setText(allSelected ? R.string.shared_string_deselect_all : R.string.shared_string_select_all);
|
||||
adapter.selectAll(allSelected);
|
||||
}
|
||||
});
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
AndroidUtils.addStatusBarPadding21v(app, root);
|
||||
}
|
||||
|
@ -207,10 +208,10 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
}
|
||||
|
||||
adapter = new ExportImportSettingsAdapter(app, nightMode, true);
|
||||
Map<ExportSettingsType, List<?>> itemsMap = new HashMap<>();
|
||||
adapter = new ExportImportSettingsAdapter(app, this, nightMode);
|
||||
Map<ExportSettingsCategory, List<ExportDataObject>> itemsMap = new HashMap<>();
|
||||
if (settingsItems != null) {
|
||||
itemsMap = SettingsHelper.getSettingsToOperate(settingsItems, false);
|
||||
itemsMap = SettingsHelper.getSettingsToOperateByCategory(settingsItems, false);
|
||||
adapter.updateSettingsList(itemsMap);
|
||||
}
|
||||
expandableList.setAdapter(adapter);
|
||||
|
@ -224,7 +225,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
} else {
|
||||
toolbarLayout.setTitle(getString(R.string.shared_string_import));
|
||||
}
|
||||
if (itemsMap.size() == 1 && itemsMap.containsKey(ExportSettingsType.PROFILE)) {
|
||||
if (itemsMap.size() == 1 && itemsMap.containsKey(ExportSettingsCategory.SETTINGS)) {
|
||||
expandableList.expandGroup(0);
|
||||
}
|
||||
}
|
||||
|
@ -235,15 +236,6 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
outState.putLong(DUPLICATES_START_TIME_KEY, duplicateStartTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Activity activity = getActivity();
|
||||
if (activity instanceof MapActivity) {
|
||||
((MapActivity) activity).closeDrawer();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUi(int toolbarTitleRes, int descriptionRes) {
|
||||
if (file != null) {
|
||||
String fileName = file.getName();
|
||||
|
@ -296,31 +288,6 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private static class ReloadIndexesTack extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private final WeakReference<MapActivity> mapActivityRef;
|
||||
private final OsmandApplication app;
|
||||
|
||||
ReloadIndexesTack(@NonNull MapActivity mapActivity) {
|
||||
this.mapActivityRef = new WeakReference<>(mapActivity);
|
||||
this.app = mapActivity.getMyApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void[] params) {
|
||||
app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList<String>());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
MapActivity mapActivity = mapActivityRef.get();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.refreshMap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SettingsHelper.CheckDuplicatesListener getDuplicatesListener() {
|
||||
return new SettingsHelper.CheckDuplicatesListener() {
|
||||
@Override
|
||||
|
@ -544,9 +511,8 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_action_close, nightMode
|
||||
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
|
||||
: getResources().getColor(R.color.active_buttons_and_links_text_light)));
|
||||
int color = ContextCompat.getColor(app, nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light);
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_action_close, color));
|
||||
toolbar.setNavigationContentDescription(R.string.shared_string_close);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -559,4 +525,20 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
private void updateFileSize() {
|
||||
long itemsSize = ExportImportSettingsAdapter.calculateItemsSize(adapter.getData());
|
||||
String size = itemsSize != 0 ? AndroidUtils.formatSize(app, itemsSize) : "";
|
||||
fileSize.setText(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategorySelected(ExportSettingsCategory type, boolean selected) {
|
||||
updateFileSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTypeSelected(ExportSettingsType type, boolean selected) {
|
||||
updateFileSize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ public class MainSettingsFragment extends BaseSettingsFragment {
|
|||
if (mapActivity != null) {
|
||||
ApplicationMode mode = getSelectedAppMode();
|
||||
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
|
||||
ExportProfileBottomSheet.showInstance(fragmentManager, this, mode, true);
|
||||
ExportSettingsFragment.showInstance(fragmentManager, mode, true);
|
||||
}
|
||||
}
|
||||
return super.onPreferenceClick(preference);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class ReloadIndexesTack extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private final WeakReference<MapActivity> mapActivityRef;
|
||||
private final OsmandApplication app;
|
||||
|
||||
ReloadIndexesTack(@NonNull MapActivity mapActivity) {
|
||||
this.mapActivityRef = new WeakReference<>(mapActivity);
|
||||
this.app = mapActivity.getMyApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void[] params) {
|
||||
app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList<String>());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
MapActivity mapActivity = mapActivityRef.get();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.refreshMap();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue