Merge pull request #174 from sbosley/120302_sb_swipe_lists_subtasks

Swipe between lists! Woooo
pull/14/head
Tim Su 13 years ago
commit 0f13cf01f7

@ -54,7 +54,13 @@ public class Filter extends FilterListItem {
* metadata.value = 'b' GROUP BY tasks.id ORDER BY tasks.title"</code> * metadata.value = 'b' GROUP BY tasks.id ORDER BY tasks.title"</code>
* </ul> * </ul>
*/ */
public String sqlQuery; protected String sqlQuery;
/**
* Field for holding a modified sqlQuery based on sqlQuery. Useful for adjusting
* query for sort/subtasks without breaking the equality checking based on sqlQuery.
*/
protected String filterOverride;
/** /**
* Values to apply to a task when quick-adding a task from this filter. * Values to apply to a task when quick-adding a task from this filter.
@ -99,9 +105,24 @@ public class Filter extends FilterListItem {
this.listingTitle = listingTitle; this.listingTitle = listingTitle;
this.title = title; this.title = title;
this.sqlQuery = sqlQuery; this.sqlQuery = sqlQuery;
this.filterOverride = null;
this.valuesForNewTasks = valuesForNewTasks; this.valuesForNewTasks = valuesForNewTasks;
} }
public String getSqlQuery() {
if (filterOverride != null)
return filterOverride;
return sqlQuery;
}
public void setSqlQuery(String sqlQuery) {
this.sqlQuery = sqlQuery;
}
public void setFilterOverrideQuery(String filterOverride) {
this.filterOverride = filterOverride;
}
/** /**
* Utility constructor * Utility constructor
* *

@ -235,7 +235,7 @@ public class C2DMReceiver extends BroadcastReceiver {
} }
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notifyIntent.putExtra(TaskListFragment.TOKEN_SOURCE, Constants.SOURCE_C2DM); notifyIntent.putExtra(TaskListActivity.TOKEN_SOURCE, Constants.SOURCE_C2DM);
PendingIntent pendingIntent = PendingIntent.getActivity(context, PendingIntent pendingIntent = PendingIntent.getActivity(context,
notifId, notifyIntent, 0); notifId, notifyIntent, 0);

@ -309,7 +309,7 @@ public class TagUpdatesFragment extends ListFragment {
private void refreshActivity(boolean manual) { private void refreshActivity(boolean manual) {
if (actFmPreferenceService.isLoggedIn()) { if (actFmPreferenceService.isLoggedIn()) {
final ProgressBarSyncResultCallback callback = new ProgressBarSyncResultCallback( final ProgressBarSyncResultCallback callback = new ProgressBarSyncResultCallback(
getActivity(), R.id.comments_progressBar, new Runnable() { getActivity(), this, R.id.comments_progressBar, new Runnable() {
@Override @Override
public void run() { public void run() {
refreshUpdatesList(); refreshUpdatesList();

@ -179,8 +179,8 @@ public class TagViewFragment extends TaskListFragment {
} }
TaskListActivity activity = (TaskListActivity) getActivity(); TaskListActivity activity = (TaskListActivity) getActivity();
String tag = activity.getIntent().getStringExtra(EXTRA_TAG_NAME); String tag = extras.getString(EXTRA_TAG_NAME);
long remoteId = activity.getIntent().getLongExtra(EXTRA_TAG_REMOTE_ID, 0); long remoteId = extras.getLong(EXTRA_TAG_REMOTE_ID, 0);
if(tag == null && remoteId == 0) if(tag == null && remoteId == 0)
return; return;
@ -206,8 +206,8 @@ public class TagViewFragment extends TaskListFragment {
super.onNewIntent(intent); super.onNewIntent(intent);
if (activity.getIntent().getBooleanExtra(TOKEN_START_ACTIVITY, false)) { if (extras.getBoolean(TOKEN_START_ACTIVITY, false)) {
activity.getIntent().removeExtra(TOKEN_START_ACTIVITY); extras.remove(TOKEN_START_ACTIVITY);
activity.showComments(); activity.showComments();
} }
} }
@ -238,6 +238,11 @@ public class TagViewFragment extends TaskListFragment {
updateCommentCount(); updateCommentCount();
} }
@Override
public void requestCommentCountUpdate() {
updateCommentCount();
}
private void updateCommentCount() { private void updateCommentCount() {
if (tagData != null) { if (tagData != null) {
long lastViewedComments = Preferences.getLong(TagUpdatesFragment.UPDATES_LAST_VIEWED + tagData.getValue(TagData.REMOTE_ID), 0); long lastViewedComments = Preferences.getLong(TagUpdatesFragment.UPDATES_LAST_VIEWED + tagData.getValue(TagData.REMOTE_ID), 0);
@ -258,7 +263,9 @@ public class TagViewFragment extends TaskListFragment {
@Override @Override
protected void initiateAutomaticSync() { public void initiateAutomaticSync() {
if (!isCurrentTaskListFragment())
return;
if (tagData != null) { if (tagData != null) {
long lastAutoSync = Preferences.getLong(LAST_FETCH_KEY + tagData.getId(), 0); long lastAutoSync = Preferences.getLong(LAST_FETCH_KEY + tagData.getId(), 0);
if(DateUtilities.now() - lastAutoSync > DateUtilities.ONE_HOUR) if(DateUtilities.now() - lastAutoSync > DateUtilities.ONE_HOUR)
@ -270,7 +277,7 @@ public class TagViewFragment extends TaskListFragment {
private void refreshData(final boolean manual) { private void refreshData(final boolean manual) {
((TextView)taskListView.findViewById(android.R.id.empty)).setText(R.string.DLG_loading); ((TextView)taskListView.findViewById(android.R.id.empty)).setText(R.string.DLG_loading);
syncService.synchronizeList(tagData, manual, new ProgressBarSyncResultCallback(getActivity(), syncService.synchronizeList(tagData, manual, new ProgressBarSyncResultCallback(getActivity(), this,
R.id.progressBar, new Runnable() { R.id.progressBar, new Runnable() {
@Override @Override
public void run() { public void run() {
@ -468,6 +475,7 @@ public class TagViewFragment extends TaskListFragment {
return; return;
filter = TagFilterExposer.filterFromTagData(getActivity(), tagData); filter = TagFilterExposer.filterFromTagData(getActivity(), tagData);
getActivity().getIntent().putExtra(TOKEN_FILTER, filter); getActivity().getIntent().putExtra(TOKEN_FILTER, filter);
extras.putParcelable(TOKEN_FILTER, filter);
Activity activity = getActivity(); Activity activity = getActivity();
if (activity instanceof TaskListActivity) { if (activity instanceof TaskListActivity) {
((TaskListActivity) activity).setListsTitle(filter.title); ((TaskListActivity) activity).setListsTitle(filter.title);

@ -22,7 +22,6 @@ import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.AstridFilterExposer; import com.todoroo.astrid.api.AstridFilterExposer;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
@ -72,7 +71,6 @@ public class GtasksFilterExposer extends BroadcastReceiver implements AstridFilt
filter.listingIcon = ((BitmapDrawable)context.getResources().getDrawable(R.drawable.gtasks_icon)).getBitmap(); filter.listingIcon = ((BitmapDrawable)context.getResources().getDrawable(R.drawable.gtasks_icon)).getBitmap();
filter.customTaskList = new ComponentName(ContextManager.getContext(), GtasksListFragment.class); filter.customTaskList = new ComponentName(ContextManager.getContext(), GtasksListFragment.class);
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putBoolean(TaskListFragment.TOKEN_OVERRIDE_ANIM, true);
extras.putLong(GtasksListFragment.TOKEN_STORE_ID, list.getId()); extras.putLong(GtasksListFragment.TOKEN_STORE_ID, list.getId());
filter.customExtras = extras; filter.customExtras = extras;

@ -70,7 +70,9 @@ public class GtasksListFragment extends SubtasksListFragment {
} }
@Override @Override
protected void initiateAutomaticSync() { public void initiateAutomaticSync() {
if (!isCurrentTaskListFragment())
return;
if (list != null && DateUtilities.now() - list.getValue(GtasksList.LAST_SYNC) > DateUtilities.ONE_HOUR) { if (list != null && DateUtilities.now() - list.getValue(GtasksList.LAST_SYNC) > DateUtilities.ONE_HOUR) {
syncService.synchronizeList(list, false, syncActionHelper.syncResultCallback); syncService.synchronizeList(list, false, syncActionHelper.syncResultCallback);
} }
@ -104,7 +106,7 @@ public class GtasksListFragment extends SubtasksListFragment {
private void clearCompletedTasks() { private void clearCompletedTasks() {
final ProgressDialog pd = new ProgressDialog(getActivity()); final ProgressDialog pd = new ProgressDialog(getActivity());
final TodorooCursor<Task> tasks = taskService.fetchFiltered(filter.sqlQuery, final TodorooCursor<Task> tasks = taskService.fetchFiltered(filter.getSqlQuery(),
null, Task.ID, Task.COMPLETION_DATE); null, Task.ID, Task.COMPLETION_DATE);
pd.setMessage(this.getString(R.string.gtasks_GTA_clearing)); pd.setMessage(this.getString(R.string.gtasks_GTA_clearing));
pd.show(); pd.show();

@ -162,14 +162,14 @@ public final class LocaleEditAlerts extends ListActivity {
if(adapter.getSelection() != null || finalSelection == null) if(adapter.getSelection() != null || finalSelection == null)
return; return;
if(item instanceof Filter) { if(item instanceof Filter) {
if(finalSelection.equals(((Filter)item).sqlQuery)) if(finalSelection.equals(((Filter)item).getSqlQuery()))
adapter.setSelection(item); adapter.setSelection(item);
} else if(item instanceof FilterCategory) { } else if(item instanceof FilterCategory) {
Filter[] filters = ((FilterCategory)item).children; Filter[] filters = ((FilterCategory)item).children;
if(filters == null) if(filters == null)
return; return;
for(Filter filter : filters) for(Filter filter : filters)
if(finalSelection.equals(filter.sqlQuery)) { if(finalSelection.equals(filter.getSqlQuery())) {
adapter.setSelection(filter); adapter.setSelection(filter);
break; break;
} }
@ -242,7 +242,7 @@ public final class LocaleEditAlerts extends ListActivity {
Filter filterItem = (Filter) selected; Filter filterItem = (Filter) selected;
storeAndForwardExtras.putString(KEY_FILTER_TITLE, filterItem.title); storeAndForwardExtras.putString(KEY_FILTER_TITLE, filterItem.title);
storeAndForwardExtras.putString(KEY_SQL, filterItem.sqlQuery); storeAndForwardExtras.putString(KEY_SQL, filterItem.getSqlQuery());
if(filterItem.valuesForNewTasks != null) if(filterItem.valuesForNewTasks != null)
storeAndForwardExtras.putString(KEY_VALUES, AndroidUtilities.contentValuesToSerializedString(filterItem.valuesForNewTasks)); storeAndForwardExtras.putString(KEY_VALUES, AndroidUtilities.contentValuesToSerializedString(filterItem.valuesForNewTasks));
storeAndForwardExtras.putInt(KEY_INTERVAL, INTERVALS[intervalIndex]); storeAndForwardExtras.putInt(KEY_INTERVAL, INTERVALS[intervalIndex]);

@ -120,7 +120,7 @@ public class NotificationFragment extends TaskListFragment implements OnTimeSetL
// hide quick add // hide quick add
getView().findViewById(R.id.taskListFooter).setVisibility(View.GONE); getView().findViewById(R.id.taskListFooter).setVisibility(View.GONE);
String title = getActivity().getIntent().getStringExtra(Notifications.EXTRAS_TEXT); String title = extras.getString(Notifications.EXTRAS_TEXT);
new ReminderDialog((AstridActivity) getActivity(), taskId, title).show(); new ReminderDialog((AstridActivity) getActivity(), taskId, title).show();
} }

@ -25,7 +25,6 @@ import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
@ -181,7 +180,7 @@ public class Notifications extends BroadcastReceiver {
notifyIntent.putExtra(NotificationFragment.TOKEN_ID, id); notifyIntent.putExtra(NotificationFragment.TOKEN_ID, id);
notifyIntent.putExtra(EXTRAS_TEXT, text); notifyIntent.putExtra(EXTRAS_TEXT, text);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
notifyIntent.putExtra(TaskListFragment.TOKEN_SOURCE, Constants.SOURCE_NOTIFICATION); notifyIntent.putExtra(TaskListActivity.TOKEN_SOURCE, Constants.SOURCE_NOTIFICATION);
requestNotification((int)id, notifyIntent, type, title, text, ringTimes); requestNotification((int)id, notifyIntent, type, title, text, ringTimes);
return true; return true;

@ -74,7 +74,7 @@ public class SubtasksUpdater extends OrderedListUpdater<String> {
protected void iterateThroughList(Filter filter, String list, OrderedListIterator iterator) { protected void iterateThroughList(Filter filter, String list, OrderedListIterator iterator) {
TodorooCursor<Task> cursor = taskService.query(Query.select(Task.ID, TodorooCursor<Task> cursor = taskService.query(Query.select(Task.ID,
Metadata.ID.as(METADATA_ID), Metadata.TASK, Metadata.KEY, SubtasksMetadata.INDENT, Metadata.ID.as(METADATA_ID), Metadata.TASK, Metadata.KEY, SubtasksMetadata.INDENT,
SubtasksMetadata.ORDER).withQueryTemplate(filter.sqlQuery)); SubtasksMetadata.ORDER).withQueryTemplate(filter.getSqlQuery()));
TodorooCursor<Metadata> metadataCursor = new TodorooCursor<Metadata>(cursor.getCursor(), TodorooCursor<Metadata> metadataCursor = new TodorooCursor<Metadata>(cursor.getCursor(),
cursor.getProperties()); cursor.getProperties());
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
@ -91,7 +91,7 @@ public class SubtasksUpdater extends OrderedListUpdater<String> {
@SuppressWarnings("nls") @SuppressWarnings("nls")
public void applySubtasksToFilter(Filter filter, String tagName) { public void applySubtasksToFilter(Filter filter, String tagName) {
String query = filter.sqlQuery; String query = filter.getSqlQuery();
if(tagName == null) if(tagName == null)
tagName = SubtasksMetadata.LIST_ACTIVE_TASKS; tagName = SubtasksMetadata.LIST_ACTIVE_TASKS;
@ -109,7 +109,7 @@ public class SubtasksUpdater extends OrderedListUpdater<String> {
query = query.replace(TaskCriteria.isVisible().toString(), query = query.replace(TaskCriteria.isVisible().toString(),
Criterion.all.toString()); Criterion.all.toString());
filter.sqlQuery = query; filter.setFilterOverrideQuery(query);
} }
} }

@ -30,7 +30,6 @@ import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.actfm.TagViewFragment; import com.todoroo.astrid.actfm.TagViewFragment;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.AstridFilterExposer; import com.todoroo.astrid.api.AstridFilterExposer;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
@ -114,7 +113,6 @@ public class TagFilterExposer extends BroadcastReceiver implements AstridFilterE
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putString(TagViewFragment.EXTRA_TAG_NAME, tag.tag); extras.putString(TagViewFragment.EXTRA_TAG_NAME, tag.tag);
extras.putLong(TagViewFragment.EXTRA_TAG_REMOTE_ID, tag.remoteId); extras.putLong(TagViewFragment.EXTRA_TAG_REMOTE_ID, tag.remoteId);
extras.putBoolean(TaskListFragment.TOKEN_OVERRIDE_ANIM, true);
filter.customExtras = extras; filter.customExtras = extras;
return filter; return filter;

@ -5,4 +5,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
style="@style/Content" style="@style/Content"
android:id="@+id/tasklist_fragment_container"> android:id="@+id/tasklist_fragment_container">
<com.todoroo.astrid.ui.TaskListFragmentPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</FrameLayout> </FrameLayout>

@ -145,21 +145,12 @@ public class AstridActivity extends FragmentActivity
if(item instanceof Filter) { if(item instanceof Filter) {
Filter filter = (Filter)item; Filter filter = (Filter)item;
if(filter instanceof FilterWithCustomIntent) {
int lastSelectedList = intent.getIntExtra(FilterListFragment.TOKEN_LAST_SELECTED, 0);
intent = ((FilterWithCustomIntent)filter).getCustomIntent();
intent.putExtra(FilterListFragment.TOKEN_LAST_SELECTED, lastSelectedList);
} else {
intent.putExtra(TaskListFragment.TOKEN_FILTER, filter);
}
setIntent(intent);
Bundle extras = configureIntentAndExtrasWithFilter(intent, filter);
if (fragmentLayout == LAYOUT_TRIPLE && getTaskEditFragment() != null) { if (fragmentLayout == LAYOUT_TRIPLE && getTaskEditFragment() != null) {
onBackPressed(); // remove the task edit fragment when switching between lists onBackPressed(); // remove the task edit fragment when switching between lists
} }
setupTasklistFragmentWithFilter(filter, extras);
setupTasklistFragmentWithFilter(filter);
// no animation for dualpane-layout // no animation for dualpane-layout
AndroidUtilities.callOverridePendingTransition(this, 0, 0); AndroidUtilities.callOverridePendingTransition(this, 0, 0);
@ -176,6 +167,23 @@ public class AstridActivity extends FragmentActivity
} }
} }
protected Bundle configureIntentAndExtrasWithFilter(Intent intent, Filter filter) {
if(filter instanceof FilterWithCustomIntent) {
int lastSelectedList = intent.getIntExtra(FilterListFragment.TOKEN_LAST_SELECTED, 0);
intent = ((FilterWithCustomIntent)filter).getCustomIntent();
intent.putExtra(FilterListFragment.TOKEN_LAST_SELECTED, lastSelectedList);
} else {
intent.putExtra(TaskListFragment.TOKEN_FILTER, filter);
}
setIntent(intent);
Bundle extras = intent.getExtras();
if (extras != null)
extras = (Bundle) extras.clone();
return extras;
}
public void setupActivityFragment(TagData tagData) { public void setupActivityFragment(TagData tagData) {
if (fragmentLayout == LAYOUT_SINGLE) if (fragmentLayout == LAYOUT_SINGLE)
return; return;
@ -190,37 +198,21 @@ public class AstridActivity extends FragmentActivity
transaction.commit(); transaction.commit();
} }
public final void setupTasklistFragmentWithFilter(Filter filter) { public void setupTasklistFragmentWithFilter(Filter filter, Bundle extras) {
Class<?> customTaskList = TaskListFragment.class; Class<?> customTaskList = TaskListFragment.class;
if(filter == null || CoreFilterExposer.isInbox(filter)) { if (shouldUseSubtasksFragmentForFilter(filter))
SharedPreferences publicPrefs = AstridPreferences.getPublicPrefs(this);
int sortFlags = publicPrefs.getInt(SortHelper.PREF_SORT_FLAGS, 0);
if(SortHelper.isManualSort(sortFlags))
customTaskList = SubtasksListFragment.class; customTaskList = SubtasksListFragment.class;
}
setupTasklistFragmentWithFilterAndCustomTaskList(filter, customTaskList); setupTasklistFragmentWithFilterAndCustomTaskList(filter, extras, customTaskList);
} }
public final void setupTasklistFragmentWithFilterAndCustomTaskList(Filter filter, Class<?> customTaskList) { public void setupTasklistFragmentWithFilterAndCustomTaskList(Filter filter, Bundle extras, Class<?> customTaskList) {
Class<?> component = customTaskList; TaskListFragment newFragment = TaskListFragment.instantiateWithFilterAndExtras(filter, extras, customTaskList);
if (filter == null)
getIntent().removeExtra(TaskListFragment.TOKEN_FILTER);
else
getIntent().putExtra(TaskListFragment.TOKEN_FILTER, filter);
if (filter instanceof FilterWithCustomIntent) {
try { try {
component = Class.forName(((FilterWithCustomIntent) filter).customTaskList.getClassName());
} catch (Exception e) {
// Invalid
}
}
FragmentManager manager = getSupportFragmentManager(); FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction(); FragmentTransaction transaction = manager.beginTransaction();
try {
TaskListFragment newFragment = (TaskListFragment) component.newInstance();
transaction.replace(R.id.tasklist_fragment_container, newFragment, transaction.replace(R.id.tasklist_fragment_container, newFragment,
TaskListFragment.TAG_TASKLIST_FRAGMENT); TaskListFragment.TAG_TASKLIST_FRAGMENT);
transaction.commit(); transaction.commit();
@ -236,6 +228,16 @@ public class AstridActivity extends FragmentActivity
} }
} }
public boolean shouldUseSubtasksFragmentForFilter(Filter filter) {
if(filter == null || CoreFilterExposer.isInbox(filter)) {
SharedPreferences publicPrefs = AstridPreferences.getPublicPrefs(this);
int sortFlags = publicPrefs.getInt(SortHelper.PREF_SORT_FLAGS, 0);
if(SortHelper.isManualSort(sortFlags))
return true;
}
return false;
}
@Override @Override
public void onTaskListItemClicked(long taskId) { public void onTaskListItemClicked(long taskId) {
Intent intent = new Intent(this, TaskEditActivity.class); Intent intent = new Intent(this, TaskEditActivity.class);
@ -299,8 +301,8 @@ public class AstridActivity extends FragmentActivity
} }
} }
protected Fragment setupFragment(String tag, int container, Class<? extends Fragment> cls) { protected Fragment setupFragment(String tag, int container, Class<? extends Fragment> cls, boolean createImmediate) {
FragmentManager fm = getSupportFragmentManager(); final FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag(tag); Fragment fragment = fm.findFragmentByTag(tag);
if(fragment == null) { if(fragment == null) {
try { try {
@ -317,6 +319,13 @@ public class AstridActivity extends FragmentActivity
else else
ft.replace(container, fragment, tag); ft.replace(container, fragment, tag);
ft.commit(); ft.commit();
if (createImmediate)
runOnUiThread(new Runnable() {
@Override
public void run() {
fm.executePendingTransactions();
}
});
} }
return fragment; return fragment;
} }

@ -122,6 +122,8 @@ public class FilterListFragment extends ListFragment {
// Check that the container activity has implemented the callback interface // Check that the container activity has implemented the callback interface
try { try {
mListener = (OnFilterItemClickedListener) activity; mListener = (OnFilterItemClickedListener) activity;
adapter = new FilterAdapter(getActivity(), null,
R.layout.filter_adapter_row, false);
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new ClassCastException(activity.toString() throw new ClassCastException(activity.toString()
+ " must implement OnFilterItemClickedListener"); //$NON-NLS-1$ + " must implement OnFilterItemClickedListener"); //$NON-NLS-1$
@ -257,8 +259,7 @@ public class FilterListFragment extends ListFragment {
/** Sets up the coach list adapter */ /** Sets up the coach list adapter */
protected void setUpList() { protected void setUpList() {
adapter = new FilterAdapter(getActivity(), getListView(), adapter.setListView(getListView());
R.layout.filter_adapter_row, false);
setListAdapter(adapter); setListAdapter(adapter);
adapter.setLastSelected(mSelectedIndex); adapter.setLastSelected(mSelectedIndex);

@ -87,8 +87,8 @@ public class ShortcutActivity extends Activity {
Intent taskListIntent = new Intent(this, TaskListActivity.class); Intent taskListIntent = new Intent(this, TaskListActivity.class);
if(extras != null && extras.containsKey(TaskListFragment.TOKEN_SOURCE)) if(extras != null && extras.containsKey(TaskListActivity.TOKEN_SOURCE))
taskListIntent.putExtra(TaskListFragment.TOKEN_SOURCE, extras.getInt(TaskListFragment.TOKEN_SOURCE)); taskListIntent.putExtra(TaskListActivity.TOKEN_SOURCE, extras.getInt(TaskListActivity.TOKEN_SOURCE));
if(extras != null && extras.containsKey(TOKEN_CUSTOM_CLASS)) { if(extras != null && extras.containsKey(TOKEN_CUSTOM_CLASS)) {
taskListIntent.putExtras(intent.getExtras()); taskListIntent.putExtras(intent.getExtras());
@ -161,7 +161,7 @@ public class ShortcutActivity extends Activity {
shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_TITLE, shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_TITLE,
filter.title); filter.title);
shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_SQL, shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_SQL,
filter.sqlQuery); filter.getSqlQuery());
if (filter.valuesForNewTasks != null) { if (filter.valuesForNewTasks != null) {
for (Entry<String, Object> item : filter.valuesForNewTasks.valueSet()) { for (Entry<String, Object> item : filter.valuesForNewTasks.valueSet()) {
String key = TOKEN_FILTER_VALUES_ITEM + item.getKey(); String key = TOKEN_FILTER_VALUES_ITEM + item.getKey();

@ -9,6 +9,7 @@ import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ActionBar; import android.support.v4.app.ActionBar;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -29,31 +30,43 @@ import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.actfm.TagSettingsActivity; import com.todoroo.astrid.actfm.TagSettingsActivity;
import com.todoroo.astrid.actfm.TagUpdatesFragment; import com.todoroo.astrid.actfm.TagUpdatesFragment;
import com.todoroo.astrid.actfm.TagViewFragment; import com.todoroo.astrid.actfm.TagViewFragment;
import com.todoroo.astrid.adapter.FilterAdapter;
import com.todoroo.astrid.adapter.TaskListFragmentPagerAdapter;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.core.CoreFilterExposer;
import com.todoroo.astrid.core.CustomFilterExposer; import com.todoroo.astrid.core.CustomFilterExposer;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.reminders.NotificationFragment; import com.todoroo.astrid.reminders.NotificationFragment;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagFilterExposer; import com.todoroo.astrid.tags.TagFilterExposer;
import com.todoroo.astrid.ui.DateChangedAlerts; import com.todoroo.astrid.ui.DateChangedAlerts;
import com.todoroo.astrid.ui.FragmentPopover; import com.todoroo.astrid.ui.FragmentPopover;
import com.todoroo.astrid.ui.MainMenuPopover; import com.todoroo.astrid.ui.MainMenuPopover;
import com.todoroo.astrid.ui.MainMenuPopover.MainMenuListener; import com.todoroo.astrid.ui.MainMenuPopover.MainMenuListener;
import com.todoroo.astrid.ui.TaskListFragmentPager;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
public class TaskListActivity extends AstridActivity implements MainMenuListener { public class TaskListActivity extends AstridActivity implements MainMenuListener, OnPageChangeListener {
public static final String TOKEN_SELECTED_FILTER = "selectedFilter"; //$NON-NLS-1$ public static final String TOKEN_SELECTED_FILTER = "selectedFilter"; //$NON-NLS-1$
/** token for indicating source of TLA launch */
public static final String TOKEN_SOURCE = "source"; //$NON-NLS-1$
private View listsNav; private View listsNav;
private ImageView listsNavDisclosure; private ImageView listsNavDisclosure;
private TextView lists; private TextView lists;
private ImageView mainMenu; private ImageView mainMenu;
private Button commentsButton; private Button commentsButton;
private TaskListFragmentPager tlfPager;
private TaskListFragmentPagerAdapter tlfPagerAdapter;
private FragmentPopover listsPopover; private FragmentPopover listsPopover;
private FragmentPopover editPopover; private FragmentPopover editPopover;
private FragmentPopover commentsPopover; private FragmentPopover commentsPopover;
@ -141,15 +154,55 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
commentsButton.setOnClickListener(commentsButtonClickListener); commentsButton.setOnClickListener(commentsButtonClickListener);
Filter savedFilter = getIntent().getParcelableExtra(TaskListFragment.TOKEN_FILTER); Filter savedFilter = getIntent().getParcelableExtra(TaskListFragment.TOKEN_FILTER);
if (savedFilter == null)
savedFilter = CoreFilterExposer.buildInboxFilter(getResources());
Bundle extras = getIntent().getExtras();
if (extras != null)
extras = (Bundle) extras.clone();
if (getIntent().getIntExtra(TaskListFragment.TOKEN_SOURCE, Constants.SOURCE_DEFAULT) == if (fragmentLayout == LAYOUT_SINGLE) {
FilterListFragment flf = getFilterListFragment();
if (flf == null)
throw new RuntimeException("Filterlist fragment was null, needs to exist to construct the fragment pager"); //$NON-NLS-1$
FilterAdapter adapter = flf.adapter;
tlfPager = (TaskListFragmentPager) findViewById(R.id.pager);
tlfPagerAdapter = new TaskListFragmentPagerAdapter(getSupportFragmentManager(), adapter);
tlfPager.setAdapter(tlfPagerAdapter);
tlfPager.setOnPageChangeListener(this);
}
if (getIntent().getIntExtra(TOKEN_SOURCE, Constants.SOURCE_DEFAULT) ==
Constants.SOURCE_NOTIFICATION) Constants.SOURCE_NOTIFICATION)
setupTasklistFragmentWithFilterAndCustomTaskList(savedFilter, NotificationFragment.class); setupTasklistFragmentWithFilterAndCustomTaskList(savedFilter, extras, NotificationFragment.class);
else else
setupTasklistFragmentWithFilter(savedFilter); setupTasklistFragmentWithFilter(savedFilter, extras);
if (savedFilter != null) if (savedFilter != null)
setListsTitle(savedFilter.title); setListsTitle(savedFilter.title);
if (getIntent().hasExtra(TOKEN_SOURCE)) {
trackActivitySource();
}
}
@Override
public TaskListFragment getTaskListFragment() {
if (fragmentLayout == LAYOUT_SINGLE) {
return tlfPager.getCurrentFragment();
} else {
return super.getTaskListFragment();
}
}
@Override
public void setupTasklistFragmentWithFilterAndCustomTaskList(Filter filter, Bundle extras, Class<?> customTaskList) {
if (fragmentLayout == LAYOUT_SINGLE) {
tlfPager.showFilterWithCustomTaskList(filter, customTaskList);
tlfPager.setAdapter(tlfPagerAdapter); // Hack to force reload of current page
} else {
super.setupTasklistFragmentWithFilterAndCustomTaskList(filter, extras, customTaskList);
}
} }
/** /**
@ -175,13 +228,13 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
} }
setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT, setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT,
R.id.filterlist_fragment_container, FilterListFragment.class); R.id.filterlist_fragment_container, FilterListFragment.class, false);
} else { } else {
fragmentLayout = LAYOUT_SINGLE; fragmentLayout = LAYOUT_SINGLE;
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
listsNav.setOnClickListener(popupMenuClickListener); listsNav.setOnClickListener(popupMenuClickListener);
createListsPopover(); createListsPopover();
setupPopoverWithFilterList((FilterListFragment) setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT, 0, FilterListFragment.class)); setupPopoverWithFilterList((FilterListFragment) setupFragment(FilterListFragment.TAG_FILTERLIST_FRAGMENT, 0, FilterListFragment.class, true));
} }
} }
@ -275,6 +328,11 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
if (listsPopover != null) if (listsPopover != null)
listsPopover.dismiss(); listsPopover.dismiss();
setCommentsCount(0); setCommentsCount(0);
if (fragmentLayout == LAYOUT_SINGLE) {
tlfPager.showFilter((Filter) item);
return true;
}
return super.onFilterItemClicked(item); return super.onFilterItemClicked(item);
} }
@ -338,6 +396,25 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
lists.setText(item.title); lists.setText(item.title);
} }
@Override
public void onPageSelected(int position) {
if (tlfPagerAdapter != null) {
configureIntentAndExtrasWithFilter(getIntent(), tlfPagerAdapter.getFilter(position));
setListsTitle(tlfPagerAdapter.getPageTitle(position).toString());
TaskListFragment fragment = getTaskListFragment();
fragment.initiateAutomaticSync();
fragment.requestCommentCountUpdate();
}
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) { /* Nothing */ }
@Override
public void onPageScrollStateChanged(int state) { /* Nothing */ }
public void setCommentsCount(int count) { public void setCommentsCount(int count) {
TypedValue tv = new TypedValue(); TypedValue tv = new TypedValue();
@ -478,6 +555,31 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
} }
} }
/**
* Report who launched this activity
*/
protected void trackActivitySource() {
switch (getIntent().getIntExtra(TOKEN_SOURCE,
Constants.SOURCE_DEFAULT)) {
case Constants.SOURCE_NOTIFICATION:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_NOTIFICATION);
break;
case Constants.SOURCE_OTHER:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_OTHER);
break;
case Constants.SOURCE_PPWIDGET:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_PPW);
break;
case Constants.SOURCE_WIDGET:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_WIDGET);
break;
case Constants.SOURCE_C2DM:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_C2DM);
break;
}
getIntent().putExtra(TOKEN_SOURCE, Constants.SOURCE_DEFAULT); // Only report source once
}
@Override @Override
public void mainMenuItemSelected(int item, Intent customIntent) { public void mainMenuItemSelected(int item, Intent customIntent) {
TaskListFragment tlf = getTaskListFragment(); TaskListFragment tlf = getTaskListFragment();
@ -530,7 +632,7 @@ public class TaskListActivity extends AstridActivity implements MainMenuListener
Filter currentlyShowing = getIntent().getParcelableExtra(TaskListFragment.TOKEN_FILTER); Filter currentlyShowing = getIntent().getParcelableExtra(TaskListFragment.TOKEN_FILTER);
if (currentlyShowing != null) { if (currentlyShowing != null) {
boolean titlesMatch = currentlyShowing.title != null && currentlyShowing.title.equals(deletedTag); boolean titlesMatch = currentlyShowing.title != null && currentlyShowing.title.equals(deletedTag);
boolean sqlMatches = currentlyShowing.sqlQuery != null && currentlyShowing.sqlQuery.equals(deletedTagSql); boolean sqlMatches = currentlyShowing.getSqlQuery() != null && currentlyShowing.getSqlQuery().equals(deletedTagSql);
if (titlesMatch && sqlMatches) if (titlesMatch && sqlMatches)
fl.switchToActiveTasks(); fl.switchToActiveTasks();
} }

@ -28,6 +28,7 @@ import android.support.v4.app.SupportActivity;
import android.support.v4.view.Menu; import android.support.v4.view.Menu;
import android.support.v4.view.MenuItem; import android.support.v4.view.MenuItem;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -68,6 +69,7 @@ import com.todoroo.astrid.adapter.TaskAdapter.OnCompletedTaskListener;
import com.todoroo.astrid.adapter.TaskAdapter.ViewHolder; import com.todoroo.astrid.adapter.TaskAdapter.ViewHolder;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterWithCustomIntent;
import com.todoroo.astrid.api.TaskContextActionExposer; import com.todoroo.astrid.api.TaskContextActionExposer;
import com.todoroo.astrid.api.TaskDecoration; import com.todoroo.astrid.api.TaskDecoration;
import com.todoroo.astrid.core.CoreFilterExposer; import com.todoroo.astrid.core.CoreFilterExposer;
@ -146,10 +148,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
/** token for passing a {@link Filter} object through extras */ /** token for passing a {@link Filter} object through extras */
public static final String TOKEN_FILTER = "filter"; //$NON-NLS-1$ public static final String TOKEN_FILTER = "filter"; //$NON-NLS-1$
/** token for indicating source of TLA launch */ private static final String TOKEN_EXTRAS = "extras"; //$NON-NLS-1$
public static final String TOKEN_SOURCE = "source"; //$NON-NLS-1$
public static final String TOKEN_OVERRIDE_ANIM = "finishAnim"; //$NON-NLS-1$
// --- instance variables // --- instance variables
@ -184,10 +183,10 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
protected Filter filter; protected Filter filter;
protected int sortFlags; protected int sortFlags;
protected int sortSort; protected int sortSort;
protected boolean overrideFinishAnim;
protected QuickAddBar quickAddBar; protected QuickAddBar quickAddBar;
private Timer backgroundTimer; private Timer backgroundTimer;
protected Bundle extras;
private boolean isInbox; private boolean isInbox;
private final TaskListContextMenuExtensionLoader contextMenuExtensionLoader = new TaskListContextMenuExtensionLoader(); private final TaskListContextMenuExtensionLoader contextMenuExtensionLoader = new TaskListContextMenuExtensionLoader();
@ -206,6 +205,57 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
AstridDependencyInjector.initialize(); AstridDependencyInjector.initialize();
} }
/**
* Instantiates and returns an instance of TaskListFragment (or some subclass). Custom types of
* TaskListFragment can be created, with the following precedence:
*
* --If the filter is of type {@link FilterWithCustomIntent}, the task list type it specifies will be used
* --Otherwise, the specified customComponent will be used
*
* See also: instantiateWithFilterAndExtras(Filter, Bundle) which uses TaskListFragment as the default
* custom component.
* @param filter
* @param extras
* @param customComponent
* @return
*/
@SuppressWarnings("nls")
public static TaskListFragment instantiateWithFilterAndExtras(Filter filter, Bundle extras, Class<?> customComponent) {
Class<?> component = customComponent;
if (filter instanceof FilterWithCustomIntent) {
try {
component = Class.forName(((FilterWithCustomIntent) filter).customTaskList.getClassName());
} catch (Exception e) {
// Invalid
}
}
TaskListFragment newFragment;
try {
newFragment = (TaskListFragment) component.newInstance();
} catch (java.lang.InstantiationException e) {
Log.e("tla-instantiate", "tla-instantiate", e);
newFragment = new TaskListFragment();
} catch (IllegalAccessException e) {
Log.e("tla-instantiate", "tla-instantiate", e);
newFragment = new TaskListFragment();
}
Bundle args = new Bundle();
args.putBundle(TOKEN_EXTRAS, extras);
newFragment.setArguments(args);
return newFragment;
}
/**
* Convenience method for calling instantiateWithFilterAndExtras(Filter, Bundle, Class<?>) with
* TaskListFragment as the default component
* @param filter
* @param extras
* @return
*/
public static TaskListFragment instantiateWithFilterAndExtras(Filter filter, Bundle extras) {
return instantiateWithFilterAndExtras(filter, extras, TaskListFragment.class);
}
/** /**
* Container Activity must implement this interface and we ensure that it * Container Activity must implement this interface and we ensure that it
* does during the onAttach() callback * does during the onAttach() callback
@ -242,6 +292,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
DependencyInjectionService.getInstance().inject(this); DependencyInjectionService.getInstance().inject(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
extras = getArguments() != null ? getArguments().getBundle(TOKEN_EXTRAS) : null;
} }
/* /*
@ -287,10 +338,6 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
upgradeService.showChangeLog(getActivity(), upgradeService.showChangeLog(getActivity(),
Preferences.getInt(AstridPreferences.P_UPGRADE_FROM, -1)); Preferences.getInt(AstridPreferences.P_UPGRADE_FROM, -1));
if (getActivity().getIntent().hasExtra(TOKEN_SOURCE)) {
trackActivitySource();
}
getActivity().runOnUiThread(new Runnable() { getActivity().runOnUiThread(new Runnable() {
public void run() { public void run() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY); Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
@ -313,31 +360,6 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
}); });
} }
/**
* Report who launched this activity
*/
protected void trackActivitySource() {
switch (getActivity().getIntent().getIntExtra(TOKEN_SOURCE,
Constants.SOURCE_DEFAULT)) {
case Constants.SOURCE_NOTIFICATION:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_NOTIFICATION);
break;
case Constants.SOURCE_OTHER:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_OTHER);
break;
case Constants.SOURCE_PPWIDGET:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_PPW);
break;
case Constants.SOURCE_WIDGET:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_WIDGET);
break;
case Constants.SOURCE_C2DM:
StatisticsService.reportEvent(StatisticsConstants.LAUNCH_FROM_C2DM);
break;
}
getActivity().getIntent().putExtra(TOKEN_SOURCE, Constants.SOURCE_DEFAULT); // Only report source once
}
/** /**
* @return the current tag you are viewing, or null if you're not viewing a tag * @return the current tag you are viewing, or null if you're not viewing a tag
*/ */
@ -346,12 +368,6 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
} }
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
overrideFinishAnim = extras.getBoolean(TOKEN_OVERRIDE_ANIM);
} else {
overrideFinishAnim = false;
}
String intentAction = intent.getAction(); String intentAction = intent.getAction();
if (Intent.ACTION_SEARCH.equals(intentAction)) { if (Intent.ACTION_SEARCH.equals(intentAction)) {
String query = intent.getStringExtra(SearchManager.QUERY).trim(); String query = intent.getStringExtra(SearchManager.QUERY).trim();
@ -361,17 +377,14 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
"%" + //$NON-NLS-1$ "%" + //$NON-NLS-1$
query.toUpperCase() + "%")), //$NON-NLS-1$ query.toUpperCase() + "%")), //$NON-NLS-1$
null); null);
intent = new Intent(getActivity(), TaskListActivity.class); Intent searchIntent = new Intent(getActivity(), TaskListActivity.class);
intent.putExtra(TaskListFragment.TOKEN_FILTER, searchFilter); searchIntent.putExtra(TaskListFragment.TOKEN_FILTER, searchFilter);
startActivity(intent); startActivity(searchIntent);
getActivity().finish(); getActivity().finish();
if (overrideFinishAnim) {
AndroidUtilities.callOverridePendingTransition(getActivity(),
R.anim.slide_right_in, R.anim.slide_right_out);
}
return; return;
} else if (extras != null && extras.containsKey(TOKEN_FILTER)) { } else if (extras != null && extras.containsKey(TOKEN_FILTER)) {
filter = extras.getParcelable(TOKEN_FILTER); filter = extras.getParcelable(TOKEN_FILTER);
extras.remove(TOKEN_FILTER); // Otherwise writing this filter to parcel gives infinite recursion
} else { } else {
filter = CoreFilterExposer.buildInboxFilter(getResources()); filter = CoreFilterExposer.buildInboxFilter(getResources());
} }
@ -421,6 +434,8 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
Activity activity = getActivity(); Activity activity = getActivity();
if (activity == null) if (activity == null)
return; return;
if (!isCurrentTaskListFragment())
return;
boolean isTablet = AndroidUtilities.isTabletSized(activity); boolean isTablet = AndroidUtilities.isTabletSized(activity);
if (activity instanceof TaskListActivity) if (activity instanceof TaskListActivity)
@ -625,10 +640,26 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
initiateAutomaticSync(); initiateAutomaticSync();
} }
protected void initiateAutomaticSync() { protected boolean isCurrentTaskListFragment() {
AstridActivity activity = (AstridActivity) getActivity();
if (activity != null) {
return activity.getTaskListFragment() == this;
}
return false;
}
public void initiateAutomaticSync() {
if (isCurrentTaskListFragment())
syncActionHelper.initiateAutomaticSync(filter); syncActionHelper.initiateAutomaticSync(filter);
} }
// Subclasses should override this
public void requestCommentCountUpdate() {
TaskListActivity activity = (TaskListActivity) getActivity();
if (activity != null)
activity.setCommentsCount(0);
}
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
@ -686,16 +717,16 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
try { try {
Bundle extras = intent.getExtras(); Bundle receivedExtras = intent.getExtras();
long taskId = extras.getLong(AstridApiConstants.EXTRAS_TASK_ID); long taskId = receivedExtras.getLong(AstridApiConstants.EXTRAS_TASK_ID);
String addOn = extras.getString(AstridApiConstants.EXTRAS_ADDON); String addOn = receivedExtras.getString(AstridApiConstants.EXTRAS_ADDON);
if (AstridApiConstants.BROADCAST_SEND_DECORATIONS.equals(intent.getAction())) { if (AstridApiConstants.BROADCAST_SEND_DECORATIONS.equals(intent.getAction())) {
TaskDecoration deco = extras.getParcelable(AstridApiConstants.EXTRAS_RESPONSE); TaskDecoration deco = receivedExtras.getParcelable(AstridApiConstants.EXTRAS_RESPONSE);
taskAdapter.decorationManager.addNew(taskId, addOn, deco, taskAdapter.decorationManager.addNew(taskId, addOn, deco,
null); null);
} else if (AstridApiConstants.BROADCAST_SEND_DETAILS.equals(intent.getAction())) { } else if (AstridApiConstants.BROADCAST_SEND_DETAILS.equals(intent.getAction())) {
String detail = extras.getString(AstridApiConstants.EXTRAS_RESPONSE); String detail = receivedExtras.getString(AstridApiConstants.EXTRAS_RESPONSE);
taskAdapter.addDetails(taskId, detail); taskAdapter.addDetails(taskId, detail);
} }
} catch (Exception e) { } catch (Exception e) {
@ -714,10 +745,6 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
if (requestCode == ACTIVITY_SETTINGS) { if (requestCode == ACTIVITY_SETTINGS) {
if (resultCode == EditPreferences.RESULT_CODE_THEME_CHANGED) { if (resultCode == EditPreferences.RESULT_CODE_THEME_CHANGED) {
getActivity().finish(); getActivity().finish();
if (overrideFinishAnim) {
AndroidUtilities.callOverridePendingTransition(getActivity(),
R.anim.slide_right_in, R.anim.slide_right_out);
}
getActivity().startActivity(getActivity().getIntent()); getActivity().startActivity(getActivity().getIntent());
TasksWidget.updateWidgets(getActivity()); TasksWidget.updateWidgets(getActivity());
} else if (resultCode == SyncProviderPreferences.RESULT_CODE_SYNCHRONIZE) { } else if (resultCode == SyncProviderPreferences.RESULT_CODE_SYNCHRONIZE) {
@ -828,7 +855,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
return; return;
sqlQueryTemplate.set(SortHelper.adjustQueryForFlagsAndSort( sqlQueryTemplate.set(SortHelper.adjustQueryForFlagsAndSort(
filter.sqlQuery, sortFlags, sortSort)); filter.getSqlQuery(), sortFlags, sortSort));
// perform query // perform query
TodorooCursor<Task> currentCursor; TodorooCursor<Task> currentCursor;
@ -1215,11 +1242,11 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
protected void toggleDragDrop(boolean newState) { protected void toggleDragDrop(boolean newState) {
if(newState) if(newState)
((AstridActivity)getActivity()).setupTasklistFragmentWithFilterAndCustomTaskList(null, ((AstridActivity)getActivity()).setupTasklistFragmentWithFilterAndCustomTaskList(filter,
SubtasksListFragment.class); extras, SubtasksListFragment.class);
else else
((AstridActivity)getActivity()).setupTasklistFragmentWithFilterAndCustomTaskList(null, ((AstridActivity)getActivity()).setupTasklistFragmentWithFilterAndCustomTaskList(filter,
TaskListFragment.class); extras, TaskListFragment.class);
} }
protected boolean isDraggable() { protected boolean isDraggable() {

@ -56,6 +56,10 @@ import com.todoroo.astrid.tags.TagService;
public class FilterAdapter extends ArrayAdapter<Filter> { public class FilterAdapter extends ArrayAdapter<Filter> {
public static interface FilterDataSourceChangedListener {
public void filterDataSourceChanged();
}
// --- style constants // --- style constants
public int filterStyle = R.style.TextAppearance_FLA_Filter; public int filterStyle = R.style.TextAppearance_FLA_Filter;
@ -70,7 +74,7 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
protected final Activity activity; protected final Activity activity;
/** owner listview */ /** owner listview */
protected final ListView listView; protected ListView listView;
/** display metrics for scaling icons */ /** display metrics for scaling icons */
private final DisplayMetrics metrics = new DisplayMetrics(); private final DisplayMetrics metrics = new DisplayMetrics();
@ -99,6 +103,9 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
private final HashMap<Filter, Integer> filterCounts; private final HashMap<Filter, Integer> filterCounts;
private FilterDataSourceChangedListener listener;
// Previous solution involved a queue of filters and a filterSizeLoadingThread. The filterSizeLoadingThread had // Previous solution involved a queue of filters and a filterSizeLoadingThread. The filterSizeLoadingThread had
// a few problems: how to make sure that the thread is resumed when the controlling activity is resumed, and // a few problems: how to make sure that the thread is resumed when the controlling activity is resumed, and
// how to make sure that the the filterQueue does not accumulate filters without being processed. I am replacing // how to make sure that the the filterQueue does not accumulate filters without being processed. I am replacing
@ -186,6 +193,13 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
offerFilter(item); offerFilter(item);
} }
public int addOrLookup(Filter filter) {
int index = getPosition(filter);
if (index >= 0) return index;
add(filter);
return getCount() - 1;
}
public void setLastSelected(int lastSelected) { public void setLastSelected(int lastSelected) {
mSelectedIndex = lastSelected; mSelectedIndex = lastSelected;
} }
@ -226,6 +240,14 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
}); });
} }
public void setDataSourceChangedListener(FilterDataSourceChangedListener listener) {
this.listener = listener;
}
public void setListView(ListView listView) {
this.listView = listView;
}
/** /**
* Create or reuse a view * Create or reuse a view
* @param convertView * @param convertView
@ -347,10 +369,10 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
if (filter instanceof FilterCategory) { if (filter instanceof FilterCategory) {
Filter[] children = ((FilterCategory) filter).children; Filter[] children = ((FilterCategory) filter).children;
for (Filter f : children) { for (Filter f : children) {
add(f); addOrLookup(f);
} }
} else if (filter instanceof Filter){ } else if (filter instanceof Filter){
add((Filter) filter); addOrLookup((Filter) filter);
} }
} }
@ -405,6 +427,13 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
} }
} }
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
if (listener != null)
listener.filterDataSourceChanged();
}
/** /**
* Broadcast a request for lists. The request is sent to every * Broadcast a request for lists. The request is sent to every
* application registered to listen for this broadcast. Each application * application registered to listen for this broadcast. Each application
@ -433,7 +462,6 @@ public class FilterAdapter extends ArrayAdapter<Filter> {
IntentFilter bladeFilter = new IntentFilter(AstridApiConstants.BROADCAST_SEND_FILTERS); IntentFilter bladeFilter = new IntentFilter(AstridApiConstants.BROADCAST_SEND_FILTERS);
bladeFilter.setPriority(1); bladeFilter.setPriority(1);
activity.registerReceiver(bladeFilterReceiver, bladeFilter); activity.registerReceiver(bladeFilterReceiver, bladeFilter);
if(getCount() == 0)
getLists(); getLists();
} }

@ -0,0 +1,121 @@
package com.todoroo.astrid.adapter;
import java.util.HashMap;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.FilterAdapter.FilterDataSourceChangedListener;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterWithCustomIntent;
public class TaskListFragmentPagerAdapter extends FragmentStatePagerAdapter implements FilterDataSourceChangedListener {
private final HashMap<Integer, Fragment> positionToFragment;
private final HashMap<Filter, Class<?>> customTaskLists;
private final FilterAdapter filterAdapter; // Shares an adapter instance with the filter list fragment
public TaskListFragmentPagerAdapter(FragmentManager fm, FilterAdapter filterAdapter) {
super(fm);
this.filterAdapter = filterAdapter;
filterAdapter.setDataSourceChangedListener(this);
positionToFragment = new HashMap<Integer, Fragment>();
customTaskLists = new HashMap<Filter, Class<?>>();
}
@Override
public void filterDataSourceChanged() {
notifyDataSetChanged();
}
/**
* Instantiates and returns a fragment for the filter at the specified position.
* Also maps the position to the fragment in a cache for later lookup
*/
@Override
public Fragment getItem(int position) {
Filter filter = filterAdapter.getItem(position);
Fragment fragment = getFragmentForFilter(filter);
positionToFragment.put(position, fragment);
return fragment;
}
/**
* Lookup the fragment for the specified position
* @param position
* @return
*/
public Fragment lookupFragmentForPosition(int position) {
return positionToFragment.get(position);
}
@Override
public CharSequence getPageTitle(int position) {
return filterAdapter.getItem(position).title;
}
/**
* Adds the specified filter to the data source if it doesn't exist,
* returning the position of that filter regardless
* @param filter
* @return
*/
public int addOrLookup(Filter filter) {
return filterAdapter.addOrLookup(filter);
}
/**
* Get the filter at the specified position
* @param position
* @return
*/
public Filter getFilter(int position) {
return filterAdapter.getItem(position);
}
@Override
public int getCount() {
return filterAdapter.getCount();
}
public void setCustomTaskListForFilter(Filter f, Class<?> customTaskList) {
customTaskLists.put(f, customTaskList);
notifyDataSetChanged();
}
public void clearCustomTaskListForFilter(Filter f) {
customTaskLists.remove(f);
}
private Fragment getFragmentForFilter(Filter filter) {
Bundle extras = getExtrasForFilter(filter);
Class<?> customList = customTaskLists.get(filter);
if (customList == null)
customList = TaskListFragment.class;
return TaskListFragment.instantiateWithFilterAndExtras(filter, extras, customList);
}
// Constructs extras corresponding to the specified filter that can be used as arguments to the fragment
private Bundle getExtrasForFilter(Filter filter) {
Bundle extras;
if (filter instanceof FilterWithCustomIntent) {
extras = ((FilterWithCustomIntent) filter).customExtras;
} else {
extras = new Bundle();
}
if (filter != null)
extras.putParcelable(TaskListFragment.TOKEN_FILTER, filter);
return extras;
}
@Override
public Parcelable saveState() {
return null; // Don't save state
}
}

@ -3,6 +3,7 @@ package com.todoroo.astrid.helper;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import android.app.Activity; import android.app.Activity;
import android.support.v4.app.Fragment;
import android.view.View; import android.view.View;
import android.view.animation.AlphaAnimation; import android.view.animation.AlphaAnimation;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -18,9 +19,9 @@ public class ProgressBarSyncResultCallback extends SyncResultCallbackAdapter {
private final AtomicInteger providers = new AtomicInteger(0); private final AtomicInteger providers = new AtomicInteger(0);
public ProgressBarSyncResultCallback(Activity activity, public ProgressBarSyncResultCallback(Activity activity, Fragment fragment,
int progressBarId, Runnable onFinished) { int progressBarId, Runnable onFinished) {
this.progressBar = (ProgressBar) activity.findViewById(progressBarId); this.progressBar = (ProgressBar) fragment.getView().findViewById(progressBarId);
this.activity = activity; this.activity = activity;
this.onFinished = onFinished; this.onFinished = onFinished;

@ -73,7 +73,7 @@ public class SyncActionHelper {
this.activity = activity; this.activity = activity;
this.fragment = fragment; this.fragment = fragment;
syncResultCallback = new ProgressBarSyncResultCallback(activity, syncResultCallback = new ProgressBarSyncResultCallback(activity, fragment,
R.id.progressBar, new Runnable() { R.id.progressBar, new Runnable() {
@Override @Override
public void run() { public void run() {

@ -328,7 +328,7 @@ public class TaskService {
/** count tasks in a given filter */ /** count tasks in a given filter */
public int countTasks(Filter filter) { public int countTasks(Filter filter) {
String queryTemplate = PermaSql.replacePlaceholders(filter.sqlQuery); String queryTemplate = PermaSql.replacePlaceholders(filter.getSqlQuery());
TodorooCursor<Task> cursor = query(Query.select(Task.ID).withQueryTemplate( TodorooCursor<Task> cursor = query(Query.select(Task.ID).withQueryTemplate(
queryTemplate)); queryTemplate));
try { try {

@ -41,6 +41,7 @@ import com.commonsware.cwac.tlv.TouchListView.DropListener;
import com.commonsware.cwac.tlv.TouchListView.GrabberClickListener; import com.commonsware.cwac.tlv.TouchListView.GrabberClickListener;
import com.commonsware.cwac.tlv.TouchListView.SwipeListener; import com.commonsware.cwac.tlv.TouchListView.SwipeListener;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.astrid.utility.Flags;
public class DraggableListView extends ListView { public class DraggableListView extends ListView {
@ -254,6 +255,7 @@ public class DraggableListView extends ListView {
if (dragThread != null && mClickListener != null) { if (dragThread != null && mClickListener != null) {
dragThread.interrupt(); dragThread.interrupt();
dragThread = null; dragThread = null;
if (action == MotionEvent.ACTION_UP)
mClickListener.onClick(viewAtPosition()); mClickListener.onClick(viewAtPosition());
} }
@ -421,6 +423,7 @@ public class DraggableListView extends ListView {
mWindowManager.addView(v, mWindowParams); mWindowManager.addView(v, mWindowParams);
mDragView = v; mDragView = v;
mDragging = true; mDragging = true;
Flags.set(Flags.TLFP_NO_INTERCEPT_TOUCH);
} }
private void dragView(MotionEvent ev) { private void dragView(MotionEvent ev) {
@ -482,7 +485,6 @@ public class DraggableListView extends ListView {
unExpandViews(false); unExpandViews(false);
if (mDragView != null) { if (mDragView != null) {
System.err.println("removing view");
WindowManager wm = (WindowManager) getContext().getSystemService( WindowManager wm = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE); Context.WINDOW_SERVICE);
wm.removeView(mDragView); wm.removeView(mDragView);
@ -505,6 +507,7 @@ public class DraggableListView extends ListView {
} }
mDragging = false; mDragging = false;
Flags.checkAndClear(Flags.TLFP_NO_INTERCEPT_TOUCH);
} }
// --- getters and setters // --- getters and setters

@ -0,0 +1,64 @@
package com.todoroo.astrid.ui;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskListFragmentPagerAdapter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.utility.Flags;
public class TaskListFragmentPager extends ViewPager {
public TaskListFragmentPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setAdapter(PagerAdapter adapter) {
if (!(adapter instanceof TaskListFragmentPagerAdapter))
throw new ClassCastException("TaskListFragmentPager requires an adapter of type TaskListFragmentPagerAdapter"); //$NON-NLS-1$
super.setAdapter(adapter);
}
/**
* Show the supplied filter, adding it to the data source if it doesn't exist
* @param f
*/
public void showFilter(Filter f) {
TaskListFragmentPagerAdapter adapter = (TaskListFragmentPagerAdapter) getAdapter();
showFilter(adapter.addOrLookup(f));
}
public void showFilterWithCustomTaskList(Filter f, Class<?> customTaskList) {
TaskListFragmentPagerAdapter adapter = (TaskListFragmentPagerAdapter) getAdapter();
adapter.setCustomTaskListForFilter(f, customTaskList);
showFilter(adapter.addOrLookup(f));
}
/**
* Show the filter at the supplied index, with animation
* @param index
*/
public void showFilter(int index) {
setCurrentItem(index, true);
}
/**
* Returns the currently showing fragment
* @return
*/
public TaskListFragment getCurrentFragment() {
return (TaskListFragment) ((TaskListFragmentPagerAdapter) getAdapter()).lookupFragmentForPosition(getCurrentItem());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!Flags.check(Flags.TLFP_NO_INTERCEPT_TOUCH))
return super.onInterceptTouchEvent(ev);
return false;
}
}

@ -31,6 +31,11 @@ public class Flags {
*/ */
public static final int TLA_RESUMED_FROM_VOICE_ADD = 1 << 6; public static final int TLA_RESUMED_FROM_VOICE_ADD = 1 << 6;
/**
* If set, indicates that TaskListFragmentPager should not intercept touch events
*/
public static final int TLFP_NO_INTERCEPT_TOUCH = 1 << 7;
public static boolean checkAndClear(int flag) { public static boolean checkAndClear(int flag) {
boolean set = (state & flag) > 0; boolean set = (state & flag) > 0;
state &= ~flag; state &= ~flag;

@ -160,7 +160,7 @@ public class TasksWidget extends AppWidgetProvider {
int flags = publicPrefs.getInt(SortHelper.PREF_SORT_FLAGS, 0); int flags = publicPrefs.getInt(SortHelper.PREF_SORT_FLAGS, 0);
int sort = publicPrefs.getInt(SortHelper.PREF_SORT_SORT, 0); int sort = publicPrefs.getInt(SortHelper.PREF_SORT_SORT, 0);
String query = SortHelper.adjustQueryForFlagsAndSort( String query = SortHelper.adjustQueryForFlagsAndSort(
filter.sqlQuery, flags, sort).replaceAll("LIMIT \\d+", "") + " LIMIT " + numberOfTasks; filter.getSqlQuery(), flags, sort).replaceAll("LIMIT \\d+", "") + " LIMIT " + numberOfTasks;
database.openForReading(); database.openForReading();
cursor = taskService.fetchFiltered(query, null, Task.ID, Task.TITLE, Task.DUE_DATE, Task.COMPLETION_DATE); cursor = taskService.fetchFiltered(query, null, Task.ID, Task.TITLE, Task.DUE_DATE, Task.COMPLETION_DATE);
@ -219,11 +219,11 @@ public class TasksWidget extends AppWidgetProvider {
Bundle extras = AndroidUtilities.bundleFromSerializedString(serializedExtras); Bundle extras = AndroidUtilities.bundleFromSerializedString(serializedExtras);
listIntent.putExtras(extras); listIntent.putExtras(extras);
} }
listIntent.putExtra(TaskListFragment.TOKEN_SOURCE, Constants.SOURCE_WIDGET); listIntent.putExtra(TaskListActivity.TOKEN_SOURCE, Constants.SOURCE_WIDGET);
listIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); listIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
if(filter != null) { if(filter != null) {
listIntent.putExtra(TaskListFragment.TOKEN_FILTER, filter); listIntent.putExtra(TaskListFragment.TOKEN_FILTER, filter);
listIntent.setAction("L" + widgetId + filter.sqlQuery); listIntent.setAction("L" + widgetId + filter.getSqlQuery());
} else { } else {
listIntent.setAction("L" + widgetId); listIntent.setAction("L" + widgetId);
} }
@ -332,7 +332,7 @@ public class TasksWidget extends AppWidgetProvider {
Filter filter = CoreFilterExposer.buildInboxFilter(getResources()); Filter filter = CoreFilterExposer.buildInboxFilter(getResources());
String sql = Preferences.getStringValue(WidgetConfigActivity.PREF_SQL + widgetId); String sql = Preferences.getStringValue(WidgetConfigActivity.PREF_SQL + widgetId);
if(sql != null) if(sql != null)
filter.sqlQuery = sql; filter.setSqlQuery(sql);
String title = Preferences.getStringValue(WidgetConfigActivity.PREF_TITLE + widgetId); String title = Preferences.getStringValue(WidgetConfigActivity.PREF_TITLE + widgetId);
if(title != null) if(title != null)
filter.title = title; filter.title = title;
@ -344,7 +344,7 @@ public class TasksWidget extends AppWidgetProvider {
+ widgetId); + widgetId);
if (customComponent != null) { if (customComponent != null) {
ComponentName component = ComponentName.unflattenFromString(customComponent); ComponentName component = ComponentName.unflattenFromString(customComponent);
filter = new FilterWithCustomIntent(filter.title, filter.title, filter.sqlQuery, filter.valuesForNewTasks); filter = new FilterWithCustomIntent(filter.title, filter.title, filter.getSqlQuery(), filter.valuesForNewTasks);
((FilterWithCustomIntent) filter).customTaskList = component; ((FilterWithCustomIntent) filter).customTaskList = component;
} }

@ -136,7 +136,7 @@ abstract public class WidgetConfigActivity extends ListActivity {
String sql = null, contentValuesString = null, title = null; String sql = null, contentValuesString = null, title = null;
if(filterListItem != null && filterListItem instanceof Filter) { if(filterListItem != null && filterListItem instanceof Filter) {
sql = ((Filter)filterListItem).sqlQuery; sql = ((Filter)filterListItem).getSqlQuery();
ContentValues values = ((Filter)filterListItem).valuesForNewTasks; ContentValues values = ((Filter)filterListItem).valuesForNewTasks;
if(values != null) if(values != null)
contentValuesString = AndroidUtilities.contentValuesToSerializedString(values); contentValuesString = AndroidUtilities.contentValuesToSerializedString(values);

Loading…
Cancel
Save