diff --git a/res/layout/task_edit.xml b/res/layout/task_edit.xml index daf056108..9e066f5df 100644 --- a/res/layout/task_edit.xml +++ b/res/layout/task_edit.xml @@ -335,6 +335,11 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/flag_after"/> + + diff --git a/res/values/strings.xml b/res/values/strings.xml index c6d721905..96bd8af8a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -154,6 +154,7 @@ As Deadlines Approach At Deadlines After Absolute Deadline Passes + Nonstop Until I View the Task Fixed Reminders Add New Reminder diff --git a/src/com/timsu/astrid/activities/TaskEdit.java b/src/com/timsu/astrid/activities/TaskEdit.java index dd74132ab..8eeae09d8 100644 --- a/src/com/timsu/astrid/activities/TaskEdit.java +++ b/src/com/timsu/astrid/activities/TaskEdit.java @@ -344,7 +344,7 @@ public class TaskEdit extends TaskModificationTabbedActivity { R.id.hiddenUntil_date, R.id.hiddenUntil_time); notes = (EditText)findViewById(R.id.notes); flags = new NotifyFlagControlSet(R.id.flag_before, - R.id.flag_during, R.id.flag_after); + R.id.flag_during, R.id.flag_after, R.id.flag_nonstop); alertsContainer = (LinearLayout)findViewById(R.id.alert_container); repeatInterval = (Spinner)findViewById(R.id.repeat_interval); repeatValue = (Button)findViewById(R.id.repeat_value); @@ -663,13 +663,14 @@ public class TaskEdit extends TaskModificationTabbedActivity { /** Control set dealing with notification flags */ public class NotifyFlagControlSet { - private CheckBox before, during, after; + private CheckBox before, during, after, nonstop; public NotifyFlagControlSet(int beforeId, int duringId, - int afterId) { + int afterId, int nonstopId) { before = (CheckBox)findViewById(beforeId); during = (CheckBox)findViewById(duringId); after = (CheckBox)findViewById(afterId); + nonstop = (CheckBox)findViewById(nonstopId); } public void setValue(int flags) { @@ -679,6 +680,8 @@ public class TaskEdit extends TaskModificationTabbedActivity { TaskModelForEdit.NOTIFY_AT_DEADLINE) > 0); after.setChecked((flags & TaskModelForEdit.NOTIFY_AFTER_DEADLINE) > 0); + nonstop.setChecked((flags & + TaskModelForEdit.NOTIFY_NONSTOP) > 0); } public int getValue() { @@ -689,6 +692,8 @@ public class TaskEdit extends TaskModificationTabbedActivity { value |= TaskModelForEdit.NOTIFY_AT_DEADLINE; if(after.isChecked()) value |= TaskModelForEdit.NOTIFY_AFTER_DEADLINE; + if(nonstop.isChecked()) + value |= TaskModelForEdit.NOTIFY_NONSTOP; return value; } } diff --git a/src/com/timsu/astrid/data/task/AbstractTaskModel.java b/src/com/timsu/astrid/data/task/AbstractTaskModel.java index b2e37eb81..37e57f1c4 100644 --- a/src/com/timsu/astrid/data/task/AbstractTaskModel.java +++ b/src/com/timsu/astrid/data/task/AbstractTaskModel.java @@ -74,6 +74,7 @@ public abstract class AbstractTaskModel extends AbstractModel { public static final int NOTIFY_BEFORE_DEADLINE = 1 << 0; public static final int NOTIFY_AT_DEADLINE = 1 << 1; public static final int NOTIFY_AFTER_DEADLINE = 1 << 2; + public static final int NOTIFY_NONSTOP = 1 << 3; /** Number of bits to shift repeat value by */ public static final int REPEAT_VALUE_OFFSET = 3; diff --git a/src/com/timsu/astrid/data/task/TaskController.java b/src/com/timsu/astrid/data/task/TaskController.java index bbfd4afda..883dd4207 100644 --- a/src/com/timsu/astrid/data/task/TaskController.java +++ b/src/com/timsu/astrid/data/task/TaskController.java @@ -293,7 +293,7 @@ public class TaskController extends AbstractController { return model; } - /** Returns a TaskModelForView corresponding to the given TaskIdentifier */ + /** Returns a TaskModelForList corresponding to the given TaskIdentifier */ public TaskModelForList fetchTaskForList(TaskIdentifier taskId) throws SQLException { Cursor cursor = fetchTaskCursor(taskId, TaskModelForList.FIELD_LIST); TaskModelForList model = new TaskModelForList(cursor); @@ -301,7 +301,15 @@ public class TaskController extends AbstractController { return model; } - /** Returns a TaskModelForView corresponding to the given TaskIdentifier */ + /** Returns a TaskModelForReminder corresponding to the given TaskIdentifier */ + public TaskModelForReminder fetchTaskForReminder(TaskIdentifier taskId) throws SQLException { + Cursor cursor = fetchTaskCursor(taskId, TaskModelForList.FIELD_LIST); + TaskModelForReminder model = new TaskModelForReminder(cursor); + cursor.close(); + return model; + } + + /** Returns a TaskModelForSync corresponding to the given TaskIdentifier */ public TaskModelForSync fetchTaskForSync(TaskIdentifier taskId) throws SQLException { Cursor cursor = fetchTaskCursor(taskId, TaskModelForSync.FIELD_LIST); TaskModelForSync model = new TaskModelForSync(cursor); diff --git a/src/com/timsu/astrid/data/task/TaskModelForList.java b/src/com/timsu/astrid/data/task/TaskModelForList.java index cc2f61ffd..1b1aa402e 100644 --- a/src/com/timsu/astrid/data/task/TaskModelForList.java +++ b/src/com/timsu/astrid/data/task/TaskModelForList.java @@ -43,6 +43,7 @@ public class TaskModelForList extends AbstractTaskModel { DEFINITE_DUE_DATE, PREFERRED_DUE_DATE, NOTIFICATIONS, + NOTIFICATION_FLAGS, PROGRESS_PERCENTAGE, COMPLETION_DATE, HIDDEN_UNTIL, @@ -196,6 +197,11 @@ public class TaskModelForList extends AbstractTaskModel { return super.getRepeat(); } + @Override + public int getNotificationFlags() { + return super.getNotificationFlags(); + } + // --- setters @Override diff --git a/src/com/timsu/astrid/data/task/TaskModelForReminder.java b/src/com/timsu/astrid/data/task/TaskModelForReminder.java new file mode 100644 index 000000000..26c93cdc1 --- /dev/null +++ b/src/com/timsu/astrid/data/task/TaskModelForReminder.java @@ -0,0 +1,83 @@ +/* + * ASTRID: Android's Simple Task Recording Dashboard + * + * Copyright (c) 2009 Tim Su + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.timsu.astrid.data.task; + +import java.util.Date; + +import android.database.Cursor; + +import com.timsu.astrid.data.AbstractController; + + + +/** Fields that you would want to see in the TaskView activity */ +public class TaskModelForReminder extends AbstractTaskModel { + + static String[] FIELD_LIST = new String[] { + AbstractController.KEY_ROWID, + NAME, + NOTIFICATION_FLAGS, + HIDDEN_UNTIL, + TIMER_START, + PROGRESS_PERCENTAGE, + }; + + // --- constructors + + public TaskModelForReminder(Cursor cursor) { + super(cursor); + + prefetchData(FIELD_LIST); + } + + // --- getters + + @Override + public String getName() { + return super.getName(); + } + + @Override + public Date getTimerStart() { + return super.getTimerStart(); + } + + @Override + public boolean isTaskCompleted() { + return super.isTaskCompleted(); + } + + @Override + public Date getHiddenUntil() { + return super.getHiddenUntil(); + } + + @Override + public int getNotificationFlags() { + return super.getNotificationFlags(); + } + + // --- setters + + @Override + public void setLastNotificationTime(Date date) { + super.setLastNotificationTime(date); + } +} diff --git a/src/com/timsu/astrid/utilities/Notifications.java b/src/com/timsu/astrid/utilities/Notifications.java index d62668385..50add2a5b 100644 --- a/src/com/timsu/astrid/utilities/Notifications.java +++ b/src/com/timsu/astrid/utilities/Notifications.java @@ -14,6 +14,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Color; import android.net.Uri; import android.util.Log; @@ -24,6 +25,7 @@ import com.timsu.astrid.data.task.TaskController; import com.timsu.astrid.data.task.TaskIdentifier; import com.timsu.astrid.data.task.TaskModelForList; import com.timsu.astrid.data.task.TaskModelForNotify; +import com.timsu.astrid.data.task.TaskModelForReminder; public class Notifications extends BroadcastReceiver { @@ -315,9 +317,10 @@ public class Notifications extends BroadcastReceiver { String taskName; TaskController controller = new TaskController(context); + boolean nonstopMode = false; try { controller.open(); - TaskModelForList task = controller.fetchTaskForList(new TaskIdentifier(id)); + TaskModelForReminder task = controller.fetchTaskForReminder(new TaskIdentifier(id)); // you're working on it - don't sound, don't delete if(task.getTimerStart() != null) @@ -338,6 +341,9 @@ public class Notifications extends BroadcastReceiver { controller.setLastNotificationTime(task.getTaskIdentifier(), new Date()); + if((task.getNotificationFlags() & TaskModelForReminder.NOTIFY_NONSTOP) > 0) + nonstopMode = true; + } catch (Exception e) { // task might have been deleted Log.e(Notifications.class.getSimpleName(), @@ -385,13 +391,21 @@ public class Notifications extends BroadcastReceiver { appName, reminder + " " + taskName, pendingIntent); - notification.defaults = Notification.DEFAULT_LIGHTS; notification.flags |= Notification.FLAG_AUTO_CANCEL; if(Preferences.isPersistenceMode(context)) { - notification.flags |= Notification.FLAG_NO_CLEAR; + notification.flags |= Notification.FLAG_NO_CLEAR | + Notification.FLAG_SHOW_LIGHTS; notification.ledOffMS = 5000; notification.ledOnMS = 700; + notification.ledARGB = Color.YELLOW; } + else + notification.defaults = Notification.DEFAULT_LIGHTS; + + if(nonstopMode && (flags & FLAG_PERIODIC) == 0) { + notification.flags |= Notification.FLAG_INSISTENT; + } + if(quietHours) { notification.vibrate = null; notification.sound = null;