From 8d8db3e1d8062944d547d9d908f6c09f0cd5277e Mon Sep 17 00:00:00 2001 From: Tim Su Date: Tue, 19 Apr 2011 19:03:11 -0700 Subject: [PATCH] Moved filter by tag to the tag plugin, created an api for task context menu actions --- .../reminders/NotificationActivity.java | 5 +- .../ReminderDebugContextActions.java | 59 ++++++ .../astrid/tags/FilterByTagContextAction.java | 103 ++++++++++ .../astrid/activity/TaskListActivity.java | 179 ++++-------------- .../astrid/api/TaskContextActionExposer.java | 43 +++++ .../astrid/api/TaskDecorationExposer.java | 6 +- 6 files changed, 254 insertions(+), 141 deletions(-) create mode 100644 astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDebugContextActions.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagContextAction.java create mode 100644 astrid/src/com/todoroo/astrid/api/TaskContextActionExposer.java diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java b/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java index 144bd5c9e..650a0b6ca 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java @@ -45,6 +45,7 @@ import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.api.Filter; +import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.repeats.RepeatControlSet; @@ -136,7 +137,7 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL public void onClick(View arg0) { Task task = new Task(); task.setId(taskId); - taskService.setComplete(task, true); + PluginServices.getTaskService().setComplete(task, true); finish(); } }); @@ -228,7 +229,7 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL Task task = new Task(); task.setId(taskId); task.setValue(Task.REMINDER_SNOOZE, time); - taskService.save(task); + PluginServices.getTaskService().save(task); finish(); } diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDebugContextActions.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDebugContextActions.java new file mode 100644 index 000000000..8f7f94aba --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDebugContextActions.java @@ -0,0 +1,59 @@ +package com.todoroo.astrid.reminders; + +import java.util.Date; + +import android.widget.Toast; + +import com.todoroo.andlib.service.ContextManager; +import com.todoroo.astrid.api.TaskContextActionExposer; +import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.reminders.ReminderService.AlarmScheduler; +import com.todoroo.astrid.utility.Constants; + +@SuppressWarnings("nls") +public class ReminderDebugContextActions { + + public static class WhenReminder implements TaskContextActionExposer { + + @Override + public Object getLabel(Task task) { + if (Constants.DEBUG) + return "when alarm?"; + return null; + } + + public void invoke(Task task) { + AlarmScheduler original = ReminderService.getInstance().getScheduler(); + ReminderService.getInstance().setScheduler(new AlarmScheduler() { + @Override + public void createAlarm(Task theTask, long time, int type) { + if(time == 0 || time == Long.MAX_VALUE) + return; + + Toast.makeText(ContextManager.getContext(), "Scheduled Alarm: " + + new Date(time), Toast.LENGTH_LONG).show(); + ReminderService.getInstance().setScheduler(null); + } + }); + ReminderService.getInstance().scheduleAlarm(task); + if(ReminderService.getInstance().getScheduler() != null) + Toast.makeText(ContextManager.getContext(), "No alarms", Toast.LENGTH_LONG).show(); + ReminderService.getInstance().setScheduler(original); + } + } + + public static class MakeNotification implements TaskContextActionExposer { + + public Object getLabel(Task task) { + if (Constants.DEBUG) + return "when alarm?"; //$NON-NLS-1$ + return null; + } + + public void invoke(Task task) { + new Notifications().showTaskNotification(task.getId(), + ReminderService.TYPE_SNOOZE, "test reminder"); + } + } + +} diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagContextAction.java b/astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagContextAction.java new file mode 100644 index 000000000..c038f775d --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagContextAction.java @@ -0,0 +1,103 @@ +package com.todoroo.astrid.tags; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import android.app.AlertDialog; +import android.content.ContentValues; +import android.content.DialogInterface; +import android.content.Intent; +import android.widget.ArrayAdapter; + +import com.timsu.astrid.R; +import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.sql.Criterion; +import com.todoroo.andlib.sql.QueryTemplate; +import com.todoroo.andlib.utility.AndroidUtilities; +import com.todoroo.astrid.activity.TaskListActivity; +import com.todoroo.astrid.api.Filter; +import com.todoroo.astrid.api.TaskContextActionExposer; +import com.todoroo.astrid.dao.TaskDao.TaskCriteria; +import com.todoroo.astrid.data.Metadata; +import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.tags.TagService.Tag; + +public class FilterByTagContextAction implements TaskContextActionExposer { + + @Override + public Object getLabel(Task task) { + TodorooCursor cursor = TagService.getInstance().getTags(task.getId()); + try { + if(cursor.getCount() > 0) + return R.string.TAd_contextFilterByTag; + } finally { + cursor.close(); + } + return null; + } + + public void invoke(Task task) { + final TodorooCursor cursor = TagService.getInstance().getTags( + task.getId()); + final List tags; + try { + if (!cursor.moveToFirst()) + return; + tags = new ArrayList(); + do { + tags.add(cursor.get(TagService.TAG)); + } while (cursor.moveToNext()); + } finally { + cursor.close(); + } + + Collator collator = Collator.getInstance(); + collator.setStrength(Collator.PRIMARY); + Collections.sort(tags, collator); + + DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + Tag tag = new Tag(tags.get(which), 0); + + String listTitle = tag.tag; + String title = ContextManager.getString( + R.string.tag_FEx_name, tag.tag); + Criterion criterion = TaskCriteria.activeAndVisible(); + QueryTemplate tagTemplate = tag.queryTemplate(criterion); + ContentValues contentValues = new ContentValues(); + contentValues.put(Metadata.KEY.name, TagService.KEY); + contentValues.put(TagService.TAG.name, tag.tag); + + Filter tagFilter = new Filter(listTitle, title, + tagTemplate, contentValues); + Intent tagIntent = new Intent(ContextManager.getContext(), + TaskListActivity.class); + tagIntent.putExtra(TaskListActivity.TOKEN_FILTER, tagFilter); + + ContextManager.getContext().startActivity(tagIntent); + AndroidUtilities.callApiMethod(5, + this, + "overridePendingTransition", //$NON-NLS-1$ + new Class[] { Integer.TYPE, Integer.TYPE }, + R.anim.slide_left_in, R.anim.slide_left_out); + } + }; + + if (tags.size() == 1) { + listener.onClick(null, 0); + } else { + new AlertDialog.Builder(ContextManager.getContext()).setTitle( + R.string.TAd_contextFilterByTag).setAdapter( + new ArrayAdapter(ContextManager.getContext(), + android.R.layout.select_dialog_item, tags), + listener).show(); + } + + } + +} diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java index 1d1966c7e..a491ec015 100644 --- a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java @@ -1,9 +1,6 @@ package com.todoroo.astrid.activity; -import java.text.Collator; import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; import java.util.LinkedHashSet; import java.util.List; import java.util.Map.Entry; @@ -65,8 +62,6 @@ import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.ExceptionService; -import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; @@ -80,6 +75,7 @@ import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.api.SyncAction; import com.todoroo.astrid.api.TaskAction; +import com.todoroo.astrid.api.TaskContextActionExposer; import com.todoroo.astrid.api.TaskDecoration; import com.todoroo.astrid.core.CoreFilterExposer; import com.todoroo.astrid.core.SortHelper; @@ -90,17 +86,14 @@ import com.todoroo.astrid.data.Task; import com.todoroo.astrid.helper.MetadataHelper; import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader; import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader.ContextMenuItem; -import com.todoroo.astrid.reminders.Notifications; -import com.todoroo.astrid.reminders.ReminderService; -import com.todoroo.astrid.reminders.ReminderService.AlarmScheduler; +import com.todoroo.astrid.reminders.ReminderDebugContextActions; import com.todoroo.astrid.service.AddOnService; import com.todoroo.astrid.service.AstridDependencyInjector; import com.todoroo.astrid.service.MetadataService; import com.todoroo.astrid.service.StartupService; import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.TaskService; -import com.todoroo.astrid.tags.TagService; -import com.todoroo.astrid.tags.TagService.Tag; +import com.todoroo.astrid.tags.FilterByTagContextAction; import com.todoroo.astrid.utility.AstridPreferences; import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Flags; @@ -137,13 +130,11 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, private static final int CONTEXT_MENU_EDIT_TASK_ID = Menu.FIRST + 20; private static final int CONTEXT_MENU_COPY_TASK_ID = Menu.FIRST + 21; - private static final int CONTEXT_MENU_FILTER_BY_TAG_ID = Menu.FIRST + 22; - private static final int CONTEXT_MENU_DELETE_TASK_ID = Menu.FIRST + 23; - private static final int CONTEXT_MENU_UNDELETE_TASK_ID = Menu.FIRST + 24; - private static final int CONTEXT_MENU_PURGE_TASK_ID = Menu.FIRST + 25; - private static final int CONTEXT_MENU_ADDON_INTENT_ID = Menu.FIRST + 26; - - private static final int CONTEXT_MENU_DEBUG = Menu.FIRST + 30; + private static final int CONTEXT_MENU_DELETE_TASK_ID = Menu.FIRST + 22; + private static final int CONTEXT_MENU_UNDELETE_TASK_ID = Menu.FIRST + 23; + private static final int CONTEXT_MENU_PURGE_TASK_ID = Menu.FIRST + 24; + private static final int CONTEXT_MENU_BROADCAST_INTENT_ID = Menu.FIRST + 25; + private static final int CONTEXT_MENU_PLUGIN_ID_FIRST = Menu.FIRST + 26; // --- constants @@ -152,20 +143,21 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, // --- instance variables - @Autowired - protected ExceptionService exceptionService; + @Autowired ExceptionService exceptionService; + + @Autowired TaskService taskService; - @Autowired - protected TaskService taskService; + @Autowired MetadataService metadataService; - @Autowired - protected MetadataService metadataService; + @Autowired Database database; - @Autowired - protected Database database; + @Autowired AddOnService addOnService; - @Autowired - protected AddOnService addOnService; + private final TaskContextActionExposer[] contextItemExposers = new TaskContextActionExposer[] { + new FilterByTagContextAction(), + new ReminderDebugContextActions.MakeNotification(), + new ReminderDebugContextActions.WhenReminder(), + }; protected TaskAdapter taskAdapter = null; protected DetailReceiver detailReceiver = new DetailReceiver(); @@ -799,7 +791,6 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, return task; } - @SuppressWarnings("nls") @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { @@ -820,31 +811,27 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, menu.add(id, CONTEXT_MENU_COPY_TASK_ID, Menu.NONE, R.string.TAd_contextCopyTask); - TodorooCursor cursor = TagService.getInstance().getTags( - id); - menu.add(id, CONTEXT_MENU_FILTER_BY_TAG_ID, Menu.NONE, - R.string.TAd_contextFilterByTag).setEnabled( - cursor.getCount() > 0); - cursor.close(); - - menu.add(id, CONTEXT_MENU_DELETE_TASK_ID, Menu.NONE, - R.string.TAd_contextDeleteTask); + for(int i = 0; i < contextItemExposers.length; i++) { + Object label = contextItemExposers[i].getLabel(task); + if(label != null) { + if(label instanceof Integer) + menu.add(id, CONTEXT_MENU_PLUGIN_ID_FIRST + i, Menu.NONE, (Integer)label); + else + menu.add(id, CONTEXT_MENU_PLUGIN_ID_FIRST + i, Menu.NONE, (String)label); + } + } long taskId = task.getId(); for(ContextMenuItem item : contextMenuExtensionLoader.getList()) { - MenuItem menuItem = menu.add(id, CONTEXT_MENU_ADDON_INTENT_ID, Menu.NONE, + MenuItem menuItem = menu.add(id, CONTEXT_MENU_BROADCAST_INTENT_ID, Menu.NONE, item.title); item.intent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); menuItem.setIntent(item.intent); } - if(Constants.DEBUG) { - menu.add("--- debug ---"); - menu.add(id, CONTEXT_MENU_DEBUG, Menu.NONE, - "when alarm?"); - menu.add(id, CONTEXT_MENU_DEBUG + 1, Menu.NONE, - "make notification"); - } + menu.add(id, CONTEXT_MENU_DELETE_TASK_ID, Menu.NONE, + R.string.TAd_contextDeleteTask); + } } @@ -970,7 +957,6 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, } @Override - @SuppressWarnings("nls") public boolean onMenuItemSelected(int featureId, final MenuItem item) { Intent intent; long itemId; @@ -1005,7 +991,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, // --- context menu items - case CONTEXT_MENU_ADDON_INTENT_ID: { + case CONTEXT_MENU_BROADCAST_INTENT_ID: { intent = item.getIntent(); sendBroadcast(intent); return true; @@ -1037,68 +1023,6 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, return true; } - case CONTEXT_MENU_FILTER_BY_TAG_ID: { - itemId = item.getGroupId(); - - final TodorooCursor cursor = TagService.getInstance().getTags( - itemId); - if (!cursor.moveToFirst()) { - cursor.close(); - return false; - } - final List tags = new ArrayList(); - do { - tags.add(cursor.get(TagService.TAG)); - } while (cursor.moveToNext()); - cursor.close(); - - Collator collator = Collator.getInstance(); - collator.setStrength(Collator.PRIMARY); - Collections.sort(tags, collator); - - DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Tag tag = new Tag(tags.get(which), 0); - - String listTitle = tag.tag; - String title = TaskListActivity.this.getString( - R.string.tag_FEx_name, tag.tag); - Criterion criterion = TaskCriteria.activeAndVisible(); - QueryTemplate tagTemplate = tag.queryTemplate(criterion); - ContentValues contentValues = new ContentValues(); - contentValues.put(Metadata.KEY.name, TagService.KEY); - contentValues.put(TagService.TAG.name, tag.tag); - - Filter tagFilter = new Filter(listTitle, title, - tagTemplate, contentValues); - Intent tagIntent = new Intent(TaskListActivity.this, - TaskListActivity.class); - tagIntent.putExtra(TaskListActivity.TOKEN_FILTER, tagFilter); - - startActivity(tagIntent); - AndroidUtilities.callApiMethod(5, - this, - "overridePendingTransition", //$NON-NLS-1$ - new Class[] { Integer.TYPE, Integer.TYPE }, - R.anim.slide_left_in, R.anim.slide_left_out); - } - }; - - if (tags.size() == 1) { - listener.onClick(null, 0); - } else { - new AlertDialog.Builder(this).setTitle( - R.string.TAd_contextFilterByTag).setAdapter( - new ArrayAdapter(this, - android.R.layout.select_dialog_item, tags), - listener).show(); - } - - return true; - } - case CONTEXT_MENU_DELETE_TASK_ID: { itemId = item.getGroupId(); Task task = new Task(); @@ -1124,41 +1048,20 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, return true; } - // --- debug - - case CONTEXT_MENU_DEBUG: { - itemId = item.getGroupId(); - Task task = new Task(); - task.setId(itemId); - AlarmScheduler original = ReminderService.getInstance().getScheduler(); - ReminderService.getInstance().setScheduler(new AlarmScheduler() { - @Override - public void createAlarm(Task theTask, long time, int type) { - if(time == 0 || time == Long.MAX_VALUE) - return; + default: { + if(item.getItemId() < CONTEXT_MENU_PLUGIN_ID_FIRST) + return false; + if(item.getItemId() - CONTEXT_MENU_PLUGIN_ID_FIRST >= contextItemExposers.length) + return false; - Toast.makeText(TaskListActivity.this, "Scheduled Alarm: " + - new Date(time), Toast.LENGTH_LONG).show(); - ReminderService.getInstance().setScheduler(null); - } - }); - ReminderService.getInstance().scheduleAlarm(task); - if(ReminderService.getInstance().getScheduler() != null) - Toast.makeText(this, "No alarms", Toast.LENGTH_LONG).show(); - ReminderService.getInstance().setScheduler(original); - return true; - } + AdapterContextMenuInfo adapterInfo = (AdapterContextMenuInfo) item.getMenuInfo(); + Task task = ((ViewHolder)adapterInfo.targetView.getTag()).task; + contextItemExposers[item.getItemId() - CONTEXT_MENU_PLUGIN_ID_FIRST].invoke(task); - case CONTEXT_MENU_DEBUG + 1: { - itemId = item.getGroupId(); - new Notifications().showTaskNotification(itemId, - ReminderService.TYPE_SNOOZE, "test reminder"); return true; } } - - return false; } @SuppressWarnings("nls") diff --git a/astrid/src/com/todoroo/astrid/api/TaskContextActionExposer.java b/astrid/src/com/todoroo/astrid/api/TaskContextActionExposer.java new file mode 100644 index 000000000..b2564beb3 --- /dev/null +++ b/astrid/src/com/todoroo/astrid/api/TaskContextActionExposer.java @@ -0,0 +1,43 @@ +package com.todoroo.astrid.api; + +import com.todoroo.astrid.data.Task; + + +/** + * API for exposing context menu items associated with a task. + * + * Due to the limitations of the Android platform, this is currently + * internal-use only, though if it can be done well, I would be open to creating + * an external API. Internal API for exposing task decorations + * + * @author Tim Su + * + */ +public interface TaskContextActionExposer { + + public class TaskContextAction{ + public int labelResource; + public Runnable action; + + public TaskContextAction(int labelResource, Runnable action) { + super(); + this.labelResource = labelResource; + this.action = action; + } + } + + /** + * Expose context menu item label, or null if item should not be shown + * @param task + * + * @return null if no item should be displayed, or string or id + */ + public Object getLabel(Task task); + + /** + * Call context menu action + * @param task + */ + public void invoke(Task task); + +} diff --git a/astrid/src/com/todoroo/astrid/api/TaskDecorationExposer.java b/astrid/src/com/todoroo/astrid/api/TaskDecorationExposer.java index 575b4952c..0cbf8bec8 100644 --- a/astrid/src/com/todoroo/astrid/api/TaskDecorationExposer.java +++ b/astrid/src/com/todoroo/astrid/api/TaskDecorationExposer.java @@ -3,7 +3,11 @@ package com.todoroo.astrid.api; import com.todoroo.astrid.data.Task; /** - * Internal API for exposing task decorations + * API for exposing decorations displayed in the task list. + * + * Due to the limitations of the Android platform, this is currently + * internal-use only, though if it can be done well, I would be open to creating + * an external API. * * @author Tim Su *