diff --git a/.classpath b/.classpath index 42ddf22..4b421f7 100644 --- a/.classpath +++ b/.classpath @@ -6,6 +6,5 @@ - diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e25dc53..e2c4b81 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="20" + android:versionName="2.0.2" > @@ -41,30 +41,6 @@ - - - - - - - - - - - - - - - - - - diff --git a/res/layout/departures.xml b/res/layout/departures.xml index 85f61b8..baa2a05 100644 --- a/res/layout/departures.xml +++ b/res/layout/departures.xml @@ -92,7 +92,7 @@ + android:layout_weight="1" + android:visibility="gone" /> - - - - - - - \ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml index f7184e4..d99f709 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -11,6 +11,30 @@ 10dp + + + + + + - - - + \ No newline at end of file diff --git a/src/com/dougkeen/bart/AbstractRouteSelectionActivity.java b/src/com/dougkeen/bart/AbstractRouteSelectionActivity.java deleted file mode 100644 index 4d1d529..0000000 --- a/src/com/dougkeen/bart/AbstractRouteSelectionActivity.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.dougkeen.bart; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.Spinner; -import android.widget.Toast; - -import com.dougkeen.bart.model.Station; - -public abstract class AbstractRouteSelectionActivity extends Activity { - - public AbstractRouteSelectionActivity() { - super(); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.route_form); - - ArrayAdapter originSpinnerAdapter = new ArrayAdapter( - this, android.R.layout.simple_spinner_item, - Station.getStationList()); - originSpinnerAdapter - .setDropDownViewResource(R.layout.simple_spinner_dropdown_item); - ((Spinner) findViewById(R.id.origin_spinner)) - .setAdapter(originSpinnerAdapter); - - ArrayAdapter destinationSpinnerAdapter = new ArrayAdapter( - this, android.R.layout.simple_spinner_item, - Station.getStationList()); - destinationSpinnerAdapter - .setDropDownViewResource(R.layout.simple_spinner_dropdown_item); - - ((Spinner) findViewById(R.id.destination_spinner)) - .setAdapter(destinationSpinnerAdapter); - - Button okButton = (Button) findViewById(R.id.okButton); - okButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - Station origin = (Station) ((Spinner) findViewById(R.id.origin_spinner)) - .getSelectedItem(); - Station destination = (Station) ((Spinner) findViewById(R.id.destination_spinner)) - .getSelectedItem(); - if (origin == null) { - Toast.makeText(v.getContext(), - com.dougkeen.bart.R.string.error_null_origin, - Toast.LENGTH_LONG).show(); - return; - } - if (destination == null) { - Toast.makeText(v.getContext(), - com.dougkeen.bart.R.string.error_null_destination, - Toast.LENGTH_LONG).show(); - return; - } - if (origin.equals(destination)) { - Toast.makeText( - v.getContext(), - com.dougkeen.bart.R.string.error_matching_origin_and_destination, - Toast.LENGTH_LONG).show(); - return; - } - onOkButtonClick(origin, destination); - } - - }); - - Button cancelButton = (Button) findViewById(R.id.cancelButton); - cancelButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - setResult(RESULT_CANCELED); - finish(); - } - }); - - } - - abstract protected void onOkButtonClick(Station origin, Station destination); -} \ No newline at end of file diff --git a/src/com/dougkeen/bart/AbstractRouteSelectionFragment.java b/src/com/dougkeen/bart/AbstractRouteSelectionFragment.java new file mode 100644 index 0000000..7ac448c --- /dev/null +++ b/src/com/dougkeen/bart/AbstractRouteSelectionFragment.java @@ -0,0 +1,102 @@ +package com.dougkeen.bart; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentActivity; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.Toast; + +import com.WazaBe.HoloEverywhere.AlertDialog; +import com.dougkeen.bart.model.Station; + +public abstract class AbstractRouteSelectionFragment extends DialogFragment { + + protected String mTitle; + + public AbstractRouteSelectionFragment(String title) { + super(); + mTitle = title; + } + + @Override + public void onStart() { + super.onStart(); + + final Dialog dialog = getDialog(); + final FragmentActivity activity = getActivity(); + ArrayAdapter originSpinnerAdapter = new ArrayAdapter( + activity, android.R.layout.simple_spinner_item, + Station.getStationList()); + originSpinnerAdapter + .setDropDownViewResource(R.layout.simple_spinner_dropdown_item); + ((Spinner) dialog.findViewById(R.id.origin_spinner)) + .setAdapter(originSpinnerAdapter); + + ArrayAdapter destinationSpinnerAdapter = new ArrayAdapter( + activity, android.R.layout.simple_spinner_item, + Station.getStationList()); + destinationSpinnerAdapter + .setDropDownViewResource(R.layout.simple_spinner_dropdown_item); + + ((Spinner) dialog.findViewById(R.id.destination_spinner)) + .setAdapter(destinationSpinnerAdapter); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final FragmentActivity activity = getActivity(); + + return new AlertDialog.Builder(activity) + .setTitle(mTitle) + .setCancelable(true) + .setView(R.layout.route_form) + .setPositiveButton(R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + handleOkClick(); + } + }) + .setNegativeButton(R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int whichButton) { + dialog.cancel(); + } + }).create(); + } + + protected void handleOkClick() { + final Dialog dialog = getDialog(); + Station origin = (Station) ((Spinner) dialog + .findViewById(R.id.origin_spinner)).getSelectedItem(); + Station destination = (Station) ((Spinner) dialog + .findViewById(R.id.destination_spinner)).getSelectedItem(); + if (origin == null) { + Toast.makeText(dialog.getContext(), + com.dougkeen.bart.R.string.error_null_origin, + Toast.LENGTH_LONG).show(); + return; + } + if (destination == null) { + Toast.makeText(dialog.getContext(), + com.dougkeen.bart.R.string.error_null_destination, + Toast.LENGTH_LONG).show(); + return; + } + if (origin.equals(destination)) { + Toast.makeText( + dialog.getContext(), + com.dougkeen.bart.R.string.error_matching_origin_and_destination, + Toast.LENGTH_LONG).show(); + return; + } + onOkButtonClick(origin, destination); + } + + abstract protected void onOkButtonClick(Station origin, Station destination); +} \ No newline at end of file diff --git a/src/com/dougkeen/bart/AddRouteActivity.java b/src/com/dougkeen/bart/AddRouteDialogFragment.java similarity index 60% rename from src/com/dougkeen/bart/AddRouteActivity.java rename to src/com/dougkeen/bart/AddRouteDialogFragment.java index 906b7ca..c4e92d1 100644 --- a/src/com/dougkeen/bart/AddRouteActivity.java +++ b/src/com/dougkeen/bart/AddRouteDialogFragment.java @@ -1,9 +1,7 @@ package com.dougkeen.bart; import android.content.ContentValues; -import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.view.View; import android.widget.CheckBox; @@ -11,12 +9,17 @@ import com.dougkeen.bart.data.RoutesColumns; import com.dougkeen.bart.model.Constants; import com.dougkeen.bart.model.Station; -public class AddRouteActivity extends AbstractRouteSelectionActivity { +public class AddRouteDialogFragment extends AbstractRouteSelectionFragment { + public AddRouteDialogFragment(String title) { + super(title); + } + @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final View checkboxText = findViewById(R.id.return_checkbox_text); - final View checkbox = findViewById(R.id.return_checkbox); + public void onStart() { + super.onStart(); + final View checkboxText = getDialog().findViewById( + R.id.return_checkbox_text); + final View checkbox = getDialog().findViewById(R.id.return_checkbox); checkboxText.setVisibility(View.VISIBLE); checkbox.setVisibility(View.VISIBLE); checkboxText.setOnClickListener(new View.OnClickListener() { @@ -33,19 +36,21 @@ public class AddRouteActivity extends AbstractRouteSelectionActivity { values.put(RoutesColumns.FROM_STATION.string, origin.abbreviation); values.put(RoutesColumns.TO_STATION.string, destination.abbreviation); - Uri newUri = getContentResolver().insert( + Uri newUri = getActivity().getContentResolver().insert( Constants.FAVORITE_CONTENT_URI, values); - if (((CheckBox) findViewById(R.id.return_checkbox)).isChecked()) { + if (((CheckBox) getDialog().findViewById(R.id.return_checkbox)) + .isChecked()) { values = new ContentValues(); values.put(RoutesColumns.FROM_STATION.string, destination.abbreviation); values.put(RoutesColumns.TO_STATION.string, origin.abbreviation); - getContentResolver().insert(Constants.FAVORITE_CONTENT_URI, values); + getActivity().getContentResolver().insert( + Constants.FAVORITE_CONTENT_URI, values); } - setResult(RESULT_OK, (new Intent()).setAction(newUri.toString())); - finish(); + dismiss(); } + } diff --git a/src/com/dougkeen/bart/QuickRouteActivity.java b/src/com/dougkeen/bart/QuickRouteDialogFragment.java similarity index 71% rename from src/com/dougkeen/bart/QuickRouteActivity.java rename to src/com/dougkeen/bart/QuickRouteDialogFragment.java index 605194c..42f1558 100644 --- a/src/com/dougkeen/bart/QuickRouteActivity.java +++ b/src/com/dougkeen/bart/QuickRouteDialogFragment.java @@ -5,7 +5,11 @@ import android.content.Intent; import com.dougkeen.bart.model.Constants; import com.dougkeen.bart.model.Station; -public class QuickRouteActivity extends AbstractRouteSelectionActivity { +public class QuickRouteDialogFragment extends AbstractRouteSelectionFragment { + + public QuickRouteDialogFragment(String title) { + super(title); + } @Override protected void onOkButtonClick(Station origin, Station destination) { diff --git a/src/com/dougkeen/bart/RoutesListActivity.java b/src/com/dougkeen/bart/RoutesListActivity.java index 6a97a9a..63cb67e 100644 --- a/src/com/dougkeen/bart/RoutesListActivity.java +++ b/src/com/dougkeen/bart/RoutesListActivity.java @@ -3,8 +3,6 @@ package com.dougkeen.bart; import java.util.Calendar; import java.util.TimeZone; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.ContentUris; import android.content.ContentValues; @@ -14,15 +12,20 @@ import android.database.Cursor; import android.database.CursorWrapper; import android.net.Uri; import android.os.Bundle; +import android.support.v4.app.DialogFragment; import android.view.View; import android.widget.AdapterView; import android.widget.Button; +import android.widget.CursorAdapter; +import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.SimpleCursorAdapter.ViewBinder; import android.widget.TextView; -import com.actionbarsherlock.app.SherlockListActivity; +import com.WazaBe.HoloEverywhere.AlertDialog; +import com.WazaBe.HoloEverywhere.AlertDialog.Builder; +import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.view.ActionMode; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; @@ -33,11 +36,11 @@ import com.dougkeen.bart.model.Constants; import com.dougkeen.bart.model.Station; import com.dougkeen.bart.networktasks.GetRouteFareTask; -public class RoutesListActivity extends SherlockListActivity { +public class RoutesListActivity extends SherlockFragmentActivity { private static final TimeZone PACIFIC_TIME = TimeZone .getTimeZone("America/Los_Angeles"); - private static final int DIALOG_DELETE_EVENT = 0; + private static final int DIALOG_DELETE_ROUTE = 0; protected Cursor mQuery; @@ -89,7 +92,19 @@ public class RoutesListActivity extends SherlockListActivity { }); setListAdapter(adapter); + getListView().setOnItemClickListener( + new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView l, View v, + int position, long id) { + startActivity(new Intent(Intent.ACTION_VIEW, + ContentUris.withAppendedId( + Constants.FAVORITE_CONTENT_URI, id))); + } + + }); + getListView().setEmptyView(findViewById(android.R.id.empty)); getListView().setOnItemLongClickListener( new AdapterView.OnItemLongClickListener() { @Override @@ -120,8 +135,9 @@ public class RoutesListActivity extends SherlockListActivity { .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - startActivity(new Intent(Intent.ACTION_PICK, - Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT)); + DialogFragment dialog = new QuickRouteDialogFragment( + getString(R.string.quick_departure_lookup)); + dialog.show(getSupportFragmentManager(), "dialog"); } }); @@ -146,6 +162,22 @@ public class RoutesListActivity extends SherlockListActivity { } } + @SuppressWarnings("unchecked") + private AdapterView getListView() { + return (AdapterView) findViewById(android.R.id.list); + } + + private CursorAdapter mListAdapter; + + protected CursorAdapter getListAdapter() { + return mListAdapter; + } + + protected void setListAdapter(SimpleCursorAdapter adapter) { + mListAdapter = adapter; + getListView().setAdapter(mListAdapter); + } + private void refreshFares() { if (mQuery.moveToFirst()) { do { @@ -222,8 +254,8 @@ public class RoutesListActivity extends SherlockListActivity { public boolean onOptionsItemSelected(MenuItem item) { int itemId = item.getItemId(); if (itemId == R.id.add_favorite_menu_button) { - startActivity(new Intent(Intent.ACTION_INSERT, - Constants.FAVORITE_CONTENT_URI)); + new AddRouteDialogFragment(getString(R.string.add_route)).show( + getSupportFragmentManager(), "dialog"); return true; } else if (itemId == R.id.view_system_map_button) { startActivity(new Intent(this, ViewMapActivity.class)); @@ -233,41 +265,6 @@ public class RoutesListActivity extends SherlockListActivity { } } - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - startActivity(new Intent(Intent.ACTION_VIEW, - ContentUris.withAppendedId(Constants.FAVORITE_CONTENT_URI, id))); - } - - @Override - protected Dialog onCreateDialog(int id) { - if (id == DIALOG_DELETE_EVENT && mCurrentlySelectedUri != null) { - final AlertDialog.Builder builder = new Builder(this); - builder.setCancelable(false); - builder.setMessage("Are you sure you want to delete this route?"); - builder.setPositiveButton(R.string.yes, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - getContentResolver().delete(mCurrentlySelectedUri, - null, null); - mCurrentlySelectedUri = null; - mCurrentlySelectedOrigin = null; - mCurrentlySelectedDestination = null; - mActionMode.finish(); - removeDialog(DIALOG_DELETE_EVENT); - } - }); - builder.setNegativeButton(R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - removeDialog(DIALOG_DELETE_EVENT); - } - }); - return builder.create(); - } - return super.onCreateDialog(id); - } - private void startContextualActionMode() { mActionMode = startActionMode(new RouteActionMode()); mActionMode.setTitle(mCurrentlySelectedOrigin.name); @@ -275,7 +272,6 @@ public class RoutesListActivity extends SherlockListActivity { } private final class RouteActionMode implements ActionMode.Callback { - @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.getMenuInflater().inflate(R.menu.route_context_menu, menu); @@ -295,7 +291,31 @@ public class RoutesListActivity extends SherlockListActivity { mode.finish(); return true; } else if (item.getItemId() == R.id.delete) { - showDialog(DIALOG_DELETE_EVENT); + final AlertDialog.Builder builder = new AlertDialog.Builder( + RoutesListActivity.this); + builder.setCancelable(false); + builder.setMessage("Are you sure you want to delete this route?"); + builder.setPositiveButton(R.string.yes, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + getContentResolver().delete( + mCurrentlySelectedUri, null, null); + mCurrentlySelectedUri = null; + mCurrentlySelectedOrigin = null; + mCurrentlySelectedDestination = null; + mActionMode.finish(); + dialog.dismiss(); + } + }); + builder.setNegativeButton(R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + dialog.cancel(); + } + }); + builder.show(); return false; } diff --git a/src/com/dougkeen/bart/ViewDeparturesActivity.java b/src/com/dougkeen/bart/ViewDeparturesActivity.java index 96e5cba..af9c6bf 100644 --- a/src/com/dougkeen/bart/ViewDeparturesActivity.java +++ b/src/com/dougkeen/bart/ViewDeparturesActivity.java @@ -48,6 +48,8 @@ public class ViewDeparturesActivity extends SherlockListActivity { private static final int UNCERTAINTY_THRESHOLD = 17; + private static final int DIALOG_SET_ALERT = 1; + private Uri mUri; private Station mOrigin; diff --git a/src/com/dougkeen/bart/model/Departure.java b/src/com/dougkeen/bart/model/Departure.java index b31e5d7..553a824 100644 --- a/src/com/dougkeen/bart/model/Departure.java +++ b/src/com/dougkeen/bart/model/Departure.java @@ -41,6 +41,7 @@ public class Departure implements Parcelable, Comparable { private boolean bikeAllowed; private String trainLength; private boolean requiresTransfer; + private boolean transferScheduled; private int minutes; @@ -141,6 +142,14 @@ public class Departure implements Parcelable, Comparable { this.requiresTransfer = requiresTransfer; } + public boolean isTransferScheduled() { + return transferScheduled; + } + + public void setTransferScheduled(boolean transferScheduled) { + this.transferScheduled = transferScheduled; + } + public int getMinutes() { return minutes; } diff --git a/src/com/dougkeen/bart/model/RealTimeDepartures.java b/src/com/dougkeen/bart/model/RealTimeDepartures.java index 60341ed..8a4495c 100644 --- a/src/com/dougkeen/bart/model/RealTimeDepartures.java +++ b/src/com/dougkeen/bart/model/RealTimeDepartures.java @@ -2,6 +2,7 @@ package com.dougkeen.bart.model; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; public class RealTimeDepartures { @@ -89,6 +90,9 @@ public class RealTimeDepartures { if (route.trainDestinationIsApplicable(destination, departure.getLine())) { departure.setRequiresTransfer(route.hasTransfer()); + departure + .setTransferScheduled(Line.YELLOW_ORANGE_SCHEDULED_TRANSFER + .equals(route.getDirectLine())); getDepartures().add(departure); departure.calculateEstimates(time); return; @@ -100,6 +104,29 @@ public class RealTimeDepartures { Collections.sort(getDepartures()); } + public void finalizeDeparturesList() { + boolean hasDirectRoute = false; + for (Departure departure : getDepartures()) { + if (!departure.getRequiresTransfer()) { + hasDirectRoute = true; + break; + } + } + if (hasDirectRoute) { + Iterator iterator = getDepartures().iterator(); + while (iterator.hasNext()) { + Departure departure = iterator.next(); + if (departure.getRequiresTransfer() + && (!departure.isTransferScheduled() || departure + .getDestination().isBetween(getOrigin(), + getDestination(), departure.getLine()))) { + iterator.remove(); + } + } + } + sortDepartures(); + } + public List getRoutes() { return routes; } diff --git a/src/com/dougkeen/bart/model/Station.java b/src/com/dougkeen/bart/model/Station.java index 06c3f59..9874fe7 100644 --- a/src/com/dougkeen/bart/model/Station.java +++ b/src/com/dougkeen/bart/model/Station.java @@ -257,4 +257,16 @@ public enum Station { public String toString() { return name; } + + public boolean isBetween(Station origin, Station destination, Line line) { + int originIndex = line.stations.indexOf(origin); + int destinationIndex = line.stations.indexOf(destination); + int stationIndex = line.stations.indexOf(this); + if (originIndex < 0 || destinationIndex < 0 || stationIndex < 0) { + return false; + } + + return Math.abs(stationIndex - originIndex) < Math.abs(destinationIndex + - originIndex); + } } diff --git a/src/com/dougkeen/bart/networktasks/EtdContentHandler.java b/src/com/dougkeen/bart/networktasks/EtdContentHandler.java index 276ec67..d310ae0 100644 --- a/src/com/dougkeen/bart/networktasks/EtdContentHandler.java +++ b/src/com/dougkeen/bart/networktasks/EtdContentHandler.java @@ -115,7 +115,7 @@ public class EtdContentHandler extends DefaultHandler { } else if (localName.equals("etd")) { currentDestination = null; } else if (localName.equals("station")) { - realTimeDepartures.sortDepartures(); + realTimeDepartures.finalizeDeparturesList(); } isParsingTag = false; currentValue = null;