From a2cab336c453fed82cfc4cb0d5d780bf55609dd4 Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Wed, 28 Sep 2016 21:11:57 +0300 Subject: [PATCH] [Quick search] Custom filters in progress --- .../src/net/osmand/osm/AbstractPoiType.java | 43 +- .../src/net/osmand/osm/MapPoiTypes.java | 31 +- .../src/net/osmand/search/SearchUICore.java | 10 +- .../osmand/search/core/SearchCoreFactory.java | 7 +- OsmAnd/res/layout/list_item_button.xml | 27 + OsmAnd/res/layout/list_item_divider.xml | 15 + OsmAnd/res/layout/poi_filter_list_item.xml | 107 +++ OsmAnd/res/layout/search_dialog_fragment.xml | 9 + OsmAnd/res/layout/search_poi_filter.xml | 83 +++ OsmAnd/res/values/phrases.xml | 3 + OsmAnd/res/values/strings.xml | 6 + .../src/net/osmand/plus/AppInitializer.java | 9 +- .../src/net/osmand/plus/poi/PoiUIFilter.java | 7 +- .../search/QuickSearchDialogFragment.java | 385 +++++----- .../osmand/plus/search/QuickSearchHelper.java | 13 +- .../search/QuickSearchPoiFilterFragment.java | 680 ++++++++++++++++++ .../android/sample1/SampleApplication.java | 5 + 17 files changed, 1258 insertions(+), 182 deletions(-) create mode 100644 OsmAnd/res/layout/list_item_button.xml create mode 100644 OsmAnd/res/layout/list_item_divider.xml create mode 100644 OsmAnd/res/layout/poi_filter_list_item.xml create mode 100644 OsmAnd/res/layout/search_poi_filter.xml create mode 100644 OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java diff --git a/OsmAnd-java/src/net/osmand/osm/AbstractPoiType.java b/OsmAnd-java/src/net/osmand/osm/AbstractPoiType.java index d1db60842e..ff2a5ea202 100644 --- a/OsmAnd-java/src/net/osmand/osm/AbstractPoiType.java +++ b/OsmAnd-java/src/net/osmand/osm/AbstractPoiType.java @@ -11,11 +11,13 @@ public abstract class AbstractPoiType { protected final String keyName; protected final MapPoiTypes registry; private List poiAdditionals = null; + private List poiAdditionalsCategorized = null; private boolean topVisible; private String lang; private AbstractPoiType baseLangType; private boolean notEditableOsm; - + private String poiAdditionalCategory; + public AbstractPoiType(String keyName, MapPoiTypes registry) { this.keyName = keyName; this.registry = registry; @@ -58,28 +60,49 @@ public abstract class AbstractPoiType { } public boolean isAdditional() { - return this instanceof PoiType && ((PoiType) this).isAdditional(); + return this instanceof PoiType && this.isAdditional(); } public String getTranslation() { return registry.getTranslation(this); } - + + public String getPoiAdditionalCategoryTranslation() { + if (poiAdditionalCategory != null) { + return registry.getPoiTranslation(poiAdditionalCategory); + } else { + return null; + } + } + public void addPoiAdditional(PoiType tp) { - if(poiAdditionals == null) { - poiAdditionals = new ArrayList(); + if (poiAdditionals == null) { + poiAdditionals = new ArrayList<>(); } poiAdditionals.add(tp); + if (tp.getPoiAdditionalCategory() != null) { + if (poiAdditionalsCategorized == null) { + poiAdditionalsCategorized = new ArrayList<>(); + } + poiAdditionalsCategorized.add(tp); + } } public List getPoiAdditionals() { - if(poiAdditionals == null) { + if (poiAdditionals == null) { return Collections.emptyList(); } return poiAdditionals; } + public List getPoiAdditionalsCategorized() { + if (poiAdditionalsCategorized == null) { + return Collections.emptyList(); + } + return poiAdditionalsCategorized; + } + public boolean isNotEditableOsm() { return notEditableOsm; } @@ -88,6 +111,14 @@ public abstract class AbstractPoiType { this.notEditableOsm = notEditableOsm; } + public String getPoiAdditionalCategory() { + return poiAdditionalCategory; + } + + public void setPoiAdditionalCategory(String poiAdditionalCategory) { + this.poiAdditionalCategory = poiAdditionalCategory; + } + public abstract Map> putTypes(Map> acceptedTypes); @Override diff --git a/OsmAnd-java/src/net/osmand/osm/MapPoiTypes.java b/OsmAnd-java/src/net/osmand/osm/MapPoiTypes.java index 328d20d842..ec7837a6a7 100644 --- a/OsmAnd-java/src/net/osmand/osm/MapPoiTypes.java +++ b/OsmAnd-java/src/net/osmand/osm/MapPoiTypes.java @@ -47,7 +47,8 @@ public class MapPoiTypes { public interface PoiTranslator { - public String getTranslation(AbstractPoiType type); + String getTranslation(AbstractPoiType type); + String getTranslation(String keyName); } @@ -276,6 +277,7 @@ public class MapPoiTypes { PoiCategory lastCategory = null; PoiFilter lastFilter = null; PoiType lastType = null; + String lastPoiAdditionalCategory = null; while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { if (tok == XmlPullParser.START_TAG) { String name = parser.getName(); @@ -302,12 +304,17 @@ public class MapPoiTypes { if (lastCategory == null) { lastCategory = getOtherMapCategory(); } - PoiType baseType = parsePoiAdditional(parser, lastCategory, lastFilter, lastType, null, null); + PoiType baseType = parsePoiAdditional(parser, lastCategory, lastFilter, lastType, null, null, lastPoiAdditionalCategory); if ("true".equals(parser.getAttributeValue("", "lang"))) { for (String lng : MapRenderingTypes.langs) { - parsePoiAdditional(parser, lastCategory, lastFilter, lastType, lng, baseType); + parsePoiAdditional(parser, lastCategory, lastFilter, lastType, lng, baseType, lastPoiAdditionalCategory); } - parsePoiAdditional(parser, lastCategory, lastFilter, lastType, "en", baseType); + parsePoiAdditional(parser, lastCategory, lastFilter, lastType, "en", baseType, lastPoiAdditionalCategory); + } + + } else if (name.equals("poi_additional_category")) { + if (lastPoiAdditionalCategory == null) { + lastPoiAdditionalCategory = parser.getAttributeValue("", "name"); } } else if (name.equals("poi_type")) { @@ -336,6 +343,8 @@ public class MapPoiTypes { lastType = null; } else if (name.equals("poi_category")) { lastCategory = null; + } else if (name.equals("poi_additional_category")) { + lastPoiAdditionalCategory = null; } } } @@ -368,7 +377,7 @@ public class MapPoiTypes { private PoiType parsePoiAdditional(XmlPullParser parser, PoiCategory lastCategory, PoiFilter lastFilter, - PoiType lastType, String lang, PoiType langBaseType) { + PoiType lastType, String lang, PoiType langBaseType, String poiAdditionalCategory) { String oname = parser.getAttributeValue("", "name"); if (lang != null) { oname += ":" + lang; @@ -393,6 +402,7 @@ public class MapPoiTypes { tp.setOsmValue(parser.getAttributeValue("", "value")); tp.setOsmTag2(parser.getAttributeValue("", "tag2")); tp.setOsmValue2(parser.getAttributeValue("", "value2")); + tp.setPoiAdditionalCategory(poiAdditionalCategory); if (lastType != null) { lastType.addPoiAdditional(tp); } else if (lastFilter != null) { @@ -548,6 +558,17 @@ public class MapPoiTypes { return Algorithms.capitalizeFirstLetterAndLowercase(name); } + public String getPoiTranslation(String keyName) { + if (poiTranslator != null) { + String translation = poiTranslator.getTranslation(keyName); + if (!Algorithms.isEmpty(translation)) { + return translation; + } + } + String name = keyName; + name = name.replace('_', ' '); + return Algorithms.capitalizeFirstLetterAndLowercase(name); + } public boolean isRegisteredType(PoiCategory t) { return getPoiCategoryByName(t.getKeyName()) != otherCategory; diff --git a/OsmAnd-java/src/net/osmand/search/SearchUICore.java b/OsmAnd-java/src/net/osmand/search/SearchUICore.java index aacdb51bcb..33469fc111 100644 --- a/OsmAnd-java/src/net/osmand/search/SearchUICore.java +++ b/OsmAnd-java/src/net/osmand/search/SearchUICore.java @@ -257,7 +257,15 @@ public class SearchUICore { apis.add(cityApi); apis.add(new SearchCoreFactory.SearchAddressByNameAPI(streetsApi, cityApi)); } - + + public void clearCustomSearchPoiFilters() { + for(SearchCoreAPI capi : apis) { + if(capi instanceof SearchAmenityTypesAPI) { + ((SearchAmenityTypesAPI) capi).clearCustomFilters(); + } + } + } + public void addCustomSearchPoiFilter(CustomSearchPoiFilter poiFilter, int priority) { for(SearchCoreAPI capi : apis) { if(capi instanceof SearchAmenityTypesAPI) { diff --git a/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java index e862ffda68..fe82c4a22d 100644 --- a/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java +++ b/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java @@ -495,7 +495,12 @@ public class SearchCoreFactory { public SearchAmenityTypesAPI(MapPoiTypes types) { this.types = types; } - + + public void clearCustomFilters() { + this.customPoiFilters.clear(); + this.customPoiFiltersPriorites.clear(); + } + public void addCustomFilter(CustomSearchPoiFilter poiFilter, int priority) { this.customPoiFilters.add(poiFilter); this.customPoiFiltersPriorites.add(priority); diff --git a/OsmAnd/res/layout/list_item_button.xml b/OsmAnd/res/layout/list_item_button.xml new file mode 100644 index 0000000000..33ba7cb0b0 --- /dev/null +++ b/OsmAnd/res/layout/list_item_button.xml @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/list_item_divider.xml b/OsmAnd/res/layout/list_item_divider.xml new file mode 100644 index 0000000000..099bb810b3 --- /dev/null +++ b/OsmAnd/res/layout/list_item_divider.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/poi_filter_list_item.xml b/OsmAnd/res/layout/poi_filter_list_item.xml new file mode 100644 index 0000000000..42fe1a5744 --- /dev/null +++ b/OsmAnd/res/layout/poi_filter_list_item.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/search_dialog_fragment.xml b/OsmAnd/res/layout/search_dialog_fragment.xml index b6da665922..b3d5393f49 100644 --- a/OsmAnd/res/layout/search_dialog_fragment.xml +++ b/OsmAnd/res/layout/search_dialog_fragment.xml @@ -179,6 +179,15 @@ android:textColor="?attr/color_dialog_buttons" android:textSize="@dimen/default_desc_text_size"/> + + diff --git a/OsmAnd/res/layout/search_poi_filter.xml b/OsmAnd/res/layout/search_poi_filter.xml new file mode 100644 index 0000000000..b89230be49 --- /dev/null +++ b/OsmAnd/res/layout/search_poi_filter.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 4461dec3e9..c32f5d8747 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -1,5 +1,8 @@  + Fuel type + Payment type + Additional Store Food store diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index eff837a0eb..99253840ba 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,12 @@ 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 --> + Filters + Apply filters + Save filter + Delete filter + New filter + Please enter name for the new filter. You will find it in the list of Categories. Subscription fee will be charged each month. You can cancel your subscription on Google Play at any time. Donation to OpenStreetMap community Part of your donation will be sent to OSM users who submit changes to OpenStreetMap. The cost of the subscription remains the same. diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index c7d4a87f0b..c5ab0979ff 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -317,14 +317,19 @@ public class AppInitializer implements IProgress { if(type.getBaseLangType() != null) { return getTranslation(type.getBaseLangType()) + " (" + app.getLangTranslation(type.getLang()).toLowerCase() +")"; } + return getTranslation(type.getIconKeyName()); + } + + @Override + public String getTranslation(String keyName) { try { - Field f = R.string.class.getField("poi_" + type.getIconKeyName()); + Field f = R.string.class.getField("poi_" + keyName); if (f != null) { Integer in = (Integer) f.get(null); return app.getString(in); } } catch (Exception e) { - System.err.println("No translation for "+ type.getIconKeyName() + " " + e.getMessage()); + System.err.println("No translation for "+ keyName + " " + e.getMessage()); } return null; } diff --git a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java index 90f462ab16..d4d9713069 100644 --- a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java @@ -44,9 +44,8 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable public final static String CUSTOM_FILTER_ID = USER_PREFIX + "custom_id"; //$NON-NLS-1$ public final static String BY_NAME_FILTER_ID = USER_PREFIX + "by_name"; //$NON-NLS-1$ - private Map> acceptedTypes = new LinkedHashMap>(); - private Map poiAdditionals = new HashMap(); + private Map> acceptedTypes = new LinkedHashMap<>(); + private Map poiAdditionals = new HashMap<>(); protected String filterId; protected String standardIconId = ""; @@ -455,7 +454,7 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable } public void clearFilter() { - acceptedTypes = new LinkedHashMap>(); + acceptedTypes = new LinkedHashMap<>(); poiAdditionals.clear(); } diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java index 210b4b0435..19f9a760c0 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java @@ -62,7 +62,6 @@ import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControll import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType; import net.osmand.search.SearchUICore; import net.osmand.search.SearchUICore.SearchResultCollection; -import net.osmand.search.core.ObjectType; import net.osmand.search.core.SearchCoreAPI; import net.osmand.search.core.SearchCoreFactory.SearchAmenityTypesAPI; import net.osmand.search.core.SearchPhrase; @@ -77,6 +76,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static net.osmand.search.core.ObjectType.POI_TYPE; + public class QuickSearchDialogFragment extends DialogFragment implements OsmAndCompassListener, OsmAndLocationListener { public static final String TAG = "QuickSearchDialogFragment"; @@ -98,6 +99,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC private View searchView; private View buttonToolbarView; private ImageView buttonToolbarImage; + private ImageButton buttonToolbarFilter; private TextView buttonToolbarText; private QuickSearchMainListFragment mainSearchFragment; private QuickSearchHistoryListFragment historySearchFragment; @@ -146,7 +148,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } @Override - @SuppressLint("PrivateResource") + @SuppressLint("PrivateResource, ValidFragment") public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final MapActivity mapActivity = getMapActivity(); @@ -209,127 +211,172 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC buttonToolbarView = view.findViewById(R.id.button_toolbar_layout); buttonToolbarImage = (ImageView) view.findViewById(R.id.buttonToolbarImage); buttonToolbarImage.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_marker_dark)); - buttonToolbarText = (TextView) view.findViewById(R.id.buttonToolbarTitle); - view.findViewById(R.id.buttonToolbar).setOnClickListener(new OnClickListener() { + buttonToolbarFilter = (ImageButton) view.findViewById(R.id.filterButton); + buttonToolbarFilter.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_filter_dark)); + buttonToolbarFilter.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { SearchPhrase searchPhrase = searchUICore.getPhrase(); - if (foundPartialLocation) { - QuickSearchCoordinatesFragment.showDialog(QuickSearchDialogFragment.this, searchPhrase.getUnknownSearchWord()); - } else if (searchPhrase.isNoSelectedType() || searchPhrase.isLastWord(ObjectType.POI_TYPE)) { - PoiUIFilter filter; - if (searchPhrase.isNoSelectedType()) { - filter = app.getPoiFilters().getSearchByNamePOIFilter(); - if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) { - filter.setFilterByName(searchPhrase.getUnknownSearchWord()); - filter.clearCurrentResults(); + if (searchPhrase.isLastWord(POI_TYPE)) { + String filterId = null; + String filterByName = searchPhrase.getUnknownSearchPhrase(); + Object object = searchPhrase.getLastSelectedWord().getResult().object; + if (object instanceof PoiUIFilter) { + PoiUIFilter model = (PoiUIFilter) object; + if (!Algorithms.isEmpty(model.getSavedFilterByName())) { + model.setFilterByName(model.getSavedFilterByName()); } - } else if (searchPhrase.getLastSelectedWord().getResult().object instanceof AbstractPoiType) { - if (searchPhrase.isNoSelectedType()) { - filter = new PoiUIFilter(null, app, ""); - } else { - AbstractPoiType abstractPoiType = (AbstractPoiType) searchPhrase.getLastSelectedWord() - .getResult().object; - filter = new PoiUIFilter(abstractPoiType, app, ""); + filterId = model.getFilterId(); + } else if (object instanceof AbstractPoiType) { + AbstractPoiType abstractPoiType = (AbstractPoiType) object; + PoiUIFilter custom = app.getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + abstractPoiType.getKeyName()); + if (custom != null) { + custom.setFilterByName(null); + custom.clearFilter(); + custom.updateTypesToAccept(abstractPoiType); + filterId = custom.getFilterId(); } - if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) { - filter.setFilterByName(searchPhrase.getUnknownSearchWord()); - } - } else { - filter = (PoiUIFilter) searchPhrase.getLastSelectedWord().getResult().object; } - app.getPoiFilters().clearSelectedPoiFilters(); - app.getPoiFilters().addSelectedPoiFilter(filter); - - mapActivity.getContextMenu().closeActiveToolbar(); - showToolbar(); - getMapActivity().refreshMap(); - hide(); - } else { - SearchWord word = searchPhrase.getLastSelectedWord(); - if (word != null && word.getLocation() != null) { - SearchResult searchResult = word.getResult(); - String name = QuickSearchListItem.getName(app, searchResult); - String typeName = QuickSearchListItem.getTypeName(app, searchResult); - PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_ADDRESS, typeName, name); - app.getSettings().setMapLocationToShow( - searchResult.location.getLatitude(), searchResult.location.getLongitude(), - searchResult.preferredZoom, pointDescription, true, searchResult.object); - - hideToolbar(); - MapActivity.launchMapActivityMoveToTop(getActivity()); - reloadHistory(); - hide(); + if (filterId != null) { + QuickSearchPoiFilterFragment.showDialog( + QuickSearchDialogFragment.this, filterByName, filterId); } } } }); + buttonToolbarText = (TextView) view.findViewById(R.id.buttonToolbarTitle); + view.findViewById(R.id.buttonToolbar).setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + SearchPhrase searchPhrase = searchUICore.getPhrase(); + if (foundPartialLocation) { + QuickSearchCoordinatesFragment.showDialog(QuickSearchDialogFragment.this, searchPhrase.getUnknownSearchWord()); + } else if (searchPhrase.isNoSelectedType() || searchPhrase.isLastWord(POI_TYPE)) { + PoiUIFilter filter; + if (searchPhrase.isNoSelectedType()) { + filter = app.getPoiFilters().getSearchByNamePOIFilter(); + if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) { + filter.setFilterByName(searchPhrase.getUnknownSearchWord()); + filter.clearCurrentResults(); + } + } else if (searchPhrase.getLastSelectedWord().getResult().object instanceof AbstractPoiType) { + if (searchPhrase.isNoSelectedType()) { + filter = new PoiUIFilter(null, app, ""); + } else { + AbstractPoiType abstractPoiType = (AbstractPoiType) searchPhrase.getLastSelectedWord() + .getResult().object; + filter = new PoiUIFilter(abstractPoiType, app, ""); + } + if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) { + filter.setFilterByName(searchPhrase.getUnknownSearchWord()); + } + } else { + filter = (PoiUIFilter) searchPhrase.getLastSelectedWord().getResult().object; + } + app.getPoiFilters().clearSelectedPoiFilters(); + app.getPoiFilters().addSelectedPoiFilter(filter); + + mapActivity.getContextMenu().closeActiveToolbar(); + showToolbar(); + getMapActivity().refreshMap(); + hide(); + } else { + SearchWord word = searchPhrase.getLastSelectedWord(); + if (word != null && word.getLocation() != null) { + SearchResult searchResult = word.getResult(); + String name = QuickSearchListItem.getName(app, searchResult); + String typeName = QuickSearchListItem.getTypeName(app, searchResult); + PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_ADDRESS, typeName, name); + app.getSettings().setMapLocationToShow( + searchResult.location.getLatitude(), searchResult.location.getLongitude(), + searchResult.preferredZoom, pointDescription, true, searchResult.object); + + hideToolbar(); + MapActivity.launchMapActivityMoveToTop(getActivity()); + reloadHistory(); + hide(); + } + } + } + } + + ); + toolbar = (Toolbar) view.findViewById(R.id.toolbar); toolbar.setNavigationIcon(app.getIconsCache().getThemedIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha)); toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); - toolbar.setNavigationOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); + toolbar.setNavigationOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + } + ); toolbarEdit = (Toolbar) view.findViewById(R.id.toolbar_edit); toolbarEdit.setNavigationIcon(app.getIconsCache().getIcon(R.drawable.ic_action_remove_dark)); toolbarEdit.setNavigationContentDescription(R.string.shared_string_cancel); - toolbarEdit.setNavigationOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - enableSelectionMode(false, -1); - } - }); + toolbarEdit.setNavigationOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + enableSelectionMode(false, -1); + } + } + ); titleEdit = (TextView) view.findViewById(R.id.titleEdit); - view.findViewById(R.id.shareButton).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - List historyEntries = new ArrayList(); - List selectedItems = historySearchFragment.getListAdapter().getSelectedItems(); - for (QuickSearchListItem searchListItem : selectedItems) { - HistoryEntry historyEntry = (HistoryEntry) searchListItem.getSearchResult().object; - historyEntries.add(historyEntry); - } - if (historyEntries.size() > 0) { - shareHistory(historyEntries); - enableSelectionMode(false, -1); - } - } - }); - view.findViewById(R.id.deleteButton).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - - new DialogFragment() { - @NonNull + view.findViewById(R.id.shareButton).setOnClickListener( + new OnClickListener() { @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.confirmation_to_delete_history_items) - .setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SearchHistoryHelper helper = SearchHistoryHelper.getInstance(app); - List selectedItems = historySearchFragment.getListAdapter().getSelectedItems(); - for (QuickSearchListItem searchListItem : selectedItems) { - HistoryEntry historyEntry = (HistoryEntry) searchListItem.getSearchResult().object; - helper.remove(historyEntry); - } - reloadHistory(); - enableSelectionMode(false, -1); - } - }) - .setNegativeButton(R.string.shared_string_no, null); - return builder.create(); + public void onClick(View v) { + List historyEntries = new ArrayList(); + List selectedItems = historySearchFragment.getListAdapter().getSelectedItems(); + for (QuickSearchListItem searchListItem : selectedItems) { + HistoryEntry historyEntry = (HistoryEntry) searchListItem.getSearchResult().object; + historyEntries.add(historyEntry); + } + if (historyEntries.size() > 0) { + shareHistory(historyEntries); + enableSelectionMode(false, -1); + } } - }.show(getChildFragmentManager(), "DeleteHistoryConfirmationFragment"); - } - }); + } + ); + view.findViewById(R.id.deleteButton).setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + + new DialogFragment() { + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.confirmation_to_delete_history_items) + .setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SearchHistoryHelper helper = SearchHistoryHelper.getInstance(app); + List selectedItems = historySearchFragment.getListAdapter().getSelectedItems(); + for (QuickSearchListItem searchListItem : selectedItems) { + HistoryEntry historyEntry = (HistoryEntry) searchListItem.getSearchResult().object; + helper.remove(historyEntry); + } + reloadHistory(); + enableSelectionMode(false, -1); + } + }) + .setNegativeButton(R.string.shared_string_no, null); + return builder.create(); + } + }.show(getChildFragmentManager(), "DeleteHistoryConfirmationFragment"); + } + } + ); viewPager = (LockableViewPager) view.findViewById(R.id.pager); pagerAdapter = new SearchFragmentPagerAdapter(getChildFragmentManager(), getResources()); @@ -340,73 +387,80 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC tabLayout = (TabLayout) view.findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); - viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - } + viewPager.addOnPageChangeListener( + new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, + int positionOffsetPixels) { + } - @Override - public void onPageSelected(int position) { - hideKeyboard(); - } + @Override + public void onPageSelected(int position) { + hideKeyboard(); + } - @Override - public void onPageScrollStateChanged(int state) { - } - }); - - searchEditText = (EditText) view.findViewById(R.id.searchEditText); - searchEditText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - String newQueryText = s.toString(); - updateClearButtonAndHint(); - updateClearButtonVisibility(true); - updateTabbarVisibility(newQueryText.length() == 0); - if (!searchQuery.equalsIgnoreCase(newQueryText)) { - searchQuery = newQueryText; - if (Algorithms.isEmpty(searchQuery)) { - searchUICore.resetPhrase(); - } else { - runSearch(); + @Override + public void onPageScrollStateChanged(int state) { } } - } - }); + ); + + searchEditText = (EditText) view.findViewById(R.id.searchEditText); + searchEditText.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + String newQueryText = s.toString(); + updateClearButtonAndHint(); + updateClearButtonVisibility(true); + updateTabbarVisibility(newQueryText.length() == 0); + if (!searchQuery.equalsIgnoreCase(newQueryText)) { + searchQuery = newQueryText; + if (Algorithms.isEmpty(searchQuery)) { + searchUICore.resetPhrase(); + } else { + runSearch(); + } + } + } + } + ); progressBar = (ProgressBar) view.findViewById(R.id.searchProgressBar); clearButton = (ImageButton) view.findViewById(R.id.clearButton); clearButton.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_remove_dark)); - clearButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (searchEditText.getText().length() > 0) { - String newText = searchUICore.getPhrase().getTextWithoutLastWord(); - searchEditText.setText(newText); - searchEditText.setSelection(newText.length()); - } else if (useMapCenter && location != null) { - useMapCenter = false; - centerLatLon = null; - updateUseMapCenterUI(); - startLocationUpdate(); - LatLon centerLatLon = new LatLon(location.getLatitude(), location.getLongitude()); - SearchSettings ss = searchUICore.getSearchSettings().setOriginalLocation( - new LatLon(centerLatLon.getLatitude(), centerLatLon.getLongitude())); - searchUICore.updateSettings(ss); - updateClearButtonAndHint(); - updateClearButtonVisibility(true); + clearButton.setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + if (searchEditText.getText().length() > 0) { + String newText = searchUICore.getPhrase().getTextWithoutLastWord(); + searchEditText.setText(newText); + searchEditText.setSelection(newText.length()); + } else if (useMapCenter && location != null) { + useMapCenter = false; + centerLatLon = null; + updateUseMapCenterUI(); + startLocationUpdate(); + LatLon centerLatLon = new LatLon(location.getLatitude(), location.getLongitude()); + SearchSettings ss = searchUICore.getSearchSettings().setOriginalLocation( + new LatLon(centerLatLon.getLatitude(), centerLatLon.getLongitude())); + searchUICore.updateSettings(ss); + updateClearButtonAndHint(); + updateClearButtonVisibility(true); + } + updateToolbarButton(); + } } - updateToolbarButton(); - } - }); + ); setupSearch(mapActivity); @@ -515,10 +569,10 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } private void updateToolbarButton() { + SearchWord word = searchUICore.getPhrase().getLastSelectedWord(); if (foundPartialLocation) { buttonToolbarText.setText(app.getString(R.string.advanced_coords_search).toUpperCase()); } else if (searchEditText.getText().length() > 0) { - SearchWord word = searchUICore.getPhrase().getLastSelectedWord(); if (word != null && word.getResult() != null) { buttonToolbarText.setText(app.getString(R.string.show_something_on_map, word.getResult().localeName).toUpperCase()); } else { @@ -527,6 +581,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } else { buttonToolbarText.setText(app.getString(R.string.shared_string_show_on_map).toUpperCase()); } + buttonToolbarFilter.setVisibility(word != null && word.getType() != null && word.getType().equals(POI_TYPE) ? View.VISIBLE : View.GONE); } private void setupSearch(final MapActivity mapActivity) { @@ -993,6 +1048,16 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC runCoreSearch(txt, false, false); } + public void replaceQueryWithUiFilter(PoiUIFilter filter) { + SearchPhrase searchPhrase = searchUICore.getPhrase(); + if (searchPhrase.isLastWord(POI_TYPE)) { + SearchResult sr = searchPhrase.getLastSelectedWord().getResult(); + sr.object = filter; + String txt = searchUICore.getPhrase().getText(true); + runCoreSearch(txt, false, false); + } + } + private void addMoreButton() { QuickSearchMoreListItem moreListItem = new QuickSearchMoreListItem(app, app.getString(R.string.search_POI_level_btn).toUpperCase(), new OnClickListener() { diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchHelper.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchHelper.java index 31974a00e6..3eb00ba0cb 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchHelper.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchHelper.java @@ -135,13 +135,20 @@ public class QuickSearchHelper implements ResourceListener { // Register WptPt search api core.registerAPI(new SearchWptAPI(app)); core.registerAPI(new SearchHistoryAPI(app)); - + + refreshCustomPoiFilters(); + + PoiFiltersHelper poiFilters = app.getPoiFilters(); + core.addCustomSearchPoiFilter(poiFilters.getLocalWikiPOIFilter(), 1); + core.addCustomSearchPoiFilter(poiFilters.getShowAllPOIFilter(), 1); + } + + public void refreshCustomPoiFilters() { + core.clearCustomSearchPoiFilters(); PoiFiltersHelper poiFilters = app.getPoiFilters(); for(CustomSearchPoiFilter udf : poiFilters.getUserDefinedPoiFilters()) { core.addCustomSearchPoiFilter(udf, 0); } - core.addCustomSearchPoiFilter(poiFilters.getLocalWikiPOIFilter(), 1); - core.addCustomSearchPoiFilter(poiFilters.getShowAllPOIFilter(), 1); } public void setRepositoriesForSearchUICore(final OsmandApplication app) { diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java new file mode 100644 index 0000000000..b034946561 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchPoiFilterFragment.java @@ -0,0 +1,680 @@ +package net.osmand.plus.search; + +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.AppCompatButton; +import android.support.v7.widget.PopupMenu; +import android.support.v7.widget.SwitchCompat; +import android.support.v7.widget.Toolbar; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import net.osmand.AndroidUtils; +import net.osmand.osm.PoiType; +import net.osmand.plus.IconsCache; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.dialogs.DirectionsDialogs; +import net.osmand.plus.poi.PoiUIFilter; +import net.osmand.plus.widgets.TextViewEx; +import net.osmand.util.Algorithms; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +public class QuickSearchPoiFilterFragment extends DialogFragment { + public static final String TAG = "QuickSearchPoiFilterFragment"; + + private static final String QUICK_SEARCH_POI_FILTER_ID_KEY = "quick_search_poi_filter_id_key"; + private static final String QUICK_SEARCH_POI_FILTER_BY_NAME_KEY = "quick_search_poi_filter_by_name_key"; + private static final String QUICK_SEARCH_POI_FILTER_SELECTED_ADDITIONALS = "quick_search_poi_filter_selected_additionals"; + private static final String QUICK_SEARCH_POI_FILTER_COLLAPSED_CATEGORIES = "quick_search_poi_filter_collapsed_categories"; + private static final String QUICK_SEARCH_POI_FILTER_SHOW_ALL_CATEGORIES = "quick_search_poi_filter_show_all_categories"; + + private View view; + private ListView listView; + private PoiFilterListAdapter adapter; + private PoiUIFilter filter; + private String filterId; + private String nameFilterText = ""; + private EditText editText; + private Set selectedPoiAdditionals = new TreeSet<>(); + private ArrayList collapsedCategories = new ArrayList<>(); + private ArrayList showAllCategories = new ArrayList<>(); + + public QuickSearchPoiFilterFragment() { + } + + private OsmandApplication getMyApplication() { + return (OsmandApplication) getActivity().getApplication(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME; + int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme; + setStyle(STYLE_NO_FRAME, themeId); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + final OsmandApplication app = getMyApplication(); + + if (getArguments() != null) { + filterId = getArguments().getString(QUICK_SEARCH_POI_FILTER_ID_KEY); + nameFilterText = getArguments().getString(QUICK_SEARCH_POI_FILTER_BY_NAME_KEY); + } else if (savedInstanceState != null) { + filterId = savedInstanceState.getString(QUICK_SEARCH_POI_FILTER_ID_KEY); + nameFilterText = savedInstanceState.getString(QUICK_SEARCH_POI_FILTER_BY_NAME_KEY); + ArrayList selectedList = savedInstanceState.getStringArrayList(QUICK_SEARCH_POI_FILTER_SELECTED_ADDITIONALS); + if (selectedList != null) { + selectedPoiAdditionals.addAll(selectedList); + } + ArrayList collapsedList = savedInstanceState.getStringArrayList(QUICK_SEARCH_POI_FILTER_COLLAPSED_CATEGORIES); + if (collapsedList != null) { + collapsedCategories.addAll(collapsedList); + } + ArrayList showAllList = savedInstanceState.getStringArrayList(QUICK_SEARCH_POI_FILTER_SHOW_ALL_CATEGORIES); + if (showAllList != null) { + showAllCategories.addAll(showAllList); + } + } + + if (filterId != null) { + filter = app.getPoiFilters().getFilterById(filterId); + } + if (filter == null) { + filter = app.getPoiFilters().getCustomPOIFilter(); + filter.clearFilter(); + } + if (selectedPoiAdditionals.size() == 0) { + processFilterFields(); + } + + view = inflater.inflate(R.layout.search_poi_filter, container, false); + + Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); + toolbar.setNavigationIcon(app.getIconsCache().getIcon(R.drawable.ic_action_remove_dark)); + toolbar.setNavigationContentDescription(R.string.shared_string_close); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + ImageButton moreButton = (ImageButton) view.findViewById(R.id.moreButton); + moreButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + IconsCache iconsCache = app.getIconsCache(); + final PopupMenu optionsMenu = new PopupMenu(getContext(), v); + DirectionsDialogs.setupPopUpMenuIcon(optionsMenu); + MenuItem item; + + 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) { + saveFilter(); + return true; + } + }); + + if (!filter.isStandardFilter()) { + item = optionsMenu.getMenu().add(R.string.delete_filter) + .setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_delete_dark)); + item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + deleteFilter(); + return true; + } + }); + } + + optionsMenu.show(); + } + }); + + listView = (ListView) view.findViewById(android.R.id.list); + listView.setBackgroundColor(getResources().getColor( + app.getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light + : R.color.ctx_menu_info_view_bg_dark)); + + View editTextView = inflater.inflate(R.layout.poi_filter_list_item, listView, false); + editText = (EditText) editTextView.findViewById(R.id.editText); + editText.setText(nameFilterText); + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + nameFilterText = s.toString(); + } + }); + + editText.setVisibility(View.VISIBLE); + final ImageView textEditIcon = (ImageView) editTextView.findViewById(R.id.icon); + textEditIcon.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_search_dark)); + textEditIcon.setVisibility(View.VISIBLE); + editTextView.findViewById(R.id.titleBold).setVisibility(View.GONE); + editTextView.findViewById(R.id.titleButton).setVisibility(View.GONE); + editTextView.findViewById(R.id.expandItem).setVisibility(View.GONE); + editTextView.findViewById(R.id.titleRegular).setVisibility(View.GONE); + editTextView.findViewById(R.id.switchItem).setVisibility(View.GONE); + editTextView.findViewById(R.id.checkboxItem).setVisibility(View.GONE); + listView.addHeaderView(editTextView); + + View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false); + listView.addFooterView(bottomShadowView); + View applyFilterButtonView = inflater.inflate(R.layout.list_item_button, listView, false); + AppCompatButton applyFilterButton = (AppCompatButton) applyFilterButtonView.findViewById(R.id.button); + applyFilterButton.setText(app.getString(R.string.apply_filters)); + applyFilterButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + applyFilterFields(); + ((QuickSearchDialogFragment) getParentFragment()).replaceQueryWithUiFilter(filter); + dismiss(); + } + }); + listView.addFooterView(applyFilterButtonView); + + adapter = new PoiFilterListAdapter(getMyApplication(), getListItems()); + listView.setAdapter(adapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + PoiFilterListItem item = adapter.getItem(position - listView.getHeaderViewsCount()); + if (item != null) { + switch (item.type) { + case GROUP_HEADER: + if (item.category != null) { + if (collapsedCategories.contains(item.category)) { + collapsedCategories.remove(item.category); + } else { + collapsedCategories.add(item.category); + } + updateListView(); + } + break; + case CHECKBOX_ITEM: + CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkboxItem); + adapter.toggleCheckbox(item, checkBox, !checkBox.isChecked()); + break; + case BUTTON_ITEM: + if (item.category != null) { + showAllCategories.add(item.category); + updateListView(); + } + break; + } + } + } + }); + + return view; + } + + private void deleteFilter() { + final OsmandApplication app = getMyApplication(); + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setMessage(R.string.edit_filter_delete_dialog_title); + builder.setNegativeButton(R.string.shared_string_no, null); + builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + if (app.getPoiFilters().removePoiFilter(filter)) { + Toast.makeText(getContext(), MessageFormat.format(getContext().getText(R.string.edit_filter_delete_message).toString(), + filter.getName()), Toast.LENGTH_SHORT).show(); + app.getSearchUICore().refreshCustomPoiFilters(); + QuickSearchPoiFilterFragment.this.dismiss(); + } + } + }); + builder.create().show(); + } + + 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); + 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); + applyFilterFields(); + 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(); + ((QuickSearchDialogFragment) getParentFragment()).replaceQueryWithUiFilter(filter); + app.getSearchUICore().refreshCustomPoiFilters(); + QuickSearchPoiFilterFragment.this.dismiss(); + } + } + }); + builder.create().show(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(QUICK_SEARCH_POI_FILTER_ID_KEY, filterId); + outState.putString(QUICK_SEARCH_POI_FILTER_BY_NAME_KEY, nameFilterText); + outState.putStringArrayList(QUICK_SEARCH_POI_FILTER_SELECTED_ADDITIONALS, new ArrayList<>(selectedPoiAdditionals)); + outState.putStringArrayList(QUICK_SEARCH_POI_FILTER_COLLAPSED_CATEGORIES, collapsedCategories); + outState.putStringArrayList(QUICK_SEARCH_POI_FILTER_SHOW_ALL_CATEGORIES, showAllCategories); + } + + @Override + public void onPause() { + super.onPause(); + hideKeyboard(); + } + + private void hideKeyboard() { + if (editText.hasFocus()) { + AndroidUtils.hideSoftKeyboard(getActivity(), editText); + } + } + + private void updateListView() { + adapter.setListItems(getListItems()); + } + + private void applyFilterFields() { + StringBuilder sb = new StringBuilder(); + if (!Algorithms.isEmpty(nameFilterText)) { + sb.append(nameFilterText); + } + for (String param : selectedPoiAdditionals) { + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(param); + } + filter.setFilterByName(sb.toString()); + } + + private void processFilterFields() { + OsmandApplication app = getMyApplication(); + String filterByName = filter.getFilterByName(); + if (!Algorithms.isEmpty(filterByName)) { + String keyNameOpen = app.getString(R.string.shared_string_is_open).replace(' ', '_').toLowerCase(); + String keyNameOpen24 = app.getString(R.string.shared_string_is_open_24_7).replace(' ', '_').toLowerCase(); + int index = filterByName.indexOf(keyNameOpen); + if (index != -1) { + selectedPoiAdditionals.add(keyNameOpen); + filterByName = filterByName.replaceAll(keyNameOpen, ""); + } + index = filterByName.indexOf(keyNameOpen24); + if (index != -1) { + selectedPoiAdditionals.add(keyNameOpen24); + filterByName = filterByName.replaceAll(keyNameOpen24, ""); + } + + Map poiAdditionals = filter.getPoiAdditionals(); + List otherAdditionalCategories = app.getPoiTypes().getOtherMapCategory().getPoiAdditionalsCategorized(); + if (poiAdditionals != null) { + Map> additionalsMap = new TreeMap<>(); + extractPoiAdditionals(poiAdditionals.values(), additionalsMap, true); + extractPoiAdditionals(otherAdditionalCategories, additionalsMap, true); + + if (additionalsMap.size() > 0) { + for (Entry> entry : additionalsMap.entrySet()) { + for (String poiTypeName : entry.getValue()) { + String keyName = poiTypeName.replace(' ', ':').toLowerCase(); + index = filterByName.indexOf(keyName); + if (index != -1) { + selectedPoiAdditionals.add(keyName); + filterByName = filterByName.replaceAll(keyName, ""); + } + } + } + } + } + if (filterByName.trim().length() > 0 && Algorithms.isEmpty(nameFilterText)) { + nameFilterText = filterByName.trim(); + } + } + } + + private List getListItems() { + OsmandApplication app = getMyApplication(); + int groupId = 0; + List items = new ArrayList<>(); + items.add(new PoiFilterListItem(PoiFilterListItemType.DIVIDER, 0, null, -1, false, false, false, null, null)); + String keyNameOpen = app.getString(R.string.shared_string_is_open).replace(' ', '_').toLowerCase(); + items.add(new PoiFilterListItem(PoiFilterListItemType.SWITCH_ITEM, + R.drawable.ic_action_time, app.getString(R.string.shared_string_is_open), ++groupId, + false, false, selectedPoiAdditionals.contains(keyNameOpen), null, keyNameOpen)); + String keyNameOpen24 = app.getString(R.string.shared_string_is_open_24_7).replace(' ', '_').toLowerCase(); + items.add(new PoiFilterListItem(PoiFilterListItemType.SWITCH_ITEM, + 0, app.getString(R.string.shared_string_is_open_24_7), groupId, false, false, + selectedPoiAdditionals.contains(keyNameOpen24), null, keyNameOpen24)); + + Map poiAdditionals = filter.getPoiAdditionals(); + List otherAdditionalCategories = app.getPoiTypes().getOtherMapCategory().getPoiAdditionalsCategorized(); + if (poiAdditionals != null) { + Map> additionalsMap = new TreeMap<>(); + extractPoiAdditionals(poiAdditionals.values(), additionalsMap, false); + extractPoiAdditionals(otherAdditionalCategories, additionalsMap, false); + + if (additionalsMap.size() > 0) { + for (Entry> entry : additionalsMap.entrySet()) { + String category = entry.getKey(); + boolean expanded = !collapsedCategories.contains(category); + boolean showAll = showAllCategories.contains(category); + items.add(new PoiFilterListItem(PoiFilterListItemType.DIVIDER, 0, null, -1, false, false, false, null, null)); + items.add(new PoiFilterListItem(PoiFilterListItemType.GROUP_HEADER, + R.drawable.ic_action_folder_stroke, category, ++groupId, true, expanded, false, category, null)); + List poiTypeNames = new ArrayList<>(entry.getValue()); + Collections.sort(poiTypeNames); + for (String poiTypeName : poiTypeNames) { + String keyName = poiTypeName.replace(' ', ':').toLowerCase(); + items.add(new PoiFilterListItem(PoiFilterListItemType.CHECKBOX_ITEM, + 0, poiTypeName, groupId, false, false, selectedPoiAdditionals.contains(keyName), category, keyName)); + } + if (!showAll && poiTypeNames.size() > 0) { + items.add(new PoiFilterListItem(PoiFilterListItemType.BUTTON_ITEM, + 0, app.getString(R.string.shared_string_show_all).toUpperCase(), groupId, false, false, false, category, null)); + } + } + } + } + return items; + } + + private void extractPoiAdditionals(Collection poiAdditionals, Map> additionalsMap, boolean extractAll) { + for (PoiType poiType : poiAdditionals) { + String category = poiType.getPoiAdditionalCategoryTranslation(); + if (category == null) { + category = ""; + } + if (collapsedCategories.contains(category) && !extractAll) { + if (!additionalsMap.containsKey(category)) { + additionalsMap.put(category, new TreeSet()); + } + continue; + } + boolean showAll = showAllCategories.contains(category) || extractAll; + String name = poiType.getTranslation(); + String keyName = name.replace(' ', ':').toLowerCase(); + if (showAll || poiType.isTopVisible() || selectedPoiAdditionals.contains(keyName)) { + Set adds = additionalsMap.get(category); + if (adds == null) { + adds = new TreeSet<>(); + additionalsMap.put(category, adds); + } + adds.add(name); + } + } + } + + public static void showDialog(DialogFragment parentFragment, String filterByName, String filterId) { + Bundle bundle = new Bundle(); + if (filterByName != null) { + bundle.putString(QUICK_SEARCH_POI_FILTER_BY_NAME_KEY, filterByName); + } + if (filterId != null) { + bundle.putString(QUICK_SEARCH_POI_FILTER_ID_KEY, filterId); + } + QuickSearchPoiFilterFragment fragment = new QuickSearchPoiFilterFragment(); + fragment.setArguments(bundle); + fragment.show(parentFragment.getChildFragmentManager(), TAG); + } + + private class PoiFilterListAdapter extends ArrayAdapter { + private OsmandApplication app; + + PoiFilterListAdapter(OsmandApplication app, List items) { + super(app, R.layout.poi_filter_list_item, items); + this.app = app; + } + + public void setListItems(List items) { + setNotifyOnChange(false); + clear(); + for (PoiFilterListItem item : items) { + add(item); + } + setNotifyOnChange(true); + notifyDataSetChanged(); + } + + @Override + public int getItemViewType(int position) { + PoiFilterListItem item = getItem(position); + return item != null && item.type == PoiFilterListItemType.DIVIDER ? 1 : 0; + } + + @Override + public int getViewTypeCount() { + return 2; + } + + public void toggleSwitch(PoiFilterListItem item, boolean isChecked) { + item.checked = isChecked; + if (item.checked) { + selectedPoiAdditionals.add(item.keyName); + } else { + selectedPoiAdditionals.remove(item.keyName); + } + } + + public void toggleCheckbox(PoiFilterListItem item, CheckBox checkBox, boolean isChecked) { + if (checkBox != null) { + checkBox.setChecked(isChecked); + } + item.checked = isChecked; + if (item.checked) { + selectedPoiAdditionals.add(item.keyName); + } else { + selectedPoiAdditionals.remove(item.keyName); + } + } + + @NonNull + @Override + public View getView(final int position, View convertView, ViewGroup parent) { + final PoiFilterListItem item = getItem(position); + final PoiFilterListItem nextItem = position < getCount() - 1 ? getItem(position + 1) : null; + + int viewType = getItemViewType(position); + + View view; + if (convertView == null) { + LayoutInflater inflater = (LayoutInflater) app.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + if (viewType == 0) { + view = inflater.inflate(R.layout.poi_filter_list_item, null); + } else { + view = inflater.inflate(R.layout.list_item_divider, null); + view.setOnClickListener(null); + } + } else { + view = convertView; + } + + if (viewType == 1) { + return view; + } + + final ImageView icon = (ImageView) view.findViewById(R.id.icon); + final TextViewEx titleRegular = (TextViewEx) view.findViewById(R.id.titleRegular); + final TextViewEx titleBold = (TextViewEx) view.findViewById(R.id.titleBold); + final TextViewEx titleButton = (TextViewEx) view.findViewById(R.id.titleButton); + final SwitchCompat switchItem = (SwitchCompat) view.findViewById(R.id.switchItem); + final CheckBox checkBoxItem = (CheckBox) view.findViewById(R.id.checkboxItem); + final ImageView expandItem = (ImageView) view.findViewById(R.id.expandItem); + final View divider = view.findViewById(R.id.divider); + + if (item != null) { + if (nextItem != null && nextItem.groupIndex == item.groupIndex) { + divider.setVisibility(View.VISIBLE); + } else { + divider.setVisibility(View.GONE); + } + if (item.iconId != 0) { + icon.setImageDrawable(app.getIconsCache().getThemedIcon(item.iconId)); + icon.setVisibility(View.VISIBLE); + } else { + icon.setVisibility(View.GONE); + } + switchItem.setOnCheckedChangeListener(null); + checkBoxItem.setOnCheckedChangeListener(null); + switch (item.type) { + case GROUP_HEADER: + titleBold.setText(item.text); + if (item.expandable) { + expandItem.setImageDrawable(item.expanded ? + app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_up) : app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_down)); + expandItem.setVisibility(View.VISIBLE); + } else { + expandItem.setVisibility(View.GONE); + } + titleBold.setVisibility(View.VISIBLE); + titleButton.setVisibility(View.GONE); + titleRegular.setVisibility(View.GONE); + switchItem.setVisibility(View.GONE); + checkBoxItem.setVisibility(View.GONE); + break; + case SWITCH_ITEM: + titleRegular.setText(item.text); + titleRegular.setVisibility(View.VISIBLE); + switchItem.setVisibility(View.VISIBLE); + switchItem.setChecked(item.checked); + switchItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + toggleSwitch(item, isChecked); + } + }); + titleBold.setVisibility(View.GONE); + titleButton.setVisibility(View.GONE); + expandItem.setVisibility(View.GONE); + checkBoxItem.setVisibility(View.GONE); + break; + case CHECKBOX_ITEM: + titleRegular.setText(item.text); + titleRegular.setVisibility(View.VISIBLE); + checkBoxItem.setVisibility(View.VISIBLE); + checkBoxItem.setChecked(item.checked); + checkBoxItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + toggleCheckbox(item, checkBoxItem, isChecked); + } + }); + switchItem.setVisibility(View.GONE); + titleBold.setVisibility(View.GONE); + titleButton.setVisibility(View.GONE); + expandItem.setVisibility(View.GONE); + break; + case BUTTON_ITEM: + titleButton.setText(item.text); + titleButton.setVisibility(View.VISIBLE); + checkBoxItem.setVisibility(View.GONE); + switchItem.setVisibility(View.GONE); + titleBold.setVisibility(View.GONE); + titleRegular.setVisibility(View.GONE); + expandItem.setVisibility(View.GONE); + break; + } + } + return view; + } + } + + public enum PoiFilterListItemType { + DIVIDER, + GROUP_HEADER, + SWITCH_ITEM, + CHECKBOX_ITEM, + BUTTON_ITEM + } + + public static class PoiFilterListItem { + private PoiFilterListItemType type; + private int iconId; + private String text; + private int groupIndex; + private boolean expandable; + private boolean expanded; + private boolean checked; + private String category; + private String keyName; + + public PoiFilterListItem(PoiFilterListItemType type, int iconId, String text, int groupIndex, + boolean expandable, boolean expanded, boolean checked, String category, + String keyName) { + this.type = type; + this.iconId = iconId; + this.text = text; + this.groupIndex = groupIndex; + this.expandable = expandable; + this.expanded = expanded; + this.checked = checked; + this.category = category; + this.keyName = keyName; + } + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java index 5b5554ebc1..16597a8b39 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java @@ -78,6 +78,11 @@ public class SampleApplication extends Application { } return null; } + + @Override + public String getTranslation(String keyName) { + return null; + } }); }