commit
a661ce677f
7 changed files with 341 additions and 846 deletions
|
@ -0,0 +1,267 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.UiUtilities.DialogButtonType;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsCategory;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
import net.osmand.plus.settings.fragments.ExportSettingsAdapter.OnItemSelectedListener;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BaseSettingsListFragment extends BaseOsmAndFragment implements OnItemSelectedListener {
|
||||
|
||||
protected static final String SETTINGS_LIST_TAG = "settings_list_tag";
|
||||
|
||||
protected OsmandApplication app;
|
||||
|
||||
protected Map<ExportSettingsType, List<?>> selectedItemsMap = new EnumMap<>(ExportSettingsType.class);
|
||||
protected Map<ExportSettingsCategory, SettingsCategoryItems> dataList = new LinkedHashMap<>();
|
||||
|
||||
protected View header;
|
||||
protected View continueBtn;
|
||||
protected View headerShadow;
|
||||
protected View headerDivider;
|
||||
protected View itemsSizeContainer;
|
||||
protected View availableSpaceContainer;
|
||||
protected TextViewEx selectedItemsSize;
|
||||
protected TextViewEx availableSpaceDescr;
|
||||
protected LinearLayout buttonsContainer;
|
||||
protected ExpandableListView expandableList;
|
||||
protected ExportSettingsAdapter adapter;
|
||||
|
||||
protected boolean nightMode;
|
||||
private boolean wasDrawerDisabled;
|
||||
|
||||
@Override
|
||||
public int getStatusBarColorId() {
|
||||
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requireMyApplication();
|
||||
nightMode = !app.getSettings().isLightContent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(app, nightMode);
|
||||
View root = themedInflater.inflate(R.layout.fragment_import, container, false);
|
||||
AndroidUtils.addStatusBarPadding21v(app, root);
|
||||
|
||||
selectedItemsSize = root.findViewById(R.id.file_size);
|
||||
itemsSizeContainer = root.findViewById(R.id.file_size_container);
|
||||
expandableList = root.findViewById(R.id.list);
|
||||
buttonsContainer = root.findViewById(R.id.buttons_container);
|
||||
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
setupToolbar(toolbar);
|
||||
ViewCompat.setNestedScrollingEnabled(expandableList, true);
|
||||
|
||||
header = themedInflater.inflate(R.layout.list_item_description_header, null);
|
||||
headerDivider = header.findViewById(R.id.divider);
|
||||
headerShadow = header.findViewById(R.id.card_bottom_divider);
|
||||
expandableList.addHeaderView(header);
|
||||
|
||||
availableSpaceContainer = themedInflater.inflate(R.layout.enough_space_warning_card, null);
|
||||
availableSpaceDescr = availableSpaceContainer.findViewById(R.id.warning_descr);
|
||||
|
||||
continueBtn = root.findViewById(R.id.continue_button);
|
||||
UiUtilities.setupDialogButton(nightMode, continueBtn, DialogButtonType.PRIMARY, getString(R.string.shared_string_continue));
|
||||
continueBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onContinueButtonClickAction();
|
||||
}
|
||||
});
|
||||
|
||||
ViewTreeObserver treeObserver = buttonsContainer.getViewTreeObserver();
|
||||
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
if (buttonsContainer != null) {
|
||||
ViewTreeObserver vts = buttonsContainer.getViewTreeObserver();
|
||||
int height = buttonsContainer.getMeasuredHeight();
|
||||
expandableList.setPadding(0, 0, 0, height);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
vts.removeOnGlobalLayoutListener(this);
|
||||
} else {
|
||||
vts.removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
adapter = new ExportSettingsAdapter(app, this, nightMode);
|
||||
adapter.updateSettingsItems(dataList, selectedItemsMap);
|
||||
expandableList.setAdapter(adapter);
|
||||
updateAvailableSpace();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected abstract void onContinueButtonClickAction();
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
wasDrawerDisabled = mapActivity.isDrawerDisabled();
|
||||
if (!wasDrawerDisabled) {
|
||||
mapActivity.disableDrawer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null && !wasDrawerDisabled) {
|
||||
mapActivity.enableDrawer();
|
||||
}
|
||||
}
|
||||
|
||||
protected void dismissFragment() {
|
||||
FragmentManager fm = getFragmentManager();
|
||||
if (fm != null && !fm.isStateSaved()) {
|
||||
getFragmentManager().popBackStack(SETTINGS_LIST_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void showExitDialog() {
|
||||
Context themedContext = UiUtilities.getThemedContext(getActivity(), nightMode);
|
||||
AlertDialog.Builder dismissDialog = new AlertDialog.Builder(themedContext);
|
||||
dismissDialog.setTitle(getString(R.string.shared_string_dismiss));
|
||||
dismissDialog.setMessage(getString(R.string.exit_without_saving));
|
||||
dismissDialog.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismissFragment();
|
||||
}
|
||||
});
|
||||
dismissDialog.show();
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_action_close, nightMode
|
||||
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
|
||||
: getResources().getColor(R.color.active_buttons_and_links_text_light)));
|
||||
toolbar.setNavigationContentDescription(R.string.shared_string_close);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showExitDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updateAvailableSpace() {
|
||||
long calculatedSize = ExportSettingsAdapter.calculateItemsSize(adapter.getData());
|
||||
if (calculatedSize != 0) {
|
||||
selectedItemsSize.setText(AndroidUtils.formatSize(app, calculatedSize));
|
||||
|
||||
File dir = app.getAppPath("").getParentFile();
|
||||
long availableSizeBytes = AndroidUtils.getAvailableSpace(dir);
|
||||
if (calculatedSize > availableSizeBytes) {
|
||||
String availableSize = AndroidUtils.formatSize(app, availableSizeBytes);
|
||||
availableSpaceDescr.setText(getString(R.string.export_not_enough_space_descr, availableSize));
|
||||
updateWarningHeaderVisibility(true);
|
||||
continueBtn.setEnabled(false);
|
||||
} else {
|
||||
updateWarningHeaderVisibility(false);
|
||||
continueBtn.setEnabled(adapter.hasSelectedData());
|
||||
}
|
||||
itemsSizeContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
updateWarningHeaderVisibility(false);
|
||||
itemsSizeContainer.setVisibility(View.INVISIBLE);
|
||||
continueBtn.setEnabled(adapter.hasSelectedData());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWarningHeaderVisibility(boolean visible) {
|
||||
if (visible) {
|
||||
if (expandableList.getHeaderViewsCount() < 2) {
|
||||
expandableList.addHeaderView(availableSpaceContainer);
|
||||
}
|
||||
AndroidUiHelper.updateVisibility(headerShadow, false);
|
||||
AndroidUiHelper.updateVisibility(headerDivider, true);
|
||||
} else {
|
||||
expandableList.removeHeaderView(availableSpaceContainer);
|
||||
AndroidUiHelper.updateVisibility(headerShadow, true);
|
||||
AndroidUiHelper.updateVisibility(headerDivider, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MapActivity getMapActivity() {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity instanceof MapActivity) {
|
||||
return (MapActivity) activity;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategorySelected(ExportSettingsCategory category, boolean selected) {
|
||||
SettingsCategoryItems categoryItems = dataList.get(category);
|
||||
for (ExportSettingsType type : categoryItems.getTypes()) {
|
||||
List<?> selectedItems = selected ? categoryItems.getItemsForType(type) : new ArrayList<>();
|
||||
selectedItemsMap.put(type, selectedItems);
|
||||
}
|
||||
updateAvailableSpace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemsSelected(ExportSettingsType type, List<?> selectedItems) {
|
||||
selectedItemsMap.put(type, selectedItems);
|
||||
adapter.notifyDataSetChanged();
|
||||
updateAvailableSpace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTypeClicked(ExportSettingsCategory category, ExportSettingsType type) {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
if (fragmentManager != null && type != ExportSettingsType.GLOBAL && type != ExportSettingsType.SEARCH_HISTORY) {
|
||||
List<Object> items = (List<Object>) dataList.get(category).getItemsForType(type);
|
||||
List<Object> selectedItems = (List<Object>) selectedItemsMap.get(type);
|
||||
ExportItemsBottomSheet.showInstance(type, selectedItems, items, fragmentManager, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,463 +0,0 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.widget.CompoundButtonCompat;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
|
||||
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
|
||||
import net.osmand.plus.helpers.FileNameTranslationHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.osmedit.OpenstreetmapPoint;
|
||||
import net.osmand.plus.osmedit.OsmEditingPlugin;
|
||||
import net.osmand.plus.osmedit.OsmNotesPoint;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.profiles.ProfileIconColors;
|
||||
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
import net.osmand.plus.settings.backend.backup.FileSettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.GlobalSettingsItem;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.view.ThreeStateCheckbox;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
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.plus.settings.backend.ExportSettingsType.OFFLINE_MAPS;
|
||||
import static net.osmand.plus.settings.backend.backup.FileSettingsItem.FileSubtype;
|
||||
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
|
||||
import static net.osmand.view.ThreeStateCheckbox.State.MISC;
|
||||
import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
|
||||
|
||||
class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ExportImportSettingsAdapter.class.getName());
|
||||
private OsmandApplication app;
|
||||
private UiUtilities uiUtilities;
|
||||
private List<? super Object> data;
|
||||
private Map<ExportSettingsType, List<?>> itemsMap;
|
||||
private List<ExportSettingsType> itemsTypes;
|
||||
private boolean nightMode;
|
||||
private boolean importState;
|
||||
private int activeColorRes;
|
||||
private int secondaryColorRes;
|
||||
|
||||
ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode, boolean importState) {
|
||||
this.app = app;
|
||||
this.nightMode = nightMode;
|
||||
this.importState = importState;
|
||||
this.itemsMap = new HashMap<>();
|
||||
this.itemsTypes = new ArrayList<>();
|
||||
this.data = new ArrayList<>();
|
||||
uiUtilities = app.getUIUtilities();
|
||||
activeColorRes = nightMode
|
||||
? R.color.icon_color_active_dark
|
||||
: R.color.icon_color_active_light;
|
||||
secondaryColorRes = nightMode
|
||||
? R.color.icon_color_secondary_dark
|
||||
: R.color.icon_color_secondary_light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
View group = convertView;
|
||||
if (group == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
group = inflater.inflate(R.layout.profile_data_list_item_group, parent, false);
|
||||
}
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
final ExportSettingsType type = itemsTypes.get(groupPosition);
|
||||
|
||||
TextView titleTv = group.findViewById(R.id.title_tv);
|
||||
TextView subTextTv = group.findViewById(R.id.sub_text_tv);
|
||||
final ThreeStateCheckbox checkBox = group.findViewById(R.id.check_box);
|
||||
FrameLayout checkBoxContainer = group.findViewById(R.id.check_box_container);
|
||||
ImageView expandIv = group.findViewById(R.id.explist_indicator);
|
||||
View lineDivider = group.findViewById(R.id.divider);
|
||||
View cardTopDivider = group.findViewById(R.id.card_top_divider);
|
||||
View cardBottomDivider = group.findViewById(R.id.card_bottom_divider);
|
||||
|
||||
titleTv.setText(getGroupTitle(type));
|
||||
lineDivider.setVisibility(importState || isExpanded || isLastGroup ? View.GONE : View.VISIBLE);
|
||||
cardTopDivider.setVisibility(importState ? View.VISIBLE : View.GONE);
|
||||
cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE);
|
||||
|
||||
final List<?> listItems = itemsMap.get(type);
|
||||
subTextTv.setText(getSelectedItemsAmount(listItems, type));
|
||||
|
||||
if (data.containsAll(listItems)) {
|
||||
checkBox.setState(CHECKED);
|
||||
} else {
|
||||
boolean contains = false;
|
||||
for (Object object : listItems) {
|
||||
if (data.contains(object)) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
checkBox.setState(contains ? MISC : UNCHECKED);
|
||||
}
|
||||
int checkBoxColor = checkBox.getState() == UNCHECKED ? secondaryColorRes : activeColorRes;
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, checkBoxColor)));
|
||||
checkBoxContainer.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
checkBox.performClick();
|
||||
if (checkBox.getState() == CHECKED) {
|
||||
for (Object object : listItems) {
|
||||
if (!data.contains(object)) {
|
||||
data.add(object);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data.removeAll(listItems);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
adjustIndicator(app, groupPosition, isExpanded, group, nightMode);
|
||||
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 = UiUtilities.getInflater(app, nightMode);
|
||||
child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false);
|
||||
}
|
||||
final Object currentItem = itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
boolean itemSelected = data.contains(currentItem);
|
||||
final ExportSettingsType type = itemsTypes.get(groupPosition);
|
||||
|
||||
TextView title = child.findViewById(R.id.title_tv);
|
||||
TextView subText = child.findViewById(R.id.sub_title_tv);
|
||||
subText.setVisibility(View.GONE);
|
||||
final CheckBox checkBox = child.findViewById(R.id.check_box);
|
||||
ImageView icon = child.findViewById(R.id.icon);
|
||||
View lineDivider = child.findViewById(R.id.divider);
|
||||
View cardBottomDivider = child.findViewById(R.id.card_bottom_divider);
|
||||
|
||||
lineDivider.setVisibility(!importState && isLastChild && !isLastGroup ? View.VISIBLE : View.GONE);
|
||||
cardBottomDivider.setVisibility(importState && isLastChild ? View.VISIBLE : View.GONE);
|
||||
int checkBoxColor = itemSelected ? activeColorRes : secondaryColorRes;
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, checkBoxColor)));
|
||||
|
||||
checkBox.setChecked(itemSelected);
|
||||
checkBox.setClickable(false);
|
||||
child.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (data.contains(currentItem)) {
|
||||
data.remove(currentItem);
|
||||
} else {
|
||||
data.add(currentItem);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
|
||||
switch (type) {
|
||||
case PROFILE:
|
||||
ApplicationModeBean modeBean = (ApplicationModeBean) currentItem;
|
||||
String profileName = modeBean.userProfileName;
|
||||
if (Algorithms.isEmpty(profileName)) {
|
||||
ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
|
||||
profileName = app.getString(appMode.getNameKeyResource());
|
||||
}
|
||||
title.setText(profileName);
|
||||
String routingProfile = "";
|
||||
String routingProfileValue = modeBean.routingProfile;
|
||||
if (!routingProfileValue.isEmpty()) {
|
||||
try {
|
||||
routingProfile = app.getString(RoutingProfilesResources.valueOf(routingProfileValue.toUpperCase()).getStringRes());
|
||||
routingProfile = Algorithms.capitalizeFirstLetterAndLowercase(routingProfile);
|
||||
} catch (IllegalArgumentException e) {
|
||||
routingProfile = Algorithms.capitalizeFirstLetterAndLowercase(routingProfileValue);
|
||||
LOG.error("Error trying to get routing resource for " + routingProfileValue + "\n" + e);
|
||||
}
|
||||
}
|
||||
if (!Algorithms.isEmpty(routingProfile)) {
|
||||
subText.setText(String.format(
|
||||
app.getString(R.string.ltr_or_rtl_combine_via_colon),
|
||||
app.getString(R.string.nav_type_hint),
|
||||
routingProfile));
|
||||
subText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
int profileIconRes = AndroidUtils.getDrawableId(app, modeBean.iconName);
|
||||
ProfileIconColors iconColor = modeBean.iconColor;
|
||||
icon.setImageDrawable(uiUtilities.getIcon(profileIconRes, iconColor.getColor(nightMode)));
|
||||
break;
|
||||
case QUICK_ACTIONS:
|
||||
title.setText(((QuickAction) currentItem).getName(app.getApplicationContext()));
|
||||
setupIcon(icon, ((QuickAction) currentItem).getIconRes(), itemSelected);
|
||||
break;
|
||||
case POI_TYPES:
|
||||
title.setText(((PoiUIFilter) currentItem).getName());
|
||||
int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId());
|
||||
setupIcon(icon, iconRes != 0 ? iconRes : R.drawable.ic_action_user, itemSelected);
|
||||
break;
|
||||
case MAP_SOURCES:
|
||||
title.setText(((ITileSource) currentItem).getName());
|
||||
setupIcon(icon, R.drawable.ic_map, itemSelected);
|
||||
break;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
String renderName = ((File) currentItem).getName();
|
||||
renderName = renderName.replace('_', ' ').replaceAll(IndexConstants.RENDERER_INDEX_EXT, "");
|
||||
title.setText(renderName);
|
||||
setupIcon(icon, R.drawable.ic_action_map_style, itemSelected);
|
||||
break;
|
||||
case CUSTOM_ROUTING:
|
||||
String routingName = ((File) currentItem).getName();
|
||||
routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
|
||||
title.setText(routingName);
|
||||
setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected);
|
||||
break;
|
||||
case AVOID_ROADS:
|
||||
AvoidRoadInfo avoidRoadInfo = (AvoidRoadInfo) currentItem;
|
||||
title.setText(avoidRoadInfo.name);
|
||||
setupIcon(icon, R.drawable.ic_action_alert, itemSelected);
|
||||
break;
|
||||
case MULTIMEDIA_NOTES:
|
||||
File file = (File) currentItem;
|
||||
title.setText(file.getName());
|
||||
int iconId = AudioVideoNotesPlugin.getIconIdForRecordingFile(file);
|
||||
if (iconId == -1) {
|
||||
iconId = R.drawable.ic_action_photo_dark;
|
||||
}
|
||||
setupIcon(icon, iconId, itemSelected);
|
||||
break;
|
||||
case TRACKS:
|
||||
String fileName = ((File) currentItem).getName();
|
||||
title.setText(GpxUiHelper.getGpxTitle(fileName));
|
||||
setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected);
|
||||
break;
|
||||
case GLOBAL:
|
||||
String name = ((GlobalSettingsItem) currentItem).getPublicName(app);
|
||||
title.setText(name);
|
||||
setupIcon(icon, R.drawable.ic_action_settings, itemSelected);
|
||||
break;
|
||||
case OSM_NOTES:
|
||||
title.setText(((OsmNotesPoint) currentItem).getText());
|
||||
setupIcon(icon, R.drawable.ic_action_osm_note_add, itemSelected);
|
||||
break;
|
||||
case OSM_EDITS:
|
||||
title.setText(OsmEditingPlugin.getTitle((OpenstreetmapPoint) currentItem, app));
|
||||
setupIcon(icon, R.drawable.ic_action_info_dark, itemSelected);
|
||||
break;
|
||||
case OFFLINE_MAPS:
|
||||
long size;
|
||||
if (currentItem instanceof FileSettingsItem) {
|
||||
FileSettingsItem currentFileItem = (FileSettingsItem) currentItem;
|
||||
file = currentFileItem.getFile();
|
||||
size = currentFileItem.getSize();
|
||||
} else {
|
||||
file = (File) currentItem;
|
||||
size = file.length();
|
||||
}
|
||||
title.setText(FileNameTranslationHelper.getFileNameWithRegion(app, file.getName()));
|
||||
FileSubtype subtype = FileSubtype.getSubtypeByPath(app, file.getPath());
|
||||
setupIcon(icon, subtype.getIconId(), itemSelected);
|
||||
subText.setText(AndroidUtils.formatSize(app, size));
|
||||
subText.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case FAVORITES:
|
||||
FavoriteGroup favoriteGroup = (FavoriteGroup) currentItem;
|
||||
title.setText(favoriteGroup.getDisplayName(app));
|
||||
setupIcon(icon, R.drawable.ic_action_favorite, itemSelected);
|
||||
break;
|
||||
case TTS_VOICE:
|
||||
case VOICE:
|
||||
file = (File) currentItem;
|
||||
title.setText(FileNameTranslationHelper.getFileNameWithRegion(app, file.getName()));
|
||||
setupIcon(icon, R.drawable.ic_action_volume_up, itemSelected);
|
||||
break;
|
||||
case ACTIVE_MARKERS:
|
||||
title.setText(R.string.map_markers);
|
||||
setupIcon(icon, R.drawable.ic_action_flag, itemSelected);
|
||||
break;
|
||||
case HISTORY_MARKERS:
|
||||
title.setText(R.string.markers_history);
|
||||
setupIcon(icon, R.drawable.ic_action_flag, itemSelected);
|
||||
break;
|
||||
case SEARCH_HISTORY:
|
||||
HistoryEntry historyEntry = (HistoryEntry) currentItem;
|
||||
title.setText(historyEntry.getName().getName());
|
||||
break;
|
||||
default:
|
||||
return child;
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return itemsTypes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int i) {
|
||||
return itemsMap.get(itemsTypes.get(i)).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGroup(int i) {
|
||||
return itemsMap.get(itemsTypes.get(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(int groupPosition, int childPosition) {
|
||||
return itemsMap.get(itemsTypes.get(groupPosition)).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 boolean isChildSelectable(int i, int i1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getSelectedItemsAmount(List<?> listItems, ExportSettingsType type) {
|
||||
int amount = 0;
|
||||
long amountSize = 0;
|
||||
for (Object item : listItems) {
|
||||
if (data.contains(item)) {
|
||||
amount++;
|
||||
if (type == OFFLINE_MAPS) {
|
||||
if (item instanceof FileSettingsItem) {
|
||||
amountSize += ((FileSettingsItem) item).getSize();
|
||||
} else {
|
||||
amountSize += ((File) item).length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String itemsOf = app.getString(R.string.n_items_of_z, String.valueOf(amount), String.valueOf(listItems.size()));
|
||||
return amountSize == 0 ? itemsOf : app.getString(R.string.ltr_or_rtl_combine_via_bold_point, itemsOf,
|
||||
AndroidUtils.formatSize(app, amountSize));
|
||||
}
|
||||
|
||||
private int getGroupTitle(ExportSettingsType type) {
|
||||
switch (type) {
|
||||
case PROFILE:
|
||||
return R.string.shared_string_profiles;
|
||||
case QUICK_ACTIONS:
|
||||
return R.string.configure_screen_quick_action;
|
||||
case POI_TYPES:
|
||||
return R.string.poi_dialog_poi_type;
|
||||
case MAP_SOURCES:
|
||||
return R.string.quick_action_map_source_title;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
return R.string.shared_string_rendering_style;
|
||||
case CUSTOM_ROUTING:
|
||||
return R.string.shared_string_routing;
|
||||
case AVOID_ROADS:
|
||||
return R.string.avoid_road;
|
||||
case TRACKS:
|
||||
return R.string.shared_string_tracks;
|
||||
case MULTIMEDIA_NOTES:
|
||||
return R.string.audionotes_plugin_name;
|
||||
case GLOBAL:
|
||||
return R.string.general_settings_2;
|
||||
case OSM_NOTES:
|
||||
return R.string.osm_notes;
|
||||
case OSM_EDITS:
|
||||
return R.string.osm_edits;
|
||||
case OFFLINE_MAPS:
|
||||
return R.string.shared_string_maps;
|
||||
case FAVORITES:
|
||||
return R.string.shared_string_favorites;
|
||||
case TTS_VOICE:
|
||||
return R.string.local_indexes_cat_tts;
|
||||
case VOICE:
|
||||
return R.string.local_indexes_cat_voice;
|
||||
case ACTIVE_MARKERS:
|
||||
return R.string.map_markers;
|
||||
case HISTORY_MARKERS:
|
||||
return R.string.markers_history;
|
||||
case SEARCH_HISTORY:
|
||||
return R.string.shared_string_search_history;
|
||||
default:
|
||||
return R.string.access_empty_list;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupIcon(ImageView icon, int iconRes, boolean itemSelected) {
|
||||
if (itemSelected) {
|
||||
icon.setImageDrawable(uiUtilities.getIcon(iconRes, activeColorRes));
|
||||
} else {
|
||||
icon.setImageDrawable(uiUtilities.getIcon(iconRes, nightMode));
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSettingsList(Map<ExportSettingsType, List<?>> itemsMap) {
|
||||
this.itemsMap = itemsMap;
|
||||
this.itemsTypes = new ArrayList<>(itemsMap.keySet());
|
||||
Collections.sort(itemsTypes);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clearSettingsList() {
|
||||
this.itemsMap.clear();
|
||||
this.itemsTypes.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void selectAll(boolean selectAll) {
|
||||
data.clear();
|
||||
if (selectAll) {
|
||||
for (List<?> values : itemsMap.values()) {
|
||||
data.addAll(values);
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
List<? super Object> getData() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
|
|||
|
||||
public class ExportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ExportImportSettingsAdapter.class.getName());
|
||||
private static final Log LOG = PlatformUtil.getLog(ExportSettingsAdapter.class.getName());
|
||||
|
||||
private final OsmandApplication app;
|
||||
private final UiUtilities uiUtilities;
|
||||
|
@ -240,6 +240,13 @@ public class ExportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clearSettingsList() {
|
||||
this.itemsMap.clear();
|
||||
this.itemsTypes.clear();
|
||||
this.selectedItemsMap.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public boolean hasSelectedData() {
|
||||
return !selectedItemsMap.isEmpty();
|
||||
}
|
||||
|
|
|
@ -4,24 +4,16 @@ import android.app.ProgressDialog;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
|
@ -31,36 +23,23 @@ import net.osmand.AndroidUtils;
|
|||
import net.osmand.FileUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.UiUtilities.DialogButtonType;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsCategory;
|
||||
import net.osmand.plus.settings.backend.ExportSettingsType;
|
||||
import net.osmand.plus.settings.backend.backup.FileSettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsExportListener;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItem;
|
||||
import net.osmand.plus.settings.fragments.ExportSettingsAdapter.OnItemSelectedListener;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.plus.settings.fragments.BaseSettingsFragment.APP_MODE_KEY;
|
||||
|
||||
public class ExportSettingsFragment extends BaseOsmAndFragment implements OnItemSelectedListener {
|
||||
public class ExportSettingsFragment extends BaseSettingsListFragment {
|
||||
|
||||
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
|
||||
public static final Log LOG = PlatformUtil.getLog(ImportSettingsFragment.class.getSimpleName());
|
||||
|
@ -76,45 +55,19 @@ public class ExportSettingsFragment extends BaseOsmAndFragment implements OnItem
|
|||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yy", Locale.US);
|
||||
|
||||
private OsmandApplication app;
|
||||
|
||||
private Map<ExportSettingsType, List<?>> selectedItemsMap = new HashMap<>();
|
||||
private Map<ExportSettingsCategory, SettingsCategoryItems> dataList = new LinkedHashMap<>();
|
||||
|
||||
private ProgressDialog progress;
|
||||
private ApplicationMode appMode;
|
||||
private SettingsExportListener exportListener;
|
||||
|
||||
private View continueBtn;
|
||||
private View headerShadow;
|
||||
private View headerDivider;
|
||||
private View itemsSizeContainer;
|
||||
private View availableSpaceContainer;
|
||||
private TextViewEx selectedItemsSize;
|
||||
private TextViewEx availableSpaceDescr;
|
||||
private LinearLayout buttonsContainer;
|
||||
private ExpandableListView expandableList;
|
||||
private ExportSettingsAdapter adapter;
|
||||
|
||||
private int progressMax;
|
||||
private int progressValue;
|
||||
|
||||
private long exportStartTime;
|
||||
|
||||
private boolean nightMode;
|
||||
private boolean globalExport;
|
||||
private boolean exportingStarted;
|
||||
|
||||
@Override
|
||||
public int getStatusBarColorId() {
|
||||
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requireMyApplication();
|
||||
nightMode = !app.getSettings().isLightContent();
|
||||
if (savedInstanceState != null) {
|
||||
appMode = ApplicationMode.valueOfStringKey(savedInstanceState.getString(APP_MODE_KEY), null);
|
||||
globalExport = savedInstanceState.getBoolean(GLOBAL_EXPORT_KEY);
|
||||
|
@ -136,64 +89,19 @@ public class ExportSettingsFragment extends BaseOsmAndFragment implements OnItem
|
|||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(app, nightMode);
|
||||
View root = themedInflater.inflate(R.layout.fragment_import, container, false);
|
||||
AndroidUtils.addStatusBarPadding21v(app, root);
|
||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
selectedItemsSize = root.findViewById(R.id.file_size);
|
||||
itemsSizeContainer = root.findViewById(R.id.file_size_container);
|
||||
expandableList = root.findViewById(R.id.list);
|
||||
buttonsContainer = root.findViewById(R.id.buttons_container);
|
||||
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
setupToolbar(toolbar);
|
||||
ViewCompat.setNestedScrollingEnabled(expandableList, true);
|
||||
|
||||
View header = themedInflater.inflate(R.layout.list_item_description_header, null);
|
||||
headerDivider = header.findViewById(R.id.divider);
|
||||
headerShadow = header.findViewById(R.id.card_bottom_divider);
|
||||
expandableList.addHeaderView(header);
|
||||
|
||||
availableSpaceContainer = themedInflater.inflate(R.layout.enough_space_warning_card, null);
|
||||
availableSpaceDescr = availableSpaceContainer.findViewById(R.id.warning_descr);
|
||||
|
||||
continueBtn = root.findViewById(R.id.continue_button);
|
||||
UiUtilities.setupDialogButton(nightMode, continueBtn, DialogButtonType.PRIMARY, getString(R.string.shared_string_continue));
|
||||
continueBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
prepareFile();
|
||||
}
|
||||
});
|
||||
|
||||
ViewTreeObserver treeObserver = buttonsContainer.getViewTreeObserver();
|
||||
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
if (buttonsContainer != null) {
|
||||
ViewTreeObserver vts = buttonsContainer.getViewTreeObserver();
|
||||
int height = buttonsContainer.getMeasuredHeight();
|
||||
expandableList.setPadding(0, 0, 0, height);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
vts.removeOnGlobalLayoutListener(this);
|
||||
} else {
|
||||
vts.removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
adapter = new ExportSettingsAdapter(app, this, nightMode);
|
||||
adapter.updateSettingsItems(dataList, selectedItemsMap);
|
||||
expandableList.setAdapter(adapter);
|
||||
|
||||
CollapsingToolbarLayout toolbarLayout = root.findViewById(R.id.toolbar_layout);
|
||||
CollapsingToolbarLayout toolbarLayout = view.findViewById(R.id.toolbar_layout);
|
||||
toolbarLayout.setTitle(getString(R.string.shared_string_export));
|
||||
TextView description = header.findViewById(R.id.description);
|
||||
description.setText(R.string.select_data_to_export);
|
||||
updateAvailableSpace();
|
||||
|
||||
return root;
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContinueButtonClickAction() {
|
||||
prepareFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -224,105 +132,6 @@ public class ExportSettingsFragment extends BaseOsmAndFragment implements OnItem
|
|||
}
|
||||
}
|
||||
|
||||
private void dismissFragment() {
|
||||
FragmentManager fm = getFragmentManager();
|
||||
if (fm != null && !fm.isStateSaved()) {
|
||||
getFragmentManager().popBackStack(EXPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void showExitDialog() {
|
||||
Context themedContext = UiUtilities.getThemedContext(getActivity(), nightMode);
|
||||
AlertDialog.Builder dismissDialog = new AlertDialog.Builder(themedContext);
|
||||
dismissDialog.setTitle(getString(R.string.shared_string_dismiss));
|
||||
dismissDialog.setMessage(getString(R.string.exit_without_saving));
|
||||
dismissDialog.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismissFragment();
|
||||
}
|
||||
});
|
||||
dismissDialog.show();
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
int color = ContextCompat.getColor(app, nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light);
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_action_close, color));
|
||||
toolbar.setNavigationContentDescription(R.string.shared_string_close);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showExitDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateAvailableSpace() {
|
||||
long calculatedSize = ExportSettingsAdapter.calculateItemsSize(adapter.getData());
|
||||
if (calculatedSize != 0) {
|
||||
selectedItemsSize.setText(AndroidUtils.formatSize(app, calculatedSize));
|
||||
|
||||
File dir = app.getAppPath("").getParentFile();
|
||||
long availableSizeBytes = AndroidUtils.getAvailableSpace(dir);
|
||||
if (calculatedSize > availableSizeBytes) {
|
||||
String availableSize = AndroidUtils.formatSize(app, availableSizeBytes);
|
||||
availableSpaceDescr.setText(getString(R.string.export_not_enough_space_descr, availableSize));
|
||||
updateWarningHeaderVisibility(true);
|
||||
continueBtn.setEnabled(false);
|
||||
} else {
|
||||
updateWarningHeaderVisibility(false);
|
||||
continueBtn.setEnabled(adapter.hasSelectedData());
|
||||
}
|
||||
itemsSizeContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
updateWarningHeaderVisibility(false);
|
||||
itemsSizeContainer.setVisibility(View.INVISIBLE);
|
||||
continueBtn.setEnabled(adapter.hasSelectedData());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWarningHeaderVisibility(boolean visible) {
|
||||
if (visible) {
|
||||
if (expandableList.getHeaderViewsCount() < 2) {
|
||||
expandableList.addHeaderView(availableSpaceContainer);
|
||||
}
|
||||
AndroidUiHelper.updateVisibility(headerShadow, false);
|
||||
AndroidUiHelper.updateVisibility(headerDivider, true);
|
||||
} else {
|
||||
expandableList.removeHeaderView(availableSpaceContainer);
|
||||
AndroidUiHelper.updateVisibility(headerShadow, true);
|
||||
AndroidUiHelper.updateVisibility(headerDivider, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategorySelected(ExportSettingsCategory category, boolean selected) {
|
||||
SettingsCategoryItems categoryItems = dataList.get(category);
|
||||
for (ExportSettingsType type : categoryItems.getTypes()) {
|
||||
List<?> selectedItems = selected ? categoryItems.getItemsForType(type) : new ArrayList<>();
|
||||
selectedItemsMap.put(type, selectedItems);
|
||||
}
|
||||
updateAvailableSpace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemsSelected(ExportSettingsType type, List<?> selectedItems) {
|
||||
selectedItemsMap.put(type, selectedItems);
|
||||
adapter.notifyDataSetChanged();
|
||||
updateAvailableSpace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTypeClicked(ExportSettingsCategory category, ExportSettingsType type) {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
if (fragmentManager != null && type != ExportSettingsType.GLOBAL && type != ExportSettingsType.SEARCH_HISTORY) {
|
||||
List<Object> items = (List<Object>) dataList.get(category).getItemsForType(type);
|
||||
List<Object> selectedItems = (List<Object>) selectedItemsMap.get(type);
|
||||
ExportItemsBottomSheet.showInstance(type, selectedItems, items, fragmentManager, this);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareFile() {
|
||||
if (app != null) {
|
||||
exportingStarted = true;
|
||||
|
@ -467,7 +276,7 @@ public class ExportSettingsFragment extends BaseOsmAndFragment implements OnItem
|
|||
fragment.globalExport = globalExport;
|
||||
fragmentManager.beginTransaction().
|
||||
replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(EXPORT_SETTINGS_TAG)
|
||||
.addToBackStack(SETTINGS_LIST_TAG)
|
||||
.commitAllowingStateLoss();
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
|
|
|
@ -40,7 +40,7 @@ import net.osmand.plus.settings.backend.backup.SettingsItem;
|
|||
import java.util.List;
|
||||
|
||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID;
|
||||
import static net.osmand.plus.settings.fragments.ImportSettingsFragment.IMPORT_SETTINGS_TAG;
|
||||
import static net.osmand.plus.settings.fragments.BaseSettingsListFragment.SETTINGS_LIST_TAG;
|
||||
|
||||
public class ImportCompleteFragment extends BaseOsmAndFragment {
|
||||
public static final String TAG = ImportCompleteFragment.class.getSimpleName();
|
||||
|
@ -58,7 +58,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
|
|||
fragment.setRetainInstance(true);
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(IMPORT_SETTINGS_TAG)
|
||||
.addToBackStack(SETTINGS_LIST_TAG)
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
|
|||
public void dismissFragment() {
|
||||
FragmentManager fm = getFragmentManager();
|
||||
if (fm != null && !fm.isStateSaved()) {
|
||||
fm.popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
fm.popBackStack(SETTINGS_LIST_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import static net.osmand.plus.settings.backend.backup.FileSettingsItem.FileSubtype;
|
||||
import static net.osmand.plus.settings.fragments.ImportSettingsFragment.IMPORT_SETTINGS_TAG;
|
||||
import static net.osmand.plus.settings.fragments.BaseSettingsListFragment.SETTINGS_LIST_TAG;
|
||||
|
||||
|
||||
public class ImportDuplicatesFragment extends BaseOsmAndFragment {
|
||||
|
@ -79,7 +79,7 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment {
|
|||
fragment.setFile(file);
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(IMPORT_SETTINGS_TAG)
|
||||
.addToBackStack(SETTINGS_LIST_TAG)
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.AsyncTask;
|
||||
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.ExpandableListView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
@ -20,27 +15,21 @@ import android.widget.TextView;
|
|||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||
import net.osmand.plus.AppInitializer;
|
||||
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SQLiteTileSource;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.UiUtilities.DialogButtonType;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.download.ReloadIndexesTask;
|
||||
import net.osmand.plus.download.ReloadIndexesTask.ReloadIndexesListener;
|
||||
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
|
@ -66,7 +55,6 @@ import net.osmand.plus.settings.backend.backup.QuickActionsSettingsItem;
|
|||
import net.osmand.plus.settings.backend.backup.SearchHistorySettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.ImportAsyncTask;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper.ImportType;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsItemType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -76,30 +64,25 @@ import org.apache.commons.logging.Log;
|
|||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ImportSettingsFragment extends BaseOsmAndFragment {
|
||||
public class ImportSettingsFragment extends BaseSettingsListFragment {
|
||||
|
||||
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 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 List<SettingsItem> settingsItems;
|
||||
|
||||
private TextView description;
|
||||
private ProgressBar progressBar;
|
||||
private LinearLayout buttonsContainer;
|
||||
private CollapsingToolbarLayout toolbarLayout;
|
||||
|
||||
private long duplicateStartTime;
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fm, @NonNull List<SettingsItem> settingsItems, @NonNull File file) {
|
||||
|
@ -108,7 +91,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
fragment.setFile(file);
|
||||
fm.beginTransaction().
|
||||
replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(IMPORT_SETTINGS_TAG)
|
||||
.addToBackStack(SETTINGS_LIST_TAG)
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
|
@ -118,70 +101,14 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
if (savedInstanceState != null) {
|
||||
duplicateStartTime = savedInstanceState.getLong(DUPLICATES_START_TIME_KEY);
|
||||
}
|
||||
app = requireMyApplication();
|
||||
settingsHelper = app.getSettingsHelper();
|
||||
nightMode = !app.getSettings().isLightContent();
|
||||
requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
showExitDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
inflater = UiUtilities.getInflater(app, nightMode);
|
||||
View root = inflater.inflate(R.layout.fragment_import, container, false);
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
View continueBtn = root.findViewById(R.id.continue_button);
|
||||
toolbarLayout = root.findViewById(R.id.toolbar_layout);
|
||||
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);
|
||||
description = header.findViewById(R.id.description);
|
||||
description.setText(R.string.select_data_to_import);
|
||||
expandableList.addHeaderView(header);
|
||||
UiUtilities.setupDialogButton(nightMode, continueBtn, DialogButtonType.PRIMARY, getString(R.string.shared_string_continue));
|
||||
continueBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (adapter.getData().isEmpty()) {
|
||||
app.showShortToastMessage(getString(R.string.shared_string_nothing_selected));
|
||||
} else {
|
||||
importItems();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
AndroidUtils.addStatusBarPadding21v(app, root);
|
||||
}
|
||||
ViewTreeObserver treeObserver = buttonsContainer.getViewTreeObserver();
|
||||
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
if (buttonsContainer != null) {
|
||||
ViewTreeObserver vts = buttonsContainer.getViewTreeObserver();
|
||||
int height = buttonsContainer.getMeasuredHeight();
|
||||
expandableList.setPadding(0, 0, 0, height);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
vts.removeOnGlobalLayoutListener(this);
|
||||
} else {
|
||||
vts.removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
ImportAsyncTask importTask = settingsHelper.getImportTask();
|
||||
if (importTask != null) {
|
||||
if (settingsItems == null) {
|
||||
|
@ -200,27 +127,24 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
adapter = new ExportImportSettingsAdapter(app, nightMode, true);
|
||||
Map<ExportSettingsType, List<?>> itemsMap = new EnumMap<>(ExportSettingsType.class);
|
||||
if (settingsItems != null) {
|
||||
itemsMap = SettingsHelper.getSettingsToOperate(settingsItems, false);
|
||||
adapter.updateSettingsList(itemsMap);
|
||||
dataList = SettingsHelper.getSettingsToOperateByCategory(settingsItems, false);
|
||||
}
|
||||
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));
|
||||
}
|
||||
if (itemsMap.size() == 1 && itemsMap.containsKey(ExportSettingsType.PROFILE)) {
|
||||
expandableList.expandGroup(0);
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
toolbarLayout = view.findViewById(R.id.toolbar_layout);
|
||||
buttonsContainer = view.findViewById(R.id.buttons_container);
|
||||
progressBar = view.findViewById(R.id.progress_bar);
|
||||
|
||||
description = header.findViewById(R.id.description);
|
||||
description.setText(R.string.select_data_to_import);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -230,11 +154,11 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Activity activity = getActivity();
|
||||
if (activity instanceof MapActivity) {
|
||||
((MapActivity) activity).closeDrawer();
|
||||
protected void onContinueButtonClickAction() {
|
||||
if (adapter.getData().isEmpty()) {
|
||||
app.showShortToastMessage(getString(R.string.shared_string_nothing_selected));
|
||||
} else {
|
||||
importItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,12 +177,12 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
|
||||
private void importItems() {
|
||||
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
|
||||
List<SettingsItem> selectedItems = getSettingsItemsFromData(adapter.getData());
|
||||
if (file != null && settingsItems != null) {
|
||||
duplicateStartTime = System.currentTimeMillis();
|
||||
settingsHelper.checkDuplicates(file, settingsItems, selectedItems, getDuplicatesListener());
|
||||
}
|
||||
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
|
||||
}
|
||||
|
||||
public SettingsHelper.SettingsImportListener getImportListener() {
|
||||
|
@ -283,38 +207,29 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
if (item instanceof FileSettingsItem && ((FileSettingsItem) item).getSubtype().isMap()) {
|
||||
Activity activity = getActivity();
|
||||
if (activity instanceof MapActivity) {
|
||||
new ReloadIndexesTack((MapActivity) activity).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>((MapActivity) activity);
|
||||
ReloadIndexesListener listener = new ReloadIndexesListener() {
|
||||
@Override
|
||||
public void reloadIndexesStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadIndexesFinished(List<String> warnings) {
|
||||
MapActivity mapActivity = mapActivityRef.get();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.refreshMap();
|
||||
}
|
||||
}
|
||||
};
|
||||
ReloadIndexesTask reloadIndexesTask = new ReloadIndexesTask(app, listener);
|
||||
reloadIndexesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReloadIndexesTack extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private final WeakReference<MapActivity> mapActivityRef;
|
||||
private final OsmandApplication app;
|
||||
|
||||
ReloadIndexesTack(@NonNull MapActivity mapActivity) {
|
||||
this.mapActivityRef = new WeakReference<>(mapActivity);
|
||||
this.app = mapActivity.getMyApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void[] params) {
|
||||
app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList<String>());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
MapActivity mapActivity = mapActivityRef.get();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.refreshMap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SettingsHelper.CheckDuplicatesListener getDuplicatesListener() {
|
||||
return new SettingsHelper.CheckDuplicatesListener() {
|
||||
@Override
|
||||
|
@ -349,13 +264,6 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void dismissFragment() {
|
||||
FragmentManager fm = getFragmentManager();
|
||||
if (fm != null && !fm.isStateSaved()) {
|
||||
getFragmentManager().popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSettingsItems(List<SettingsItem> settingsItems) {
|
||||
this.settingsItems = settingsItems;
|
||||
}
|
||||
|
@ -523,39 +431,6 @@ public class ImportSettingsFragment extends BaseOsmAndFragment {
|
|||
return settingsItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusBarColorId() {
|
||||
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
|
||||
}
|
||||
|
||||
public void showExitDialog() {
|
||||
Context themedContext = UiUtilities.getThemedContext(getActivity(), nightMode);
|
||||
AlertDialog.Builder dismissDialog = new AlertDialog.Builder(themedContext);
|
||||
dismissDialog.setTitle(getString(R.string.shared_string_dismiss));
|
||||
dismissDialog.setMessage(getString(R.string.exit_without_saving));
|
||||
dismissDialog.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismissFragment();
|
||||
}
|
||||
});
|
||||
dismissDialog.show();
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_action_close, nightMode
|
||||
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
|
||||
: getResources().getColor(R.color.active_buttons_and_links_text_light)));
|
||||
toolbar.setNavigationContentDescription(R.string.shared_string_close);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showExitDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue