From adea1b31264cb13da3bca556a98a9f026f4fcfef Mon Sep 17 00:00:00 2001 From: Tim Su Date: Tue, 24 Aug 2010 02:02:33 -0700 Subject: [PATCH] AST-246 - caching task details --- astrid/AndroidManifest.xml | 38 ++- astrid/astrid.launch | 2 +- .../astrid/alarms/AlarmDetailExposer.java | 9 +- .../astrid/notes/NoteDetailExposer.java | 9 +- .../producteev/ProducteevDetailExposer.java | 9 +- .../astrid/repeats/RepeatDetailExposer.java | 4 +- .../astrid/rmilk/MilkDetailExposer.java | 9 +- .../todoroo/astrid/tags/TagDetailExposer.java | 9 +- astrid/res/layout/task_adapter_row.xml | 2 +- .../astrid/activity/TaskListActivity.java | 4 +- .../todoroo/astrid/adapter/TaskAdapter.java | 229 +++++++++++------- .../com/todoroo/astrid/api/DetailExposer.java | 26 -- .../src/com/todoroo/astrid/dao/Database.java | 6 +- .../src/com/todoroo/astrid/dao/TaskDao.java | 4 + astrid/src/com/todoroo/astrid/model/Task.java | 13 +- 15 files changed, 207 insertions(+), 166 deletions(-) delete mode 100644 astrid/src/com/todoroo/astrid/api/DetailExposer.java diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 16bf4d4ec..0aca243eb 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -189,6 +189,12 @@ + + + + + + @@ -202,6 +208,12 @@ + + + + + + @@ -217,6 +229,12 @@ + + + + + + @@ -255,6 +273,12 @@ + + + + + + - + + + + + + + @@ -373,6 +403,12 @@ + + + + + + diff --git a/astrid/astrid.launch b/astrid/astrid.launch index 19f7df00c..89ae0a49d 100644 --- a/astrid/astrid.launch +++ b/astrid/astrid.launch @@ -12,7 +12,7 @@ - + diff --git a/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmDetailExposer.java index b8596da3b..4a25599e1 100644 --- a/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmDetailExposer.java @@ -12,7 +12,6 @@ import com.timsu.astrid.R; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; import com.todoroo.astrid.model.Metadata; /** @@ -21,7 +20,7 @@ import com.todoroo.astrid.model.Metadata; * @author Tim Su * */ -public class AlarmDetailExposer extends BroadcastReceiver implements DetailExposer { +public class AlarmDetailExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -44,7 +43,6 @@ public class AlarmDetailExposer extends BroadcastReceiver implements DetailExpos context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } - @Override public String getTaskDetails(Context context, long id, boolean extended) { if(extended) return null; @@ -71,9 +69,4 @@ public class AlarmDetailExposer extends BroadcastReceiver implements DetailExpos } } - @Override - public String getPluginIdentifier() { - return AlarmService.IDENTIFIER; - } - } diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java index ba9a879c0..29df48da9 100644 --- a/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java @@ -10,7 +10,6 @@ import android.content.Intent; import com.timsu.astrid.R; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.model.Task; import com.todoroo.astrid.utility.Preferences; @@ -21,7 +20,7 @@ import com.todoroo.astrid.utility.Preferences; * @author Tim Su * */ -public class NoteDetailExposer extends BroadcastReceiver implements DetailExposer { +public class NoteDetailExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -44,7 +43,6 @@ public class NoteDetailExposer extends BroadcastReceiver implements DetailExpose context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } - @Override public String getTaskDetails(Context context, long id, boolean extended) { if(Preferences.getBoolean(R.string.p_showNotes, false)) { @@ -65,9 +63,4 @@ public class NoteDetailExposer extends BroadcastReceiver implements DetailExpose return " " + notes; //$NON-NLS-1$ } - @Override - public String getPluginIdentifier() { - return NotesPlugin.IDENTIFIER; - } - } diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java index 545a3f822..69f14ccfd 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java @@ -11,7 +11,6 @@ import com.timsu.astrid.R; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.StoreObject; import com.todoroo.astrid.producteev.sync.ProducteevDashboard; @@ -27,7 +26,7 @@ import com.todoroo.astrid.utility.Preferences; * @author Tim Su * */ -public class ProducteevDetailExposer extends BroadcastReceiver implements DetailExposer{ +public class ProducteevDetailExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -52,7 +51,6 @@ public class ProducteevDetailExposer extends BroadcastReceiver implements Detail context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } - @Override public String getTaskDetails(Context context, long id, boolean extended) { Metadata metadata = ProducteevDataService.getInstance().getTaskMetadata(id); if(metadata == null) @@ -133,9 +131,4 @@ public class ProducteevDetailExposer extends BroadcastReceiver implements Detail return null; } - @Override - public String getPluginIdentifier() { - return ProducteevUtilities.IDENTIFIER; - } - } diff --git a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatDetailExposer.java index e3cc35d97..9ae22f082 100644 --- a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatDetailExposer.java @@ -17,7 +17,6 @@ import com.google.ical.values.RRule; import com.google.ical.values.WeekdayNum; import com.timsu.astrid.R; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.model.Task; @@ -27,7 +26,7 @@ import com.todoroo.astrid.model.Task; * @author Tim Su * */ -public class RepeatDetailExposer extends BroadcastReceiver implements DetailExposer { +public class RepeatDetailExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -119,7 +118,6 @@ public class RepeatDetailExposer extends BroadcastReceiver implements DetailExpo return null; } - @Override public String getPluginIdentifier() { return RepeatsPlugin.IDENTIFIER; } diff --git a/astrid/plugin-src/com/todoroo/astrid/rmilk/MilkDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/rmilk/MilkDetailExposer.java index 6f0eebdd4..4348f354d 100644 --- a/astrid/plugin-src/com/todoroo/astrid/rmilk/MilkDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/rmilk/MilkDetailExposer.java @@ -11,7 +11,6 @@ import com.timsu.astrid.R; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.rmilk.data.MilkDataService; import com.todoroo.astrid.rmilk.data.MilkNote; @@ -26,7 +25,7 @@ import com.todoroo.astrid.rmilk.data.MilkTask; * @author Tim Su * */ -public class MilkDetailExposer extends BroadcastReceiver implements DetailExposer{ +public class MilkDetailExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -51,7 +50,6 @@ public class MilkDetailExposer extends BroadcastReceiver implements DetailExpose context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } - @Override public String getTaskDetails(Context context, long id, boolean extended) { Metadata metadata = MilkDataService.getInstance().getTaskMetadata(id); if(metadata == null) @@ -92,9 +90,4 @@ public class MilkDetailExposer extends BroadcastReceiver implements DetailExpose return result.substring(0, result.length() - TaskAdapter.DETAIL_SEPARATOR.length()); } - @Override - public String getPluginIdentifier() { - return MilkUtilities.IDENTIFIER; - } - } diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java index 21172fe2e..a4f0b26fe 100644 --- a/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java @@ -8,7 +8,6 @@ import android.content.Context; import android.content.Intent; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; /** * Exposes Task Detail for tags, i.e. "Tags: frogs, animals" @@ -16,7 +15,7 @@ import com.todoroo.astrid.api.DetailExposer; * @author Tim Su * */ -public class TagDetailExposer extends BroadcastReceiver implements DetailExposer { +public class TagDetailExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -39,7 +38,6 @@ public class TagDetailExposer extends BroadcastReceiver implements DetailExposer context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } - @Override public String getTaskDetails(Context context, long id, boolean extended) { if(extended) return null; @@ -51,9 +49,4 @@ public class TagDetailExposer extends BroadcastReceiver implements DetailExposer return " " + tagList; //$NON-NLS-1$ } - @Override - public String getPluginIdentifier() { - return TagsPlugin.IDENTIFIER; - } - } diff --git a/astrid/res/layout/task_adapter_row.xml b/astrid/res/layout/task_adapter_row.xml index 40c201cac..136776479 100644 --- a/astrid/res/layout/task_adapter_row.xml +++ b/astrid/res/layout/task_adapter_row.xml @@ -8,13 +8,13 @@ android:paddingBottom="4dip" android:paddingLeft="4dip" android:paddingRight="4dip" - android:minHeight="40dip" android:orientation="vertical"> diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java index a574089ca..50c8a6e1b 100644 --- a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java @@ -477,9 +477,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, } else if(AstridApiConstants.BROADCAST_SEND_DETAILS.equals(intent.getAction())) { String detail = extras.getString(AstridApiConstants.EXTRAS_RESPONSE); if(extras.getBoolean(AstridApiConstants.EXTRAS_EXTENDED)) - taskAdapter.detailManager.addNew(taskId, addOn, detail); - else taskAdapter.extendedDetailManager.addNew(taskId, addOn, detail); + else + 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); diff --git a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java index a36f16fab..dcd7ca948 100644 --- a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java @@ -1,6 +1,7 @@ package com.todoroo.astrid.adapter; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -15,6 +16,7 @@ import android.database.Cursor; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.text.Html; +import android.text.TextUtils; import android.text.Html.ImageGetter; import android.text.util.Linkify; import android.view.ContextMenu; @@ -43,18 +45,12 @@ import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.SoftHashMap; import com.todoroo.astrid.activity.TaskEditActivity; import com.todoroo.astrid.activity.TaskListActivity; -import com.todoroo.astrid.alarms.AlarmDetailExposer; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.DetailExposer; import com.todoroo.astrid.api.TaskAction; import com.todoroo.astrid.api.TaskDecoration; import com.todoroo.astrid.model.Task; -import com.todoroo.astrid.notes.NoteDetailExposer; -import com.todoroo.astrid.producteev.ProducteevDetailExposer; -import com.todoroo.astrid.repeats.RepeatDetailExposer; -import com.todoroo.astrid.rmilk.MilkDetailExposer; +import com.todoroo.astrid.service.AddOnService; import com.todoroo.astrid.service.TaskService; -import com.todoroo.astrid.tags.TagDetailExposer; import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Preferences; @@ -83,16 +79,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { Task.COMPLETION_DATE, Task.HIDE_UNTIL, Task.DELETION_DATE, - }; - - /** Internal Task Detail exposers */ - public static final DetailExposer[] EXPOSERS = new DetailExposer[] { - new TagDetailExposer(), - new RepeatDetailExposer(), - new NoteDetailExposer(), - new MilkDetailExposer(), - new ProducteevDetailExposer(), - new AlarmDetailExposer(), + Task.DETAILS, }; private static int[] IMPORTANCE_COLORS = null; @@ -105,6 +92,9 @@ public class TaskAdapter extends CursorAdapter implements Filterable { @Autowired private TaskService taskService; + @Autowired + private AddOnService addOnService; + protected final ListActivity activity; protected final HashMap completedItems = new HashMap(); private OnCompletedTaskListener onCompletedTaskListener = null; @@ -112,6 +102,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { private final int resource; private final LayoutInflater inflater; private int fontSize; + private DetailLoaderThread detailLoader; private final AtomicReference query; @@ -120,8 +111,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { // --- task detail and decoration soft caches - public final DetailManager detailManager = new DetailManager(false); - public final DetailManager extendedDetailManager = new DetailManager(true); + public final DetailManager extendedDetailManager = new DetailManager(); public final DecorationManager decorationManager = new DecorationManager(); public final TaskActionManager taskActionManager = new TaskActionManager(); @@ -159,6 +149,9 @@ public class TaskAdapter extends CursorAdapter implements Filterable { if(IMPORTANCE_COLORS == null) IMPORTANCE_COLORS = Task.getImportanceColors(activity.getResources()); } + + detailLoader = new DetailLoaderThread(); + detailLoader.start(); } /* ====================================================================== @@ -221,6 +214,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { ViewHolder viewHolder = ((ViewHolder)view.getTag()); Task task = viewHolder.task; + task.clear(); task.readFromCursor(cursor); setFieldContentsAndVisibility(view); @@ -324,9 +318,21 @@ public class TaskAdapter extends CursorAdapter implements Filterable { importanceView.setBackgroundColor(0); } + String details; + if(tasksToLoad.containsKey(task.getId())) + details = tasksToLoad.get(task.getId()).getValue(Task.DETAILS); + else + details = task.getValue(Task.DETAILS); + if(TextUtils.isEmpty(details)) { + viewHolder.details.setVisibility(View.GONE); + } else { + viewHolder.details.setVisibility(View.VISIBLE); + viewHolder.details.setText(Html.fromHtml(details.trim().replace("\n", //$NON-NLS-1$ + "
"), detailImageGetter, null)); //$NON-NLS-1$ + } + // details and decorations, expanded if(!isFling) { - detailManager.request(viewHolder); decorationManager.request(viewHolder); if(expanded == task.getId()) { extendedDetailManager.request(viewHolder); @@ -337,8 +343,9 @@ public class TaskAdapter extends CursorAdapter implements Filterable { } } else { long taskId = viewHolder.task.getId(); - detailManager.reset(viewHolder, taskId); decorationManager.reset(viewHolder, taskId); + viewHolder.extendedDetails.setVisibility(View.GONE); + viewHolder.actions.setVisibility(View.GONE); } } @@ -359,6 +366,81 @@ public class TaskAdapter extends CursorAdapter implements Filterable { container.setOnClickListener(listener); } + /* ====================================================================== + * ============================================================== details + * ====================================================================== */ + + private final Map tasksToLoad = Collections.synchronizedMap(new HashMap()); + + public class DetailLoaderThread extends Thread { + @Override + public void run() { + // for all of the tasks returned by our cursor, verify details + TodorooCursor fetchCursor = taskService.fetchFiltered( + query.get(), null, Task.ID, Task.DETAILS); + activity.startManagingCursor(fetchCursor); + Task task = new Task(); + for(fetchCursor.moveToFirst(); !fetchCursor.isAfterLast(); fetchCursor.moveToNext()) { + task.clear(); + task.readFromCursor(fetchCursor); + if(!task.containsNonNullValue(Task.DETAILS)) { + System.err.println("READING details for " + task.getId()); + + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_DETAILS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId()); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_EXTENDED, false); + activity.sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); + + Task loadHolder = new Task(fetchCursor); + tasksToLoad.put(task.getId(), loadHolder); + + task.setValue(Task.DETAILS, ""); //$NON-NLS-1$ + taskService.save(task); + } + } + } + } + + /** + * Add detail to a task + * + * @param id + * @param detail + */ + public void addDetails(long id, String detail) { + final Task task = tasksToLoad.get(id); + if(task == null) + return; + String newDetails = task.getValue(Task.DETAILS); + if(TextUtils.isEmpty(newDetails)) + newDetails = detail; + else if(newDetails.contains(detail)) + return; + else + newDetails += DETAIL_SEPARATOR + detail; + task.setValue(Task.DETAILS, newDetails); + taskService.save(task); + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + notifyDataSetInvalidated(); + } + }); + } + + private final ImageGetter detailImageGetter = new ImageGetter() { + public Drawable getDrawable(String source) { + Resources r = activity.getResources(); + int drawable = r.getIdentifier("drawable/" + source, null, Constants.PACKAGE); //$NON-NLS-1$ + if(drawable == 0) + return null; + Drawable d = r.getDrawable(drawable); + d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight()); + return d; + } + }; + /* ====================================================================== * ============================================================== add-ons * ====================================================================== */ @@ -367,10 +449,11 @@ public class TaskAdapter extends CursorAdapter implements Filterable { * Called to tell the cache to be cleared */ public void flushCaches() { - detailManager.clearCache(); extendedDetailManager.clearCache(); decorationManager.clearCache(); taskActionManager.clearCache(); + detailLoader = new DetailLoaderThread(); + detailLoader.start(); } /** @@ -380,62 +463,21 @@ public class TaskAdapter extends CursorAdapter implements Filterable { */ public class DetailManager extends AddOnManager { - private final ImageGetter imageGetter = new ImageGetter() { - public Drawable getDrawable(String source) { - Resources r = activity.getResources(); - int drawable = r.getIdentifier("drawable/" + source, null, Constants.PACKAGE); //$NON-NLS-1$ - if(drawable == 0) - return null; - Drawable d = r.getDrawable(drawable); - d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight()); - return d; - } - }; - - private final boolean extended; - public DetailManager(boolean extended) { - this.extended = extended; + public DetailManager() { + // } @Override Intent createBroadcastIntent(long taskId) { Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_DETAILS); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_EXTENDED, extended); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_EXTENDED, true); return broadcastIntent; } @Override - public boolean request(final ViewHolder viewHolder) { - if(super.request(viewHolder)) { - final long taskId = viewHolder.task.getId(); - // load internal details - new Thread() { - @Override - public void run() { - for(DetailExposer exposer : EXPOSERS) { - final String detail = exposer.getTaskDetails(activity, - taskId, extended); - if(detail == null) - continue; - final Collection cacheList = - addIfNotExists(taskId, exposer.getPluginIdentifier(), - detail); - if(cacheList != null) { - if(taskId != viewHolder.task.getId()) - continue; - activity.runOnUiThread(new Runnable() { - public void run() { - draw(viewHolder, taskId, cacheList); - } - }); - } - } - }; - }.start(); - return true; - } - return false; + public void addNew(long taskId, String addOn, String item) { + super.addNew(taskId, addOn, item); } @SuppressWarnings("nls") @@ -443,9 +485,9 @@ public class TaskAdapter extends CursorAdapter implements Filterable { void draw(ViewHolder viewHolder, long taskId, Collection details) { if(details == null || viewHolder.task.getId() != taskId) return; - TextView view = extended ? viewHolder.extendedDetails : viewHolder.details; - reset(viewHolder, taskId); - if(details.isEmpty() || (extended && expanded != taskId)) { + TextView view = viewHolder.extendedDetails; + if(details.isEmpty() || (expanded != taskId)) { + reset(viewHolder, taskId); return; } view.setVisibility(View.VISIBLE); @@ -457,7 +499,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { } String string = detailText.toString(); if(string.contains("<")) - view.setText(Html.fromHtml(string.trim().replace("\n", "
"), imageGetter, null)); + view.setText(Html.fromHtml(string.trim().replace("\n", "
"), + detailImageGetter, null)); else view.setText(string.trim()); Linkify.addLinks(view, Linkify.ALL); @@ -465,7 +508,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { @Override void reset(ViewHolder viewHolder, long taskId) { - TextView view = extended ? viewHolder.extendedDetails : viewHolder.details; + TextView view = viewHolder.extendedDetails; view.setVisibility(View.GONE); } } @@ -533,6 +576,11 @@ public class TaskAdapter extends CursorAdapter implements Filterable { * */ public class TaskActionManager extends AddOnManager { + + private final LinearLayout.LayoutParams params = + new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT, 1f); + @Override Intent createBroadcastIntent(long taskId) { Intent intent = new Intent(AstridApiConstants.BROADCAST_REQUEST_ACTIONS); @@ -545,15 +593,24 @@ public class TaskAdapter extends CursorAdapter implements Filterable { if(actions == null || viewHolder.task.getId() != taskId) return; - reset(viewHolder, taskId); + // hack because we know we have > 1 button + if(addOnService.hasPowerPack() && actions.size() == 0) + return; - LinearLayout.LayoutParams params = - new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, - LayoutParams.FILL_PARENT, 1f); + for(int i = viewHolder.actions.getChildCount(); i < actions.size() + 1; i++) { + Button editButton = new Button(activity); + editButton.setLayoutParams(params); + viewHolder.actions.addView(editButton); + } + if(actions.size() + 1 < viewHolder.actions.getChildCount()) + viewHolder.actions.removeViews(0, viewHolder.actions.getChildCount() - + actions.size() - 1); - Button editButton = new Button(activity); - editButton.setText(R.string.TAd_actionEditTask); - editButton.setOnClickListener(new OnClickListener() { + int i = 0; + Button button = (Button) viewHolder.actions.getChildAt(i++); + + button.setText(R.string.TAd_actionEditTask); + button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(activity, TaskEditActivity.class); @@ -561,17 +618,14 @@ public class TaskAdapter extends CursorAdapter implements Filterable { activity.startActivityForResult(intent, TaskListActivity.ACTIVITY_EDIT_TASK); } }); - editButton.setLayoutParams(params); - viewHolder.actions.addView(editButton); for(TaskAction action : actions) { - Button view = new Button(activity); - view.setText(action.text); - view.setOnClickListener(new ActionClickListener(action)); - view.setLayoutParams(params); - viewHolder.actions.addView(view); + button = (Button) viewHolder.actions.getChildAt(i++); + button.setText(action.text); + button.setOnClickListener(new ActionClickListener(action)); } + reset(viewHolder, taskId); } @Override @@ -581,7 +635,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { return; } viewHolder.actions.setVisibility(View.VISIBLE); - viewHolder.actions.removeAllViews(); } } diff --git a/astrid/src/com/todoroo/astrid/api/DetailExposer.java b/astrid/src/com/todoroo/astrid/api/DetailExposer.java deleted file mode 100644 index 90ef95b9d..000000000 --- a/astrid/src/com/todoroo/astrid/api/DetailExposer.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.todoroo.astrid.api; - -import android.content.Context; - -/** - * Internal API for Task Details - * - * @author Tim Su - * - */ -public interface DetailExposer { - - /** - * @param id - * task id - * @param extended - * whether this request is for extended details (which are - * displayed when user presses a task), or standard (which are - * always displayed) - * @return null if no details, or task details - */ - public String getTaskDetails(Context context, long id, boolean extended); - - public String getPluginIdentifier(); - -} diff --git a/astrid/src/com/todoroo/astrid/dao/Database.java b/astrid/src/com/todoroo/astrid/dao/Database.java index 6bef32257..949845695 100644 --- a/astrid/src/com/todoroo/astrid/dao/Database.java +++ b/astrid/src/com/todoroo/astrid/dao/Database.java @@ -28,7 +28,7 @@ public class Database extends AbstractDatabase { * Database version number. This variable must be updated when database * tables are updated, as it determines whether a database needs updating. */ - public static final int VERSION = 4; + public static final int VERSION = 5; /** * Database name (must be unique) @@ -119,6 +119,10 @@ public class Database extends AbstractDatabase { append(')'); database.execSQL(sql.toString()); } + case 4: { + database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " + + Task.DETAILS.accept(visitor, null)); + } return true; } diff --git a/astrid/src/com/todoroo/astrid/dao/TaskDao.java b/astrid/src/com/todoroo/astrid/dao/TaskDao.java index 6298f9af6..f55ba4c6a 100644 --- a/astrid/src/com/todoroo/astrid/dao/TaskDao.java +++ b/astrid/src/com/todoroo/astrid/dao/TaskDao.java @@ -157,6 +157,10 @@ public class TaskDao extends GenericDao { return false; } + // clear task detail cache + if(values != null && !values.containsKey(Task.DETAILS.name)) + values.put(Task.DETAILS.name, (String)null); + if (task.getId() == Task.NO_ID) { saveSuccessful = createNew(task); } else { diff --git a/astrid/src/com/todoroo/astrid/model/Task.java b/astrid/src/com/todoroo/astrid/model/Task.java index b0130614d..aa81af7f8 100644 --- a/astrid/src/com/todoroo/astrid/model/Task.java +++ b/astrid/src/com/todoroo/astrid/model/Task.java @@ -14,11 +14,11 @@ import android.content.res.Resources; import com.timsu.astrid.R; import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.Property; +import com.todoroo.andlib.data.Table; +import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.Property.IntegerProperty; import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.StringProperty; -import com.todoroo.andlib.data.Table; -import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.utility.DateUtilities; /** @@ -72,7 +72,13 @@ public final class Task extends AbstractModel { public static final LongProperty DELETION_DATE = new LongProperty( TABLE, "deleted"); - // --- for migration purposes from astrid 2 (eventually we will want to + /** Cached Details Column - built from add-on detail exposers. A null + * value means there is no value in the cache and it needs to be + * refreshed */ + public static final StringProperty DETAILS = new StringProperty( + TABLE, "details"); + + // --- for migration purposes from astrid 2 (eventually we may want to // move these into the metadata table and treat them as plug-ins public static final StringProperty NOTES = new StringProperty( @@ -179,6 +185,7 @@ public final class Task extends AbstractModel { defaultValues.put(NOTES.name, ""); defaultValues.put(FLAGS.name, 0); defaultValues.put(TIMER_START.name, 0); + defaultValues.put(DETAILS.name, (String)null); } @Override