New task actions--killed the quick action bar and REQUEST_ACTIONS api constant

pull/14/head
Sam Bosley 13 years ago
parent d814380b0b
commit 451abd43c6

@ -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
* <li> 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
* <li> EXTRAS_ADDON your add-on identifier
* <li> EXTRAS_TASK_ID id of the task
* <li> EXTRAS_RESPONSE a String
*/
public static final String BROADCAST_SEND_ACTIONS = PACKAGE + ".SEND_ACTIONS";
// --- Task Decorations API
/**

@ -343,13 +343,6 @@
android:theme="@style/Theme.Dialog"/>
<activity android:name="com.todoroo.astrid.actfm.TagUpdatesActivity"
android:windowSoftInputMode="stateHidden"/>
<!-- <receiver android:name="com.todoroo.astrid.actfm.EditPeopleExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_ACTIONS" />
<action android:name="com.todoroo.astrid.EDIT_PEOPLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver> -->
<receiver android:name="com.timsu.astrid.C2DMReceiver" permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>

@ -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 <tim@todoroo.com>
*
*/
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);
}
}
}

@ -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 <tim@todoroo.com>
*
*/
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<TaskAction> getActionsForTask(Context context, long taskId) {
List<TaskAction> result = new ArrayList<TaskAction>();
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<ResolveInfo> 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;
}
}

@ -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 <tim@todoroo.com>
*
*/
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);
}
}
}

@ -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<Metadata> 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<String> tags;
final TodorooCursor<Metadata> cursor = TagService.getInstance().getTags(
taskId);
try {
if (!cursor.moveToFirst())
return;
tags = new ArrayList<String>();
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<String>(ContextManager.getContext(),
android.R.layout.select_dialog_item, tags),
listener).show();
}
}
}

@ -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 <tim@todoroo.com>
*
*/
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);
}
}
}

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

@ -78,13 +78,27 @@
<!-- due date -->
<TextView
android:id="@+id/dueDate"
<LinearLayout
android:id="@+id/taskActionContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:minHeight="40dip"
android:layout_marginRight="4dip"
android:gravity="center_vertical|right" />
android:orientation="vertical"
android:gravity="right|center_vertical">
<TextView
android:id="@+id/dueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:gravity="center_vertical|right" />
<ImageView
android:id="@+id/taskActionIcon"
android:layout_width="20dip"
android:layout_height="20dip"
android:scaleType="fitCenter"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
<!-- details line 1 -->

@ -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$

@ -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<Long, StringBuilder> taskDetailLoader = Collections.synchronizedMap(new HashMap<Long, StringBuilder>(0));
private final Map<Long, TaskAction> taskActionLoader = Collections.synchronizedMap(new HashMap<Long, TaskAction>());
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<Task> 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<TaskAction> 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 <tim@todoroo.com>
*
*/
public class TaskActionManager extends TaskAdapterAddOnManager<TaskAction> {
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<TaskAction> get(long taskId) {
return super.get(taskId);
}
@Override
protected void draw(final ViewHolder viewHolder, final long taskId, Collection<TaskAction> 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<Integer, TaskAction> positionActionMap =
new HashMap<Integer, TaskAction>(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<TaskAction> 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<TaskAction> 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<TaskAction> 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) {

Loading…
Cancel
Save