Merge remote-tracking branch 'origin/master' into slope_hillshade_ui

# Conflicts:
#	OsmAnd/res/values/strings.xml
This commit is contained in:
veliymolfar 2020-03-13 17:13:50 +02:00
commit 8dac325964
26 changed files with 1097 additions and 464 deletions

View file

@ -128,6 +128,16 @@
</com.google.android.material.appbar.CollapsingToolbarLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/activity_background_basic">
<androidx.core.widget.NestedScrollView
android:id="@+id/nested_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
osmand:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/list_header_settings_top_margin"
android:paddingEnd="@dimen/content_padding"
android:paddingBottom="@dimen/list_header_settings_top_margin"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/import_complete_description" />
<include
layout="@layout/divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingBottom="@dimen/bottom_sheet_cancel_button_height" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?attr/bg_color"
android:orientation="vertical">
<include layout="@layout/divider" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dialog_button_height"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding_small"
android:background="?attr/dlg_btn_secondary">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/button_close"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="@string/shared_string_close"
android:textColor="?attr/active_color_basic"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Button" />
</FrameLayout>
</LinearLayout>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height_expanded"
android:background="?attr/colorPrimary"
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"
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_complete"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<ImageView
android:id="@+id/shadowView"
android:layout_width="match_parent"
android:layout_height="@dimen/abp__shadow_height"
android:src="@drawable/preference_activity_action_bar_shadow"
tools:ignore="ContentDescription" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -3,6 +3,7 @@
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/activity_background_basic">
<androidx.core.widget.NestedScrollView
@ -128,12 +129,22 @@
osmand:titleMarginStart="0dp"
osmand:layout_collapseMode="pin"
osmand:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed"
osmand:title="@string/import_duplicates_title">
tools:title="@string/import_duplicates_title">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -7,49 +7,57 @@
android:minHeight="@dimen/setting_list_item_small_height"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
<FrameLayout
android:background="?attr/bg_color"
android:gravity="center_vertical">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
tools:src="@drawable/ic_action_offroad" />
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="@dimen/content_padding_small"
android:paddingBottom="@dimen/content_padding_small">
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
tools:src="@drawable/ic_action_offroad" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="OffRoad" />
android:orientation="vertical"
android:paddingTop="@dimen/content_padding_small"
android:paddingBottom="@dimen/content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Navigation type: Car" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="OffRoad" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Navigation type: Car" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
<include
android:id="@+id/bottom_divider"

View file

@ -17,6 +17,12 @@
<string name="restore_all_profile_settings">Restore all profile settings?</string>
<string name="saving_new_profile">Saving new profile</string>
<string name="profile_backup_failed">Could not back up profile.</string>
<string name="importing_from">Importing data from %1$s</string>
<string name="shared_string_importing">Importing</string>
<string name="checking_for_duplicate_description">OsmAnd check %1$s for duplicates with existing items in the application.\n\nIt may take some time.</string>
<string name="items_added">Items added</string>
<string name="shared_string_import_complete">Import complete</string>
<string name="import_complete_description">All data from the %1$s is imported, you can use buttons below to open needed part of the application to manage it.</string>
<string name="shared_string_hillshade">Hillshade</string>
<string name="terrain_empty_state_text">Enable to view hillshade or slope map. You can read more about this map types on our site</string>
<string name="shared_string_legend">Legend</string>

View file

