diff --git a/OsmAnd/res/layout/search_dialog_fragment.xml b/OsmAnd/res/layout/search_dialog_fragment.xml index 7dca8801ae..10a7122b19 100644 --- a/OsmAnd/res/layout/search_dialog_fragment.xml +++ b/OsmAnd/res/layout/search_dialog_fragment.xml @@ -1,220 +1,240 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + android:layout_height="wrap_content"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - \ No newline at end of file + \ No newline at end of file diff --git a/OsmAnd/res/layout/subcategories_dialog_title.xml b/OsmAnd/res/layout/subcategories_dialog_title.xml new file mode 100644 index 0000000000..cd8808eac7 --- /dev/null +++ b/OsmAnd/res/layout/subcategories_dialog_title.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 60fd9c1f23..c09698b6f9 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,8 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Edit filter + Subcategories Selected categories Create custom POI Custom search diff --git a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java index f852fbd009..8e6fd6b972 100644 --- a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java @@ -456,6 +456,8 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable public void clearFilter() { acceptedTypes = new LinkedHashMap<>(); poiAdditionals.clear(); + filterByName = null; + clearCurrentResults(); } public boolean areAllTypesAccepted() { diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchCustomPoiFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchCustomPoiFragment.java index 18e7b217ea..435dcbb865 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchCustomPoiFragment.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchCustomPoiFragment.java @@ -5,6 +5,7 @@ import android.content.DialogInterface; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.support.v7.widget.AppCompatImageView; import android.support.v7.widget.AppCompatTextView; @@ -15,7 +16,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ListView; +import android.widget.TextView; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; @@ -50,6 +54,8 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { private View bottomBar; private AppCompatTextView barTitle; private AppCompatTextView barButton; + private boolean editMode; + public QuickSearchCustomPoiFragment() { } @@ -83,6 +89,7 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { filter = helper.getCustomPOIFilter(); filter.clearFilter(); } + editMode = !filterId.equals(helper.getCustomPOIFilter().getFilterId()); view = inflater.inflate(R.layout.search_custom_poi, container, false); @@ -96,6 +103,11 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { } }); + TextView title = (TextView) view.findViewById(R.id.title); + if (editMode) { + title.setText(filter.getName()); + } + listView = (ListView) view.findViewById(android.R.id.list); listView.setBackgroundColor(getResources().getColor( app.getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light @@ -111,7 +123,7 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { PoiCategory category = listAdapter.getItem(position - listView.getHeaderViewsCount()); - showDialog(category); + showDialog(category, false); } }); @@ -122,7 +134,10 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { @Override public void onClick(View v) { dismiss(); - ((QuickSearchDialogFragment) getParentFragment()).showFilter(filterId); + QuickSearchDialogFragment quickSearchDialogFragment = getQuickSearchDialogFragment(); + if (quickSearchDialogFragment != null) { + quickSearchDialogFragment.showFilter(filterId); + } } }); @@ -135,6 +150,31 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { outState.putString(QUICK_SEARCH_CUSTOM_POI_FILTER_ID_KEY, filterId); } + @Override + public void onDismiss(DialogInterface dialog) { + if (editMode) { + QuickSearchDialogFragment quickSearchDialogFragment = getQuickSearchDialogFragment(); + if (quickSearchDialogFragment != null) { + getMyApplication().getSearchUICore().refreshCustomPoiFilters(); + quickSearchDialogFragment.replaceQueryWithUiFilter(filter, ""); + quickSearchDialogFragment.reloadCategories(); + } + } + super.onDismiss(dialog); + } + + private QuickSearchDialogFragment getQuickSearchDialogFragment() { + Fragment parent = getParentFragment(); + if (parent instanceof QuickSearchDialogFragment) { + return (QuickSearchDialogFragment) parent; + } else if (parent instanceof QuickSearchPoiFilterFragment + && parent.getParentFragment() instanceof QuickSearchDialogFragment) { + return (QuickSearchDialogFragment) parent.getParentFragment(); + } else { + return null; + } + } + private int getIconId(PoiCategory category) { OsmandApplication app = getMyApplication(); String id = null; @@ -197,6 +237,7 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { iconView.setImageDrawable(null); } secondaryIconView.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_additional_option)); + check.setOnCheckedChangeListener(null); check.setChecked(filter.isTypeAccepted(category)); String textString = category.getTranslation(); titleView.setText(textString); @@ -225,17 +266,16 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { } private void addRowListener(final PoiCategory category, final SwitchCompat check) { - check.setOnClickListener(new View.OnClickListener() { + check.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override - public void onClick(View v) { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (check.isChecked()) { - filter.setTypeToAccept(category, true); - showDialog(category); + showDialog(category, true); } else { filter.setTypeToAccept(category, false); saveFilter(); + notifyDataSetChanged(); } - notifyDataSetChanged(); } }); } @@ -243,19 +283,21 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { private void saveFilter() { helper.editPoiFilter(filter); - if (filter.isEmpty()) { - bottomBar.setVisibility(View.GONE); - } else { - barTitle.setText(getContext().getString(R.string.selected_categories) + ": " + filter.getAcceptedTypesCount()); - bottomBar.setVisibility(View.VISIBLE); + if (!editMode) { + if (filter.isEmpty()) { + bottomBar.setVisibility(View.GONE); + } else { + barTitle.setText(getContext().getString(R.string.selected_categories) + ": " + filter.getAcceptedTypesCount()); + bottomBar.setVisibility(View.VISIBLE); + } } } - private void showDialog(final PoiCategory poiCategory) { + private void showDialog(final PoiCategory poiCategory, boolean selectAll) { final int index = listView.getFirstVisiblePosition(); View v = listView.getChildAt(0); final int top = (v == null) ? 0 : v.getTop(); - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); final LinkedHashMap subCategories = new LinkedHashMap(); Set acceptedCategories = filter.getAcceptedSubtypes(poiCategory); if (acceptedCategories != null) { @@ -281,17 +323,27 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { }); final String[] visibleNames = new String[array.length]; final boolean[] selected = new boolean[array.length]; - + boolean allSelected = true; for (int i = 0; i < array.length; i++) { final String subcategory = array[i]; visibleNames[i] = subCategories.get(subcategory); - if (acceptedCategories == null) { + if (acceptedCategories == null || selectAll) { selected[i] = true; } else { + if (allSelected) { + allSelected = false; + } selected[i] = acceptedCategories.contains(subcategory); } } - builder.setTitle(poiCategory.getTranslation()); + + View titleView = LayoutInflater.from(getActivity()) + .inflate(R.layout.subcategories_dialog_title, null); + TextView titleTextView = (TextView) titleView.findViewById(R.id.title); + titleTextView.setText(poiCategory.getTranslation()); + SwitchCompat check = (SwitchCompat) titleView.findViewById(R.id.check); + check.setChecked(allSelected); + builder.setCustomTitle(titleView); builder.setCancelable(true); builder.setNegativeButton(getContext().getText(R.string.shared_string_cancel), new DialogInterface.OnClickListener() { @@ -323,16 +375,6 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { } }); - /* - builder.setPositiveButton(getContext().getText(R.string.shared_string_select_all), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - selectAllFromCategory(poiCategory); - listView.setSelectionFromTop(index, top); - } - }); - */ - builder.setMultiChoiceItems(visibleNames, selected, new DialogInterface.OnMultiChoiceClickListener() { @Override @@ -340,13 +382,19 @@ public class QuickSearchCustomPoiFragment extends DialogFragment { selected[item] = isChecked; } }); - builder.show(); - - } - - public void selectAllFromCategory(PoiCategory poiCategory) { - filter.updateTypesToAccept(poiCategory); - saveFilter(); - listAdapter.notifyDataSetChanged(); + final AlertDialog dialog = builder.show(); + check.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + Arrays.fill(selected, true); + } else { + Arrays.fill(selected, false); + } + for (int i = 0; i < selected.length; i++) { + dialog.getListView().setItemChecked(i, selected[i]); + } + } + }); } } diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java index 257a5d7d5c..4ab8d65d83 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java @@ -31,9 +31,11 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import net.osmand.AndroidUtils; import net.osmand.Location; @@ -75,6 +77,7 @@ import net.osmand.util.MapUtils; import java.io.File; import java.io.IOException; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; @@ -91,6 +94,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC private static final String QUICK_SEARCH_HIDDEN_KEY = "quick_search_hidden_key"; private static final String QUICK_SEARCH_TOOLBAR_TITLE_KEY = "quick_search_toolbar_title_key"; private static final String QUICK_SEARCH_TOOLBAR_VISIBLE_KEY = "quick_search_toolbar_visible_key"; + private static final String QUICK_SEARCH_FAB_VISIBLE_KEY = "quick_search_fab_visible_key"; private Toolbar toolbar; private LockableViewPager viewPager; @@ -110,6 +114,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC private Toolbar toolbarEdit; private TextView titleEdit; + private View fab; private EditText searchEditText; private ProgressBar progressBar; @@ -136,6 +141,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC private boolean interruptedSearch; private long hideTimeMs; private boolean poiFilterApplied; + private boolean fabVisible; private static final double DISTANCE_THRESHOLD = 70000; // 70km private static final int EXPIRATION_TIME_MIN = 10; // 10 minutes @@ -189,6 +195,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC hidden = savedInstanceState.getBoolean(QUICK_SEARCH_HIDDEN_KEY, false); toolbarTitle = savedInstanceState.getString(QUICK_SEARCH_TOOLBAR_TITLE_KEY); toolbarVisible = savedInstanceState.getBoolean(QUICK_SEARCH_TOOLBAR_VISIBLE_KEY, false); + fabVisible = savedInstanceState.getBoolean(QUICK_SEARCH_FAB_VISIBLE_KEY, false); } if (searchQuery == null && arguments != null) { searchQuery = arguments.getString(QUICK_SEARCH_QUERY_KEY); @@ -429,6 +436,10 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC if (textEmpty && poiFilterApplied) { poiFilterApplied = false; reloadCategories(); + if (fabVisible) { + fabVisible = false; + updateFab(); + } } if (!searchQuery.equalsIgnoreCase(newQueryText)) { searchQuery = newQueryText; @@ -470,6 +481,15 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } ); + fab = view.findViewById(R.id.fab); + fab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + saveCustomFilter(); + } + }); + updateFab(); + setupSearch(mapActivity); return view; @@ -490,6 +510,51 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } } + public void saveCustomFilter() { + final OsmandApplication app = getMyApplication(); + final PoiUIFilter filter = app.getPoiFilters().getCustomPOIFilter(); + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle(R.string.access_hint_enter_name); + + final EditText editText = new EditText(getContext()); + editText.setHint(R.string.new_filter); + + final TextView textView = new TextView(getContext()); + textView.setText(app.getString(R.string.new_filter_desc)); + textView.setTextAppearance(getContext(), R.style.TextAppearance_ContextMenuSubtitle); + LinearLayout ll = new LinearLayout(getContext()); + ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + ll.setOrientation(LinearLayout.VERTICAL); + ll.setPadding(AndroidUtils.dpToPx(getContext(), 20f), AndroidUtils.dpToPx(getContext(), 12f), AndroidUtils.dpToPx(getContext(), 20f), AndroidUtils.dpToPx(getContext(), 12f)); + ll.addView(editText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + textView.setPadding(AndroidUtils.dpToPx(getContext(), 4f), AndroidUtils.dpToPx(getContext(), 6f), AndroidUtils.dpToPx(getContext(), 4f), AndroidUtils.dpToPx(getContext(), 4f)); + ll.addView(textView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + + builder.setView(ll); + + builder.setNegativeButton(R.string.shared_string_cancel, null); + builder.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + PoiUIFilter nFilter = new PoiUIFilter(editText.getText().toString(), null, filter.getAcceptedTypes(), app); + if (!Algorithms.isEmpty(filter.getFilterByName())) { + nFilter.setSavedFilterByName(filter.getFilterByName()); + } + if (app.getPoiFilters().createPoiFilter(nFilter)) { + Toast.makeText(getContext(), MessageFormat.format(getContext().getText(R.string.edit_filter_create_message).toString(), + editText.getText().toString()), Toast.LENGTH_SHORT).show(); + app.getSearchUICore().refreshCustomPoiFilters(); + replaceQueryWithUiFilter(nFilter, ""); + reloadCategories(); + + fabVisible = false; + updateFab(); + } + } + }); + builder.create().show(); + } + public void restoreToolbar() { if (toolbarVisible) { if (toolbarTitle != null) { @@ -680,6 +745,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC outState.putDouble(QUICK_SEARCH_LAT_KEY, centerLatLon.getLatitude()); outState.putDouble(QUICK_SEARCH_LON_KEY, centerLatLon.getLongitude()); } + outState.putBoolean(QUICK_SEARCH_FAB_VISIBLE_KEY, fabVisible); } @Override @@ -1297,8 +1363,14 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } } - public void showFilter(String filterId) { + public void showFilter(@NonNull String filterId) { PoiUIFilter filter = app.getPoiFilters().getFilterById(filterId); + boolean isCustomFilter = filterId.equals(app.getPoiFilters().getCustomPOIFilter().getFilterId()); + if (isCustomFilter) { + fabVisible = true; + poiFilterApplied = true; + updateFab(); + } SearchResult sr = new SearchResult(searchUICore.getPhrase()); sr.localeName = filter.getName(); @@ -1319,6 +1391,10 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC runCoreSearch(txt, false, false); } + private void updateFab() { + fab.setVisibility(fabVisible ? View.VISIBLE : View.GONE); + } + public class SearchFragmentPagerAdapter extends FragmentPagerAdapter { private final String[] fragments = new String[]{QuickSearchHistoryListFragment.class.getName(), QuickSearchCategoriesListFragment.class.getName()}; diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java index d7fd4a3c14..1b0f6be10d 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java @@ -152,8 +152,25 @@ public class QuickSearchPoiFilterFragment extends DialogFragment { DirectionsDialogs.setupPopUpMenuIcon(optionsMenu); MenuItem item; - item = optionsMenu.getMenu().add(R.string.save_filter).setIcon( - iconsCache.getThemedIcon(R.drawable.ic_action_save)); + if (!filter.isStandardFilter()) { + item = optionsMenu.getMenu().add(R.string.edit_filter).setIcon( + iconsCache.getThemedIcon(R.drawable.ic_action_edit_dark)); + item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + editFilter(); + return true; + } + }); + } + + if (!filter.isStandardFilter()) { + item = optionsMenu.getMenu().add(R.string.edit_filter_save_as_menu_item).setIcon( + iconsCache.getThemedIcon(R.drawable.ic_action_save)); + } else { + item = optionsMenu.getMenu().add(R.string.save_filter).setIcon( + iconsCache.getThemedIcon(R.drawable.ic_action_save)); + } item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { @@ -304,13 +321,19 @@ public class QuickSearchPoiFilterFragment extends DialogFragment { builder.create().show(); } + private void editFilter() { + QuickSearchCustomPoiFragment.showDialog(this, filter.getFilterId()); + } + private void saveFilter() { final OsmandApplication app = getMyApplication(); AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(R.string.access_hint_enter_name); + final EditText editText = new EditText(getContext()); editText.setHint(R.string.new_filter); editText.setText(filter.getName()); + final TextView textView = new TextView(getContext()); textView.setText(app.getString(R.string.new_filter_desc)); textView.setTextAppearance(getContext(), R.style.TextAppearance_ContextMenuSubtitle); @@ -321,7 +344,9 @@ public class QuickSearchPoiFilterFragment extends DialogFragment { ll.addView(editText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); textView.setPadding(AndroidUtils.dpToPx(getContext(), 4f), AndroidUtils.dpToPx(getContext(), 6f), AndroidUtils.dpToPx(getContext(), 4f), AndroidUtils.dpToPx(getContext(), 4f)); ll.addView(textView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + builder.setView(ll); + builder.setNegativeButton(R.string.shared_string_cancel, null); builder.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() { @Override