From cc7bf205620f1991afb2440a70e4ed7dc76a0614 Mon Sep 17 00:00:00 2001 From: Tim Su Date: Tue, 7 Sep 2010 11:00:41 +0800 Subject: [PATCH] Made snooze time override other alarms, also created preference for new old-style snooze dialog --- astrid/AndroidManifest.xml | 6 +- astrid/astrid.launch | 6 +- .../reminders/NotificationActivity.java | 94 ++++++++++++++++--- .../astrid/reminders/ReminderPreferences.java | 5 + .../astrid/reminders/ReminderService.java | 30 +++++- .../astrid/repeats/RepeatControlSet.java | 20 ++-- astrid/res/layout/snooze_dialog.xml | 49 ++++++++++ astrid/res/values/keys.xml | 3 + astrid/res/values/strings-reminders.xml | 7 ++ astrid/res/xml/preferences_reminders.xml | 4 + .../src/com/todoroo/astrid/dao/Database.java | 6 +- .../com/todoroo/astrid/utility/Constants.java | 2 +- 12 files changed, 203 insertions(+), 29 deletions(-) create mode 100644 astrid/res/layout/snooze_dialog.xml diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 7c917cfd8..d706ea233 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -370,7 +370,11 @@ android:launchMode="singleTask" android:screenOrientation="portrait" android:finishOnTaskLaunch="true" - android:clearTaskOnLaunch="true" /> + android:clearTaskOnLaunch="true"> + + + + diff --git a/astrid/astrid.launch b/astrid/astrid.launch index 3f96633e8..35549a40e 100644 --- a/astrid/astrid.launch +++ b/astrid/astrid.launch @@ -5,8 +5,8 @@ - - + + @@ -15,9 +15,11 @@ + + diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java b/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java index 91e2fbad2..db2d3b541 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationActivity.java @@ -21,14 +21,21 @@ package com.todoroo.astrid.reminders; import java.util.Date; +import android.app.AlertDialog; import android.app.TimePickerDialog; import android.app.TimePickerDialog.OnTimeSetListener; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.View.OnClickListener; import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.Spinner; import android.widget.TextView; import android.widget.TimePicker; @@ -38,6 +45,8 @@ import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.dao.TaskDao.TaskCriteria; +import com.todoroo.astrid.repeats.RepeatControlSet; +import com.todoroo.astrid.ui.NumberPicker; import com.todoroo.astrid.utility.Preferences; /** @@ -74,7 +83,7 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL private void populateFilter(Intent intent) { taskId = intent.getLongExtra(TOKEN_ID, -1); if(taskId == -1) - return; + taskId = 389; // TODO no Filter itemFilter = new Filter(getString(R.string.rmd_NoA_filter), getString(R.string.rmd_NoA_filter), @@ -119,20 +128,78 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL }); } + public static class SnoozeDialog extends FrameLayout implements DialogInterface.OnClickListener { + + LinearLayout snoozePicker; + NumberPicker snoozeValue; + Spinner snoozeUnits; + NotificationActivity parent; + + public SnoozeDialog(NotificationActivity parent) { + super(parent); + this.parent = parent; + + LayoutInflater mInflater = (LayoutInflater) parent.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + mInflater.inflate(R.layout.snooze_dialog, this, true); + + snoozePicker = (LinearLayout) findViewById(R.id.snoozePicker); + snoozeValue = (NumberPicker) findViewById(R.id.numberPicker); + snoozeUnits = (Spinner) findViewById(R.id.numberUnits); + + snoozeValue.setIncrementBy(1); + snoozeValue.setRange(1, 99); + snoozeUnits.setSelection(RepeatControlSet.INTERVAL_HOURS); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + long time = DateUtilities.now(); + int value = snoozeValue.getCurrent(); + switch(snoozeUnits.getSelectedItemPosition()) { + case RepeatControlSet.INTERVAL_DAYS: + time += value * DateUtilities.ONE_DAY; + break; + case RepeatControlSet.INTERVAL_HOURS: + time += value * DateUtilities.ONE_HOUR; + break; + case RepeatControlSet.INTERVAL_WEEKS: + time += value * 7 * DateUtilities.ONE_DAY; + break; + case RepeatControlSet.INTERVAL_MONTHS: + time += value * 30 * DateUtilities.ONE_DAY; + break; + } + + parent.snoozeTime(time); + } + + } + /** * Snooze and re-trigger this alarm */ private void snooze() { - Date now = new Date(); - now.setHours(now.getHours() + 1); - int hour = now.getHours(); - int minute = now.getMinutes(); - TimePickerDialog timePicker = new TimePickerDialog(this, this, - hour, minute, DateUtilities.is24HourFormat(this)); - timePicker.show(); + if(Preferences.getBoolean(R.string.p_rmd_snooze_dialog, true)) { + Date now = new Date(); + now.setHours(now.getHours() + 1); + int hour = now.getHours(); + int minute = now.getMinutes(); + TimePickerDialog tpd = new TimePickerDialog(this, this, hour, minute, + DateUtilities.is24HourFormat(this)); + tpd.show(); + tpd.setOwnerActivity(this); + } else { + SnoozeDialog sd = new SnoozeDialog(this); + new AlertDialog.Builder(this) + .setTitle(R.string.rmd_NoA_snooze) + .setView(sd) + .setPositiveButton(android.R.string.ok, sd) + .setNegativeButton(android.R.string.cancel, null) + .show().setOwnerActivity(this); + } } - /** snooze timer set */ + /** on time dialog return set */ @Override public void onTimeSet(TimePicker picker, int hours, int minutes) { Date alarmTime = new Date(); @@ -140,9 +207,12 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL alarmTime.setMinutes(minutes); if(alarmTime.getTime() < DateUtilities.now()) alarmTime.setDate(alarmTime.getDate() + 1); - ReminderService.getInstance().scheduleSnoozeAlarm(taskId, alarmTime.getTime()); - finish(); + snoozeTime(alarmTime.getTime()); } + public void snoozeTime(long time) { + ReminderService.getInstance().scheduleSnoozeAlarm(taskId, time); + finish(); + } } diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderPreferences.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderPreferences.java index a4550858f..ce031f8e3 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderPreferences.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderPreferences.java @@ -74,6 +74,11 @@ public class ReminderPreferences extends TodorooPreferences { preference.setSummary(r.getString(R.string.rmd_EPr_nagging_desc_true)); else preference.setSummary(r.getString(R.string.rmd_EPr_nagging_desc_false)); + } else if(r.getString(R.string.p_rmd_snooze_dialog).equals(preference.getKey())) { + if(value == null || ((Boolean)value) == true) + preference.setSummary(r.getString(R.string.rmd_EPr_snooze_dialog_desc_true)); + else + preference.setSummary(r.getString(R.string.rmd_EPr_snooze_dialog_desc_false)); } } diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java index 535807ddb..4d0299d96 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java @@ -45,7 +45,8 @@ public final class ReminderService { Task.DUE_DATE, Task.REMINDER_FLAGS, Task.REMINDER_PERIOD, - Task.REMINDER_LAST + Task.REMINDER_LAST, + Task.REMINDER_SNOOZE }; /** flag for due date reminder */ @@ -163,6 +164,9 @@ public final class ReminderService { if(task.isCompleted() || task.isDeleted()) return; + // snooze reminder + long whenSnooze = calculateNextSnoozeReminder(task); + // random reminders long whenRandom = calculateNextRandomReminder(task); @@ -176,7 +180,10 @@ public final class ReminderService { if(whenRandom != NO_ALARM && whenDueDate - whenRandom < DateUtilities.ONE_DAY) whenRandom = NO_ALARM; - if(whenRandom < whenDueDate && whenRandom < whenOverdue) + // snooze trumps all + if(whenSnooze != NO_ALARM) + scheduler.createAlarm(task, whenSnooze, TYPE_SNOOZE); + else if(whenRandom < whenDueDate && whenRandom < whenOverdue) scheduler.createAlarm(task, whenRandom, TYPE_RANDOM); else if(whenDueDate < whenOverdue) scheduler.createAlarm(task, whenDueDate, TYPE_DUE); @@ -186,6 +193,21 @@ public final class ReminderService { scheduler.createAlarm(task, 0, 0); } + /** + * Calculate the next alarm time for snooze. + *

+ * Pretty simple - if a snooze time is in the future, we use that. If it + * has already passed, we do nothing. + * + * @param task + * @return + */ + private long calculateNextSnoozeReminder(Task task) { + if(task.getValue(Task.REMINDER_SNOOZE) > DateUtilities.now()) + return task.getValue(Task.REMINDER_SNOOZE); + return NO_ALARM; + } + /** * Calculate the next alarm time for overdue reminders. *

@@ -297,6 +319,10 @@ public final class ReminderService { return; Task task = taskDao.fetch(taskId, PROPERTIES); scheduler.createAlarm(task, time, TYPE_SNOOZE); + + // record snooze time + task.setValue(Task.REMINDER_SNOOZE, time); + taskDao.saveExisting(task); } // --- alarm manager alarm creation diff --git a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java index 832937900..8cbb667d9 100644 --- a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java +++ b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java @@ -12,13 +12,13 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.LinearLayout; import android.widget.Spinner; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.CompoundButton.OnCheckedChangeListener; import com.google.ical.values.Frequency; import com.google.ical.values.RRule; @@ -44,10 +44,10 @@ public class RepeatControlSet implements TaskEditControlSet { // --- spinner constants - private static final int INTERVAL_DAYS = 0; - private static final int INTERVAL_WEEKS = 1; - private static final int INTERVAL_MONTHS = 2; - private static final int INTERVAL_HOURS = 3; + public static final int INTERVAL_DAYS = 0; + public static final int INTERVAL_WEEKS = 1; + public static final int INTERVAL_MONTHS = 2; + public static final int INTERVAL_HOURS = 3; private static final int TYPE_DUE_DATE = 0; private static final int TYPE_COMPLETION_DATE = 1; @@ -177,7 +177,7 @@ public class RepeatControlSet implements TaskEditControlSet { String recurrence = task.getValue(Task.RECURRENCE); if(recurrence == null) - recurrence = ""; //$NON-NLS-1$ + recurrence = ""; // read recurrence rule if(recurrence.length() > 0) { @@ -202,7 +202,7 @@ public class RepeatControlSet implements TaskEditControlSet { default: // an unhandled recurrence exceptionService.reportError("repeat-unhandled-rule", //$NON-NLS-1$ - new Exception("Unhandled rrule frequency: " + recurrence)); //$NON-NLS-1$ + new Exception("Unhandled rrule frequency: " + recurrence)); } // clear all day of week checks, then update them @@ -219,7 +219,7 @@ public class RepeatControlSet implements TaskEditControlSet { setInterval = true; } catch (ParseException e) { recurrence = ""; //$NON-NLS-1$ - exceptionService.reportError("repeat-parse-exception", e); //$NON-NLS-1$ + exceptionService.reportError("repeat-parse-exception", e); } } enabled.setChecked(recurrence.length() > 0); @@ -237,7 +237,7 @@ public class RepeatControlSet implements TaskEditControlSet { public String writeToModel(Task task) { String result; if(!enabled.isChecked()) - result = ""; //$NON-NLS-1$ + result = ""; else { RRule rrule = new RRule(); rrule.setInterval((Integer)value.getTag()); diff --git a/astrid/res/layout/snooze_dialog.xml b/astrid/res/layout/snooze_dialog.xml new file mode 100644 index 000000000..8c1296b41 --- /dev/null +++ b/astrid/res/layout/snooze_dialog.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/astrid/res/values/keys.xml b/astrid/res/values/keys.xml index a4b5073c8..7055dccba 100644 --- a/astrid/res/values/keys.xml +++ b/astrid/res/values/keys.xml @@ -28,6 +28,9 @@ nagging + + snooze_dialog + reminder_time diff --git a/astrid/res/values/strings-reminders.xml b/astrid/res/values/strings-reminders.xml index 6b42f43cc..d816c3588 100644 --- a/astrid/res/values/strings-reminders.xml +++ b/astrid/res/values/strings-reminders.xml @@ -99,6 +99,13 @@ Astrid will show up to give you an encouragement during reminders Astrid not give you any encouragement messages + + + Snooze Dialog HH:MM + + Snooze by selecting new snooze time (HH:MM) + + Snooze by selecting # days/hours to snooze Random Reminders diff --git a/astrid/res/xml/preferences_reminders.xml b/astrid/res/xml/preferences_reminders.xml index 2af701ada..f34d8b2ff 100644 --- a/astrid/res/xml/preferences_reminders.xml +++ b/astrid/res/xml/preferences_reminders.xml @@ -23,6 +23,10 @@ android:key="@string/p_rmd_nagging" android:title="@string/rmd_EPr_nagging_title" android:defaultValue="true" /> +