@ -126,9 +126,9 @@ public class SQLiteTileSource implements ITileSource {
db = ctx.getSQLiteAPI().getOrCreateDatabase(
ctx.getAppPath(TILES_INDEX_DIR).getAbsolutePath() + "/" + name + SQLITE_EXT, true);
db.execSQL("CREATE TABLE tiles (x int, y int, z int, s int, image blob, time long, PRIMARY KEY (x,y,z,s))");
db.execSQL("CREATE INDEX IND on tiles (x,y,z,s)");
db.execSQL("CREATE TABLE info(tilenumbering,minzoom,maxzoom)");
db.execSQL("CREATE TABLE IF NOT EXISTS tiles (x int, y int, z int, s int, image blob, time long, PRIMARY KEY (x,y,z,s))");
db.execSQL("CREATE INDEX IF NOT EXISTS IND on tiles (x,y,z,s)");
db.execSQL("CREATE TABLE IF NOT EXISTS info(tilenumbering,minzoom,maxzoom)");
db.execSQL("INSERT INTO info (tilenumbering,minzoom,maxzoom) VALUES ('simple','" + minZoom + "','" + maxZoom + "');");
addInfoColumn(URL, urlTemplate);

View file

@ -1,13 +1,11 @@
package net.osmand.plus;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@ -96,16 +94,20 @@ public class SettingsHelper {
private static final int BUFFER = 1024;
private OsmandApplication app;
private Activity activity;
private boolean importing;
private boolean importSuspended;
private boolean collectOnly;
private ImportAsyncTask importTask;
private Map<File, ExportAsyncTask> exportAsyncTasks = new HashMap<>();
public interface SettingsImportListener {
void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items);
void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items);
}
public interface SettingsCollectListener {
void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items);
}
public interface CheckDuplicatesListener {
void onDuplicatesChecked(@NonNull List<Object> duplicates, List<SettingsItem> items);
}
public interface SettingsExportListener {
@ -116,31 +118,6 @@ public class SettingsHelper {
this.app = app;
}
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
if (importing && !collectOnly) {
importTask.processNextItem();
}
}
public void resetActivity(Activity activity) {
if (this.activity == activity) {
if (importing) {
importTask.suspendImport();
importSuspended = true;
}
this.activity = null;
}
}
public boolean isImporting() {
return importing;
}
public enum SettingsItemType {
GLOBAL,
PROFILE,
@ -263,6 +240,11 @@ public class SettingsHelper {
return items;
}
@NonNull
public List<T> getDuplicateItems() {
return duplicateItems;
}
@NonNull
public List<T> excludeDuplicateItems() {
if (!items.isEmpty()) {
@ -1801,135 +1783,179 @@ public class SettingsHelper {
}
@SuppressLint("StaticFieldLeak")
private class ImportAsyncTask extends AsyncTask<Void, Void, List<SettingsItem>> {
public class ImportAsyncTask extends AsyncTask<Void, Void, List<SettingsItem>> {
private File file;
private String latestChanges;
private int version;
private SettingsImportListener listener;
private SettingsImportListener importListener;
private SettingsCollectListener collectListener;
private CheckDuplicatesListener duplicatesListener;
private SettingsImporter importer;
private List<SettingsItem> items = new ArrayList<>();
private List<SettingsItem> processedItems = new ArrayList<>();
private SettingsItem currentItem;
private AlertDialog dialog;
ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) {
this.file = settingsFile;
this.listener = listener;
private List<SettingsItem> items = new ArrayList<>();
private List<SettingsItem> selectedItems = new ArrayList<>();
private List<Object> duplicates;
private ImportType importType;
private boolean importDone;
ImportAsyncTask(@NonNull File file, String latestChanges, int version, @Nullable SettingsCollectListener collectListener) {
this.file = file;
this.collectListener = collectListener;
this.latestChanges = latestChanges;
this.version = version;
importer = new SettingsImporter(app);
collectOnly = true;
importType = ImportType.COLLECT;
}
ImportAsyncTask(@NonNull File settingsFile, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener listener) {
this.file = settingsFile;
this.listener = listener;
ImportAsyncTask(@NonNull File file, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener importListener) {
this.file = file;
this.importListener = importListener;
this.items = items;
this.latestChanges = latestChanges;
this.version = version;
importer = new SettingsImporter(app);
collectOnly = false;
importType = ImportType.IMPORT;
}
ImportAsyncTask(@NonNull File file, @NonNull List<SettingsItem> items, @NonNull List<SettingsItem> selectedItems, @Nullable CheckDuplicatesListener duplicatesListener) {
this.file = file;
this.items = items;
this.duplicatesListener = duplicatesListener;
this.selectedItems = selectedItems;
importer = new SettingsImporter(app);
importType = ImportType.CHECK_DUPLICATES;
}
@Override
protected void onPreExecute() {
if (importing) {
finishImport(listener, false, false, items);
ImportAsyncTask importTask = SettingsHelper.this.importTask;
if (importTask != null && !importTask.importDone) {
finishImport(importListener, false, items);
}
importing = true;
importSuspended = false;
importTask = this;
SettingsHelper.this.importTask = this;
}
@Override
protected List<SettingsItem> doInBackground(Void... voids) {
if (collectOnly) {
try {
return importer.collectItems(file);
} catch (IllegalArgumentException e) {
LOG.error("Failed to collect items from: " + file.getName(), e);
} catch (IOException e) {
LOG.error("Failed to collect items from: " + file.getName(), e);
}
} else {
return this.items;
switch (importType) {
case COLLECT:
try {
return importer.collectItems(file);
} catch (IllegalArgumentException e) {
LOG.error("Failed to collect items from: " + file.getName(), e);
} catch (IOException e) {
LOG.error("Failed to collect items from: " + file.getName(), e);
}
break;
case CHECK_DUPLICATES:
this.duplicates = getDuplicatesData(selectedItems);
return selectedItems;
case IMPORT:
return items;
}
return null;
}
@Override
protected void onPostExecute(@Nullable List<SettingsItem> items) {
if (items != null) {
if (items != null && importType != ImportType.CHECK_DUPLICATES) {
this.items = items;
}
if (collectOnly) {
listener.onSettingsImportFinished(true, false, this.items);
} else if (items != null && items.size() > 0) {
processNextItem();
}
}
private void processNextItem() {
if (activity == null) {
return;
}
if (items.size() == 0 && !importSuspended) {
if (processedItems.size() > 0) {
new ImportItemsAsyncTask(file, listener, processedItems).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
finishImport(listener, false, true, items);
}
return;
}
final SettingsItem item;
if (importSuspended && currentItem != null) {
item = currentItem;
} else if (items.size() > 0) {
item = items.remove(0);
currentItem = item;
} else {
item = null;
selectedItems = items;
}
importSuspended = false;
if (item != null) {
acceptItem(item);
} else {
processNextItem();
switch (importType) {
case COLLECT:
importDone = true;
collectListener.onSettingsCollectFinished(true, false, this.items);
break;
case CHECK_DUPLICATES:
importDone = true;
if (duplicatesListener != null) {
duplicatesListener.onDuplicatesChecked(duplicates, selectedItems);
}
break;
case IMPORT:
if (items != null && items.size() > 0) {
for (SettingsItem item : items) {
item.apply();
}
new ImportItemsAsyncTask(file, importListener, items).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
break;
}
}
private void suspendImport() {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
}
private void acceptItem(SettingsItem item) {
item.apply();
processedItems.add(item);
processNextItem();
}
public List<SettingsItem> getItems() {
return this.items;
return items;
}
public File getFile() {
return this.file;
return file;
}
public void setImportListener(SettingsImportListener importListener) {
this.importListener = importListener;
}
public void setDuplicatesListener(CheckDuplicatesListener duplicatesListener) {
this.duplicatesListener = duplicatesListener;
}
ImportType getImportType() {
return importType;
}
boolean isImportDone() {
return importDone;
}
public List<Object> getDuplicates() {
return duplicates;
}
public List<SettingsItem> getSelectedItems() {
return selectedItems;
}
private List<Object> getDuplicatesData(List<SettingsItem> items) {
List<Object> duplicateItems = new ArrayList<>();
for (SettingsItem item : items) {
if (item instanceof ProfileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((ProfileSettingsItem) item).getModeBean());
}
} else if (item instanceof CollectionSettingsItem) {
List duplicates = ((CollectionSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof FileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((FileSettingsItem) item).getFile());
}
}
}
return duplicateItems;
}
}
@Nullable
public List<SettingsItem> getSettingsItems() {
return this.importTask.getItems();
public ImportAsyncTask getImportTask() {
return importTask;
}
@Nullable
public File getSettingsFile() {
return this.importTask.getFile();
public ImportType getImportTaskType() {
ImportAsyncTask importTask = this.importTask;
return importTask != null ? importTask.getImportType() : null;
}
public boolean isImportDone() {
ImportAsyncTask importTask = this.importTask;
return importTask == null || importTask.isImportDone();
}
public boolean isFileExporting(File file) {
@ -1975,16 +2001,14 @@ public class SettingsHelper {
@Override
protected void onPostExecute(Boolean success) {
finishImport(listener, success, false, items);
finishImport(listener, success, items);
}
}
private void finishImport(@Nullable SettingsImportListener listener, boolean success, boolean empty, @NonNull List<SettingsItem> items) {
importing = false;
importSuspended = false;
private void finishImport(@Nullable SettingsImportListener listener, boolean success, @NonNull List<SettingsItem> items) {
importTask = null;
if (listener != null) {
listener.onSettingsImportFinished(success, empty, items);
listener.onSettingsImportFinished(success, items);
}
}
@ -2028,10 +2052,15 @@ public class SettingsHelper {
}
}
public void importSettings(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) {
public void collectSettings(@NonNull File settingsFile, String latestChanges, int version,
@Nullable SettingsCollectListener listener) {
new ImportAsyncTask(settingsFile, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void checkDuplicates(@NonNull File file, @NonNull List<SettingsItem> items, @NonNull List<SettingsItem> selectedItems, CheckDuplicatesListener listener) {
new ImportAsyncTask(file, items, selectedItems, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void importSettings(@NonNull File settingsFile, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener listener) {
new ImportAsyncTask(settingsFile, items, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -2047,4 +2076,10 @@ public class SettingsHelper {
@NonNull SettingsItem... items) {
exportSettings(fileDir, fileName, listener, new ArrayList<>(Arrays.asList(items)));
}
public enum ImportType {
COLLECT,
CHECK_DUPLICATES,
IMPORT
}
}

View file

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
@ -11,6 +12,9 @@ import android.graphics.drawable.RippleDrawable;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Build;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -36,14 +40,21 @@ import com.google.android.material.snackbar.Snackbar;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.plus.views.DirectionDrawable;
import net.osmand.plus.widgets.TextViewEx;
import org.apache.commons.logging.Log;
import java.util.Locale;
import gnu.trove.map.hash.TLongObjectHashMap;
public class UiUtilities {
private static final Log LOG = PlatformUtil.getLog(UiUtilities.class);
private TLongObjectHashMap<Drawable> drawableCache = new TLongObjectHashMap<>();
private OsmandApplication app;
private static final int ORIENTATION_0 = 0;
@ -554,4 +565,20 @@ public class UiUtilities {
v.requestLayout();
}
}
public static SpannableString createSpannableString(@NonNull String text, @NonNull String textToStyle, @NonNull StyleSpan styleSpan) {
SpannableString spannable = new SpannableString(text);
try {
int startIndex = text.indexOf(textToStyle);
spannable.setSpan(
styleSpan,
startIndex,
startIndex + textToStyle.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return spannable;
} catch (RuntimeException e) {
LOG.error("Error trying to find index of " + textToStyle + " " + e);
return spannable;
}
}
}

View file

@ -33,6 +33,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.access.AccessibilityAssistant;
@ -221,7 +222,10 @@ public class FavoritesSearchFragment extends DialogFragment {
public void onDismiss(DialogInterface dialog) {
Activity activity = getActivity();
if (activity != null) {
getChildFragmentManager().popBackStack();
FragmentManager fragmentManager = getChildFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
}
super.onDismiss(dialog);
}

View file

@ -136,6 +136,7 @@ import net.osmand.plus.settings.BaseSettingsFragment;
import net.osmand.plus.settings.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.settings.ConfigureProfileFragment;
import net.osmand.plus.settings.DataStorageFragment;
import net.osmand.plus.settings.ImportCompleteFragment;
import net.osmand.plus.settings.ImportSettingsFragment;
import net.osmand.plus.settings.ProfileAppearanceFragment;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
@ -734,6 +735,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
importSettingsFragment.showExitDialog();
return;
}
ImportCompleteFragment importCompleteFragment = getImportCompleteFragment();
if (importCompleteFragment != null) {
importCompleteFragment.dismissFragment();
return;
}
super.onBackPressed();
}
@ -903,7 +909,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
app.getDownloadThread().setUiActivity(this);
app.getSettingsHelper().setActivity(this);
boolean routeWasFinished = routingHelper.isRouteWasFinished();
if (routeWasFinished && !DestinationReachedMenu.wasShown()) {
@ -1128,10 +1133,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
public void dismissCardDialog() {
try {
getSupportFragmentManager().popBackStack(ContextMenuCardDialogFragment.TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
FragmentManager fragmentManager = getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack(ContextMenuCardDialogFragment.TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
@ -1504,7 +1508,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
app.getMapMarkersHelper().removeListener(this);
app.getRoutingHelper().removeListener(this);
app.getDownloadThread().resetUiActivity(this);
app.getSettingsHelper().resetActivity(this);
if (atlasMapRendererView != null) {
atlasMapRendererView.handleOnPause();
}
@ -2166,10 +2169,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
public void dismissSettingsScreens() {
try {
getSupportFragmentManager().popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
FragmentManager fragmentManager = getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
@ -2453,10 +2455,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
return getFragment(ImportSettingsFragment.TAG);
}
public ImportCompleteFragment getImportCompleteFragment() {
return getFragment(ImportCompleteFragment.TAG);
}
public void backToConfigureProfileFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
int backStackEntryCount = fragmentManager.getBackStackEntryCount();
if (backStackEntryCount > 0) {
if (backStackEntryCount > 0 && !fragmentManager.isStateSaved()) {
BackStackEntry entry = fragmentManager.getBackStackEntryAt(backStackEntryCount - 1);
if (ConfigureProfileFragment.TAG.equals(entry.getName())) {
fragmentManager.popBackStack();

View file

@ -8,6 +8,7 @@ import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.plus.R;
@ -59,6 +60,12 @@ public class AudioVideoNoteRecordingMenuFullScreenFragment extends Fragment {
public void dismiss() {
dismissing = true;
getActivity().getSupportFragmentManager().popBackStack();
FragmentActivity activity = getActivity();
if (activity != null) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
}
}
}

View file

@ -937,11 +937,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
if (isSingleFragment()) {
FragmentActivity activity = getActivity();
if (activity != null) {
try {
activity.getSupportFragmentManager().popBackStack(getFragmentTag(),
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
//
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack(getFragmentTag(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
}

View file

@ -1,7 +1,6 @@
package net.osmand.plus.helpers;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
@ -48,6 +47,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.SettingsHelper.SettingsImportListener;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.ActivityResultListener;
@ -341,9 +341,10 @@ public class ImportHelper {
@Override
protected void onPreExecute() {
progress = ProgressDialog
.show(activity, app.getString(R.string.loading_smth, ""),
app.getString(R.string.loading_data));
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""),
app.getString(R.string.loading_data));
}
}
@Override
@ -362,7 +363,7 @@ public class ImportHelper {
@Override
protected void onPostExecute(GPXFile result) {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG)
@ -679,7 +680,9 @@ public class ImportHelper {
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
}
mFileName = fileName;
}
@ -705,7 +708,7 @@ public class ImportHelper {
loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override
public void onRoutingFilesLoaded() {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
RoutingConfiguration.Builder builder = app.getCustomRoutingConfig(mFileName);
@ -720,7 +723,7 @@ public class ImportHelper {
}
});
} else {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
app.showShortToastMessage(app.getString(R.string.file_import_error, mFileName, error));
@ -762,7 +765,9 @@ public class ImportHelper {
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
}
}
@Override
@ -780,24 +785,21 @@ public class ImportHelper {
File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
final File file = new File(tempDir, name);
if (error == null && file.exists()) {
app.getSettingsHelper().importSettings(file, latestChanges, version, new SettingsImportListener() {
app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() {
@Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
if (succeed) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (fragmentManager != null) {
ImportSettingsFragment.showInstance(fragmentManager, items, file);
}
ImportSettingsFragment.showInstance(activity.getSupportFragmentManager(), items, file);
} else if (empty) {
app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error)));
}
}
});
} else {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
app.showShortToastMessage(app.getString(R.string.file_import_error, name, error));
@ -889,7 +891,9 @@ public class ImportHelper {
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
}
mFileName = fileName;
}
@ -916,7 +920,7 @@ public class ImportHelper {
} else {
app.showShortToastMessage(app.getString(R.string.file_import_error, mFileName, error));
}
if (AndroidUtils.isActivityNotDestroyed(activity)) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
}

View file

@ -2120,9 +2120,9 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
public void dismissMenu() {
FragmentActivity activity = getActivity();
if (activity != null) {
try {
activity.getSupportFragmentManager().popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
}

View file

@ -134,11 +134,9 @@ public class ContextMenuCardDialogFragment extends BaseOsmAndFragment {
public void dismiss() {
MapActivity activity = dialog.getMapActivity();
if (activity != null) {
try {
activity.getSupportFragmentManager().popBackStack(TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
}

View file

@ -1,37 +0,0 @@
package net.osmand.plus.profiles;
import java.util.List;
public class AdditionalDataWrapper {
private Type type;
private List<?> items;
public AdditionalDataWrapper(Type type, List<?> items) {
this.type = type;
this.items = items;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public List<?> getItems() {
return items;
}
public enum Type {
PROFILE,
QUICK_ACTIONS,
POI_TYPES,
MAP_SOURCES,
CUSTOM_RENDER_STYLE,
CUSTOM_ROUTING,
AVOID_ROADS
}
}

View file

@ -1023,7 +1023,10 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
hideToolbar();
mapActivity.updateStatusBarColor();
mapActivity.refreshMap();
getChildFragmentManager().popBackStack();
FragmentManager fragmentManager = getChildFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
}
super.onDismiss(dialog);
}

View file

@ -585,7 +585,10 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
public void dismiss() {
FragmentActivity activity = getActivity();
if (activity != null) {
activity.getSupportFragmentManager().popBackStack();
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
}
}

View file

@ -36,6 +36,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
@ -182,9 +183,9 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
}
private void restoreCustomModeFromFile(final File file) {
app.getSettingsHelper().importSettings(file, "", 1, new SettingsHelper.SettingsImportListener() {
app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() {
@Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (succeed) {
for (SettingsHelper.SettingsItem item : items) {
item.setShouldReplace(true);
@ -198,7 +199,7 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
private void importBackupSettingsItems(File file, List<SettingsHelper.SettingsItem> items) {
app.getSettingsHelper().importSettings(file, items, "", 1, new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsHelper.SettingsItem> items) {
app.showToastMessage(R.string.profile_prefs_reset_successful);
updateCopiedOrResetPrefs();
}

View file

@ -10,6 +10,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.map.ITileSource;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ApplicationMode.ApplicationModeBean;
@ -111,12 +112,12 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView
} else if (currentItem instanceof File) {
File file = (File) currentItem;
itemHolder.title.setText(file.getName());
if (file.getName().contains("/rendering/")) {
if (file.getName().contains(IndexConstants.RENDERERS_DIR)) {
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_map_style, nightMode));
itemHolder.icon.setVisibility(View.VISIBLE);
} else {
itemHolder.icon.setImageResource(R.drawable.ic_action_info_dark);
itemHolder.icon.setVisibility(View.INVISIBLE);
} else if (file.getName().contains(IndexConstants.ROUTING_PROFILES_DIR)) {
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_route_distance, nightMode));
itemHolder.icon.setVisibility(View.VISIBLE);
}
itemHolder.subTitle.setVisibility(View.GONE);
} else if (currentItem instanceof AvoidRoadInfo) {

View file

@ -13,6 +13,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.widget.CompoundButtonCompat;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.map.ITileSource;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
@ -21,7 +22,6 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AdditionalDataWrapper;
import net.osmand.plus.profiles.ProfileIconColors;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.render.RenderingIcons;
@ -30,7 +30,10 @@ import net.osmand.view.ThreeStateCheckbox;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
import static net.osmand.view.ThreeStateCheckbox.State.MISC;
@ -40,24 +43,18 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
private OsmandApplication app;
private List<? super Object> dataToOperate;
private List<AdditionalDataWrapper> dataList;
private Map<Type, List<?>> itemsMap;
private List<Type> itemsTypes;
private boolean nightMode;
private boolean importState;
private int profileColor;
ExportImportSettingsAdapter(OsmandApplication app, List<AdditionalDataWrapper> dataList, boolean nightMode, boolean importState) {
ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode, boolean importState) {
this.app = app;
this.dataList = dataList;
this.nightMode = nightMode;
this.importState = importState;
this.dataToOperate = new ArrayList<>();
this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode);
}
ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode) {
this.app = app;
this.nightMode = nightMode;
this.dataList = new ArrayList<>();
this.itemsMap = new HashMap<>();
this.itemsTypes = new ArrayList<>();
this.dataToOperate = new ArrayList<>();
this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode);
}
@ -71,7 +68,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
}
boolean isLastGroup = groupPosition == getGroupCount() - 1;
final AdditionalDataWrapper.Type type = dataList.get(groupPosition).getType();
final Type type = itemsTypes.get(groupPosition);
TextView titleTv = group.findViewById(R.id.title_tv);
TextView subTextTv = group.findViewById(R.id.sub_text_tv);
@ -88,7 +85,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE);
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor)));
final List<?> listItems = dataList.get(groupPosition).getItems();
final List<?> listItems = itemsMap.get(type);
subTextTv.setText(String.valueOf(listItems.size()));
if (dataToOperate.containsAll(listItems)) {
@ -119,7 +116,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
notifyDataSetChanged();
}
});
adjustIndicator(app, groupPosition, isExpanded, group, true);
adjustIndicator(app, groupPosition, isExpanded, group, nightMode);
return group;
}
@ -130,10 +127,10 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false);
}
final Object currentItem = dataList.get(groupPosition).getItems().get(childPosition);
final Object currentItem = itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
boolean isLastGroup = groupPosition == getGroupCount() - 1;
final AdditionalDataWrapper.Type type = dataList.get(groupPosition).getType();
final Type type = itemsTypes.get(groupPosition);
TextView title = child.findViewById(R.id.title_tv);
TextView subText = child.findViewById(R.id.sub_title_tv);
@ -204,17 +201,17 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
break;
case CUSTOM_RENDER_STYLE:
String renderName = ((File) currentItem).getName();
renderName = renderName.replace('_', ' ').replaceAll(".render.xml", "");
renderName = renderName.replace('_', ' ').replaceAll(IndexConstants.RENDERER_INDEX_EXT, "");
title.setText(renderName);
icon.setImageResource(R.drawable.ic_action_info_dark);
icon.setVisibility(View.INVISIBLE);
icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_map_style, nightMode));
icon.setVisibility(View.VISIBLE);
subText.setVisibility(View.GONE);
break;
case CUSTOM_ROUTING:
String routingName = ((File) currentItem).getName();
routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
title.setText(routingName);
icon.setImageResource(R.drawable.ic_action_map_style);
icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_route_distance, nightMode));
icon.setVisibility(View.VISIBLE);
subText.setVisibility(View.GONE);
break;
@ -233,22 +230,22 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
@Override
public int getGroupCount() {
return dataList.size();
return itemsTypes.size();
}
@Override
public int getChildrenCount(int i) {
return dataList.get(i).getItems().size();
return itemsMap.get(itemsTypes.get(i)).size();
}
@Override
public Object getGroup(int i) {
return dataList.get(i);
return itemsMap.get(itemsTypes.get(i));
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return dataList.get(groupPosition).getItems().get(childPosition);
return itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
}
@Override
@ -271,7 +268,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
return true;
}
private int getGroupTitle(AdditionalDataWrapper.Type type) {
private int getGroupTitle(Type type) {
switch (type) {
case PROFILE:
return R.string.shared_string_profiles;
@ -292,21 +289,24 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
}
}
public void updateSettingsList(List<AdditionalDataWrapper> settingsList) {
this.dataList = settingsList;
public void updateSettingsList(Map<Type, List<?>> itemsMap) {
this.itemsMap = itemsMap;
this.itemsTypes = new ArrayList<>(itemsMap.keySet());
Collections.sort(itemsTypes);
notifyDataSetChanged();
}
public void clearSettingsList() {
this.dataList.clear();
this.itemsMap.clear();
this.itemsTypes.clear();
notifyDataSetChanged();
}
public void selectAll(boolean selectAll) {
dataToOperate.clear();
if (selectAll) {
for (AdditionalDataWrapper item : dataList) {
dataToOperate.addAll(item.getItems());
for (List<?> values : itemsMap.values()) {
dataToOperate.addAll(values);
}
}
notifyDataSetChanged();
@ -315,4 +315,14 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
List<? super Object> getDataToOperate() {
return this.dataToOperate;
}
public enum Type {
PROFILE,
QUICK_ACTIONS,
POI_TYPES,
MAP_SOURCES,
CUSTOM_RENDER_STYLE,
CUSTOM_ROUTING,
AVOID_ROADS
}
}

View file

@ -38,16 +38,17 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AdditionalDataWrapper;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionFactory;
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import org.apache.commons.logging.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -63,7 +64,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
private OsmandApplication app;
private ApplicationMode profile;
private List<AdditionalDataWrapper> dataList = new ArrayList<>();
private Map<Type, List<?>> dataList = new HashMap<>();
private ExportImportSettingsAdapter adapter;
private SettingsHelper.SettingsExportListener exportListener;
@ -122,7 +123,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
if (!dataList.isEmpty()) {
final View additionalDataView = inflater.inflate(R.layout.bottom_sheet_item_additional_data, null);
ExpandableListView listView = additionalDataView.findViewById(R.id.list);
adapter = new ExportImportSettingsAdapter(app, nightMode);
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);
@ -214,22 +215,18 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
}
}
private List<AdditionalDataWrapper> getAdditionalData() {
List<AdditionalDataWrapper> dataList = new ArrayList<>();
private Map<Type, List<?>> getAdditionalData() {
Map<Type, List<?>> dataList = new HashMap<>();
QuickActionFactory factory = new QuickActionFactory();
List<QuickAction> actionsList = factory.parseActiveActionsList(app.getSettings().QUICK_ACTION_LIST.get());
if (!actionsList.isEmpty()) {
dataList.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.QUICK_ACTIONS, actionsList));
dataList.put(Type.QUICK_ACTIONS, actionsList);
}
List<PoiUIFilter> poiList = app.getPoiFilters().getUserDefinedPoiFilters(false);
if (!poiList.isEmpty()) {
dataList.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.POI_TYPES,
poiList
));
dataList.put(Type.POI_TYPES, poiList);
}
List<ITileSource> iTileSources = new ArrayList<>();
@ -249,37 +246,25 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
}
}
if (!iTileSources.isEmpty()) {
dataList.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.MAP_SOURCES,
iTileSources
));
dataList.put(Type.MAP_SOURCES, iTileSources);
}
Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers();
if (!externalRenderers.isEmpty()) {
dataList.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
new ArrayList<>(externalRenderers.values())
));
dataList.put(Type.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.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
Arrays.asList(fl)
));
dataList.put(Type.CUSTOM_ROUTING, Arrays.asList(fl));
}
}
Map<LatLon, AvoidRoadInfo> impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
if (!impassableRoads.isEmpty()) {
dataList.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.AVOID_ROADS,
new ArrayList<>(impassableRoads.values())
));
dataList.put(Type.AVOID_ROADS, new ArrayList<>(impassableRoads.values()));
}
return dataList;
}

