From c814f6e81efe98d81d2bb36a7c2776f3ce4dbff3 Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Sun, 26 Mar 2017 14:31:19 +0300 Subject: [PATCH] Added search in city row to address search --- OsmAnd/res/layout/search_custom_list_item.xml | 1 - OsmAnd/res/values/strings.xml | 2 + .../search/QuickSearchDialogFragment.java | 103 ++++++++++++++++++ .../plus/search/QuickSearchListAdapter.java | 24 +++- .../listitems/QuickSearchButtonListItem.java | 33 +++++- .../search/listitems/QuickSearchListItem.java | 6 + 6 files changed, 162 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/layout/search_custom_list_item.xml b/OsmAnd/res/layout/search_custom_list_item.xml index 71424737c4..f66e73158e 100644 --- a/OsmAnd/res/layout/search_custom_list_item.xml +++ b/OsmAnd/res/layout/search_custom_list_item.xml @@ -31,7 +31,6 @@ android:gravity="center_vertical" android:textColor="?attr/color_dialog_buttons" android:textSize="@dimen/default_sub_text_size" - osmand:textAllCapsCompat="true" osmand:typeface="@string/font_roboto_medium"/> diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index b2a8522548..0b4555a4f5 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 --> + Select streets + in %1$s Type address Type city or town Type postcode diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java index 1fe5d1bf80..6eb1034b98 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java @@ -20,7 +20,10 @@ import android.support.v4.view.ViewPager; import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.text.Editable; +import android.text.Spannable; +import android.text.SpannableString; import android.text.TextWatcher; +import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -41,6 +44,8 @@ import net.osmand.Location; import net.osmand.ResultMatcher; import net.osmand.access.AccessibilityAssistant; import net.osmand.access.NavigationInfo; +import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.data.City; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.osm.AbstractPoiType; @@ -63,6 +68,7 @@ import net.osmand.plus.activities.MapActivity.ShowQuickSearchMode; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.poi.PoiUIFilter; +import net.osmand.plus.resources.RegionAddressRepository; import net.osmand.plus.search.QuickSearchHelper.SearchHistoryAPI; import net.osmand.plus.search.listitems.QuickSearchButtonListItem; import net.osmand.plus.search.listitems.QuickSearchHeaderListItem; @@ -1064,7 +1070,29 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC stopAddressSearch(); } + OsmandSettings settings = app.getSettings(); List rows = new ArrayList<>(); + + final SearchResult lastCityResult = getLastCityResult(); + if (lastCityResult != null) { + String selectStreets = app.getString(R.string.select_streets); + String inCityName = app.getString(R.string.shared_string_in_name, settings.getLastSearchedCityName()); + Spannable spannable = new SpannableString(selectStreets + " " + inCityName); + boolean light = settings.isLightContent(); + spannable.setSpan(new ForegroundColorSpan(getResources().getColor(light ? R.color.icon_color : R.color.color_white)), + selectStreets.length() + 1, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + rows.add(new QuickSearchButtonListItem(app, R.drawable.ic_action_street_name, + spannable, new OnClickListener() { + @Override + public void onClick(View v) { + completeQueryWithObject(lastCityResult); + + searchEditText.requestFocus(); + AndroidUtils.softKeyboardDelayed(searchEditText); + } + })); + } rows.add(new QuickSearchButtonListItem(app, R.drawable.ic_action_building_number, app.getString(R.string.select_city), new OnClickListener() { @Override @@ -1073,6 +1101,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC startCitySearch(); updateTabbarVisibility(false); runCoreSearch("", false, false); + searchEditText.requestFocus(); AndroidUtils.softKeyboardDelayed(searchEditText); } @@ -1114,6 +1143,53 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC } } + private SearchResult getLastCityResult() throws IOException { + OsmandSettings settings = app.getSettings(); + final long lastCityId = settings.getLastSearchedCity(); + final LatLon lastPoint = settings.getLastSearchedPoint(); + if (lastCityId != -1 && lastPoint != null) { + final String lastCityName = settings.getLastSearchedCityName(); + LatLon prevLatLon = startLastCitySearch(lastPoint); + SearchResultCollection lastCity = searchUICore.shallowSearch(SearchAddressByNameAPI.class, lastCityName, new ResultMatcher() { + + boolean cityFound = false; + + @Override + public boolean publish(SearchResult object) { + if (object.objectType == ObjectType.CITY && ((City) object.object).getId() == lastCityId) { + cityFound = true; + return true; + } else { + return false; + } + } + + @Override + public boolean isCancelled() { + return cityFound; + } + }); + if (addressSearch) { + startAddressSearch(); + } else { + stopAddressSearch(); + } + // Restore previous search location + searchUICore.updateSettings(searchUICore.getSearchSettings().setOriginalLocation(prevLatLon)); + + if (lastCity != null) { + List results = lastCity.getCurrentSearchResults(); + if (results.size() > 0) { + final SearchResult sr = results.get(0); + if (sr.objectType == ObjectType.CITY) { + return sr; + } + } + } + } + return null; + } + public void reloadHistory() { if (app.isApplicationInitializing()) { showProgressBar(); @@ -1194,6 +1270,20 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC searchUICore.updateSettings(settings); } + private LatLon startLastCitySearch(LatLon latLon) { + SearchSettings settings = searchUICore.getSearchSettings(); + LatLon prevLatLon = settings.getOriginalLocation(); + settings = settings.setEmptyQueryAllowed(true) + .setAddressSearch(true) + .setSortByName(false) + .setSearchTypes(ObjectType.CITY) + .setOriginalLocation(latLon) + .setRadiusLevel(1); + + searchUICore.updateSettings(settings); + return prevLatLon; + } + private void startPostcodeSearch() { SearchSettings settings = searchUICore.getSearchSettings() .setSearchTypes(ObjectType.POSTCODE) @@ -1395,6 +1485,19 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC searchUICore.selectSearchResult(sr); if (addressSearch) { startAddressSearch(); + if (sr.objectType == ObjectType.CITY) { + if (sr.relatedObject != null && sr.relatedObject instanceof BinaryMapIndexReader) { + File f = ((BinaryMapIndexReader) sr.relatedObject).getFile(); + if (f != null) { + RegionAddressRepository region = app.getResourceManager().getRegionRepository(f.getName()); + if (region != null) { + app.getSettings().setLastSearchedRegion(region.getFileName(), region.getEstimatedRegionCenter()); + City city = (City) sr.object; + app.getSettings().setLastSearchedCity(city.getId(), sr.localeName, city.getLocation()); + } + } + } + } } String txt = searchUICore.getPhrase().getText(true); searchQuery = txt; diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchListAdapter.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchListAdapter.java index c4840ca60e..1f771ae948 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchListAdapter.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchListAdapter.java @@ -220,7 +220,11 @@ public class QuickSearchListAdapter extends ArrayAdapter { view = (LinearLayout) convertView; } - ((TextView) view.findViewById(R.id.title)).setText(listItem.getName()); + if (listItem.getSpannableName() != null) { + ((TextView) view.findViewById(R.id.title)).setText(listItem.getSpannableName()); + } else { + ((TextView) view.findViewById(R.id.title)).setText(listItem.getName()); + } } else if (type == QuickSearchListItemType.BUTTON) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) app @@ -231,7 +235,11 @@ public class QuickSearchListAdapter extends ArrayAdapter { view = (LinearLayout) convertView; } ((ImageView) view.findViewById(R.id.imageView)).setImageDrawable(listItem.getIcon()); - ((TextView) view.findViewById(R.id.title)).setText(listItem.getName()); + if (listItem.getSpannableName() != null) { + ((TextView) view.findViewById(R.id.title)).setText(listItem.getSpannableName()); + } else { + ((TextView) view.findViewById(R.id.title)).setText(listItem.getName()); + } } else if (type == QuickSearchListItemType.SELECT_ALL) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) app @@ -262,7 +270,11 @@ public class QuickSearchListAdapter extends ArrayAdapter { } view.findViewById(R.id.top_divider) .setVisibility(((QuickSearchHeaderListItem)listItem).isShowTopDivider() ? View.VISIBLE : View.GONE); - ((TextView) view.findViewById(R.id.title)).setText(listItem.getName()); + if (listItem.getSpannableName() != null) { + ((TextView) view.findViewById(R.id.title)).setText(listItem.getSpannableName()); + } else { + ((TextView) view.findViewById(R.id.title)).setText(listItem.getName()); + } } else if (type == QuickSearchListItemType.TOP_SHADOW) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) app @@ -314,7 +326,11 @@ public class QuickSearchListAdapter extends ArrayAdapter { imageView.setImageDrawable(listItem.getIcon()); String name = listItem.getName(); - title.setText(name); + if (listItem.getSpannableName() != null) { + title.setText(listItem.getSpannableName()); + } else { + title.setText(name); + } String desc = listItem.getTypeName(); boolean hasDesc = false; diff --git a/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchButtonListItem.java b/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchButtonListItem.java index 307ad58e2b..7899a1638f 100644 --- a/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchButtonListItem.java +++ b/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchButtonListItem.java @@ -1,6 +1,10 @@ package net.osmand.plus.search.listitems; import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.Spanned; import android.view.View; import net.osmand.plus.OsmandApplication; @@ -10,13 +14,22 @@ public class QuickSearchButtonListItem extends QuickSearchListItem { private int iconId; private String title; + private Spannable spannableTitle; private View.OnClickListener onClickListener; private int colorId; - public QuickSearchButtonListItem(OsmandApplication app, int iconId, String title, View.OnClickListener onClickListener) { + public QuickSearchButtonListItem(OsmandApplication app, int iconId, @NonNull String title, View.OnClickListener onClickListener) { super(app, null); this.iconId = iconId; - this.title = title; + this.title = title.toUpperCase(); + this.onClickListener = onClickListener; + this.colorId = app.getSettings().isLightContent() ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark; + } + + public QuickSearchButtonListItem(OsmandApplication app, int iconId, @NonNull Spannable title, View.OnClickListener onClickListener) { + super(app, null); + this.iconId = iconId; + this.spannableTitle = spannedToUpperCase(title); this.onClickListener = onClickListener; this.colorId = app.getSettings().isLightContent() ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark; } @@ -39,7 +52,23 @@ public class QuickSearchButtonListItem extends QuickSearchListItem { return title; } + @Override + public Spannable getSpannableName() { + return spannableTitle; + } + public View.OnClickListener getOnClickListener() { return onClickListener; } + + private static Spannable spannedToUpperCase(@NonNull Spanned s) { + Object[] spans = s.getSpans(0, s.length(), Object.class); + SpannableString spannableString = new SpannableString(s.toString().toUpperCase()); + + // reapply the spans to the now uppercase string + for (Object span : spans) { + spannableString.setSpan(span, s.getSpanStart(span), s.getSpanEnd(span), s.getSpanFlags(span)); + } + return spannableString; + } } diff --git a/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchListItem.java b/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchListItem.java index 2ec1f0f757..d56522258d 100644 --- a/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchListItem.java +++ b/OsmAnd/src/net/osmand/plus/search/listitems/QuickSearchListItem.java @@ -2,6 +2,8 @@ package net.osmand.plus.search.listitems; import android.content.Context; import android.graphics.drawable.Drawable; +import android.text.Spannable; + import net.osmand.binary.BinaryMapIndexReader; import net.osmand.data.Amenity; import net.osmand.data.City; @@ -73,6 +75,10 @@ public class QuickSearchListItem { return getName(app, searchResult); } + public Spannable getSpannableName() { + return null; + } + public static String getName(OsmandApplication app, SearchResult searchResult) { switch (searchResult.objectType) { case STREET: