diff --git a/api/src/com/todoroo/astrid/api/AstridApiConstants.java b/api/src/com/todoroo/astrid/api/AstridApiConstants.java index aa55d876b..c61601977 100644 --- a/api/src/com/todoroo/astrid/api/AstridApiConstants.java +++ b/api/src/com/todoroo/astrid/api/AstridApiConstants.java @@ -167,22 +167,6 @@ public class AstridApiConstants { */ public static final String BROADCAST_SEND_SYNC_ACTIONS = PACKAGE + ".SEND_SYNC_ACTIONS"; - // --- Task Actions API - - /** - * Action name for broadcast intent requesting actions for a task - *
  • EXTRAS_TASK_ID id of the task - */ - public static final String BROADCAST_REQUEST_ACTIONS = PACKAGE + ".REQUEST_ACTIONS"; - - /** - * Action name for broadcast intent sending actions back to Astrid - *
  • EXTRAS_ADDON your add-on identifier - *
  • EXTRAS_TASK_ID id of the task - *
  • EXTRAS_RESPONSE a String - */ - public static final String BROADCAST_SEND_ACTIONS = PACKAGE + ".SEND_ACTIONS"; - // --- Task Decorations API /** diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 60f4dd7e0..f3731ecff 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -343,13 +343,6 @@ android:theme="@style/Theme.Dialog"/> - diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleExposer.java b/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleExposer.java deleted file mode 100644 index a7d4675e8..000000000 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleExposer.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.actfm; - -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.timsu.astrid.R; -import com.todoroo.andlib.service.ContextManager; -import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; -import com.todoroo.astrid.activity.TaskEditFragment; -import com.todoroo.astrid.activity.TaskEditActivity; -import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.TaskAction; -import com.todoroo.astrid.api.TaskDecoration; -import com.todoroo.astrid.service.AstridDependencyInjector; - -/** - * Exposes {@link TaskDecoration} for timers - * - * @author Tim Su - * - */ -public class EditPeopleExposer extends BroadcastReceiver { - - private static final String ACTION = "com.todoroo.astrid.EDIT_PEOPLE"; //$NON-NLS-1$ - - static { - AstridDependencyInjector.initialize(); - } - - @Override - public void onReceive(Context context, Intent intent) { - ContextManager.setContext(context); - long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); - if(taskId == -1) - return; - - if(AstridApiConstants.BROADCAST_REQUEST_ACTIONS.equals(intent.getAction())) { - final String label = context.getString(R.string.EPE_action); - final int drawable = R.drawable.ic_qbar_share; - Intent newIntent = new Intent(ACTION); - newIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - TaskAction action = new TaskAction(label, - PendingIntent.getBroadcast(context, (int)taskId, newIntent, 0), null); - action.drawable = drawable; - - // transmit - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ACTIONS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, ActFmPreferenceService.IDENTIFIER); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, action); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); - } else if(ACTION.equals(intent.getAction())) { - Intent launchIntent = new Intent(context, TaskEditActivity.class); - launchIntent.putExtra(TaskEditFragment.TOKEN_ID, taskId); - launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - ContextManager.getContext().startActivity(launchIntent); - } - } - -} diff --git a/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java b/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java index 4f7e76cec..a0e20892d 100644 --- a/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java @@ -3,14 +3,15 @@ */ package com.todoroo.astrid.core; +import java.util.ArrayList; import java.util.List; import android.app.PendingIntent; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -19,8 +20,7 @@ import android.text.Spannable; import android.text.style.URLSpan; import android.text.util.Linkify; -import com.todoroo.andlib.service.ContextManager; -import com.todoroo.astrid.api.AstridApiConstants; +import com.timsu.astrid.R; import com.todoroo.astrid.api.TaskAction; import com.todoroo.astrid.api.TaskDecoration; import com.todoroo.astrid.data.Task; @@ -31,26 +31,24 @@ import com.todoroo.astrid.data.Task; * @author Tim Su * */ -public class LinkActionExposer extends BroadcastReceiver { +public class LinkActionExposer { private PackageManager pm; - @Override - public void onReceive(Context context, Intent intent) { - ContextManager.setContext(context); - long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); + public List getActionsForTask(Context context, long taskId) { + List result = new ArrayList(); if(taskId == -1) - return; + return result; Task task = PluginServices.getTaskService().fetchById(taskId, Task.ID, Task.TITLE); - if (task == null) return; + if (task == null) return result; Spannable titleSpan = Spannable.Factory.getInstance().newSpannable(task.getValue(Task.TITLE)); Linkify.addLinks(titleSpan, Linkify.ALL); URLSpan[] urlSpans = titleSpan.getSpans(0, titleSpan.length(), URLSpan.class); if(urlSpans.length == 0) - return; + return result; pm = context.getPackageManager(); @@ -59,11 +57,15 @@ public class LinkActionExposer extends BroadcastReceiver { int start = titleSpan.getSpanStart(urlSpan); int end = titleSpan.getSpanEnd(urlSpan); String text = titleSpan.subSequence(start, end).toString(); - sendLinkAction(context, taskId, url, text); + TaskAction taskAction = createLinkAction(context, url, text); + if (taskAction != null) + result.add(taskAction); } + return result; } - private void sendLinkAction(Context context, long taskId, String url, String text) { + @SuppressWarnings("nls") + private TaskAction createLinkAction(Context context, String url, String text) { Intent itemIntent = new Intent(Intent.ACTION_VIEW); itemIntent.setData(Uri.parse(url)); List resolveInfoList = pm.queryIntentActivities(itemIntent, 0); @@ -82,9 +84,17 @@ public class LinkActionExposer extends BroadcastReceiver { // no intents -> no item else - return; - - Drawable icon = resolveInfoList.get(0).loadIcon(pm); + return null; + + Resources r = context.getResources(); + Drawable icon; + if (url.startsWith("mailto")) { + icon = r.getDrawable(R.drawable.action_mail); + } else if (url.startsWith("tel")) { + icon = r.getDrawable(R.drawable.action_tel); + } else { + icon = r.getDrawable(R.drawable.action_web); + } Bitmap bitmap = ((BitmapDrawable)icon).getBitmap(); if(text.length() > 15) @@ -92,13 +102,7 @@ public class LinkActionExposer extends BroadcastReceiver { TaskAction action = new TaskAction(text, PendingIntent.getActivity(context, 0, actionIntent, 0), bitmap); - - // transmit - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ACTIONS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, CorePlugin.IDENTIFIER); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, action); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); + return action; } } diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteExposer.java b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteExposer.java deleted file mode 100644 index ead1b9c59..000000000 --- a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteExposer.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.notes; - -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.timsu.astrid.R; -import com.todoroo.andlib.service.Autowired; -import com.todoroo.andlib.service.ContextManager; -import com.todoroo.andlib.service.DependencyInjectionService; -import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; -import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.TaskAction; -import com.todoroo.astrid.api.TaskDecoration; -import com.todoroo.astrid.core.PluginServices; -import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.service.AstridDependencyInjector; - -/** - * Exposes {@link TaskDecoration} for timers - * - * @author Tim Su - * - */ -public class EditNoteExposer extends BroadcastReceiver { - - private static final String ACTION = "com.todoroo.astrid.EDIT_NOTES"; //$NON-NLS-1$ - - @Autowired ActFmPreferenceService actFmPreferenceService; - - static { - AstridDependencyInjector.initialize(); - } - - @Override - public void onReceive(Context context, Intent intent) { - ContextManager.setContext(context); - DependencyInjectionService.getInstance().inject(this); - long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); - if(taskId == -1) - return; - - if(AstridApiConstants.BROADCAST_REQUEST_ACTIONS.equals(intent.getAction())) { - String label; - int drawable; - - if(!actFmPreferenceService.isLoggedIn()) { - Task task = PluginServices.getTaskService().fetchById(taskId, Task.ID, Task.NOTES); - if(task == null || !NotesPlugin.hasNotes(task)) - return; - label = context.getString(R.string.ENE_label); - drawable = R.drawable.ic_qbar_comments; - } else { - label = context.getString(R.string.ENE_label_comments); - drawable = R.drawable.ic_qbar_comments; - } - Intent newIntent = new Intent(ACTION); - newIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - TaskAction action = new TaskAction(label, - PendingIntent.getBroadcast(context, (int)taskId, newIntent, 0), null); - action.drawable = drawable; - - // transmit - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ACTIONS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, NotesPlugin.IDENTIFIER); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, action); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); - } else if(ACTION.equals(intent.getAction())) { - Intent launchIntent = new Intent(context, EditNoteActivity.class); - launchIntent.putExtra(EditNoteActivity.EXTRA_TASK_ID, taskId); - launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - ContextManager.getContext().startActivity(launchIntent); - } - } - -} diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagExposer.java b/astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagExposer.java deleted file mode 100644 index 2b0b6a524..000000000 --- a/astrid/plugin-src/com/todoroo/astrid/tags/FilterByTagExposer.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.todoroo.astrid.tags; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ContentValues; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -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.TaskListFragment; -import com.todoroo.astrid.activity.TaskListActivity; -import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.api.TaskAction; -import com.todoroo.astrid.dao.TaskDao.TaskCriteria; -import com.todoroo.astrid.data.Metadata; -import com.todoroo.astrid.tags.TagService.Tag; - -public class FilterByTagExposer extends BroadcastReceiver { - - private static final String FILTER_ACTION = "com.todoroo.astrid.FILTER_BY_TAG"; //$NON-NLS-1$ - - @Override - public void onReceive(Context context, Intent intent) { - ContextManager.setContext(context); - long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); - if(taskId == -1) - return; - - TodorooCursor cursor = TagService.getInstance().getTags(taskId); - try { - if(cursor.getCount() == 0) - return; - } finally { - cursor.close(); - } - - if(AstridApiConstants.BROADCAST_REQUEST_ACTIONS.equals(intent.getAction())) { - final String label = context.getString(R.string.TAd_contextFilterByTag); - final Drawable drawable = context.getResources().getDrawable(R.drawable.med_tag); - Intent newIntent = new Intent(FILTER_ACTION); - newIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - Bitmap icon = ((BitmapDrawable)drawable).getBitmap(); - TaskAction action = new TaskAction(label, - PendingIntent.getBroadcast(context, (int)taskId, newIntent, 0), icon); - - // transmit - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ACTIONS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, TagsPlugin.IDENTIFIER); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, action); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); - } else if(FILTER_ACTION.equals(intent.getAction())) { - invoke(taskId); - } - } - - public void invoke(long taskId) { - final List tags; - final TodorooCursor cursor = TagService.getInstance().getTags( - taskId); - 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, 0); - - String listTitle = tag.tag; - String title = 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(TaskListFragment.TOKEN_FILTER, tagFilter); - - ContextManager.getContext().startActivity(tagIntent); - if (ContextManager.getContext() instanceof Activity) - AndroidUtilities.callOverridePendingTransition((Activity) ContextManager.getContext(), 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/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java b/astrid/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java deleted file mode 100644 index 534225ad3..000000000 --- a/astrid/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.timers; - -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.timsu.astrid.R; -import com.todoroo.andlib.service.ContextManager; -import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.TaskAction; -import com.todoroo.astrid.api.TaskDecoration; -import com.todoroo.astrid.core.PluginServices; -import com.todoroo.astrid.data.Task; - -/** - * Exposes {@link TaskDecoration} for timers - * - * @author Tim Su - * - */ -public class TimerActionExposer extends BroadcastReceiver { - - private static final String TIMER_ACTION = "com.todoroo.astrid.TIMER_BUTTON"; //$NON-NLS-1$ - - @Override - public void onReceive(Context context, Intent intent) { - ContextManager.setContext(context); - long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); - if(taskId == -1) - return; - - Task task = PluginServices.getTaskService().fetchById(taskId, Task.ID, Task.TIMER_START, - Task.ELAPSED_SECONDS); - if(task == null) - return; - - // was part of a broadcast for actions - if(AstridApiConstants.BROADCAST_REQUEST_ACTIONS.equals(intent.getAction())) { - final String label; - final int drawable; - if(task.getValue(Task.TIMER_START) == 0) { - label = context.getString(R.string.TAE_startTimer); - drawable = R.drawable.ic_qbar_timer_start; - } else { - label = context.getString(R.string.TAE_stopTimer); - drawable = R.drawable.ic_qbar_timer_stop; - } - Intent newIntent = new Intent(TIMER_ACTION); - newIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - TaskAction action = new TaskAction(label, - PendingIntent.getBroadcast(context, (int)taskId, newIntent, 0), null); - action.drawable = drawable; - - // transmit - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ACTIONS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, TimerPlugin.IDENTIFIER); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, action); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); - } else if(TIMER_ACTION.equals(intent.getAction())) { - if(task.getValue(Task.TIMER_START) == 0) - TimerPlugin.updateTimer(context, task, true); - else - TimerPlugin.updateTimer(context, task, false); - } - } - -} diff --git a/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java b/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java index d10e0e3aa..9894b351c 100644 --- a/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java +++ b/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java @@ -60,11 +60,6 @@ public class TimerPlugin extends BroadcastReceiver { } } PluginServices.getTaskService().save(task); - - // transmit new intents - Intent intent = new Intent(AstridApiConstants.BROADCAST_REQUEST_ACTIONS); - intent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId()); - new TimerActionExposer().onReceive(context, intent); new TimerDecorationExposer().updateDecoration(context, task); // update notification diff --git a/astrid/res/drawable/action_mail.png b/astrid/res/drawable/action_mail.png new file mode 100644 index 000000000..0b402716c Binary files /dev/null and b/astrid/res/drawable/action_mail.png differ diff --git a/astrid/res/drawable/action_tel.png b/astrid/res/drawable/action_tel.png new file mode 100644 index 000000000..3de59e32c Binary files /dev/null and b/astrid/res/drawable/action_tel.png differ diff --git a/astrid/res/drawable/action_web.png b/astrid/res/drawable/action_web.png new file mode 100644 index 000000000..2926d1f90 Binary files /dev/null and b/astrid/res/drawable/action_web.png differ diff --git a/astrid/res/layout/task_adapter_row.xml b/astrid/res/layout/task_adapter_row.xml index a2b82a00c..730c33d50 100644 --- a/astrid/res/layout/task_adapter_row.xml +++ b/astrid/res/layout/task_adapter_row.xml @@ -78,13 +78,27 @@ - + android:orientation="vertical" + android:gravity="right|center_vertical"> + + + diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java b/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java index f085a9b8b..898ae0bc1 100644 --- a/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java @@ -95,7 +95,6 @@ import com.todoroo.astrid.api.AstridApiConstants; 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; @@ -752,8 +751,6 @@ public class TaskListFragment extends ListFragment implements OnScrollListener, new IntentFilter(AstridApiConstants.BROADCAST_SEND_DETAILS)); getActivity().registerReceiver(detailReceiver, new IntentFilter(AstridApiConstants.BROADCAST_SEND_DECORATIONS)); - getActivity().registerReceiver(detailReceiver, - new IntentFilter(AstridApiConstants.BROADCAST_SEND_ACTIONS)); getActivity().registerReceiver(refreshReceiver, new IntentFilter(AstridApiConstants.BROADCAST_EVENT_REFRESH)); getActivity().registerReceiver( @@ -878,10 +875,6 @@ public class TaskListFragment extends ListFragment implements OnScrollListener, } else if (AstridApiConstants.BROADCAST_SEND_DETAILS.equals(intent.getAction())) { String detail = extras.getString(AstridApiConstants.EXTRAS_RESPONSE); taskAdapter.addDetails(taskId, detail); - } else if (AstridApiConstants.BROADCAST_SEND_ACTIONS.equals(intent.getAction())) { - TaskAction action = extras.getParcelable(AstridApiConstants.EXTRAS_RESPONSE); - taskAdapter.taskActionManager.addNew(taskId, addOn, action, - null); } } catch (Exception e) { exceptionService.reportError("receive-detail-" + //$NON-NLS-1$ diff --git a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java index 47a7442ce..939ccf360 100644 --- a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java @@ -1,15 +1,12 @@ package com.todoroo.astrid.adapter; import greendroid.widget.AsyncImageView; -import greendroid.widget.QuickAction; -import greendroid.widget.QuickActionBar; -import greendroid.widget.QuickActionWidget; -import greendroid.widget.QuickActionWidget.OnQuickActionClickListener; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; @@ -18,16 +15,13 @@ import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; -import android.content.BroadcastReceiver; +import android.app.PendingIntent.CanceledException; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.content.res.Resources; import android.database.Cursor; -import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.text.Html; import android.text.Html.ImageGetter; @@ -56,7 +50,6 @@ import android.widget.CursorAdapter; import android.widget.Filterable; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; @@ -76,6 +69,7 @@ import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.TaskAction; import com.todoroo.astrid.api.TaskDecoration; import com.todoroo.astrid.api.TaskDecorationExposer; +import com.todoroo.astrid.core.LinkActionExposer; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.helper.TaskAdapterAddOnManager; import com.todoroo.astrid.notes.NotesDecorationExposer; @@ -177,10 +171,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { private final int minRowHeight; - // quick action bar - private QuickActionWidget mBar; - private final QuickActionListener mBarListener = new QuickActionListener(); - // measure utilities protected final Paint paint; protected final DisplayMetrics displayMetrics; @@ -188,7 +178,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { // --- task detail and decoration soft caches public final DecorationManager decorationManager; - public final TaskActionManager taskActionManager; /** * Constructor @@ -230,7 +219,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { } decorationManager = new DecorationManager(); - taskActionManager = new TaskActionManager(); scaleAnimation = new ScaleAnimation(1.4f, 1.0f, 1.4f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); @@ -278,7 +266,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { viewHolder.details1 = (TextView)view.findViewById(R.id.details1); viewHolder.details2 = (TextView)view.findViewById(R.id.details2); viewHolder.taskRow = (LinearLayout)view.findViewById(R.id.task_row); - + viewHolder.taskActionContainer = view.findViewById(R.id.taskActionContainer); + viewHolder.taskActionIcon = (ImageView)view.findViewById(R.id.taskActionIcon); if (Preferences.getBoolean(R.string.p_showNotes, false)) { @@ -343,6 +332,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { public TextView dueDate; public TextView details1, details2; public LinearLayout taskRow; + public View taskActionContainer; + public ImageView taskActionIcon; public View[] decorations; } @@ -489,6 +480,20 @@ public class TaskAdapter extends CursorAdapter implements Filterable { } } + // Task action + ImageView taskAction = viewHolder.taskActionIcon; + if (taskAction != null) { + if (taskActionLoader.containsKey(task.getId())) { + taskAction.setVisibility(View.VISIBLE); + TaskAction action = taskActionLoader.get(task.getId()); + taskAction.setImageBitmap(action.icon); + taskAction.setTag(action); + } else { + taskAction.setVisibility(View.GONE); + taskAction.setTag(null); + } + } + if(Math.abs(DateUtilities.now() - task.getValue(Task.MODIFICATION_DATE)) < 2000L) mostRecentlyMade = task.getId(); @@ -563,6 +568,20 @@ public class TaskAdapter extends CursorAdapter implements Filterable { viewHolder.completeBox.setOnTouchListener(otl); viewHolder.completeBox.setOnClickListener(completeBoxListener); + viewHolder.taskActionContainer.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + TaskAction action = (TaskAction) viewHolder.taskActionIcon.getTag(); + if (action != null) { + try { + action.intent.send(); + } catch (CanceledException e) { + // Oh well + } + } + } + }); + if(applyListenersToRowBody) { viewHolder.rowBody.setOnCreateContextMenuListener(listener); viewHolder.rowBody.setOnClickListener(listener); @@ -611,6 +630,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { // a large number of tasks to load, since it all goes into memory. // it's best to do this, though, in order to append details to each other private final Map taskDetailLoader = Collections.synchronizedMap(new HashMap(0)); + private final Map taskActionLoader = Collections.synchronizedMap(new HashMap()); public class DetailLoaderThread extends Thread { @Override @@ -618,18 +638,24 @@ public class TaskAdapter extends CursorAdapter implements Filterable { // for all of the tasks returned by our cursor, verify details AndroidUtilities.sleepDeep(500L); TodorooCursor fetchCursor = taskService.fetchFiltered( - query.get(), null, Task.ID, Task.DETAILS, Task.DETAILS_DATE, + query.get(), null, Task.ID, Task.TITLE, Task.DETAILS, Task.DETAILS_DATE, Task.MODIFICATION_DATE, Task.COMPLETION_DATE); try { Random random = new Random(); Task task = new Task(); + LinkActionExposer linkActionExposer = new LinkActionExposer(); + for(fetchCursor.moveToFirst(); !fetchCursor.isAfterLast(); fetchCursor.moveToNext()) { task.clear(); task.readFromCursor(fetchCursor); if(task.isCompleted()) continue; + List actions = linkActionExposer.getActionsForTask(ContextManager.getContext(), task.getId()); + if (actions.size() > 0) + taskActionLoader.put(task.getId(), actions.get(0)); + if(detailsAreRecentAndUpToDate(task)) { // even if we are up to date, randomly load a fraction if(random.nextFloat() < 0.1) { @@ -653,7 +679,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { requestNewDetails(task); } - if(taskDetailLoader.size() > 0) { + if(taskDetailLoader.size() > 0 || taskActionLoader.size() > 0) { Activity activity = fragment.getActivity(); if (activity != null) { activity.runOnUiThread(new Runnable() { @@ -764,8 +790,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { public void flushCaches() { completedItems.clear(); decorationManager.clearCache(); - taskActionManager.clearCache(); taskDetailLoader.clear(); + taskActionLoader.clear(); detailLoader = new DetailLoaderThread(); detailLoader.start(); } @@ -776,8 +802,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { public void flushSpecific(long taskId) { completedItems.put(taskId, null); decorationManager.clearCache(taskId); - taskActionManager.clearCache(taskId); taskDetailLoader.remove(taskId); + taskActionLoader.remove(taskId); } /** @@ -884,76 +910,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { } } - /** - * AddOnManager for TaskActions - * - * @author Tim Su - * - */ - public class TaskActionManager extends TaskAdapterAddOnManager { - - private final Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_ACTIONS); - - public TaskActionManager() { - super(fragment); - } - - @Override - protected Intent createBroadcastIntent(Task task) { - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId()); - return broadcastIntent; - } - - @Override - public synchronized void addNew(long taskId, String addOn, final TaskAction item, ViewHolder thisViewHolder) { - addIfNotExists(taskId, addOn, item); - if(mBar != null) { - ListView listView = fragment.getListView(); - ViewHolder myHolder = null; - - // update view if it is visible - int length = listView.getChildCount(); - for(int i = 0; i < length; i++) { - ViewHolder viewHolder = (ViewHolder) listView.getChildAt(i).getTag(); - if(viewHolder == null || viewHolder.task.getId() != taskId) - continue; - myHolder = viewHolder; - break; - } - - if(myHolder != null) { - final ViewHolder viewHolder = myHolder; - Activity activity = fragment.getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - mBarListener.addWithAction(item); - if (!viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) - mBar.show(viewHolder.view); - } - }); - } - } - } - } - - @Override - public Collection get(long taskId) { - return super.get(taskId); - } - - @Override - protected void draw(final ViewHolder viewHolder, final long taskId, Collection actions) { - // do not draw - } - - @Override - protected void reset(ViewHolder viewHolder, long taskId) { - // do not draw - } - } - /* ====================================================================== * ======================================================= event handlers * ====================================================================== */ @@ -991,78 +947,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { return (ViewHolder)((View)v.getParent()).getTag(); } - private final class QuickActionListener implements OnQuickActionClickListener { - private final HashMap positionActionMap = - new HashMap(2); - private long taskId; - private int itemCount = 0; - private int iconWidth; - - public void initialize(long newTaskId) { - this.taskId = newTaskId; - itemCount = 0; - positionActionMap.clear(); - mBar.setOnQuickActionClickListener(this); - iconWidth = fragment.getResources().getDrawable(R.drawable.ic_qbar_edit).getIntrinsicHeight(); - } - - public void addWithAction(TaskAction item) { - Drawable drawable; - if(item.drawable > 0) - drawable = fragment.getResources().getDrawable(item.drawable); - else { - Bitmap scaledBitmap = Bitmap.createScaledBitmap(item.icon, iconWidth, iconWidth, true); - drawable = new BitmapDrawable(fragment.getResources(), scaledBitmap); - } - addWithAction(new QuickAction(drawable, item.text), item); - } - - public void addWithAction(QuickAction quickAction, TaskAction taskAction) { - positionActionMap.put(itemCount++, taskAction); - mBar.addQuickAction(quickAction); - } - - public void onQuickActionClicked(QuickActionWidget widget, int position){ - if(mBar != null) - mBar.dismiss(); - mBar = null; - - if(position == 0) { - editTask(taskId); - } else { - flushSpecific(taskId); - try { - TaskAction taskAction = positionActionMap.get(position); - if(taskAction != null) { - taskAction.intent.send(); - } - } catch (Exception e) { - exceptionService.displayAndReportError(fragment.getActivity(), - "Error launching action", e); //$NON-NLS-1$ - } - } - notifyDataSetChanged(); - } - } - private class TaskRowListener implements OnCreateContextMenuListener, OnClickListener { - // prepare quick action bar - private void prepareQuickActionBar(ViewHolder viewHolder, Collection collection){ - mBar = new QuickActionBar(viewHolder.view.getContext()); - QuickAction editAction = new QuickAction(fragment.getActivity(), R.drawable.ic_qbar_edit, - fragment.getString(R.string.TAd_actionEditTask)); - mBarListener.initialize(viewHolder.task.getId()); - - mBarListener.addWithAction(editAction, null); - - if(collection != null) { - for(TaskAction item : collection) { - mBarListener.addWithAction(item); - } - } - } - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // this is all a big sham. it's actually handled in Task List @@ -1077,51 +963,10 @@ public class TaskAdapter extends CursorAdapter implements Filterable { return; long taskId = viewHolder.task.getId(); - - Collection actions = taskActionManager.get(taskId); - prepareQuickActionBar(viewHolder, actions); - //mBarAnchor = v; - if(actions != null && !viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) { - if (actions.size() > 0) - mBar.show(v); - else { - editTask(taskId); - } - } else if (!viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) { - // Register a temporary receiver in case we clicked a task with no actions forthcoming and should start - IntentFilter filter = new IntentFilter(AstridApiConstants.BROADCAST_REQUEST_ACTIONS); - filter.setPriority(-1); - fragment.getActivity().registerReceiver(new TaskActionsFinishedReceiver(), filter); - } - taskActionManager.request(viewHolder); - - - notifyDataSetChanged(); - } - } - - private class TaskActionsFinishedReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - AndroidUtilities.sleepDeep(10L); // Allow preemption for send_actions to be delivered - long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); - if (taskId != -1) { - Collection actions = taskActionManager.get(taskId); - if (actions != null && actions.size() == 0) { - editTask(taskId); - } - } - - try { - Activity activity = fragment.getActivity(); - if (activity != null) - activity.unregisterReceiver(this); - } catch (IllegalArgumentException e) { - // ignore + if (!viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) { + editTask(taskId); } } - } private void editTask(long taskId) {