package farom.iparcos; import android.app.AlertDialog; import android.app.ListActivity; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.app.SearchManager; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.SearchView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import farom.iparcos.catalog.Catalog; import farom.iparcos.catalog.CatalogEntry; import farom.iparcos.catalog.Coordinates; import laazotea.indi.Constants; import laazotea.indi.client.INDIDevice; import laazotea.indi.client.INDIDeviceListener; import laazotea.indi.client.INDINumberElement; import laazotea.indi.client.INDINumberProperty; import laazotea.indi.client.INDIProperty; import laazotea.indi.client.INDIPropertyListener; import laazotea.indi.client.INDIServerConnection; import laazotea.indi.client.INDIServerConnectionListener; import laazotea.indi.client.INDISwitchElement; import laazotea.indi.client.INDISwitchProperty; /** * Allow the user to search for an astronomical object and display the result. */ public class SearchActivity extends ListActivity implements MenuItem.OnActionExpandListener, SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,INDIServerConnectionListener, INDIPropertyListener, INDIDeviceListener { ArrayAdapter<CatalogEntry> adapter; private ArrayList<CatalogEntry> entries; private Catalog catalog; // INDI properties private INDINumberProperty telescopeCoordP = null; private INDINumberElement telescopeCoordRA = null; private INDINumberElement telescopeCoordDE = null; private INDISwitchProperty telescopeOnCoordSetP = null; private INDISwitchElement telescopeOnCoordSetSync = null; private INDISwitchElement telescopeOnCoordSetSlew = null; /** * Called at the activity creation. Disable opening animation and load default content. * @param savedInstanceState */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); overridePendingTransition(0, 0); // list setup entries = new ArrayList<CatalogEntry>(); adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_2, android.R.id.text1, entries) { @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); TextView text1 = (TextView) view.findViewById(android.R.id.text1); TextView text2 = (TextView) view.findViewById(android.R.id.text2); text1.setText(entries.get(position).getName()); text2.setText(entries.get(position).createSummary(getContext())); return view; } }; setListAdapter(adapter); // List loading final Context act = this; new Thread(new Runnable(){ @Override public void run() { catalog = new Catalog(act); entries.addAll(catalog.getEntries()); } }).start(); // TODO : faire plus propre avec Cursor et Loader // Set up INDI connection ConnectionActivity.getInstance().registerPermanentConnectionListener(this); // Enumerate existing properties INDIServerConnection connection = ConnectionActivity.getConnection(); if (connection != null) { List<INDIDevice> list = connection.getDevicesAsList(); if (list != null) { for (Iterator<INDIDevice> it = list.iterator(); it.hasNext();) { INDIDevice device = it.next(); device.addINDIDeviceListener(this); List<INDIProperty> properties = device.getPropertiesAsList(); for (Iterator<INDIProperty> it2 = properties.iterator(); it2.hasNext();) { this.newProperty(device, it2.next()); } } } } getListView().setOnItemClickListener(this); } /** * perform the search * @param query */ private void doMySearch(String query) { // TextView text = (TextView) findViewById(R.id.textViewtest); // text.setText(query); // Log.d("GLOBALLOG", "Search for " + query); // entries.clear(); // entries.addAll(dsoCatalog.search(query)); // entries.add(new DSOEntry("48 Tuc 4 Gb 30.9 00 24 06.1-72 05 00X")); // Log.d("GLOBALLOG", "entries.size() = " + entries.size()); // adapter.notifyDataSetChanged(); if(catalog!=null){ if(catalog.isReady()) { getListView().setSelection(catalog.searchIndex(query)); } } } /** * Initiate the menu (only the search view in fact). * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the options menu from XML MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_search, menu); // Get the SearchView and set the searchable configuration SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); // expand the view at the beginning searchView.setSubmitButtonEnabled(false); // disable the submit button (the search is done every time the user change the text in the searchView) searchView.setOnQueryTextListener(this); // to recover text change MenuItem searchItem = menu.findItem(R.id.menu_search); searchItem.expandActionView(); // force expand the view at the beginning (the searchView.setIconifiedByDefault is not working) searchItem.setOnActionExpandListener(this); // recover the collapse event to quit the activity return true; } /** * (from OnActionExpandListener) Called when the search menu is expanded. It can only happens at the menu initialisation. Nothing to do. * @param item * @return */ @Override public boolean onMenuItemActionExpand(MenuItem item) { return true; } /** * (from OnActionExpandListener) Called when the user closes the search menu. It shall kill the activity. * @param item * @return */ @Override public boolean onMenuItemActionCollapse(MenuItem item) { finish(); overridePendingTransition(0, 0); // Disable the swipe animation for the activity end. return true; } /** * (from OnQueryTextListener) Called when the user changes the search string * @param newText * @return */ @Override public boolean onQueryTextChange(String newText) { doMySearch(newText); return false; } /** * (from OnQueryTextListener) Called when the user submits the query. Nothing to do since it is done in onQueryTextChange * @param query * @return */ @Override public boolean onQueryTextSubmit(String query) { return false; } /** * Callback method to be invoked when an item in this AdapterView has * been clicked. * <p/> * Implementers can call getItemAtPosition(position) if they need * to access the data associated with the selected item. * * @param parent The AdapterView where the click happened. * @param view The view within the AdapterView that was clicked (this * will be a view provided by the adapter) * @param position The position of the view in the adapter. * @param id The row id of the item that was clicked. */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final Context ctx = view.getContext(); final Coordinates coord = entries.get(position).getCoordinates(); AlertDialog.Builder builder = new AlertDialog.Builder(ctx); builder.setMessage(entries.get(position).createDescription(this)) .setTitle(entries.get(position).getName()); // Only display buttons if the telescope is ready if(telescopeCoordP!=null && telescopeOnCoordSetP!=null){ builder.setPositiveButton(R.string.GOTO,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { try { telescopeOnCoordSetSlew.setDesiredValue(Constants.SwitchStatus.ON); telescopeOnCoordSetSync.setDesiredValue(Constants.SwitchStatus.OFF); telescopeOnCoordSetP.sendChangesToDriver(); telescopeCoordRA.setDesiredValue(coord.getRaStr()); telescopeCoordDE.setDesiredValue(coord.getDeStr()); telescopeCoordP.sendChangesToDriver(); Toast toast = Toast.makeText(ctx, ctx.getString(R.string.slew_ok), Toast.LENGTH_LONG); toast.show(); } catch (Exception e) { Toast toast = Toast.makeText(ctx, ctx.getString(R.string.sync_slew_error), Toast.LENGTH_LONG); toast.show(); } } }); builder.setNeutralButton(R.string.sync,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { try { telescopeOnCoordSetSync.setDesiredValue(Constants.SwitchStatus.ON); telescopeOnCoordSetSlew.setDesiredValue(Constants.SwitchStatus.OFF); telescopeOnCoordSetP.sendChangesToDriver(); telescopeCoordRA.setDesiredValue(coord.getRaStr()); telescopeCoordDE.setDesiredValue(coord.getDeStr()); telescopeCoordP.sendChangesToDriver(); Toast toast = Toast.makeText(ctx, ctx.getString(R.string.sync_ok), Toast.LENGTH_LONG); toast.show(); } catch (Exception e) { Toast toast = Toast.makeText(ctx, ctx.getString(R.string.sync_slew_error), Toast.LENGTH_LONG); toast.show(); } } }); } builder.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog = builder.create(); dialog.show(); } @Override public void newProperty(INDIDevice device, INDIProperty property) { // Look for properties if (property.getName().equals("ON_COORD_SET")) { telescopeOnCoordSetSlew = (INDISwitchElement) property.getElement("TRACK"); if(telescopeOnCoordSetSlew==null){telescopeOnCoordSetSync = (INDISwitchElement) property.getElement("SLEW");} telescopeOnCoordSetSync = (INDISwitchElement) property.getElement("SYNC"); if (telescopeOnCoordSetSlew != null && telescopeOnCoordSetSync != null) { property.addINDIPropertyListener(this); telescopeOnCoordSetP = (INDISwitchProperty) property; Log.i("SearchActivity", "New Property (" + property.getName() + ") added to device " + device.getName()); }else{ Log.w("SearchActivity", "Bad property: " + property.getName() + ", device: " + device.getName()); } } if (property.getName().equals("EQUATORIAL_COORD") || property.getName().equals("EQUATORIAL_EOD_COORD") ) { telescopeCoordRA = (INDINumberElement) property.getElement("RA"); telescopeCoordDE = (INDINumberElement) property.getElement("DEC"); if (telescopeCoordDE!= null && telescopeCoordRA != null) { property.addINDIPropertyListener(this); telescopeCoordP = (INDINumberProperty) property; Log.i("SearchActivity", "New Property (" + property.getName() + ") added to device " + device.getName()); }else{ Log.w("SearchActivity", "Bad property: " + property.getName() + ", device: " + device.getName()); } } } @Override public void removeProperty(INDIDevice device, INDIProperty property) { if (property.getName().equals("ON_COORD_SET")) { telescopeCoordP = null; telescopeCoordRA = null; telescopeCoordDE = null; } if (property.getName().equals("EQUATORIAL_COORD")) { telescopeOnCoordSetP = null; telescopeOnCoordSetSlew = null; telescopeOnCoordSetSync = null; } Log.d("SearchActivity", "Removed property (" + property.getName() + ") to device " + device.getName()); } @Override public void messageChanged(INDIDevice device) { } @Override public void propertyChanged(INDIProperty property) { } @Override public void newDevice(INDIServerConnection connection, INDIDevice device) { // We just simply listen to this Device Log.i("SearchActivity", getString(R.string.new_device) + device.getName()); device.addINDIDeviceListener(this); } @Override public void removeDevice(INDIServerConnection connection, INDIDevice device) { // We just remove ourselves as a listener of the removed device Log.i("SearchActivity", getString(R.string.device_removed) + device.getName()); device.removeINDIDeviceListener(this); } @Override public void connectionLost(INDIServerConnection connection) { telescopeCoordP = null; telescopeCoordRA = null; telescopeCoordDE = null; telescopeOnCoordSetP = null; telescopeOnCoordSetSlew = null; telescopeOnCoordSetSync = null; } @Override public void newMessage(INDIServerConnection connection, Date timestamp, String message) { } }