diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 553a7bb4f..e5ca88c42 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -250,7 +250,7 @@ + android:clearTaskOnLaunch="true" /> diff --git a/astrid/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java b/astrid/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java index 373091982..fed1e858e 100644 --- a/astrid/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/timers/TimerActionExposer.java @@ -9,7 +9,6 @@ import android.content.Context; import android.content.Intent; import com.timsu.astrid.R; -import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.TaskAction; import com.todoroo.astrid.api.TaskDecoration; @@ -54,19 +53,10 @@ public class TimerActionExposer extends BroadcastReceiver { broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } else if(TIMER_ACTION.equals(intent.getAction())) { - // toggle the timer if(task.getValue(Task.TIMER_START) == 0) - task.setValue(Task.TIMER_START, DateUtilities.now()); - else { - TimerTaskCompleteListener.stopTimer(task); - } - PluginServices.getTaskService().save(task, true); - TimerDecorationExposer.removeFromCache(taskId); - - // transmit new intents TimerDecoration - new TimerDecorationExposer().onReceive(context, intent); - intent.setAction(AstridApiConstants.BROADCAST_REQUEST_ACTIONS); - onReceive(context, intent); + TimerPlugin.updateTimer(context, task, true); + else + TimerPlugin.updateTimer(context, task, false); } } diff --git a/astrid/plugin-src/com/todoroo/astrid/timers/TimerFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/timers/TimerFilterExposer.java index 0bb994146..224dd34fc 100644 --- a/astrid/plugin-src/com/todoroo/astrid/timers/TimerFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/timers/TimerFilterExposer.java @@ -11,16 +11,13 @@ import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import com.timsu.astrid.R; -import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.sql.QueryTemplate; -import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.activity.FilterListActivity; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.core.PluginServices; -import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.model.Task; /** @@ -33,19 +30,12 @@ public final class TimerFilterExposer extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Resources r = context.getResources(); if(PluginServices.getTaskService().count(Query.select(Task.ID). where(Task.TIMER_START.gt(0))) == 0) return; - ContentValues values = new ContentValues(); - values.put(Task.TIMER_START.name, Filter.VALUE_NOW); - Filter workingOn = new Filter(r.getString(R.string.TFE_workingOn), - r.getString(R.string.TFE_workingOn), - new QueryTemplate().where(Task.TIMER_START.gt(0)), - values); - workingOn.listingIcon = ((BitmapDrawable)r.getDrawable(R.drawable.tango_clock)).getBitmap(); + Filter workingOn = createFilter(context); // transmit filter list FilterListItem[] list = new FilterListItem[1]; @@ -55,17 +45,16 @@ public final class TimerFilterExposer extends BroadcastReceiver { context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } - /** - * Build inbox filter - * @return - */ - public static Filter buildInboxFilter(Resources r) { - Filter inbox = new Filter(r.getString(R.string.BFE_Active), r.getString(R.string.BFE_Active_title), - new QueryTemplate().where(Criterion.and(TaskCriteria.isActive(), - TaskCriteria.isVisible(DateUtilities.now()))), - null); - inbox.listingIcon = ((BitmapDrawable)r.getDrawable(R.drawable.tango_home)).getBitmap(); - return inbox; + public static Filter createFilter(Context context) { + Resources r = context.getResources(); + ContentValues values = new ContentValues(); + values.put(Task.TIMER_START.name, Filter.VALUE_NOW); + Filter workingOn = new Filter(r.getString(R.string.TFE_workingOn), + r.getString(R.string.TFE_workingOn), + new QueryTemplate().where(Task.TIMER_START.gt(0)), + values); + workingOn.listingIcon = ((BitmapDrawable)r.getDrawable(R.drawable.tango_clock)).getBitmap(); + return workingOn; } } diff --git a/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java b/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java index 45bf1e168..a2fbe632b 100644 --- a/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java +++ b/astrid/plugin-src/com/todoroo/astrid/timers/TimerPlugin.java @@ -1,11 +1,24 @@ package com.todoroo.astrid.timers; +import android.app.Notification; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; +import com.timsu.astrid.R; +import com.todoroo.andlib.service.NotificationManager; +import com.todoroo.andlib.service.NotificationManager.AndroidNotificationManager; +import com.todoroo.andlib.sql.Query; +import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.activity.ShortcutActivity; import com.todoroo.astrid.api.Addon; import com.todoroo.astrid.api.AstridApiConstants; +import com.todoroo.astrid.api.Filter; +import com.todoroo.astrid.core.PluginServices; +import com.todoroo.astrid.model.Task; +import com.todoroo.astrid.utility.Constants; public class TimerPlugin extends BroadcastReceiver { @@ -22,4 +35,63 @@ public class TimerPlugin extends BroadcastReceiver { context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } + /** + * stops timer and sets elapsed time. you still need to save the task. + * @param task + * @param start if true, start timer. else, stop it + */ + public static void updateTimer(Context context, Task task, boolean start) { + if(start) { + if(task.getValue(Task.TIMER_START) == 0) + task.setValue(Task.TIMER_START, DateUtilities.now()); + } else { + if(task.getValue(Task.TIMER_START) > 0) { + int newElapsed = (int)((DateUtilities.now() - task.getValue(Task.TIMER_START)) / 1000L); + task.setValue(Task.TIMER_START, 0L); + task.setValue(Task.ELAPSED_SECONDS, + task.getValue(Task.ELAPSED_SECONDS) + newElapsed); + } + } + PluginServices.getTaskService().save(task, true); + TimerDecorationExposer.removeFromCache(task.getId()); + + // transmit new intents + Intent intent = new Intent(AstridApiConstants.BROADCAST_REQUEST_ACTIONS); + intent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId()); + new TimerDecorationExposer().onReceive(context, intent); + new TimerActionExposer().onReceive(context, intent); + + // update notification + TimerPlugin.updateNotifications(context); + } + + private static void updateNotifications(Context context) { + NotificationManager nm = new AndroidNotificationManager(context); + + int count = PluginServices.getTaskService().count(Query.select(Task.ID). + where(Task.TIMER_START.gt(0))); + if(count == 0) { + nm.cancel(Constants.NOTIFICATION_TIMER); + } else { + Filter filter = TimerFilterExposer.createFilter(context); + Intent notifyIntent = ShortcutActivity.createIntent(filter); + notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent pendingIntent = PendingIntent.getActivity(context, + 0, notifyIntent, 0); + + Resources r = context.getResources(); + String appName = r.getString(R.string.app_name); + String text = r.getString(R.string.TPl_notification, + r.getQuantityString(R.plurals.Ntasks, count, count)); + Notification notification = new Notification( + R.drawable.timers_notification, text, System.currentTimeMillis()); + notification.setLatestEventInfo(context, appName, + text, pendingIntent); + notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; + notification.flags &= ~Notification.FLAG_AUTO_CANCEL; + + nm.notify(Constants.NOTIFICATION_TIMER, notification); + } + } + } diff --git a/astrid/plugin-src/com/todoroo/astrid/timers/TimerTaskCompleteListener.java b/astrid/plugin-src/com/todoroo/astrid/timers/TimerTaskCompleteListener.java index 6f8404496..8da52acaf 100644 --- a/astrid/plugin-src/com/todoroo/astrid/timers/TimerTaskCompleteListener.java +++ b/astrid/plugin-src/com/todoroo/astrid/timers/TimerTaskCompleteListener.java @@ -4,24 +4,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.model.Task; public class TimerTaskCompleteListener extends BroadcastReceiver { - /** - * stops timer and sets elapsed time. you still need to save the task. - * @param task - */ - public static void stopTimer(Task task) { - int newElapsed = (int)((DateUtilities.now() - task.getValue(Task.TIMER_START)) / 1000L); - task.setValue(Task.TIMER_START, 0L); - task.setValue(Task.ELAPSED_SECONDS, - task.getValue(Task.ELAPSED_SECONDS) + newElapsed); - } - @Override public void onReceive(Context context, Intent intent) { long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); @@ -33,8 +21,7 @@ public class TimerTaskCompleteListener extends BroadcastReceiver { if(task == null || task.getValue(Task.TIMER_START) == 0) return; - stopTimer(task); - PluginServices.getTaskService().save(task, true); + TimerPlugin.updateTimer(context, task, false); } } diff --git a/astrid/res/drawable/timers_notification.png b/astrid/res/drawable/timers_notification.png new file mode 100644 index 000000000..6484e6e7d Binary files /dev/null and b/astrid/res/drawable/timers_notification.png differ diff --git a/astrid/res/layout/timer_decoration.xml b/astrid/res/layout/timer_decoration.xml index 1c9a53d02..c618f2da6 100644 --- a/astrid/res/layout/timer_decoration.xml +++ b/astrid/res/layout/timer_decoration.xml @@ -2,7 +2,8 @@ diff --git a/astrid/res/values/strings-timers.xml b/astrid/res/values/strings-timers.xml index 1e1c695c5..bbecc35d5 100644 --- a/astrid/res/values/strings-timers.xml +++ b/astrid/res/values/strings-timers.xml @@ -10,8 +10,8 @@ Stop Timer - - Elapsed Time: %s + + Timers Active for %s! Timer Filters diff --git a/astrid/src/com/todoroo/astrid/activity/FilterListActivity.java b/astrid/src/com/todoroo/astrid/activity/FilterListActivity.java index fa863f684..c9e86b9d8 100644 --- a/astrid/src/com/todoroo/astrid/activity/FilterListActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/FilterListActivity.java @@ -313,16 +313,7 @@ public class FilterListActivity extends ExpandableListActivity { Filter filter = (Filter) item; info.targetView.setTag(filter); menuItem = menu.add(0, CONTEXT_MENU_SHORTCUT, 0, R.string.FLA_context_shortcut); - Intent shortcutIntent = new Intent(this, ShortcutActivity.class); - shortcutIntent.setAction(Intent.ACTION_VIEW); - shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_TITLE, filter.title); - shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_SQL, filter.sqlQuery); - if(filter.valuesForNewTasks != null) { - shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_VALUES, - filter.valuesForNewTasks.toString()); - } - - menuItem.setIntent(shortcutIntent); + menuItem.setIntent(ShortcutActivity.createIntent(filter)); } for(int i = 0; i < item.contextMenuLabels.length; i++) { diff --git a/astrid/src/com/todoroo/astrid/activity/ShortcutActivity.java b/astrid/src/com/todoroo/astrid/activity/ShortcutActivity.java index e8e528e75..a0db742f7 100644 --- a/astrid/src/com/todoroo/astrid/activity/ShortcutActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/ShortcutActivity.java @@ -24,6 +24,7 @@ import android.content.ContentValues; import android.content.Intent; import android.os.Bundle; +import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.astrid.api.Filter; @@ -90,4 +91,17 @@ public class ShortcutActivity extends Activity { } finish(); } + + public static Intent createIntent(Filter filter) { + Intent shortcutIntent = new Intent(ContextManager.getContext(), + ShortcutActivity.class); + shortcutIntent.setAction(Intent.ACTION_VIEW); + shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_TITLE, filter.title); + shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_SQL, filter.sqlQuery); + if(filter.valuesForNewTasks != null) { + shortcutIntent.putExtra(ShortcutActivity.TOKEN_FILTER_VALUES, + filter.valuesForNewTasks.toString()); + } + return shortcutIntent; + } } diff --git a/astrid/src/com/todoroo/astrid/utility/Constants.java b/astrid/src/com/todoroo/astrid/utility/Constants.java index b76187437..d7ba910ef 100644 --- a/astrid/src/com/todoroo/astrid/utility/Constants.java +++ b/astrid/src/com/todoroo/astrid/utility/Constants.java @@ -32,7 +32,10 @@ public final class Constants { // --- notification id's - /** Notification Manager id for RMilk notifications */ + /** Notification Manager id for sync notifications */ public static final int NOTIFICATION_SYNC = -1; + /** Notification Manager id for timing */ + public static final int NOTIFICATION_TIMER = -2; + }