/**
*
*/
package net.osmand.plus.activities.search;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.Location;
import net.osmand.ResultMatcher;
import net.osmand.access.AccessibilityAssistant;
import net.osmand.access.NavigationInfo;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.osm.PoiType;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.R.color;
import net.osmand.plus.activities.EditPOIFilterActivity;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.OsmandListActivity;
import net.osmand.plus.dashboard.DashLocationFragment;
import net.osmand.plus.poi.NominatimPoiFilter;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.poi.PoiUIFilter.AmenityNameFilter;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.views.DirectionDrawable;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import net.osmand.util.OpeningHoursParser;
import net.osmand.util.OpeningHoursParser.OpeningHours;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import gnu.trove.set.hash.TLongHashSet;
/**
* Search poi activity
*/
public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompassListener, OsmAndLocationListener {
public static final String AMENITY_FILTER = "net.osmand.amenity_filter"; //$NON-NLS-1$
public static final String SEARCH_NEARBY = SearchActivity.SEARCH_NEARBY; //$NON-NLS-1$
public static final String SEARCH_LAT = SearchActivity.SEARCH_LAT; //$NON-NLS-1$
public static final String SEARCH_LON = SearchActivity.SEARCH_LON; //$NON-NLS-1$
private static final float MIN_DISTANCE_TO_RESEARCH = 100;
private static final float MIN_DISTANCE_TO_REFRESH = 5;
private static final int SEARCH_MORE = 0;
private static final int SHOW_ON_MAP = 1;
private static final int FILTER = 2;
private static final int EDIT_FILTER = 4;
private static final int DELETE_FILTER = 5;
private static final int SAVE_FILTER = 6;
private PoiUIFilter filter;
private AmenityAdapter amenityAdapter;
private EditText searchFilter;
private View searchFilterLayout;
private NavigationInfo navigationInfo;
private boolean searchNearBy = false;
private net.osmand.Location location = null;
private net.osmand.Location lastSearchedLocation = null;
private Float heading = null;
private SearchAmenityTask currentSearchTask = null;
private AccessibilityAssistant accessibilityAssistant;
private OsmandApplication app;
private MenuItem showFilterItem;
private MenuItem showOnMapItem;
private MenuItem searchPOILevel;
private static int RESULT_REQUEST_CODE = 54;
private CharSequence tChange;
@Override
public boolean onCreateOptionsMenu(Menu omenu) {
Menu menu = getClearToolbar(true).getMenu();
searchPOILevel = menu.add(0, SEARCH_MORE, 0, R.string.search_POI_level_btn);
MenuItemCompat.setShowAsAction(searchPOILevel, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
searchPOILevel.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return search();
}
});
showFilterItem = menu.add(0, FILTER, 0, R.string.search_poi_filter);
MenuItemCompat.setShowAsAction(showFilterItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
showFilterItem = showFilterItem.setIcon(getMyApplication().getIconsCache().getIcon(
R.drawable.ic_action_filter_dark));
showFilterItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (searchFilterLayout.getVisibility() == View.GONE) {
searchFilterLayout.setVisibility(View.VISIBLE);
searchFilter.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(searchFilter, InputMethodManager.SHOW_IMPLICIT);
} else {
if (filter != null) {
searchFilter.setText(filter.getSavedFilterByName() == null ? "" :
filter.getSavedFilterByName());
}
searchFilterLayout.setVisibility(View.GONE);
}
return true;
}
});
showOnMapItem = menu.add(0, SHOW_ON_MAP, 0, R.string.shared_string_show_on_map);
MenuItemCompat.setShowAsAction(showOnMapItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
showOnMapItem = showOnMapItem.setIcon(getMyApplication().getIconsCache().getIcon(
R.drawable.ic_show_on_map));
showOnMapItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
OsmandSettings settings = app.getSettings();
filter.setFilterByName(searchFilter.getText().toString().trim());
app.getPoiFilters().addSelectedPoiFilter(filter);
if (location != null) {
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), 15);
}
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
return true;
}
});
showOnMapItem.setEnabled(!isNameSearch() || amenityAdapter.getCount() > 0);
if (filter != null && !isNameSearch()) {
createMenuItem(omenu, SAVE_FILTER, R.string.edit_filter_save_as_menu_item, R.drawable.ic_action_fav_dark,
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
if (!filter.isStandardFilter()) {
createMenuItem(omenu, DELETE_FILTER, R.string.shared_string_delete, R.drawable.ic_action_delete_dark,
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
}
}
updateButtonState(false);
return true;
}
@Override
protected void onDestroy() {
// Issue 2657
super.onDestroy();
if (!(currentSearchTask == null || currentSearchTask.getStatus() == Status.FINISHED)) {
currentSearchTask.cancel(true);
}
}
public Toolbar getClearToolbar(boolean visible) {
final Toolbar tb = (Toolbar) findViewById(R.id.poiSplitbar);
tb.setTitle(null);
tb.getMenu().clear();
tb.setVisibility(visible ? View.VISIBLE : View.GONE);
return tb;
}
private boolean search() {
String query = searchFilter.getText().toString().trim();
if (query.length() < 2 && isNameSearch()) {
Toast.makeText(SearchPOIActivity.this, R.string.poi_namefinder_query_empty, Toast.LENGTH_LONG)
.show();
return true;
}
if ((isNameSearch() && !Algorithms.objectEquals(filter.getFilterByName(), query))) {
filter.clearPreviousZoom();
filter.setFilterByName(query);
runNewSearchQuery(location, NEW_SEARCH_INIT);
} else {
filter.setFilterByName(query);
runNewSearchQuery(location, SEARCH_FURTHER);
}
return true;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.searchpoi);
getSupportActionBar().setTitle(R.string.searchpoi_activity);
// getSupportActionBar().setIcon(R.drawable.tab_search_poi_icon);
setSupportProgressBarIndeterminateVisibility(false);
app = (OsmandApplication) getApplication();
amenityAdapter = new AmenityAdapter(new ArrayList<Amenity>());
setListAdapter(amenityAdapter);
searchFilterLayout = findViewById(R.id.SearchFilterLayout);
searchFilter = (EditText) findViewById(R.id.searchEditText);
accessibilityAssistant = new AccessibilityAssistant(this);
navigationInfo = new NavigationInfo(app);
searchFilter.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
tChange = s;
// Issue #2667 (3)
if (currentSearchTask == null) {
changeFilter(tChange);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
searchFilter.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
searchFilter.setHint(R.string.filter_poi_hint);
((ImageView) findViewById(R.id.search_icon)).setImageDrawable(
getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_filter_dark));
((ImageView) findViewById(R.id.options)).
setImageDrawable(getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_overflow_menu_white));
findViewById(R.id.options).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showOptionsMenu(v);
}
});
updateIntent(getIntent());
}
public void updateIntent(Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle.containsKey(SEARCH_LAT) && bundle.containsKey(SEARCH_LON)) {
location = new net.osmand.Location("internal"); //$NON-NLS-1$
location.setLatitude(bundle.getDouble(SEARCH_LAT));
location.setLongitude(bundle.getDouble(SEARCH_LON));
}
searchNearBy = bundle.containsKey(SEARCH_NEARBY);
String filterId = bundle.getString(AMENITY_FILTER);
this.filter = app.getPoiFilters().getFilterById(filterId);
if (filter != null) {
if (filter.isEmpty() && !isNameSearch()) {
showEditActivity(filter);
} else {
filter.clearPreviousZoom();
// run query again
runNewSearchQuery(location, NEW_SEARCH_INIT);
}
} else {
amenityAdapter.setNewModel(Collections.<Amenity>emptyList());
finish();
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
updateIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
updateButtonState(false);
if (filter != null) {
String text = filter.getFilterByName() != null ? filter.getFilterByName() : "";
searchFilter.setText(text);
searchFilterLayout.setVisibility(text.length() > 0 || isNameSearch() ? View.VISIBLE : View.GONE);
app.getLocationProvider().removeCompassListener(app.getLocationProvider().getNavigationInfo());
app.getLocationProvider().addCompassListener(this);
app.getLocationProvider().registerOrUnregisterCompassListener(true);
}
if (searchNearBy) {
app.getLocationProvider().addLocationListener(this);
location = app.getLocationProvider().getLastKnownLocation();
app.getLocationProvider().resumeAllUpdates();
}
updateLocation(location);
}
private void changeFilter(CharSequence s) {
String queue = s.toString().trim();
// if (!isNameSearch() ) {
amenityAdapter.getFilter().filter(queue);
String cfilter = filter == null || filter.getFilterByName() == null ? "" :
filter.getFilterByName().toLowerCase();
if (!isNameSearch() && !queue.toString().toLowerCase().startsWith(cfilter)) {
filter.setFilterByName(queue.toString());
runNewSearchQuery(location, SEARCH_AGAIN);
}
updateButtonState(false);
}
private void showOptionsMenu(View v) {
// Show menu with search all, name finder, name finder poi
IconsCache iconsCache = getMyApplication().getIconsCache();
final PopupMenu optionsMenu = new PopupMenu(this, v);
final PoiUIFilter f = this.filter;
MenuItem item = optionsMenu.getMenu().add(R.string.shared_string_edit)
.setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_edit_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
PoiUIFilter custom = getMyApplication().getPoiFilters().getCustomPOIFilter();
custom.replaceWithPoiFilter(f);
showEditActivity(custom);
return true;
}
});
addFilter(optionsMenu, getString(R.string.shared_string_is_open));
addFilter(optionsMenu, getString(R.string.shared_string_is_open_24_7));
Map<String, PoiType> poiAdditionals = f.getPoiAdditionals();
if (poiAdditionals != null) {
TreeMap<String, PoiType> adds = new TreeMap<String, PoiType>();
for (PoiType vtype : poiAdditionals.values()) {
if (vtype.isTopVisible()) {
adds.put(vtype.getTranslation().replace(' ', ':').toLowerCase(), vtype);
}
}
for (String vtype : adds.keySet()) {
addFilter(optionsMenu, vtype);
}
}
optionsMenu.show();
}
private void addFilter(PopupMenu optionsMenu, final String value) {
IconsCache iconsCache = getMyApplication().getIconsCache();
MenuItem item = optionsMenu.getMenu().add(getString(R.string.search_poi_filter) + ": " + value)
.setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_filter_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (searchFilterLayout.getVisibility() == View.GONE) {
searchFilterLayout.setVisibility(View.VISIBLE);
}
searchFilter.setText((searchFilter.getText().toString() + " " + value.replace(' ', '_').toLowerCase()).trim());
return true;
}
});
}
private void showEditActivity(PoiUIFilter poi) {
Intent newIntent = new Intent(this, EditPOIFilterActivity.class);
// folder selected
newIntent.putExtra(EditPOIFilterActivity.AMENITY_FILTER, poi.getFilterId());
if (location != null) {
newIntent.putExtra(SearchActivity.SEARCH_LAT, location.getLatitude());
newIntent.putExtra(SearchActivity.SEARCH_LON, location.getLongitude());
}
if (searchNearBy) {
newIntent.putExtra(SearchActivity.SEARCH_NEARBY, true);
}
startActivityForResult(newIntent, RESULT_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_REQUEST_CODE && resultCode == EditPOIFilterActivity.EDIT_ACTIVITY_RESULT_OK) {
PoiUIFilter custom = app.getPoiFilters().getCustomPOIFilter();
if (this.filter.isStandardFilter()) {
this.filter = custom;
if (!Algorithms.isEmpty(searchFilter.getText().toString())) {
this.filter.setFilterByName(searchFilter.getText().toString());
} else {
this.filter.setFilterByName(null);
}
} else {
this.filter.replaceWithPoiFilter(custom);
}
filter.clearPreviousZoom();
// run query again
runNewSearchQuery(location, NEW_SEARCH_INIT);
}
if (filter == null || filter.isEmpty()) {
finish();
}
}
private void updateButtonState(boolean next) {
if (showFilterItem != null) {
showFilterItem.setVisible(filter != null && !isNameSearch());
}
if (filter != null) {
int maxLength = 24;
String name = filter.getGeneratedName(maxLength);
// Next displays the actual query term instead of the generic "Seach by name", can be enabled for debugging or in general
if (isNameSearch()) {
name = "'" + filter.getFilterByName() + "'";
}
if (name.length() >= maxLength) {
name = name.substring(0, maxLength) + getString(R.string.shared_string_ellipsis);
}
if (filter instanceof NominatimPoiFilter && !((NominatimPoiFilter) filter).isPlacesQuery()) {
// nothing to add
} else {
name += " " + filter.getSearchArea(next);
}
getSupportActionBar().setTitle(name);
}
if (searchPOILevel != null) {
int title = location == null ? R.string.search_poi_location : R.string.search_POI_level_btn;
boolean taskAlreadyFinished = currentSearchTask == null || currentSearchTask.getStatus() != Status.RUNNING;
boolean enabled = taskAlreadyFinished && location != null &&
filter != null && filter.isSearchFurtherAvailable();
if (isNameSearch() && !Algorithms.objectEquals(searchFilter.getText().toString(), filter.getFilterByName())) {
title = R.string.search_button;
// Issue #2667 (2)
if (currentSearchTask == null) {
enabled = true;
}
}
searchPOILevel.setEnabled(enabled);
searchPOILevel.setTitle(title);
}
}
private synchronized void runNewSearchQuery(net.osmand.Location location, int requestType) {
if (currentSearchTask == null || currentSearchTask.getStatus() == Status.FINISHED) {
currentSearchTask = new SearchAmenityTask(location, requestType);
currentSearchTask.execute();
}
}
public boolean isNominatimFilter() {
return filter instanceof NominatimPoiFilter;
}
public boolean isOfflineSearchByNameFilter() {
return filter != null && PoiUIFilter.BY_NAME_FILTER_ID.equals(filter.getFilterId());
}
public boolean isNameSearch() {
return isNominatimFilter() || isOfflineSearchByNameFilter();
}
@Override
public void updateLocation(net.osmand.Location location) {
boolean handled = false;
if (location != null && filter != null) {
net.osmand.Location searchedLocation = lastSearchedLocation;
if (searchedLocation == null) {
if (!isNameSearch()) {
runNewSearchQuery(location, NEW_SEARCH_INIT);
}
handled = true;
} else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) {
searchedLocation = location;
runNewSearchQuery(location, SEARCH_AGAIN);
handled = true;
} else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_REFRESH) {
handled = true;
}
} else {
if (location != null) {
handled = true;
}
}
if (handled) {
this.location = location;
ListView lv = getListView();
final int index = lv.getFirstVisiblePosition();
View v = lv.getChildAt(0);
final int top = (v == null) ? 0 : v.getTop();
accessibilityAssistant.lockEvents();
amenityAdapter.notifyDataSetChanged();
lv.setSelectionFromTop(index, top);
updateButtonState(false);
accessibilityAssistant.unlockEvents();
navigationInfo.updateLocation(location);
}
}
@Override
public void updateCompassValue(float value) {
// 99 in next line used to one-time initalize arrows (with reference vs. fixed-north direction) on non-compass
// devices
float lastHeading = heading != null ? heading : 99;
heading = value;
if (heading != null && Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) {
accessibilityAssistant.lockEvents();
amenityAdapter.notifyDataSetChanged();
accessibilityAssistant.unlockEvents();
} else {
heading = lastHeading;
}
// Comment out and use lastHeading above to see if this fixes issues seen on some devices
// if(!uiHandler.hasMessages(COMPASS_REFRESH_MSG_ID)){
// Message msg = Message.obtain(uiHandler, new Runnable(){
// @Override
// public void run() {
// amenityAdapter.notifyDataSetChanged();
// }
// });
// msg.what = COMPASS_REFRESH_MSG_ID;
// uiHandler.sendMessageDelayed(msg, 100);
// }
final View selected = accessibilityAssistant.getFocusedView();
if (selected != null) {
try {
int position = getListView().getPositionForView(selected);
if ((position != AdapterView.INVALID_POSITION) && (position >= getListView().getHeaderViewsCount())) {
navigationInfo.updateTargetDirection(amenityAdapter.getItem(position - getListView().getHeaderViewsCount()).getLocation(), heading.floatValue());
}
} catch (Exception e) {
return;
}
}
}
@Override
protected void onPause() {
super.onPause();
app.getLocationProvider().pauseAllUpdates();
app.getLocationProvider().removeCompassListener(this);
app.getLocationProvider().addCompassListener(app.getLocationProvider().getNavigationInfo());
if (searchNearBy) {
app.getLocationProvider().removeLocationListener(this);
}
if (!app.accessibilityEnabled()) {
app.getLocationProvider().removeCompassListener(this);
}
}
@Override
public void onDetachedFromWindow() {
accessibilityAssistant.forgetFocus();
}
@Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position);
final OsmandSettings settings = app.getSettings();
String poiSimpleFormat = OsmAndFormatter.getPoiStringWithoutType(amenity,
app.getSettings().MAP_PREFERRED_LOCALE.get(),
app.getSettings().MAP_TRANSLITERATE_NAMES.get());
PointDescription name = new PointDescription(PointDescription.POINT_TYPE_POI, poiSimpleFormat);
int z = Math.max(16, settings.getLastKnownMapZoom());
LatLon location = amenity.getLocation();
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
z,
name,
true,
amenity); //$NON-NLS-1$
MapActivity.launchMapActivityMoveToTop(this);
}
private static final int SEARCH_AGAIN = 1;
private static final int NEW_SEARCH_INIT = 2;
private static final int SEARCH_FURTHER = 3;
class SearchAmenityTask extends AsyncTask<Void, Amenity, List<Amenity>> implements ResultMatcher<Amenity> {
private int requestType;
private TLongHashSet existingObjects = null;
private TLongHashSet updateExisting;
private Location searchLocation;
public SearchAmenityTask(net.osmand.Location location, int requestType) {
this.searchLocation = location;
this.requestType = requestType;
}
net.osmand.Location getSearchedLocation() {
return searchLocation;
}
@Override
protected void onPreExecute() {
setSupportProgressBarIndeterminateVisibility(true);
if (searchPOILevel != null) {
searchPOILevel.setEnabled(false);
}
existingObjects = new TLongHashSet();
updateExisting = new TLongHashSet();
if (requestType == NEW_SEARCH_INIT) {
amenityAdapter.clear();
} else if (requestType == SEARCH_FURTHER) {
List<Amenity> list = amenityAdapter.getOriginalAmenityList();
for (Amenity a : list) {
updateExisting.add(getAmenityId(a));
}
}
updateButtonState(requestType == SEARCH_FURTHER);
}
private long getAmenityId(Amenity a) {
return (a.getId() << 8) + a.getType().ordinal();
}
@Override
protected void onPostExecute(List<Amenity> result) {
setSupportProgressBarIndeterminateVisibility(false);
currentSearchTask = null;
updateButtonState(false);
if (isNameSearch()) {
if (isNominatimFilter() && !Algorithms.isEmpty(((NominatimPoiFilter) filter).getLastError())) {
Toast.makeText(SearchPOIActivity.this, ((NominatimPoiFilter) filter).getLastError(),
Toast.LENGTH_LONG).show();
}
amenityAdapter.setNewModel(result);
if (showOnMapItem != null) {
showOnMapItem.setEnabled(amenityAdapter.getCount() > 0);
}
} else {
amenityAdapter.setNewModel(result);
}
// Issue #2667 (1)
if (tChange != null) {
changeFilter(tChange);
tChange = null;
}
amenityAdapter.notifyDataSetChanged();
lastSearchedLocation = searchLocation;
}
@Override
protected void onProgressUpdate(Amenity... values) {
for (Amenity a : values) {
amenityAdapter.add(a);
}
}
@Override
protected List<Amenity> doInBackground(Void... params) {
if (searchLocation != null) {
if (requestType == NEW_SEARCH_INIT) {
return filter.initializeNewSearch(searchLocation.getLatitude(), searchLocation.getLongitude(),
-1, this);
} else if (requestType == SEARCH_FURTHER) {
return filter.searchFurther(searchLocation.getLatitude(), searchLocation.getLongitude(), this);
} else if (requestType == SEARCH_AGAIN) {
return filter.searchAgain(searchLocation.getLatitude(), searchLocation.getLongitude());
}
}
return Collections.emptyList();
}
@Override
public boolean publish(Amenity object) {
long id = getAmenityId(object);
if (existingObjects != null && !existingObjects.contains(id)) {
existingObjects.add(id);
if (requestType == NEW_SEARCH_INIT) {
publishProgress(object);
} else if (requestType == SEARCH_FURTHER) {
if (!updateExisting.contains(id)) {
publishProgress(object);
}
}
return true;
}
return false;
}
}
class AmenityAdapter extends ArrayAdapter<Amenity> {
private AmenityFilter listFilter;
private List<Amenity> originalAmenityList;
private int screenOrientation;
AmenityAdapter(List<Amenity> list) {
super(SearchPOIActivity.this, R.layout.searchpoi_list, list);
originalAmenityList = new ArrayList<Amenity>(list);
this.setNotifyOnChange(false);
}
public List<Amenity> getOriginalAmenityList() {
return originalAmenityList;
}
public void setNewModel(List<Amenity> amenityList) {
setNotifyOnChange(false);
screenOrientation = DashLocationFragment.getScreenOrientation(SearchPOIActivity.this);
originalAmenityList = new ArrayList<Amenity>(amenityList);
clear();
for (Amenity obj : amenityList) {
add(obj);
}
setNotifyOnChange(true);
this.notifyDataSetInvalidated();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.searchpoi_list, parent, false);
}
float[] mes = null;
TextView label = (TextView) row.findViewById(R.id.poi_label);
TextView distanceText = (TextView) row.findViewById(R.id.distance);
TextView timeText = (TextView) row.findViewById(R.id.time);
ImageView direction = (ImageView) row.findViewById(R.id.poi_direction);
ImageView timeIcon = (ImageView) row.findViewById(R.id.time_icon);
ImageView icon = (ImageView) row.findViewById(R.id.poi_icon);
Amenity amenity = getItem(position);
if (amenity.getOpeningHours() != null) {
OpeningHours rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
if (rs != null) {
Calendar inst = Calendar.getInstance();
inst.setTimeInMillis(System.currentTimeMillis());
boolean worksNow = rs.isOpenedForTime(inst);
inst.setTimeInMillis(System.currentTimeMillis() + 30 * 60 * 1000); // 30 minutes later
boolean worksLater = rs.isOpenedForTime(inst);
int colorId = worksNow ? worksLater ? color.color_ok : color.color_intermediate : color.color_warning;
timeIcon.setVisibility(View.VISIBLE);
timeText.setVisibility(View.VISIBLE);
timeIcon.setImageDrawable(app.getIconsCache().getIcon(R.drawable.ic_small_time, colorId));
timeText.setTextColor(app.getResources().getColor(colorId));
String rt = rs.getCurrentRuleTime(inst);
timeText.setText(rt == null ? "" : rt);
} else {
timeIcon.setVisibility(View.GONE);
timeText.setVisibility(View.GONE);
}
} else {
timeIcon.setVisibility(View.GONE);
timeText.setVisibility(View.GONE);
}
Drawable dd = direction.getDrawable();
DirectionDrawable draw;
if (dd instanceof DirectionDrawable) {
draw = (DirectionDrawable) dd;
} else {
draw = new DirectionDrawable(SearchPOIActivity.this, 24, 24,
R.drawable.ic_direction_arrow, R.color.color_distance);
direction.setImageDrawable(draw);
}
net.osmand.Location loc = location;
if (loc != null) {
mes = new float[2];
LatLon l = amenity.getLocation();
net.osmand.Location.distanceBetween(l.getLatitude(), l.getLongitude(), loc.getLatitude(),
loc.getLongitude(), mes);
}
if (loc != null) {
float a = heading != null ? heading : 0;
draw.setAngle(mes[1] - a + 180 + screenOrientation);
} else {
draw.setAngle(0);
}
draw.setColorId(searchNearBy ? color.color_myloc_distance : color.color_distance);
direction.setImageDrawable(draw);
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
if (st != null) {
if (RenderingIcons.containsBigIcon(st.getIconKeyName())) {
icon.setImageResource(RenderingIcons.getBigIconResourceId(st.getIconKeyName()));
} else if (RenderingIcons.containsBigIcon(st.getOsmTag() + "_" + st.getOsmValue())) {
icon.setImageResource(RenderingIcons.getBigIconResourceId(st.getOsmTag() + "_" + st.getOsmValue()));
} else {
icon.setImageDrawable(null);
}
} else {
icon.setImageDrawable(null);
}
String distance = " ";
if (mes != null) {
distance = " " + OsmAndFormatter.getFormattedDistance((int) mes[0], getMyApplication()) + " "; //$NON-NLS-1$
}
String poiType = OsmAndFormatter.getPoiStringWithoutType(amenity,
app.getSettings().MAP_PREFERRED_LOCALE.get(),
app.getSettings().MAP_TRANSLITERATE_NAMES.get());
label.setText(poiType);
distanceText.setText(distance);
ViewCompat.setAccessibilityDelegate(row, accessibilityAssistant);
return (row);
}
@Override
public Filter getFilter() {
if (listFilter == null) {
listFilter = new AmenityFilter();
}
return listFilter;
}
private final class AmenityFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<Amenity> listToFilter = originalAmenityList;
if (constraint == null || constraint.length() == 0 || filter == null) {
results.values = listToFilter;
results.count = listToFilter.size();
} else {
List<Amenity> res = new ArrayList<Amenity>();
AmenityNameFilter nm = filter.getNameFilter(constraint.toString().toLowerCase());
for (Amenity item : listToFilter) {
if (nm.accept(item)) {
res.add(item);
}
}
results.values = res;
results.count = res.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
for (Amenity item : (Collection<Amenity>) results.values) {
add(item);
}
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
if (getIntent().hasExtra(MapActivity.INTENT_KEY_PARENT_MAP_ACTIVITY)) {
Intent newIntent = new Intent(this, app.getAppCustomization().getSearchActivity());
if (location != null) {
newIntent.putExtra(SearchActivity.SEARCH_LAT, location.getLatitude());
newIntent.putExtra(SearchActivity.SEARCH_LON, location.getLongitude());
if (searchNearBy) {
newIntent.putExtra(SearchActivity.SEARCH_NEARBY, true);
}
}
newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(newIntent);
finish();
return true;
}
break;
case DELETE_FILTER:
removePoiFilter();
return true;
case SAVE_FILTER:
savePoiFilter();
return true;
}
return super.onOptionsItemSelected(item);
}
private void removePoiFilter() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
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(
SearchPOIActivity.this,
MessageFormat.format(SearchPOIActivity.this.getText(R.string.edit_filter_delete_message).toString(),
filter.getName()), Toast.LENGTH_SHORT).show();
SearchPOIActivity.this.finish();
}
}
});
builder.create().show();
}
public void savePoiFilter() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.edit_filter_save_as_menu_item);
final EditText editText = new EditText(this);
if (filter.isStandardFilter()) {
editText.setText((filter.getName() + " " + searchFilter.getText()).trim());
} else {
editText.setText(filter.getName());
}
LinearLayout ll = new LinearLayout(this);
ll.setPadding(5, 3, 5, 0);
ll.addView(editText, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
builder.setView(ll);
builder.setNegativeButton(R.string.shared_string_cancel, null);
builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
PoiUIFilter nFilter = new PoiUIFilter(editText.getText().toString(),
null,
filter.getAcceptedTypes(), (OsmandApplication) getApplication());
if (searchFilter.getText().toString().length() > 0) {
nFilter.setSavedFilterByName(searchFilter.getText().toString());
}
if (app.getPoiFilters().createPoiFilter(nFilter)) {
Toast.makeText(
SearchPOIActivity.this,
MessageFormat.format(SearchPOIActivity.this.getText(R.string.edit_filter_create_message).toString(),
editText.getText().toString()), Toast.LENGTH_SHORT).show();
}
SearchPOIActivity.this.finish();
}
});
builder.create().show();
}
}