diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 82a3f211f..92d45f3c0 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -152,7 +152,7 @@ - @@ -180,8 +180,8 @@ - - + + diff --git a/astrid/src/com/todoroo/astrid/dao/DatabaseUpdateListener.java b/astrid/src/com/todoroo/astrid/dao/DatabaseUpdateListener.java new file mode 100644 index 000000000..69a6e9cf9 --- /dev/null +++ b/astrid/src/com/todoroo/astrid/dao/DatabaseUpdateListener.java @@ -0,0 +1,7 @@ +package com.todoroo.astrid.dao; + +public interface DatabaseUpdateListener { + + public void onDatabaseUpdated(); + +} diff --git a/astrid/src/com/todoroo/astrid/dao/TaskDao.java b/astrid/src/com/todoroo/astrid/dao/TaskDao.java index f9643d559..301273477 100644 --- a/astrid/src/com/todoroo/astrid/dao/TaskDao.java +++ b/astrid/src/com/todoroo/astrid/dao/TaskDao.java @@ -17,15 +17,16 @@ import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Functions; import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.provider.Astrid2TaskProvider; +import com.todoroo.astrid.provider.Astrid3ContentProvider; import com.todoroo.astrid.reminders.Notifications; import com.todoroo.astrid.reminders.ReminderService; -import com.todoroo.andlib.utility.Preferences; -import com.todoroo.astrid.widget.PowerWidget; import com.todoroo.astrid.widget.PowerWidget42; +import com.todoroo.astrid.widget.PowerWidget44; import com.todoroo.astrid.widget.TasksWidget; /** @@ -244,14 +245,26 @@ public class TaskDao extends DatabaseDao { afterTasklistChange(); } + private final DatabaseUpdateListener[] taskChangeListeners = new DatabaseUpdateListener[] { + new DatabaseUpdateListener() { + @Override + public void onDatabaseUpdated() { + Astrid2TaskProvider.notifyDatabaseModification(); + Astrid3ContentProvider.notifyDatabaseModification(); + TasksWidget.updateWidgets(ContextManager.getContext()); + } + }, + new PowerWidget44(), + new PowerWidget42() + }; + /** * Called when task list has changed */ private void afterTasklistChange() { - Astrid2TaskProvider.notifyDatabaseModification(); - TasksWidget.updateWidgets(ContextManager.getContext()); - PowerWidget.updateWidgets(ContextManager.getContext()); - PowerWidget42.updateWidgets(ContextManager.getContext()); + for(DatabaseUpdateListener listener : taskChangeListeners) { + listener.onDatabaseUpdated(); + } } /** diff --git a/astrid/src/com/todoroo/astrid/provider/Astrid3ContentProvider.java b/astrid/src/com/todoroo/astrid/provider/Astrid3ContentProvider.java index dd6fd796f..b412a9726 100644 --- a/astrid/src/com/todoroo/astrid/provider/Astrid3ContentProvider.java +++ b/astrid/src/com/todoroo/astrid/provider/Astrid3ContentProvider.java @@ -4,6 +4,7 @@ package com.todoroo.astrid.provider; import android.content.ContentProvider; +import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; @@ -17,6 +18,7 @@ import com.todoroo.andlib.data.AbstractDatabase; import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.DatabaseDao; import com.todoroo.andlib.service.Autowired; +import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.ExceptionService; import com.todoroo.astrid.api.AstridApiConstants; @@ -371,4 +373,11 @@ public class Astrid3ContentProvider extends ContentProvider { return cursor; } + // --- change listeners + + public static void notifyDatabaseModification() { + ContentResolver cr = ContextManager.getContext().getContentResolver(); + cr.notifyChange(Task.CONTENT_URI, null); + } + } diff --git a/astrid/src/com/todoroo/astrid/widget/PowerWidget.java b/astrid/src/com/todoroo/astrid/widget/PowerWidget.java index 337dfab8b..d9b013b99 100644 --- a/astrid/src/com/todoroo/astrid/widget/PowerWidget.java +++ b/astrid/src/com/todoroo/astrid/widget/PowerWidget.java @@ -31,26 +31,31 @@ import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.core.CoreFilterExposer; import com.todoroo.astrid.dao.Database; +import com.todoroo.astrid.dao.DatabaseUpdateListener; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.service.AstridDependencyInjector; import com.todoroo.astrid.service.TaskService; /** - * Power Pack widget. Supports 4x4 size. Configured via - * ConfigurePowerWidgetActivity when widget is added to homescreen. + * Power Pack widget * * @author jwong (jwong@dayspring-tech.com) * */ @SuppressWarnings("nls") -public class PowerWidget extends AppWidgetProvider { +abstract public class PowerWidget extends AppWidgetProvider implements DatabaseUpdateListener { static final String LOG_TAG = "PowerWidget"; - static Class updateService; + // --- abstract hooks + + /** service for updating the widget */ + abstract public Class getUpdateService(); + + // --- implementation + static { AstridDependencyInjector.initialize(); - updateService = PowerWidget.UpdateService.class; } @@ -100,9 +105,6 @@ public class PowerWidget extends AppWidgetProvider { R.id.checkbox3, R.id.checkbox4, R.id.checkbox5, R.id.checkbox6, R.id.checkbox7, R.id.checkbox8, R.id.checkbox9, R.id.checkbox10 }; - // # of rows defined in the xml file - static int ROW_LIMIT = 10; - public static int[] IMPORTANCE_DRAWABLES = new int[] { R.drawable.importance_1, R.drawable.importance_2, R.drawable.importance_3, R.drawable.importance_4, R.drawable.importance_5, R.drawable.importance_6 @@ -119,7 +121,7 @@ public class PowerWidget extends AppWidgetProvider { super.onUpdate(context, appWidgetManager, appWidgetIds); // Start in service to prevent Application Not Responding timeout - Intent updateIntent = new Intent(context, updateService); + Intent updateIntent = new Intent(context, getUpdateService()); updateIntent.putExtra(APP_WIDGET_IDS, appWidgetIds); context.startService(updateIntent); } catch (SecurityException e) { @@ -158,7 +160,7 @@ public class PowerWidget extends AppWidgetProvider { if (intent != null && (ACTION_SCROLL_UP.equals(intent.getAction()) || ACTION_SCROLL_DOWN.equals(intent.getAction()) || ACTION_MARK_COMPLETE.equals(intent.getAction()))) { - Intent updateIntent = new Intent(context, updateService); + Intent updateIntent = new Intent(context, getUpdateService()); updateIntent.setAction(intent.getAction()); updateIntent.putExtras(intent.getExtras()); context.startService(updateIntent); @@ -168,34 +170,36 @@ public class PowerWidget extends AppWidgetProvider { } - - /** - * Update all widgets - * @param id - */ - public static void updateWidgets(Context context) { - context.startService(new Intent(ContextManager.getContext(), - updateService)); + @Override + public void onDatabaseUpdated() { + Context context = ContextManager.getContext(); + context.startService(new Intent(context, getUpdateService())); } /** * Update widget with the given id * @param id */ - public static void updateAppWidget(Context context, int appWidgetId){ - Intent updateIntent = new Intent(context, updateService); + public void updateAppWidget(Context context, int appWidgetId){ + Intent updateIntent = new Intent(context, getUpdateService()); updateIntent.putExtra(APP_WIDGET_IDS, new int[]{ appWidgetId }); context.startService(updateIntent); } - public static class UpdateService extends Service { - static Class widgetClass; - static int widgetLayout; + abstract public static class UpdateService extends Service { - static { - widgetClass = PowerWidget.class; - widgetLayout = R.layout.widget_power_44; - } + // --- abstract hooks + + /** widget class */ + abstract public Class getWidgetClass(); + + /** widget layout resource id */ + abstract public int getWidgetLayout(); + + /** # rows defined in the xml file */ + abstract public int getRowLimit(); + + // --- implementation private static final int SCROLL_OFFSET_UNSET = -1; @@ -232,7 +236,7 @@ public class PowerWidget extends AppWidgetProvider { manager.updateAppWidget(appWidgetId, views); } else { if (appWidgetIds == null){ - appWidgetIds = manager.getAppWidgetIds(new ComponentName(this, widgetClass)); + appWidgetIds = manager.getAppWidgetIds(new ComponentName(this, getWidgetClass())); } for (int id : appWidgetIds) { RemoteViews views = buildUpdate(this, id, scrollOffset); @@ -250,7 +254,7 @@ public class PowerWidget extends AppWidgetProvider { DependencyInjectionService.getInstance().inject(this); RemoteViews views = new RemoteViews(context.getPackageName(), - widgetLayout); + getWidgetLayout()); String color = Preferences.getStringValue(PowerWidget.PREF_COLOR + appWidgetId); @@ -344,7 +348,7 @@ public class PowerWidget extends AppWidgetProvider { scrollOffset = Math.max(0, scrollOffset); query = query.replaceAll("[lL][iI][mM][iI][tT] +[^ ]+", "") + " LIMIT " + - scrollOffset + "," + (ROW_LIMIT + 1); + scrollOffset + "," + (getRowLimit() + 1); // load last completed task Task lastCompleted = null; @@ -364,7 +368,7 @@ public class PowerWidget extends AppWidgetProvider { Task task = new Task(); int position; - for (position = 0; position < cursor.getCount() && position < ROW_LIMIT; position++) { + for (position = 0; position < cursor.getCount() && position < getRowLimit(); position++) { if(lastCompleted != null && lastCompletedPosition == position + scrollOffset) { task = lastCompleted; } else { @@ -386,7 +390,7 @@ public class PowerWidget extends AppWidgetProvider { IMPORTANCE_DRAWABLES[task.getValue(Task.IMPORTANCE)]); // check box - Intent markCompleteIntent = new Intent(context, widgetClass); + Intent markCompleteIntent = new Intent(context, getWidgetClass()); markCompleteIntent.setAction(ACTION_MARK_COMPLETE); markCompleteIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); markCompleteIntent.putExtra(COMPLETED_TASK_ID, taskId); @@ -441,7 +445,7 @@ public class PowerWidget extends AppWidgetProvider { views.setViewVisibility(TASK_DUE[position], View.VISIBLE); } - for(; position < ROW_LIMIT; position++) { + for(; position < getRowLimit(); position++) { views.setViewVisibility(TASK_IMPORTANCE[position], View.INVISIBLE); views.setViewVisibility(TASK_CHECKBOX[position], View.INVISIBLE); views.setViewVisibility(TASK_TITLE[position], View.INVISIBLE); @@ -449,7 +453,7 @@ public class PowerWidget extends AppWidgetProvider { } // create intent to scroll up - Intent scrollUpIntent = new Intent(context, widgetClass); + Intent scrollUpIntent = new Intent(context, getWidgetClass()); scrollUpIntent.setAction(ACTION_SCROLL_UP); scrollUpIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); scrollUpIntent.setType(AppWidgetManager.EXTRA_APPWIDGET_ID + appWidgetId); @@ -467,7 +471,7 @@ public class PowerWidget extends AppWidgetProvider { views.setOnClickPendingIntent(R.id.scroll_up_alt, pScrollUpIntent); // create intent to scroll down - Intent scrollDownIntent = new Intent(context, widgetClass); + Intent scrollDownIntent = new Intent(context, getWidgetClass()); scrollDownIntent.setAction(ACTION_SCROLL_DOWN); scrollDownIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); scrollDownIntent.setType(AppWidgetManager.EXTRA_APPWIDGET_ID + appWidgetId); diff --git a/astrid/src/com/todoroo/astrid/widget/PowerWidget42.java b/astrid/src/com/todoroo/astrid/widget/PowerWidget42.java index 0891259fe..0386a58f0 100644 --- a/astrid/src/com/todoroo/astrid/widget/PowerWidget42.java +++ b/astrid/src/com/todoroo/astrid/widget/PowerWidget42.java @@ -2,37 +2,28 @@ package com.todoroo.astrid.widget; import com.timsu.astrid.R; -/** - * Power Pack widget. Supports 4x2 size. Configured via - * ConfigurePowerWidget42Activity when widget is added to homescreen. - * - * This class extends PowerWidget but sets references to itself for use in Intents. - * - * @author jwong (jwong@dayspring-tech.com) - * - */ public class PowerWidget42 extends PowerWidget { - static { - // set reference to my UpdateService for calls to launch the service - updateService = PowerWidget42.UpdateService.class; - - ROW_LIMIT = 5; + @Override + public Class getUpdateService() { + return UpdateService42.class; } - /** - * Extend PowerWidget's UpdateService so that the widget provider class - * can be specified. We can't just used PowerWidget's UpdateService - * since it's a static class and uses PowerWidget's variables, not this - * class' variables. - * - * @author jwong (jwong@dayspring-tech.com) - * - */ - public static class UpdateService extends PowerWidget.UpdateService { - static { - widgetClass = PowerWidget42.class; - widgetLayout = R.layout.widget_power_42; + public static class UpdateService42 extends PowerWidget.UpdateService { + + @Override + public Class getWidgetClass() { + return PowerWidget42.class; + } + + @Override + public int getWidgetLayout() { + return R.layout.widget_power_42; + } + + @Override + public int getRowLimit() { + return 5; } } diff --git a/astrid/src/com/todoroo/astrid/widget/PowerWidget44.java b/astrid/src/com/todoroo/astrid/widget/PowerWidget44.java new file mode 100644 index 000000000..728fa6b3d --- /dev/null +++ b/astrid/src/com/todoroo/astrid/widget/PowerWidget44.java @@ -0,0 +1,30 @@ +package com.todoroo.astrid.widget; + +import com.timsu.astrid.R; + +public class PowerWidget44 extends PowerWidget { + + @Override + public Class getUpdateService() { + return UpdateService44.class; + } + + public static class UpdateService44 extends PowerWidget.UpdateService { + + @Override + public Class getWidgetClass() { + return PowerWidget44.class; + } + + @Override + public int getWidgetLayout() { + return R.layout.widget_power_44; + } + + @Override + public int getRowLimit() { + return 10; + } + } + +} diff --git a/astrid/src/com/todoroo/astrid/widget/WidgetConfigActivity.java b/astrid/src/com/todoroo/astrid/widget/WidgetConfigActivity.java index 93041bc92..7a475b778 100644 --- a/astrid/src/com/todoroo/astrid/widget/WidgetConfigActivity.java +++ b/astrid/src/com/todoroo/astrid/widget/WidgetConfigActivity.java @@ -111,9 +111,6 @@ public class WidgetConfigActivity extends ExpandableListActivity { // Save configuration options saveConfiguration(adapter.getSelection(), color, enableCalendar, !disableEncouragements); - // Push widget update to surface with newly set prefix - PowerWidget.updateAppWidget(context, mAppWidgetId); - // Make sure we pass back the original appWidgetId Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);