package de.blau.android.dialogs; import android.annotation.SuppressLint; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog.Builder; import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatDialog; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; import de.blau.android.R; import de.blau.android.osm.BoundingBox; import de.blau.android.prefs.AdvancedPrefDatabase; import de.blau.android.prefs.AdvancedPrefDatabase.Geocoder; import de.blau.android.prefs.Preferences; import de.blau.android.util.Search; import de.blau.android.util.Search.SearchResult; import de.blau.android.util.SearchItemFoundCallback; import de.blau.android.util.ThemeUtils; /** * Display a dialog asking for a search string that is then found with nominatim * */ public class SearchForm extends DialogFragment { private static final String DEBUG_TAG = SearchForm.class.getSimpleName(); private static final String TAG = "fragment_search_form"; private BoundingBox bbox; private SearchItemFoundCallback callback; /** * */ static public void showDialog(AppCompatActivity activity, final BoundingBox bbox, final SearchItemFoundCallback callback) { dismissDialog(activity); FragmentManager fm = activity.getSupportFragmentManager(); SearchForm searchFormFragment = newInstance(bbox, callback); if (searchFormFragment != null) { searchFormFragment.show(fm, TAG); } else { Log.e(DEBUG_TAG,"Unable to create search form dialog "); } } private static void dismissDialog(AppCompatActivity activity) { FragmentManager fm = activity.getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); Fragment fragment = fm.findFragmentByTag(TAG); if (fragment != null) { ft.remove(fragment); } ft.commit(); } /** */ static private SearchForm newInstance(final BoundingBox bbox, final SearchItemFoundCallback callback) { SearchForm f = new SearchForm(); Bundle args = new Bundle(); args.putSerializable("bbox", bbox); args.putSerializable("callback", callback); f.setArguments(args); f.setShowsDialog(true); return f; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCancelable(true); bbox = (BoundingBox) getArguments().getSerializable("bbox"); callback = (SearchItemFoundCallback) getArguments().getSerializable("callback"); } @NonNull @Override @SuppressLint("InflateParams") public AppCompatDialog onCreateDialog(Bundle savedInstanceState) { final LayoutInflater inflater = ThemeUtils.getLayoutInflater(getActivity()); LinearLayout searchLayout = (LinearLayout) inflater.inflate(R.layout.query_entry, null); Builder searchBuilder = new AlertDialog.Builder(getActivity()); // builder.setIcon(ThemeUtils.getResIdFromAttribute(getActivity(),R.attr.alert_dialog)); searchBuilder.setTitle(R.string.menu_find); searchBuilder.setMessage(R.string.find_message); searchBuilder.setView(searchLayout); final EditText searchEdit = (EditText) searchLayout.findViewById(R.id.location_search_edit); searchEdit.setImeOptions(EditorInfo.IME_ACTION_SEARCH); final Spinner searchGeocoder = (Spinner) searchLayout.findViewById(R.id.location_search_geocoder); AdvancedPrefDatabase db = new AdvancedPrefDatabase(getActivity()); final Geocoder[] geocoders = db.getActiveGeocoders(); String[] geocoderNames = new String[geocoders.length]; for (int i=0;i<geocoders.length;i++) { geocoderNames[i] = geocoders[i].name; } ArrayAdapter<String> adapter = new ArrayAdapter<String>( getActivity(), android.R.layout.simple_spinner_item, geocoderNames); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); searchGeocoder.setAdapter(adapter); final Preferences prefs = new Preferences(getActivity()); searchGeocoder.setSelection(prefs.getGeocoder()); searchGeocoder.setOnItemSelectedListener(new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int pos, long arg3) { prefs.setGeocoder(pos); } @Override public void onNothingSelected(AdapterView<?> arg0) { }}); searchBuilder.setPositiveButton(R.string.search, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { searchEdit.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); // emulate pressing the enter button } }); searchBuilder.setNegativeButton(R.string.cancel, null); final AppCompatDialog searchDialog = searchBuilder.create(); /* * NOTE this is slightly hackish but needed to ensure the original dialog (this) gets dismissed */ final SearchItemFoundCallback realCallback = new SearchItemFoundCallback() { private static final long serialVersionUID = 1L; @Override public void onItemFound(SearchResult sr) { searchDialog.dismiss(); callback.onItemFound(sr); } }; searchEdit.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH || (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) { Search search = new Search((AppCompatActivity) getActivity(), realCallback); search.find(geocoders[searchGeocoder.getSelectedItemPosition()],v.getText().toString(),bbox); return true; } return false; } }); return searchDialog; } @Override public void onStart() { super.onStart(); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } }