/******************************************************************************* * Gaggle is Copyright 2010 by Geeksville Industries LLC, a California limited liability corporation. * * Gaggle is distributed under a dual license. We've chosen this approach because within Gaggle we've used a number * of components that Geeksville Industries LLC might reuse for commercial products. Gaggle can be distributed under * either of the two licenses listed below. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Commercial Distribution License * If you would like to distribute Gaggle (or portions thereof) under a license other than * the "GNU General Public License, version 2", contact Geeksville Industries. Geeksville Industries reserves * the right to release Gaggle source code under a commercial license of its choice. * * GNU Public License, version 2 * All other distribution of Gaggle must conform to the terms of the GNU Public License, version 2. The full * text of this license is included in the Gaggle source, see assets/manual/gpl-2.0.txt. ******************************************************************************/ package com.geeksville.android; import android.app.AlertDialog; import android.app.ListActivity; import android.content.DialogInterface; import android.database.Cursor; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Toast; import com.flurry.android.FlurryAgent; import com.geeksville.gaggle.R; import com.geeksville.location.LocationLogDbAdapter; public abstract class DBListActivity extends ListActivity { protected Cursor myCursor; // / Should the user be shown a confirming dialog protected Boolean isConfirmDeletes = true; BaseAdapter adapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myCursor = createCursor(); startManagingCursor(myCursor); adapter = createListAdapter(); setListAdapter(adapter); // Turn on the context menu registerForContextMenu(getListView()); } /** * Collect app metrics on Flurry * * @see android.app.Activity#onStart() */ @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); FlurryAgent.onStartSession(this, "XBPNNCR4T72PEBX17GKF"); } /** * Collect app metrics on Flurry * * @see android.app.Activity#onStop() */ @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); FlurryAgent.onEndSession(this); } private void doDelete(MenuItem item) { if (handleDeleteItem(item)) { myCursor.requery(); // We just deleted a // row, it seems we need // to manually refetch the cursor Toast.makeText(this, R.string.deleted, Toast.LENGTH_SHORT).show(); } // adapter.notifyDataSetChanged(); // this // doesn't seem to do // anything } private void confirmDelete(final MenuItem item) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.confirm_delete_) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); doDelete(item); } }) .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); } /** * Handle our context menu * * @see android.app.Activity#onContextItemSelected(android.view.MenuItem) */ @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.delete_menu: if (isConfirmDeletes) confirmDelete(item); else doDelete(item); return true; case R.id.view_menu: handleViewItem(item); return true; default: break; } return super.onContextItemSelected(item); } /** * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, * android.view.View, android.view.ContextMenu.ContextMenuInfo) */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { getMenuInflater().inflate(R.menu.db_list_activity_context, menu); } /** * Create our options menu * * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) */ @Override public boolean onCreateOptionsMenu(Menu menu) { // FIXME - our menus are not yet ready return super.onCreateOptionsMenu(menu); // getMenuInflater().inflate(R.menu.logged_flight_optionmenu, menu); // return true; } /** * Given a row num, return the db id for that row * * @param rowNum * @return * */ protected long rowToRowId(int rowNum) { myCursor.moveToPosition(rowNum); long flightid = myCursor.getLong(myCursor .getColumnIndexOrThrow(LocationLogDbAdapter.KEY_ROWID)); return flightid; } /** * Find the row number for the selected context menu item * * @param item * @return */ protected int itemToRowNum(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item .getMenuInfo(); return info.position; } /** * Find the flight id for the selected context menu item * * @param item * @return */ protected long itemToRowId(MenuItem item) { return rowToRowId(itemToRowNum(item)); } /** * Generate a cursor with data for this view * * @return */ protected abstract Cursor createCursor(); /** * Generate the adapter for viewing our cursor * * @return */ protected abstract BaseAdapter createListAdapter(); /** * Called when the user wants to delete a row * * @param item * @return true if we did the deletion and should show the user a Toast */ protected abstract boolean handleDeleteItem(MenuItem item); /** * Called when the user wants to view a row * * @param item */ protected abstract void handleViewItem(MenuItem item); }