/*
* Copyright (C) 2014 Paul Watts (paulcwatts@gmail.com),
* University of South Florida (sjbarbeau@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.android.ui;
import org.onebusaway.android.R;
import org.onebusaway.android.io.ObaAnalytics;
import org.onebusaway.android.provider.ObaContract;
import org.onebusaway.android.tripservice.TripService;
import org.onebusaway.android.util.UIUtils;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.ContextMenu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
public final class MyRemindersFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<Cursor> {
public static final String TAG = "MyRemindersFragment";
private static final String[] PROJECTION = {
ObaContract.Trips._ID,
ObaContract.Trips.NAME,
ObaContract.Trips.HEADSIGN,
ObaContract.Trips.DEPARTURE,
ObaContract.Trips.ROUTE_ID,
ObaContract.Trips.STOP_ID
};
private static final int COL_ID = 0;
private static final int COL_NAME = 1;
private static final int COL_HEADSIGN = 2;
private static final int COL_DEPARTURE = 3;
private static final int COL_ROUTE_ID = 4;
private static final int COL_STOP_ID = 5;
private static final Handler mHandler = new Handler();
private class Observer extends ContentObserver {
Observer() {
super(mHandler);
}
@Override
public boolean deliverSelfNotifications() {
return false;
}
public void onChange(boolean selfChange) {
if (isAdded()) {
getLoaderManager().restartLoader(0, null, MyRemindersFragment.this);
}
}
}
private SimpleCursorAdapter mAdapter;
private Observer mObserver;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Set empty text
setEmptyText(getString(R.string.trip_list_notrips));
registerForContextMenu(getListView());
// Create our generic adapter
mAdapter = newAdapter();
setListAdapter(mAdapter);
ContentResolver cr = getActivity().getContentResolver();
mObserver = new Observer();
cr.registerContentObserver(ObaContract.Trips.CONTENT_URI, true, mObserver);
// Prepare the loader
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onStart() {
ObaAnalytics.reportFragmentStart(this);
super.onStart();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ListView listView = getListView();
listView.setBackgroundColor(getResources().getColor(R.color.listview_background));
}
@Override
public void onDestroy() {
if (mObserver != null) {
ContentResolver cr = getActivity().getContentResolver();
cr.unregisterContentObserver(mObserver);
mObserver = null;
}
super.onDestroy();
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
ObaContract.Trips.CONTENT_URI,
PROJECTION,
null,
null,
ObaContract.Trips.NAME + " asc");
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
private SimpleCursorAdapter newAdapter() {
final String[] from = {
ObaContract.Trips.NAME,
ObaContract.Trips.HEADSIGN,
ObaContract.Trips.DEPARTURE,
ObaContract.Trips.ROUTE_ID
};
final int[] to = {
R.id.name,
R.id.headsign,
R.id.departure_time,
R.id.route_name
};
SimpleCursorAdapter simpleAdapter =
new SimpleCursorAdapter(getActivity(), R.layout.trip_list_listitem, null, from,
to, 0);
simpleAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view,
Cursor cursor,
int columnIndex) {
if (columnIndex == COL_NAME) {
TextView text = (TextView) view;
String name = cursor.getString(columnIndex);
if (name.length() == 0) {
name = getString(R.string.trip_info_noname);
}
text.setText(name);
return true;
} else if (columnIndex == COL_HEADSIGN) {
String headSign = cursor.getString(columnIndex);
TextView text = (TextView) view;
text.setText(UIUtils.formatDisplayText(headSign));
return true;
} else if (columnIndex == COL_DEPARTURE) {
TextView text = (TextView) view;
text.setText(TripInfoActivity.getDepartureTime(
getActivity(),
ObaContract.Trips.convertDBToTime(cursor
.getInt(columnIndex))
));
return true;
} else if (columnIndex == COL_ROUTE_ID) {
//
// Translate the Route ID into the Route Name by looking
// it up in the Routes table.
//
TextView text = (TextView) view;
final String routeId = cursor.getString(columnIndex);
final String routeName = TripService.getRouteShortName(
getActivity(), routeId);
if (routeName != null) {
text.setText(getString(R.string.trip_info_route,
routeName));
}
return true;
}
return false;
}
});
return simpleAdapter;
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String[] ids = getIds(l, position);
TripInfoActivity.start(getActivity(), ids[0], ids[1]);
}
private static final int CONTEXT_MENU_DEFAULT = 1;
private static final int CONTEXT_MENU_DELETE = 2;
private static final int CONTEXT_MENU_SHOWSTOP = 3;
private static final int CONTEXT_MENU_SHOWROUTE = 4;
@Override
public void onCreateContextMenu(ContextMenu menu,
View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
final TextView text = (TextView) info.targetView.findViewById(R.id.name);
menu.setHeaderTitle(text.getText());
menu.add(0, CONTEXT_MENU_DEFAULT, 0, R.string.trip_list_context_edit);
menu.add(0, CONTEXT_MENU_DELETE, 0, R.string.trip_list_context_delete);
menu.add(0, CONTEXT_MENU_SHOWSTOP, 0,
R.string.trip_list_context_showstop);
menu.add(0, CONTEXT_MENU_SHOWROUTE, 0,
R.string.trip_list_context_showroute);
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
switch (item.getItemId()) {
case CONTEXT_MENU_DEFAULT:
// Fake a click
onListItemClick(getListView(), info.targetView, info.position,
info.id);
return true;
case CONTEXT_MENU_DELETE:
deleteTrip(getListView(), info.position);
return true;
case CONTEXT_MENU_SHOWSTOP:
goToStop(getListView(), info.position);
return true;
case CONTEXT_MENU_SHOWROUTE:
goToRoute(getListView(), info.position);
return true;
default:
return super.onContextItemSelected(item);
}
}
private void deleteTrip(ListView l, int position) {
String[] ids = getIds(l, position);
// TODO: Confirmation dialog?
ContentResolver cr = getActivity().getContentResolver();
cr.delete(ObaContract.Trips.buildUri(ids[0], ids[1]), null, null);
TripService.scheduleAll(getActivity());
getLoaderManager().getLoader(0).onContentChanged();
}
private void goToStop(ListView l, int position) {
String[] ids = getIds(l, position);
ArrivalsListActivity.start(getActivity(), ids[1]);
}
private void goToRoute(ListView l, int position) {
String[] ids = getIds(l, position);
RouteInfoActivity.start(getActivity(), ids[2]);
}
private String[] getIds(ListView l, int position) {
// Get the cursor and fetch the stop ID from that.
SimpleCursorAdapter cursorAdapter = (SimpleCursorAdapter) l.getAdapter();
final Cursor c = cursorAdapter.getCursor();
c.moveToPosition(position - l.getHeaderViewsCount());
final String[] result = new String[]{
c.getString(COL_ID),
c.getString(COL_STOP_ID),
c.getString(COL_ROUTE_ID)
};
return result;
}
}