View file

@ -0,0 +1,184 @@
package net.osmand.plus.settings;
import android.app.Activity;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment;
import net.osmand.plus.quickaction.QuickActionListFragment;
import net.osmand.plus.routepreparationmenu.AvoidRoadsBottomSheetDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import java.util.List;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID;
import static net.osmand.plus.settings.ImportSettingsFragment.IMPORT_SETTINGS_TAG;
import static net.osmand.plus.settings.ImportSettingsFragment.getSettingsToOperate;
public class ImportCompleteFragment extends BaseOsmAndFragment {
public static final String TAG = ImportCompleteFragment.class.getSimpleName();
private OsmandApplication app;
private RecyclerView recyclerView;
private List<SettingsItem> settingsItems;
private String fileName;
private boolean nightMode;
public static void showInstance(FragmentManager fm, @NonNull List<SettingsItem> settingsItems,
@NonNull String fileName) {
ImportCompleteFragment fragment = new ImportCompleteFragment();
fragment.setSettingsItems(settingsItems);
fragment.setFileName(fileName);
fragment.setRetainInstance(true);
fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
.commitAllowingStateLoss();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = requireMyApplication();
nightMode = !app.getSettings().isLightContent();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
inflater = UiUtilities.getInflater(app, nightMode);
View root = inflater.inflate(R.layout.fragment_import_complete, container, false);
TextView description = root.findViewById(R.id.description);
TextView btnClose = root.findViewById(R.id.button_close);
recyclerView = root.findViewById(R.id.list);
description.setText(UiUtilities.createSpannableString(
String.format(getString(R.string.import_complete_description), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
));
btnClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissFragment();
}
});
if (Build.VERSION.SDK_INT >= 21) {
AndroidUtils.addStatusBarPadding21v(app, root);
}
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (settingsItems != null) {
ImportedSettingsItemsAdapter adapter = new ImportedSettingsItemsAdapter(
app,
getSettingsToOperate(settingsItems),
nightMode,
new ImportedSettingsItemsAdapter.OnItemClickListener() {
@Override
public void onItemClick(Type type) {
navigateTo(type);
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(getMyApplication()));
recyclerView.setAdapter(adapter);
}
}
public void dismissFragment() {
FragmentManager fm = getFragmentManager();
if (fm != null && !fm.isStateSaved()) {
fm.popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
private void navigateTo(Type type) {
FragmentManager fm = getFragmentManager();
Activity activity = requireActivity();
if (fm == null || fm.isStateSaved()) {
return;
}
dismissFragment();
fm.popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE);
switch (type) {
case CUSTOM_ROUTING:
case PROFILE:
BaseSettingsFragment.showInstance(
requireActivity(),
BaseSettingsFragment.SettingsScreenType.MAIN_SETTINGS
);
break;
case QUICK_ACTIONS:
fm.beginTransaction()
.add(R.id.fragmentContainer, new QuickActionListFragment(), QuickActionListFragment.TAG)
.addToBackStack(QuickActionListFragment.TAG).commit();
break;
case POI_TYPES:
if (activity instanceof MapActivity) {
QuickSearchDialogFragment.showInstance(
(MapActivity) activity,
"",
null,
QuickSearchDialogFragment.QuickSearchType.REGULAR,
QuickSearchDialogFragment.QuickSearchTab.CATEGORIES,
null
);
}
break;
case MAP_SOURCES:
if (activity instanceof MapActivity) {
((MapActivity) activity).getDashboard()
.setDashboardVisibility(
true,
DashboardOnMap.DashboardType.CONFIGURE_MAP,
null
);
}
break;
case CUSTOM_RENDER_STYLE:
new SelectMapStyleBottomSheetDialogFragment().show(fm, SelectMapStyleBottomSheetDialogFragment.TAG);
break;
case AVOID_ROADS:
new AvoidRoadsBottomSheetDialogFragment().show(fm, AvoidRoadsBottomSheetDialogFragment.TAG);
break;
default:
break;
}
}
@Override
public int getStatusBarColorId() {
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
}
public void setSettingsItems(List<SettingsItem> settingsItems) {
this.settingsItems = settingsItems;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}

View file

@ -1,23 +1,27 @@
package net.osmand.plus.settings;
import android.graphics.drawable.Drawable;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.core.widget.NestedScrollView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils;
import net.osmand.map.ITileSource;
import net.osmand.plus.AppInitializer;
@ -25,6 +29,8 @@ import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.ImportAsyncTask;
import net.osmand.plus.SettingsHelper.ImportType;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment;
@ -37,7 +43,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.settings.ImportSettingsFragment.getDuplicatesData;
import static net.osmand.plus.settings.ImportSettingsFragment.IMPORT_SETTINGS_TAG;
public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View.OnClickListener {
@ -51,6 +57,10 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
private List<SettingsItem> settingsItems;
private File file;
private boolean nightMode;
private ProgressBar progressBar;
private CollapsingToolbarLayout toolbarLayout;
private TextView description;
private SettingsHelper settingsHelper;
public static void showInstance(@NonNull FragmentManager fm, List<? super Object> duplicatesList,
List<SettingsItem> settingsItems, File file) {
@ -58,20 +68,30 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
fragment.setDuplicatesList(duplicatesList);
fragment.setSettingsItems(settingsItems);
fragment.setFile(file);
fm.beginTransaction().replace(R.id.fragmentContainer, fragment, TAG).addToBackStack(null).commit();
fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
.commitAllowingStateLoss();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent();
if (settingsItems == null) {
settingsItems = app.getSettingsHelper().getSettingsItems();
duplicatesList = getDuplicatesData(settingsItems);
}
if (file == null) {
file = app.getSettingsHelper().getSettingsFile();
ImportAsyncTask importTask = settingsHelper.getImportTask();
if (importTask != null) {
if (settingsItems == null) {
settingsItems = importTask.getSelectedItems();
}
if (duplicatesList == null) {
duplicatesList = importTask.getDuplicates();
}
if (file == null) {
file = importTask.getFile();
}
importTask.setImportListener(getImportListener());
}
}
@ -80,11 +100,15 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
inflater = UiUtilities.getInflater(app, nightMode);
View root = inflater.inflate(R.layout.fragment_import_duplicates, container, false);
setupToolbar((Toolbar) root.findViewById(R.id.toolbar));
Toolbar toolbar = root.findViewById(R.id.toolbar);
setupToolbar(toolbar);
ComplexButton replaceAllBtn = root.findViewById(R.id.replace_all_btn);
ComplexButton keepBothBtn = root.findViewById(R.id.keep_both_btn);
buttonsContainer = root.findViewById(R.id.buttons_container);
nestedScroll = root.findViewById(R.id.nested_scroll);
description = root.findViewById(R.id.description);
progressBar = root.findViewById(R.id.progress_bar);
toolbarLayout = root.findViewById(R.id.toolbar_layout);
keepBothBtn.setIcon(getPaintedContentIcon(R.drawable.ic_action_keep_both,
nightMode
? getResources().getColor(R.color.icon_color_active_dark)
@ -121,16 +145,23 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
DuplicatesSettingsAdapter adapter = new DuplicatesSettingsAdapter(app, prepareDuplicates(), nightMode);
list.setLayoutManager(new LinearLayoutManager(getMyApplication()));
list.setAdapter(adapter);
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (duplicatesList != null) {
DuplicatesSettingsAdapter adapter = new DuplicatesSettingsAdapter(app, prepareDuplicates(duplicatesList), nightMode);
list.setLayoutManager(new LinearLayoutManager(getMyApplication()));
list.setAdapter(adapter);
}
if (settingsHelper.getImportTaskType() == ImportType.IMPORT) {
setupImportingUi();
} else {
toolbarLayout.setTitle(getString(R.string.import_duplicates_title));
}
toolbarLayout.setTitle(getString(R.string.import_duplicates_title));
}
private List<Object> prepareDuplicates() {
private List<Object> prepareDuplicates(List<? super Object> duplicatesList) {
List<? super Object> duplicates = new ArrayList<>();
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
List<QuickAction> actions = new ArrayList<>();
@ -211,50 +242,60 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
}
private void importItems(boolean shouldReplace) {
for (SettingsItem item : settingsItems) {
item.setShouldReplace(shouldReplace);
if (settingsItems != null && file != null) {
setupImportingUi();
for (SettingsItem item : settingsItems) {
item.setShouldReplace(shouldReplace);
}
settingsHelper.importSettings(file, settingsItems, "", 1, getImportListener());
}
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, new SettingsHelper.SettingsImportListener() {
}
private void setupImportingUi() {
toolbarLayout.setTitle(getString(R.string.shared_string_importing));
description.setText(UiUtilities.createSpannableString(
String.format(getString(R.string.importing_from), file.getName()),
file.getName(),
new StyleSpan(Typeface.BOLD)
));
progressBar.setVisibility(View.VISIBLE);
list.setVisibility(View.GONE);
buttonsContainer.setVisibility(View.GONE);
}
private SettingsHelper.SettingsImportListener getImportListener() {
return new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
if (succeed) {
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override
public void onRoutingFilesLoaded() {
}
});
} else if (empty) {
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error)));
FragmentManager fm = getFragmentManager();
if (fm != null && file != null) {
ImportCompleteFragment.showInstance(fm, items, file.getName());
}
}
}
});
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.popBackStackImmediate();
Fragment fragment = fm.findFragmentByTag(ImportSettingsFragment.TAG);
if (fragment != null) {
fm.beginTransaction().remove(fragment).commit();
fm.popBackStackImmediate();
}
}
};
}
private void setupToolbar(Toolbar toolbar) {
Drawable icBack = getPaintedContentIcon(AndroidUtils.getNavigationIconResId(getContext()),
toolbar.setTitle(R.string.import_duplicates_title);
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_arrow_back,
nightMode
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
: getResources().getColor(R.color.active_buttons_and_links_text_light));
toolbar.setNavigationIcon(icBack);
: getResources().getColor(R.color.active_buttons_and_links_text_light)));
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
if (fm != null) {
if (fm != null && !fm.isStateSaved()) {
fm.popBackStackImmediate();
ImportSettingsFragment.showInstance(fm, null, file);
}
}
});

