/**
* Copyright (c) 2011 Christine Gerpheide <christine.ger@pheide.com>
*
* This code is distributed under the MIT License. Please see LICENSE.txt
* for more details.
*/
package com.pheide.trainose;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.TextView;
/**
* Class which displays the list of downloaded routes.
*
* @author Christine Gerpheide
*/
public class Routes extends ListActivity {
private static final String TAG = "Routes";
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_TIMETABLES = 1;
private static final int NEW_ID = Menu.FIRST;
private static final int DELETE_ID = Menu.FIRST + 1;
private static final int SYNC_ID = Menu.FIRST + 2;
private static final int ABOUT_ID = Menu.FIRST + 3;
RoutesDbAdapter mRoutesDbAdapter;
/**
* Initialize this view
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.routes_list);
mRoutesDbAdapter = new RoutesDbAdapter(this);
mRoutesDbAdapter.open();
this.populateList();
this.registerForContextMenu(this.getListView());
}
/* Lists */
/**
* Populate the view with a list of all stored routes.
*/
private void populateList() {
Cursor routesCursor = mRoutesDbAdapter.fetchAll();
this.startManagingCursor(routesCursor);
String[] from = new String[]{RoutesDbAdapter.KEY_SOURCE, RoutesDbAdapter.KEY_DESTINATION};
int[] to = new int[]{R.id.source, R.id.destination};
SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.routes_row, routesCursor, from, to);
this.setListAdapter(notes);
}
/**
* Handler for when a route is clicked.
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
this.showTimetables(id);
}
/* Context menu */
/**
* Build the context menu for a route.
*/
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.ctxmenu_delete_route);
}
/**
* Handler for when a route's context menu item is clicked.
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mRoutesDbAdapter.delete(info.id);
this.populateList();
return true;
}
return super.onContextItemSelected(item);
}
/* Options menu */
/**
* Build the options menu for routes.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, NEW_ID, 0, R.string.optmenu_new_route);
menu.add(0, SYNC_ID, 0, R.string.optmenu_sync_all);
menu.add(0, ABOUT_ID, 0, R.string.optmenu_about);
return true;
}
/**
* Handler for when an option menu item is pressed.
*/
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case NEW_ID:
this.showNewRoute();
return true;
case SYNC_ID:
this.syncAllRoutes();
return true;
case ABOUT_ID:
this.showAbout();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
/**
* Start a new activity to show the timetables for a route.
*
* @param long the routeId to show timetables for
*/
private void showTimetables(long routeId) {
Intent i = new Intent(this, Timetables.class);
i.putExtra(RoutesDbAdapter.KEY_ROWID, routeId);
this.startActivityForResult(i, ACTIVITY_TIMETABLES);
}
/**
* Start a new activity to create a new route.
*/
private void showNewRoute() {
Intent i = new Intent(this, RouteEdit.class);
this.startActivityForResult(i, ACTIVITY_CREATE);
}
/**
* Show a dialog with info about this application.
*/
private void showAbout() { //TODO put these in some kind of "view"
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.about_dialog);
dialog.setTitle(R.string.app_desc_title);
TextView versionTextView = (TextView) dialog.findViewById(R.id.version);
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(getApplicationInfo().packageName, 0);
versionTextView.setText(packageInfo.versionName + " ("
+ this.getString(R.string.build_number) + " " + packageInfo.versionCode + ")");
TextView appDescTextView = (TextView) dialog.findViewById(R.id.app_desc);
ViewHelper.linkifyTextView(this, appDescTextView, R.string.app_desc);
TextView moreInfoTextView = (TextView) dialog.findViewById(R.id.more_info);
ViewHelper.linkifyTextView(this,moreInfoTextView, R.string.app_moreinfo);
} catch (NameNotFoundException e) {
// TODO Log error
}
dialog.show();
}
/**
* Initiate a background task that will cycle through each route
* and synchronize it.
*/
private void syncAllRoutes() {
new AsyncTask<Void, Void, Void>() {
ProgressDialog mDialog;
protected void onPreExecute() {
mDialog = ProgressDialog.show(Routes.this, "",
Routes.this.getString(R.string.sync_in_progress), true);
}
protected Void doInBackground(Void... params){
try {
Cursor routesCursor = mRoutesDbAdapter.fetchAll();
Routes.this.startManagingCursor(routesCursor);
int routeIdIdx = routesCursor.getColumnIndex(RoutesDbAdapter.KEY_ROWID);
for (routesCursor.moveToFirst(); routesCursor.isAfterLast() == false;
routesCursor.moveToNext()) {
long routeId = routesCursor.getLong(routeIdIdx);
TimetablesSynchronizer timetablesSynchronizer = new TimetablesSynchronizer(Routes.this);
timetablesSynchronizer.syncTimetablesForRoute(routeId);
}
routesCursor.close();
} catch (Exception e) {
Log.e(TAG, "Exception syncing routes", e);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
mDialog.dismiss();
Routes.this.populateList();
}
}.execute();
}
/* Activity methods */
/**
* Handle when a view returns to this view.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch(requestCode) {
case ACTIVITY_CREATE:
if (resultCode == RESULT_OK) {
Bundle extras = intent.getExtras();
long routeId = extras != null ? extras.getLong(RoutesDbAdapter.KEY_ROWID) : null;
showTimetables(routeId);
}
}
}
}