From 1daa371dff851f9a14489acae8e4dd6adc3e47c9 Mon Sep 17 00:00:00 2001 From: veliymolfar Date: Thu, 23 Jan 2020 19:06:41 +0200 Subject: [PATCH] initial commit --- .../bottom_sheet_item_additional_data.xml | 31 + .../layout/profile_data_list_item_child.xml | 49 ++ .../layout/profile_data_list_item_group.xml | 72 +++ OsmAnd/res/values/strings.xml | 5 + .../src/net/osmand/plus/SettingsHelper.java | 110 ++++ .../plus/profiles/AdditionalDataWrapper.java | 35 ++ .../ExportImportProfileBottomSheet.java | 567 ++++++++++++++++++ .../settings/ConfigureProfileFragment.java | 40 +- 8 files changed, 877 insertions(+), 32 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_item_additional_data.xml create mode 100644 OsmAnd/res/layout/profile_data_list_item_child.xml create mode 100644 OsmAnd/res/layout/profile_data_list_item_group.xml create mode 100644 OsmAnd/src/net/osmand/plus/profiles/AdditionalDataWrapper.java create mode 100644 OsmAnd/src/net/osmand/plus/profiles/ExportImportProfileBottomSheet.java diff --git a/OsmAnd/res/layout/bottom_sheet_item_additional_data.xml b/OsmAnd/res/layout/bottom_sheet_item_additional_data.xml new file mode 100644 index 0000000000..286b32260f --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_additional_data.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/profile_data_list_item_child.xml b/OsmAnd/res/layout/profile_data_list_item_child.xml new file mode 100644 index 0000000000..4b8ad4c01b --- /dev/null +++ b/OsmAnd/res/layout/profile_data_list_item_child.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/profile_data_list_item_group.xml b/OsmAnd/res/layout/profile_data_list_item_group.xml new file mode 100644 index 0000000000..8b889bb860 --- /dev/null +++ b/OsmAnd/res/layout/profile_data_list_item_group.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 93ca5c4889..afd34bbbe5 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,11 @@ Thx - Hardy --> + Routing + Custom rendering style + Include additional data + The imported profile contains additional data. Click Import to import only profile data or select additional data to import. + You can select additional data to export along with the profile. \'%1$s\' file doesn\'t contain routing rules, please choose another file. Not supported file type. You need to select a file with %1$s extension. Import from file diff --git a/OsmAnd/src/net/osmand/plus/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/SettingsHelper.java index 61509da462..5855d98941 100644 --- a/OsmAnd/src/net/osmand/plus/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/SettingsHelper.java @@ -7,11 +7,21 @@ import android.content.DialogInterface; import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentManager; import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import net.osmand.PlatformUtil; import net.osmand.plus.ApplicationMode.ApplicationModeBuilder; import net.osmand.plus.OsmandSettings.OsmandPreference; +import net.osmand.plus.poi.PoiUIFilter; +import net.osmand.plus.profiles.AdditionalDataWrapper; +import net.osmand.plus.profiles.ExportImportProfileBottomSheet; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionFactory; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -125,6 +135,7 @@ public class SettingsHelper { PLUGIN, DATA, FILE, + QUICK_ACTION } public abstract static class SettingsItem { @@ -457,6 +468,10 @@ public class SettingsHelper { } } + public ApplicationMode getAppMode() { + return appMode; + } + @Override void writeToJson(@NonNull JSONObject json) throws JSONException { super.writeToJson(json); @@ -693,6 +708,98 @@ public class SettingsHelper { } } + public static class QuickActionSettingsItem extends OsmandSettingsItem { + + private List quickActions; + + public QuickActionSettingsItem(@NonNull OsmandSettings settings, + @NonNull List quickActions) { + super(SettingsItemType.QUICK_ACTION, settings); + this.quickActions = quickActions; + } + + public QuickActionSettingsItem(@NonNull OsmandSettings settings, + @NonNull JSONObject jsonObject) throws JSONException { + super(SettingsItemType.QUICK_ACTION, settings, jsonObject); + readFromJson(jsonObject); + } + + public List getQuickActions() { + return quickActions; + } + + @NonNull + @Override + public String getName() { + return "quick_actions"; + } + + @NonNull + @Override + public String getPublicName(@NonNull Context ctx) { + return null; + } + + @NonNull + @Override + public String getFileName() { + return getName() + ".json"; + } + + @NonNull + @Override + SettingsItemReader getReader() { + return new OsmandSettingsItemReader(this, getSettings()) { + + @Override + protected void readPreferenceFromJson(@NonNull OsmandPreference preference, @NonNull JSONObject json) throws JSONException { + + } + + @Override + public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException { + StringBuilder buf = new StringBuilder(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); + String str; + while ((str = in.readLine()) != null) { + buf.append(str); + } + } catch (IOException e) { + throw new IOException("Cannot read json body", e); + } + String jsonStr = buf.toString(); + if (Algorithms.isEmpty(jsonStr)) { + throw new IllegalArgumentException("Cannot find json body"); + } + final JSONObject json; + String itemsString; + try { + json = new JSONObject(jsonStr); + itemsString = json.getString("items"); + getSettings().QUICK_ACTION_LIST.set(itemsString); + QuickActionFactory factory = new QuickActionFactory(); + quickActions = factory.parseActiveActionsList(itemsString); + } catch (JSONException e) { + throw new IllegalArgumentException("Json parse error", e); + } + } + }; + } + + @NonNull + @Override + SettingsItemWriter getWriter() { + return new OsmandSettingsItemWriter(this, getSettings()) { + @Override + protected void writePreferenceToJson(@NonNull OsmandPreference preference, @NonNull JSONObject json) throws JSONException { + QuickActionFactory factory = new QuickActionFactory(); + json.put("items", new JSONArray(factory.quickActionListToString(quickActions))); + } + }; + } + } + private static class SettingsItemsFactory { private OsmandApplication app; @@ -749,6 +856,9 @@ public class SettingsHelper { case FILE: item = new FileSettingsItem(app, json); break; + case QUICK_ACTION: + item = new QuickActionSettingsItem(settings, json); + break; } return item; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/AdditionalDataWrapper.java b/OsmAnd/src/net/osmand/plus/profiles/AdditionalDataWrapper.java new file mode 100644 index 0000000000..a4358828ac --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/AdditionalDataWrapper.java @@ -0,0 +1,35 @@ +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 { + QUICK_ACTIONS, + POI_TYPES, + MAP_SOURCES, + CUSTOM_RENDER_STYLE, + ROUTING + } +} diff --git a/OsmAnd/src/net/osmand/plus/profiles/ExportImportProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/ExportImportProfileBottomSheet.java new file mode 100644 index 0000000000..0d5d3ab0a9 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/profiles/ExportImportProfileBottomSheet.java @@ -0,0 +1,567 @@ +package net.osmand.plus.profiles; + +import android.content.Context; +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.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.content.ContextCompat; +import android.support.v4.widget.CompoundButtonCompat; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.ExpandableListView; +import android.widget.ImageView; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import net.osmand.AndroidUtils; +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; +import net.osmand.plus.ApplicationMode; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.SettingsHelper; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.plus.poi.PoiUIFilter; +import net.osmand.plus.quickaction.QuickAction; +import net.osmand.plus.quickaction.QuickActionFactory; +import net.osmand.plus.render.RenderingIcons; +import net.osmand.plus.settings.BaseSettingsFragment; +import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; + +import org.apache.commons.logging.Log; + +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class ExportImportProfileBottomSheet extends BasePreferenceBottomSheet { + + private static final Log LOG = PlatformUtil.getLog(ExportImportProfileBottomSheet.class); + + public static final String TAG = ExportImportProfileBottomSheet.class.getSimpleName(); + + private static final String STATE_KEY = "EXPORT_IMPORT_DIALOG_STATE_KEY"; + + private OsmandApplication app; + + private Context context; + + private OsmandSettings settings; + + private ApplicationMode profile; + + private boolean includeAdditionalData = false; + + private State state; + + private List dataList; + + private ExpandableListView listView; + + private ProfileAdditionalDataAdapter adapter; + + private List dataToOperate = new ArrayList<>(); + + private List settingsItems; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + app = requiredMyApplication(); + context = requireContext(); + settings = app.getSettings(); + Bundle bundle = getArguments(); + if (bundle != null) { + this.state = (State) getArguments().getSerializable(STATE_KEY); + } + + dataList = state == State.IMPORT ? getDataFromSettingsItems() : getAdditionalData(); + for (AdditionalDataWrapper dataWrapper : dataList) { + dataToOperate.addAll(dataWrapper.getItems()); + } + } + + + private ApplicationMode getAppModeFromItems() { + for (SettingsHelper.SettingsItem item : settingsItems) { + if (item.getType().equals(SettingsHelper.SettingsItemType.PROFILE)) { + return ((SettingsHelper.ProfileSettingsItem) item).getAppMode(); + } + } + return getAppMode(); + } + + @Override + public void createMenuItems(Bundle savedInstanceState) { + final Context context = getContext(); + if (context == null) { + return; + } + + profile = state == State.IMPORT ? getAppModeFromItems() : 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}; + + items.add(new TitleItem(state == State.EXPORT ? + getString(R.string.export_profile) + : getString(R.string.import_profile))); + + 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(context)) + .setBackground(new LayerDrawable(layers)) + .setLayoutId(R.layout.preference_profile_item_with_radio_btn) + .create(); + items.add(profileItem); + + BaseBottomSheetItem descriptionItem = new BottomSheetItemWithDescription.Builder() + .setDescription(state == State.EXPORT ? + getString(R.string.export_profile_dialog_description) + : getString(R.string.import_profile_dialog_description)) + .setLayoutId(R.layout.bottom_sheet_item_pref_info) + .create(); + items.add(descriptionItem); + + final View additionalDataView = View.inflate(new ContextThemeWrapper(context, themeRes), + R.layout.bottom_sheet_item_additional_data, null); + listView = additionalDataView.findViewById(R.id.list); + Switch switchItem = additionalDataView.findViewById(R.id.switchItem); + switchItem.setTextColor(getResources().getColor(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light)); + + switchItem.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + includeAdditionalData = !includeAdditionalData; + listView.setVisibility(includeAdditionalData ? + View.VISIBLE : View.GONE); + } + }); + adapter = new ProfileAdditionalDataAdapter(requiredMyApplication(), dataList, profileColor); + listView.setAdapter(adapter); + final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder() + .setCustomView(additionalDataView) + .create(); + items.add(titleItem); + } + + private List getDataFromSettingsItems() { + List dataList = new ArrayList<>(); + + List quickActions = new ArrayList<>(); + for (SettingsHelper.SettingsItem item : settingsItems) { + if (item.getType().equals(SettingsHelper.SettingsItemType.QUICK_ACTION)) { + quickActions.addAll(((SettingsHelper.QuickActionSettingsItem) item).getQuickActions()); + } + } + dataList.add(new AdditionalDataWrapper( + AdditionalDataWrapper.Type.QUICK_ACTIONS, + quickActions)); + + return dataList; + } + + private List getAdditionalData() { + List dataList = new ArrayList<>(); + + QuickActionFactory factory = new QuickActionFactory(); + List quickActions = factory.parseActiveActionsList(settings.QUICK_ACTION_LIST.get()); + dataList.add(new AdditionalDataWrapper( + AdditionalDataWrapper.Type.QUICK_ACTIONS, quickActions)); + + List poiList = app.getPoiFilters().getUserDefinedPoiFilters(false); + dataList.add(new AdditionalDataWrapper( + AdditionalDataWrapper.Type.POI_TYPES, + poiList + )); + + final LinkedHashMap entriesMap = new LinkedHashMap<>(settings.getTileSourceEntries()); + List mapSourceWrapperList = new ArrayList<>(); + for (Map.Entry entry : entriesMap.entrySet()) { + mapSourceWrapperList.add(new MapSourceWrapper(entry.getKey(), entry.getValue())); + } + dataList.add(new AdditionalDataWrapper( + AdditionalDataWrapper.Type.MAP_SOURCES, + mapSourceWrapperList + )); + + return dataList; + } + + public void setSettingsItems(List settingsItems) { + this.settingsItems = settingsItems; + } + + @Override + protected int getRightBottomButtonTextId() { + return state == State.EXPORT ? R.string.shared_string_export : R.string.shared_string_import; + } + + @Override + protected void onRightBottomButtonClick() { + super.onRightBottomButtonClick(); + prepareFile(); +// if (state == State.EXPORT) { +// if (includeAdditionalData) { +// prepareFileWithAdditional(); +// } else { +// prepareFile(); +// } +// } else { +// +// } + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected boolean useScrollableItemsContainer() { + return false; + } + + private List prepareSettingsItems() { + List settingsItems = new ArrayList<>(); + settingsItems.add(new SettingsHelper.ProfileSettingsItem(app.getSettings(), profile)); + + if (includeAdditionalData) { + List quickActions = new ArrayList<>(); + List poiUIFilters = new ArrayList<>(); + List mapSourceWrappers = new ArrayList<>(); + for (Object object : dataToOperate) { + if (object instanceof QuickAction) { + quickActions.add((QuickAction) object); + } else if (object instanceof PoiUIFilter) { + poiUIFilters.add((PoiUIFilter) object); + } else if (object instanceof MapSourceWrapper) { + mapSourceWrappers.add((MapSourceWrapper) object); + } + } + if (!quickActions.isEmpty()) { + settingsItems.add(new SettingsHelper.QuickActionSettingsItem(app.getSettings(), quickActions)); + } +// if (!poiUIFilters.isEmpty()) { +// settingsItems.add(); +// } +// if (!mapSourceWrappers.isEmpty()) { +// settingsItems.add(); +// } + } + return settingsItems; + } + + private void prepareFile() { + if (app != null) { + File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + String fileName = profile.toHumanString(context); + app.getSettingsHelper().exportSettings(tempDir, fileName, new SettingsHelper.SettingsExportListener() { + @Override + public void onSettingsExportFinished(@NonNull File file, boolean succeed) { + if (succeed) { + shareProfile(file, profile); + } else { + app.showToastMessage(R.string.export_profile_failed); + } + } + }, prepareSettingsItems()); + } + } + + private void shareProfile(@NonNull File file, @NonNull ApplicationMode profile) { + try { + Context ctx = requireContext(); + final Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.exported_osmand_profile, profile.toHumanString(ctx))); + 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(context, R.string.export_profile_failed, Toast.LENGTH_SHORT).show(); + LOG.error("Share profile error", e); + } + } + + public static boolean showInstance(@NonNull FragmentManager fragmentManager, + State state, + Fragment target, + @NonNull ApplicationMode appMode) { + try { + Bundle bundle = new Bundle(); + bundle.putSerializable(STATE_KEY, state); + ExportImportProfileBottomSheet fragment = new ExportImportProfileBottomSheet(); + fragment.setArguments(bundle); + fragment.setAppMode(appMode); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); + return true; + } catch (RuntimeException e) { + return false; + } + } + + public static boolean showInstance(@NonNull FragmentManager fragmentManager, + State state, + List items) { + try { + Bundle bundle = new Bundle(); + bundle.putSerializable(STATE_KEY, state); + ExportImportProfileBottomSheet fragment = new ExportImportProfileBottomSheet(); + fragment.setArguments(bundle); + fragment.setSettingsItems(items); + fragment.show(fragmentManager, TAG); + return true; + } catch (RuntimeException e) { + return false; + } + } + + public enum State { + EXPORT, + IMPORT + } + + boolean isContainsInDataToOperate(AdditionalDataWrapper.Type type, Object object) { + return dataToOperate.contains(object); + +// for (AdditionalDataWrapper data : dataList) { +// if (data.getType() == type) { +// return data.getItems().contains(object); +// } +// } +// return false; + } + + class ProfileAdditionalDataAdapter extends OsmandBaseExpandableListAdapter { + + private OsmandApplication app; + + private List list; + + private int profileColor; + + + ProfileAdditionalDataAdapter(OsmandApplication app, List list, int profileColor) { + this.app = app; + this.list = list; + this.profileColor = profileColor; + } + + @Override + public int getGroupCount() { + return list.size(); + } + + @Override + public int getChildrenCount(int i) { + return list.get(i).getItems().size(); + } + + @Override + public Object getGroup(int i) { + return list.get(i); + } + + @Override + public Object getChild(int groupPosition, int childPosition) { + return list.get(groupPosition).getItems().get(childPosition); + } + + @Override + public long getGroupId(int i) { + return i; + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 10000 + childPosition; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + View group = convertView; + if (group == null) { + LayoutInflater inflater = (LayoutInflater) app.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + group = inflater.inflate(R.layout.profile_data_list_item_group, parent, false); + } + + + boolean isLastGroup = groupPosition == getGroupCount() - 1; + final AdditionalDataWrapper.Type type = list.get(groupPosition).getType(); + + TextView titleTv = group.findViewById(R.id.title_tv); + TextView subTextTv = group.findViewById(R.id.sub_text_tv); + final CheckBox checkBox = group.findViewById(R.id.check_box); + ImageView expandIv = group.findViewById(R.id.explist_indicator); + View divider = group.findViewById(R.id.divider); + + titleTv.setText(getGroupTitle(type)); + divider.setVisibility(isExpanded || isLastGroup ? View.GONE : View.VISIBLE); + CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor))); + + final List listItems = list.get(groupPosition).getItems(); + subTextTv.setText(String.valueOf(listItems.size())); + + checkBox.setChecked(dataToOperate.containsAll(listItems)); + checkBox.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (checkBox.isChecked()) { + for (Object object : listItems) { + if (!isContainsInDataToOperate(type, object)) { + dataToOperate.add(object); + } + } + } else { + dataToOperate.removeAll(listItems); + } + notifyDataSetInvalidated(); + } + }); + + adjustIndicator(app, groupPosition, isExpanded, group, true); + + return group; + } + + @Override + public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { + View child = convertView; + if (child == null) { + LayoutInflater inflater = (LayoutInflater) app.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false); + } + final Object currentItem = list.get(groupPosition).getItems().get(childPosition); + + + boolean isLastGroup = groupPosition == getGroupCount() - 1; + final AdditionalDataWrapper.Type type = list.get(groupPosition).getType(); + + TextView title = child.findViewById(R.id.title_tv); + final CheckBox checkBox = child.findViewById(R.id.check_box); + ImageView icon = child.findViewById(R.id.icon); + View divider = child.findViewById(R.id.divider); + + divider.setVisibility(isLastChild && !isLastGroup ? View.VISIBLE : View.GONE); + CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor))); + + checkBox.setChecked(isContainsInDataToOperate(type, currentItem)); + checkBox.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (checkBox.isChecked()) { + dataToOperate.add(currentItem); + } else { + dataToOperate.remove(currentItem); + } + } + }); + + switch (type) { + case QUICK_ACTIONS: + title.setText(((QuickAction) currentItem).getName(app.getApplicationContext())); + icon.setVisibility(View.INVISIBLE); + icon.setImageResource(R.drawable.ic_action_info_dark); + break; + case POI_TYPES: + title.setText(((PoiUIFilter) currentItem).getName()); + icon.setVisibility(View.VISIBLE); + int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId()); + icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes != 0 ? iconRes : R.drawable.ic_person, profileColor)); + break; + case MAP_SOURCES: + title.setText(((MapSourceWrapper) currentItem).getName()); + icon.setVisibility(View.INVISIBLE); + icon.setImageResource(R.drawable.ic_action_info_dark); + break; + default: + return child; + } + return child; + } + + @Override + public boolean isChildSelectable(int i, int i1) { + return false; + } + + private int getGroupTitle(AdditionalDataWrapper.Type type) { + switch (type) { + 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_custom_rendering_style; + case ROUTING: + return R.string.shared_string_routing; + default: + return R.string.access_empty_list; + } + } + } + + class MapSourceWrapper { + private String name; + private String url; + + MapSourceWrapper(String name, String url) { + this.name = name; + this.url = url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/ConfigureProfileFragment.java b/OsmAnd/src/net/osmand/plus/settings/ConfigureProfileFragment.java index ea40709d09..fad8ef9748 100644 --- a/OsmAnd/src/net/osmand/plus/settings/ConfigureProfileFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/ConfigureProfileFragment.java @@ -40,6 +40,7 @@ import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin; +import net.osmand.plus.profiles.ExportImportProfileBottomSheet; import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet; import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet; import net.osmand.plus.skimapsplugin.SkiMapsPlugin; @@ -288,22 +289,6 @@ public class ConfigureProfileFragment extends BaseSettingsFragment { isNightMode() ? R.color.active_color_primary_dark : R.color.active_color_primary_light)); } - private void shareProfile(@NonNull File file, @NonNull ApplicationMode profile) { - try { - Context ctx = requireContext(); - final Intent sendIntent = new Intent(); - sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.exported_osmand_profile, profile.toHumanString(ctx))); - sendIntent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), file)); - sendIntent.setType("*/*"); - sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(sendIntent); - } catch (Exception e) { - app.showToastMessage(R.string.export_profile_failed); - LOG.error("Share profile error", e); - } - } - private void setupOsmandPluginsPref(PreferenceCategory preferenceCategory) { Context ctx = getContext(); if (ctx == null) { @@ -362,23 +347,14 @@ public class ConfigureProfileFragment extends BaseSettingsFragment { ResetProfilePrefsBottomSheet.showInstance(fragmentManager, prefId, this, false, getSelectedAppMode()); } } else if (EXPORT_PROFILE.equals(prefId)) { - Context ctx = requireContext(); - final ApplicationMode profile = getSelectedAppMode(); - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); + FragmentManager fragmentManager = getFragmentManager(); + if (fragmentManager != null) { + ExportImportProfileBottomSheet.showInstance( + fragmentManager, + ExportImportProfileBottomSheet.State.EXPORT, + this, + getSelectedAppMode()); } - String fileName = profile.toHumanString(ctx); - app.getSettingsHelper().exportSettings(tempDir, fileName, new SettingsHelper.SettingsExportListener() { - @Override - public void onSettingsExportFinished(@NonNull File file, boolean succeed) { - if (succeed) { - shareProfile(file, profile); - } else { - app.showToastMessage(R.string.export_profile_failed); - } - } - }, new ProfileSettingsItem(app.getSettings(), profile)); } else if (DELETE_PROFILE.equals(prefId)) { onDeleteProfileClick(); }