View file

@ -2,12 +2,16 @@ package net.osmand.plus.settings;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -17,7 +21,11 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
import net.osmand.plus.AppInitializer;
@ -26,50 +34,66 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.SettingsHelper.*;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AdditionalDataWrapper;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import org.apache.commons.logging.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ImportSettingsFragment extends BaseOsmAndFragment
implements View.OnClickListener {
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
public static final Log LOG = PlatformUtil.getLog(ImportSettingsFragment.class.getSimpleName());
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 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 CollapsingToolbarLayout toolbarLayout;
private SettingsHelper settingsHelper;
private long duplicateStartTime;
public static void showInstance(@NonNull FragmentManager fm, List<SettingsItem> settingsItems, @NonNull File file) {
public static void showInstance(@NonNull FragmentManager fm, @NonNull List<SettingsItem> settingsItems, @NonNull File file) {
ImportSettingsFragment fragment = new ImportSettingsFragment();
fragment.setSettingsItems(settingsItems);
fragment.setFile(file);
fm.beginTransaction().replace(R.id.fragmentContainer, fragment, TAG).addToBackStack(null).commit();
fm.beginTransaction().
replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
.commitAllowingStateLoss();
}
@Override
public void onCreate(Bundle savedInstanceState) {
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
duplicateStartTime = savedInstanceState.getLong(DUPLICATES_START_TIME_KEY);
}
app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent();
if (settingsItems == null) {
settingsItems = app.getSettingsHelper().getSettingsItems();
}
if (file == null) {
file = app.getSettingsHelper().getSettingsFile();
}
}
@Nullable
@ -77,13 +101,17 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
inflater = UiUtilities.getInflater(app, nightMode);
View root = inflater.inflate(R.layout.fragment_import, container, false);
setupToolbar((Toolbar) root.findViewById(R.id.toolbar));
Toolbar toolbar = root.findViewById(R.id.toolbar);
TextViewEx continueBtn = root.findViewById(R.id.continue_button);
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);
setupToolbar(toolbar);
ViewCompat.setNestedScrollingEnabled(expandableList, true);
View header = inflater.inflate(R.layout.list_item_description_header, null);
TextView description = header.findViewById(R.id.description);
description = header.findViewById(R.id.description);
description.setText(R.string.select_data_to_import);
expandableList.addHeaderView(header);
continueBtn.setOnClickListener(this);
@ -95,10 +123,48 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
adapter = new ExportImportSettingsAdapter(app, getSettingsToOperate(), nightMode, true);
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImportAsyncTask importTask = settingsHelper.getImportTask();
if (importTask != null) {
if (settingsItems == null) {
settingsItems = importTask.getItems();
}
if (file == null) {
file = importTask.getFile();
}
List<Object> duplicates = importTask.getDuplicates();
List<SettingsItem> selectedItems = importTask.getSelectedItems();
if (duplicates == null) {
importTask.setDuplicatesListener(getDuplicatesListener());
} else if (duplicates.isEmpty()) {
if (selectedItems != null && file != null) {
settingsHelper.importSettings(file, selectedItems, "", 1, getImportListener());
}
}
}
adapter = new ExportImportSettingsAdapter(app, nightMode, true);
if (settingsItems != null) {
adapter.updateSettingsList(getSettingsToOperate(settingsItems));
}
expandableList.setAdapter(adapter);
toolbarLayout.setTitle(getString(R.string.shared_string_import));
ImportType importTaskType = settingsHelper.getImportTaskType();
if (importTaskType == ImportType.CHECK_DUPLICATES && !settingsHelper.isImportDone()) {
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
} else if (importTaskType == ImportType.IMPORT) {
updateUi(R.string.shared_string_importing, R.string.importing_from);
} else {
toolbarLayout.setTitle(getString(R.string.shared_string_import));
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(DUPLICATES_START_TIME_KEY, duplicateStartTime);
}
@Override
@ -121,69 +187,89 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
}
}
private void importItems() {
List<SettingsItem> settingsItems = getSettingsItemsFromData(adapter.getDataToOperate());
List<Object> duplicateItems = getDuplicatesData(settingsItems);
if (duplicateItems.isEmpty()) {
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (succeed) {
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override
public void onRoutingFilesLoaded() {
}
});
} else if (empty) {
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error)));
}
}
});
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.popBackStackImmediate();
}
} else {
ImportDuplicatesFragment.showInstance(requireActivity().getSupportFragmentManager(), duplicateItems, settingsItems, file);
private void updateUi(int toolbarTitleRes, int descriptionRes) {
if (file != null) {
String fileName = file.getName();
toolbarLayout.setTitle(getString(toolbarTitleRes));
description.setText(UiUtilities.createSpannableString(
String.format(getString(descriptionRes), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
));
buttonsContainer.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
adapter.clearSettingsList();
}
}
public static List<Object> getDuplicatesData(List<SettingsItem> items) {
List<Object> duplicateItems = new ArrayList<>();
for (SettingsItem item : items) {
if (item instanceof SettingsHelper.ProfileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
}
} else if (item instanceof SettingsHelper.QuickActionSettingsItem) {
List<QuickAction> duplicates = ((SettingsHelper.QuickActionSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.PoiUiFilterSettingsItem) {
List<PoiUIFilter> duplicates = ((SettingsHelper.PoiUiFilterSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.MapSourcesSettingsItem) {
List<ITileSource> duplicates = ((SettingsHelper.MapSourcesSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.FileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.FileSettingsItem) item).getFile());
}
} else if (item instanceof SettingsHelper.AvoidRoadsSettingsItem) {
List<AvoidRoadInfo> avoidRoads = ((SettingsHelper.AvoidRoadsSettingsItem) item).excludeDuplicateItems();
if (!avoidRoads.isEmpty()) {
duplicateItems.addAll(avoidRoads);
private void importItems() {
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
List<SettingsItem> selectedItems = getSettingsItemsFromData(adapter.getDataToOperate());
if (file != null && settingsItems != null) {
duplicateStartTime = System.currentTimeMillis();
settingsHelper.checkDuplicates(file, settingsItems, selectedItems, getDuplicatesListener());
}
}
private SettingsHelper.SettingsImportListener getImportListener() {
return new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
FragmentManager fm = getFragmentManager();
if (succeed) {
app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override
public void onRoutingFilesLoaded() {
}
});
if (fm != null && file != null) {
ImportCompleteFragment.showInstance(fm, items, file.getName());
}
}
}
};
}
private SettingsHelper.CheckDuplicatesListener getDuplicatesListener() {
return new SettingsHelper.CheckDuplicatesListener() {
@Override
public void onDuplicatesChecked(@NonNull final List<Object> duplicates, final List<SettingsItem> items) {
long spentTime = System.currentTimeMillis() - duplicateStartTime;
if (spentTime < MIN_DELAY_TIME_MS) {
long delay = MIN_DELAY_TIME_MS - spentTime;
app.runInUIThread(new Runnable() {
@Override
public void run() {
processDuplicates(duplicates, items);
}
}, delay);
} else {
processDuplicates(duplicates, items);
}
}
};
}
private void processDuplicates(List<Object> duplicates, List<SettingsItem> items) {
FragmentManager fm = getFragmentManager();
if (file != null) {
if (duplicates.isEmpty()) {
if (isAdded()) {
updateUi(R.string.shared_string_importing, R.string.importing_from);
}
settingsHelper.importSettings(file, items, "", 1, getImportListener());
} else if (fm != null && !isStateSaved()) {
ImportDuplicatesFragment.showInstance(fm, duplicates, items, file);
}
}
}
private void dismissFragment() {
FragmentManager fm = getFragmentManager();
if (fm != null && !fm.isStateSaved()) {
getFragmentManager().popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
return duplicateItems;
}
public void setSettingsItems(List<SettingsItem> settingsItems) {
@ -228,8 +314,8 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
return settingsItems;
}
private List<AdditionalDataWrapper> getSettingsToOperate() {
List<AdditionalDataWrapper> settingsToOperate = new ArrayList<>();
public static Map<Type, List<?>> getSettingsToOperate(List<SettingsItem> settingsItems) {
Map<Type, List<?>> settingsToOperate = new HashMap<>();
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
List<QuickAction> quickActions = new ArrayList<>();
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
@ -238,64 +324,50 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
List<File> renderFilesList = new ArrayList<>();
List<AvoidRoadInfo> avoidRoads = new ArrayList<>();
for (SettingsHelper.SettingsItem item : settingsItems) {
if (item.getType().equals(SettingsHelper.SettingsItemType.PROFILE)) {
profiles.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.QUICK_ACTION)) {
quickActions.addAll(((SettingsHelper.QuickActionSettingsItem) item).getItems());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.POI_UI_FILTERS)) {
poiUIFilters.addAll(((SettingsHelper.PoiUiFilterSettingsItem) item).getItems());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.MAP_SOURCES)) {
tileSourceTemplates.addAll(((SettingsHelper.MapSourcesSettingsItem) item).getItems());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.FILE)) {
if (item.getName().startsWith("/rendering/")) {
renderFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile());
} else if (item.getName().startsWith("/routing/")) {
routingFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile());
for (SettingsItem item : settingsItems) {
if (item.getType().equals(SettingsItemType.PROFILE)) {
profiles.add(((ProfileSettingsItem) item).getModeBean());
} else if (item.getType().equals(SettingsItemType.QUICK_ACTION)) {
quickActions.addAll(((QuickActionSettingsItem) item).getItems());
quickActions.addAll(((QuickActionSettingsItem) item).getDuplicateItems());
} else if (item.getType().equals(SettingsItemType.POI_UI_FILTERS)) {
poiUIFilters.addAll(((PoiUiFilterSettingsItem) item).getItems());
poiUIFilters.addAll(((PoiUiFilterSettingsItem) item).getDuplicateItems());
} else if (item.getType().equals(SettingsItemType.MAP_SOURCES)) {
tileSourceTemplates.addAll(((MapSourcesSettingsItem) item).getItems());
tileSourceTemplates.addAll(((MapSourcesSettingsItem) item).getDuplicateItems());
} else if (item.getType().equals(SettingsItemType.FILE)) {
if (item.getName().contains(IndexConstants.RENDERERS_DIR)) {
renderFilesList.add(((FileSettingsItem) item).getFile());
} else if (item.getName().contains(IndexConstants.ROUTING_PROFILES_DIR)) {
routingFilesList.add(((FileSettingsItem) item).getFile());
}
} else if (item.getType().equals(SettingsHelper.SettingsItemType.AVOID_ROADS)) {
avoidRoads.addAll(((SettingsHelper.AvoidRoadsSettingsItem) item).getItems());
} else if (item.getType().equals(SettingsItemType.AVOID_ROADS)) {
avoidRoads.addAll(((AvoidRoadsSettingsItem) item).getItems());
avoidRoads.addAll(((AvoidRoadsSettingsItem) item).getDuplicateItems());
}
}
if (!profiles.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.PROFILE,
profiles));
settingsToOperate.put(Type.PROFILE, profiles);
}
if (!quickActions.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.QUICK_ACTIONS,
quickActions));
settingsToOperate.put(Type.QUICK_ACTIONS, quickActions);
}
if (!poiUIFilters.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.POI_TYPES,
poiUIFilters));
settingsToOperate.put(Type.POI_TYPES, poiUIFilters);
}
if (!tileSourceTemplates.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.MAP_SOURCES,
tileSourceTemplates
));
settingsToOperate.put(Type.MAP_SOURCES, tileSourceTemplates);
}
if (!renderFilesList.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
renderFilesList
));
settingsToOperate.put(Type.CUSTOM_RENDER_STYLE, renderFilesList);
}
if (!routingFilesList.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
routingFilesList
));
settingsToOperate.put(Type.CUSTOM_ROUTING, routingFilesList);
}
if (!avoidRoads.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper(
AdditionalDataWrapper.Type.AVOID_ROADS,
avoidRoads
));
settingsToOperate.put(Type.AVOID_ROADS, avoidRoads);
}
return settingsToOperate;
}
@ -314,10 +386,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.popBackStackImmediate();
}
dismissFragment();
}
});
dismissDialog.show();

View file

@ -0,0 +1,131 @@
package net.osmand.plus.settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class ImportedSettingsItemsAdapter extends
RecyclerView.Adapter<ImportedSettingsItemsAdapter.ItemViewHolder> {
private Map<Type, List<?>> itemsMap;
private List<Type> itemsTypes;
private UiUtilities uiUtils;
private OsmandApplication app;
private boolean nightMode;
private OnItemClickListener listener;
ImportedSettingsItemsAdapter(@NonNull OsmandApplication app, Map<Type, List<?>> itemsMap,
boolean nightMode, OnItemClickListener listener) {
this.app = app;
this.itemsMap = itemsMap;
this.nightMode = nightMode;
this.listener = listener;
uiUtils = app.getUIUtilities();
itemsTypes = new ArrayList<>(itemsMap.keySet());
Collections.sort(itemsTypes);
}
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
View view = inflater.inflate(R.layout.list_item_import, parent, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
final Type currentItemType = itemsTypes.get(position);
boolean isLastItem = itemsTypes.size() - 1 == position;
int activeColorRes = nightMode
? R.color.active_color_primary_dark
: R.color.active_color_primary_light;
holder.icon.setPadding(0, 0, AndroidUtils.dpToPx(app, 16), 0);
holder.title.setTextColor(app.getResources().getColor(activeColorRes));
holder.divider.setVisibility(isLastItem ? View.VISIBLE : View.GONE);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(currentItemType);
}
});
holder.subTitle.setText(String.format(
app.getString(R.string.ltr_or_rtl_combine_via_colon),
app.getString(R.string.items_added),
String.valueOf(itemsMap.get(currentItemType).size()))
);
switch (currentItemType) {
case PROFILE:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.map_action_settings, activeColorRes));
holder.title.setText(R.string.shared_string_settings);
break;
case QUICK_ACTIONS:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.map_quick_action, activeColorRes));
holder.title.setText(R.string.configure_screen_quick_action);
break;
case POI_TYPES:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_search_dark, activeColorRes));
holder.title.setText(R.string.search_activity);
break;
case MAP_SOURCES:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_layers, activeColorRes));
holder.title.setText(R.string.configure_map);
break;
case CUSTOM_RENDER_STYLE:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_map_style, activeColorRes));
holder.title.setText(R.string.shared_string_rendering_style);
break;
case CUSTOM_ROUTING:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_route_distance, activeColorRes));
holder.title.setText(R.string.shared_string_routing);
break;
case AVOID_ROADS:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_alert, activeColorRes));
holder.title.setText(R.string.avoid_road);
break;
}
}
@Override
public int getItemCount() {
return itemsMap.keySet().size();
}
public static class ItemViewHolder extends RecyclerView.ViewHolder {
ImageView icon;
TextView title;
TextView subTitle;
View divider;
ItemViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
subTitle = itemView.findViewById(R.id.sub_title);
icon = itemView.findViewById(R.id.icon);
divider = itemView.findViewById(R.id.bottom_divider);
}
}
interface OnItemClickListener {
void onItemClick(Type type);
}
}