Made snooze time override other alarms, also created preference for new old-style snooze dialog

pull/14/head
Tim Su 15 years ago
parent ebc277d4db
commit cc7bf20562

@ -370,7 +370,11 @@
android:launchMode="singleTask" android:launchMode="singleTask"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:finishOnTaskLaunch="true" android:finishOnTaskLaunch="true"
android:clearTaskOnLaunch="true" /> android:clearTaskOnLaunch="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<!-- producteev --> <!-- producteev -->
<receiver android:name="com.todoroo.astrid.producteev.ProducteevFilterExposer"> <receiver android:name="com.todoroo.astrid.producteev.ProducteevFilterExposer">

@ -5,8 +5,8 @@
<stringAttribute key="ch.zork.quicklaunch.icon" value="14.gif"/> <stringAttribute key="ch.zork.quicklaunch.icon" value="14.gif"/>
<intAttribute key="ch.zork.quicklaunch.index" value="0"/> <intAttribute key="ch.zork.quicklaunch.index" value="0"/>
<stringAttribute key="ch.zork.quicklaunch.mode" value="run"/> <stringAttribute key="ch.zork.quicklaunch.mode" value="run"/>
<intAttribute key="com.android.ide.eclipse.adt.action" value="0"/> <intAttribute key="com.android.ide.eclipse.adt.action" value="1"/>
<stringAttribute key="com.android.ide.eclipse.adt.activity" value="com.todoroo.astrid.core.CustomFilterActivity"/> <stringAttribute key="com.android.ide.eclipse.adt.activity" value="com.todoroo.astrid.reminders.NotificationActivity"/>
<stringAttribute key="com.android.ide.eclipse.adt.commandline" value="-scale 0.7"/> <stringAttribute key="com.android.ide.eclipse.adt.commandline" value="-scale 0.7"/>
<intAttribute key="com.android.ide.eclipse.adt.delay" value="0"/> <intAttribute key="com.android.ide.eclipse.adt.delay" value="0"/>
<booleanAttribute key="com.android.ide.eclipse.adt.nobootanim" value="true"/> <booleanAttribute key="com.android.ide.eclipse.adt.nobootanim" value="true"/>
@ -15,9 +15,11 @@
<booleanAttribute key="com.android.ide.eclipse.adt.wipedata" value="false"/> <booleanAttribute key="com.android.ide.eclipse.adt.wipedata" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/astrid"/> <listEntry value="/astrid"/>
<listEntry value="/astrid/AndroidManifest.xml"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/> <listEntry value="4"/>
<listEntry value="1"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>

@ -21,14 +21,21 @@ package com.todoroo.astrid.reminders;
import java.util.Date; import java.util.Date;
import android.app.AlertDialog;
import android.app.TimePickerDialog; import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener; import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.TimePicker; import android.widget.TimePicker;
@ -38,6 +45,8 @@ import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria; 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; import com.todoroo.astrid.utility.Preferences;
/** /**
@ -74,7 +83,7 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL
private void populateFilter(Intent intent) { private void populateFilter(Intent intent) {
taskId = intent.getLongExtra(TOKEN_ID, -1); taskId = intent.getLongExtra(TOKEN_ID, -1);
if(taskId == -1) if(taskId == -1)
return; taskId = 389; // TODO no
Filter itemFilter = new Filter(getString(R.string.rmd_NoA_filter), Filter itemFilter = new Filter(getString(R.string.rmd_NoA_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 * Snooze and re-trigger this alarm
*/ */
private void snooze() { private void snooze() {
Date now = new Date(); if(Preferences.getBoolean(R.string.p_rmd_snooze_dialog, true)) {
now.setHours(now.getHours() + 1); Date now = new Date();
int hour = now.getHours(); now.setHours(now.getHours() + 1);
int minute = now.getMinutes(); int hour = now.getHours();
TimePickerDialog timePicker = new TimePickerDialog(this, this, int minute = now.getMinutes();
hour, minute, DateUtilities.is24HourFormat(this)); TimePickerDialog tpd = new TimePickerDialog(this, this, hour, minute,
timePicker.show(); 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 @Override
public void onTimeSet(TimePicker picker, int hours, int minutes) { public void onTimeSet(TimePicker picker, int hours, int minutes) {
Date alarmTime = new Date(); Date alarmTime = new Date();
@ -140,9 +207,12 @@ public class NotificationActivity extends TaskListActivity implements OnTimeSetL
alarmTime.setMinutes(minutes); alarmTime.setMinutes(minutes);
if(alarmTime.getTime() < DateUtilities.now()) if(alarmTime.getTime() < DateUtilities.now())
alarmTime.setDate(alarmTime.getDate() + 1); alarmTime.setDate(alarmTime.getDate() + 1);
ReminderService.getInstance().scheduleSnoozeAlarm(taskId, alarmTime.getTime()); snoozeTime(alarmTime.getTime());
finish();
} }
public void snoozeTime(long time) {
ReminderService.getInstance().scheduleSnoozeAlarm(taskId, time);
finish();
}
} }

@ -74,6 +74,11 @@ public class ReminderPreferences extends TodorooPreferences {
preference.setSummary(r.getString(R.string.rmd_EPr_nagging_desc_true)); preference.setSummary(r.getString(R.string.rmd_EPr_nagging_desc_true));
else else
preference.setSummary(r.getString(R.string.rmd_EPr_nagging_desc_false)); 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));
} }
} }

@ -45,7 +45,8 @@ public final class ReminderService {
Task.DUE_DATE, Task.DUE_DATE,
Task.REMINDER_FLAGS, Task.REMINDER_FLAGS,
Task.REMINDER_PERIOD, Task.REMINDER_PERIOD,
Task.REMINDER_LAST Task.REMINDER_LAST,
Task.REMINDER_SNOOZE
}; };
/** flag for due date reminder */ /** flag for due date reminder */
@ -163,6 +164,9 @@ public final class ReminderService {
if(task.isCompleted() || task.isDeleted()) if(task.isCompleted() || task.isDeleted())
return; return;
// snooze reminder
long whenSnooze = calculateNextSnoozeReminder(task);
// random reminders // random reminders
long whenRandom = calculateNextRandomReminder(task); long whenRandom = calculateNextRandomReminder(task);
@ -176,7 +180,10 @@ public final class ReminderService {
if(whenRandom != NO_ALARM && whenDueDate - whenRandom < DateUtilities.ONE_DAY) if(whenRandom != NO_ALARM && whenDueDate - whenRandom < DateUtilities.ONE_DAY)
whenRandom = NO_ALARM; 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); scheduler.createAlarm(task, whenRandom, TYPE_RANDOM);
else if(whenDueDate < whenOverdue) else if(whenDueDate < whenOverdue)
scheduler.createAlarm(task, whenDueDate, TYPE_DUE); scheduler.createAlarm(task, whenDueDate, TYPE_DUE);
@ -186,6 +193,21 @@ public final class ReminderService {
scheduler.createAlarm(task, 0, 0); scheduler.createAlarm(task, 0, 0);
} }
/**
* Calculate the next alarm time for snooze.
* <p>
* 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. * Calculate the next alarm time for overdue reminders.
* <p> * <p>
@ -297,6 +319,10 @@ public final class ReminderService {
return; return;
Task task = taskDao.fetch(taskId, PROPERTIES); Task task = taskDao.fetch(taskId, PROPERTIES);
scheduler.createAlarm(task, time, TYPE_SNOOZE); scheduler.createAlarm(task, time, TYPE_SNOOZE);
// record snooze time
task.setValue(Task.REMINDER_SNOOZE, time);
taskDao.saveExisting(task);
} }
// --- alarm manager alarm creation // --- alarm manager alarm creation

@ -12,13 +12,13 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Spinner; 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.Frequency;
import com.google.ical.values.RRule; import com.google.ical.values.RRule;
@ -44,10 +44,10 @@ public class RepeatControlSet implements TaskEditControlSet {
// --- spinner constants // --- spinner constants
private static final int INTERVAL_DAYS = 0; public static final int INTERVAL_DAYS = 0;
private static final int INTERVAL_WEEKS = 1; public static final int INTERVAL_WEEKS = 1;
private static final int INTERVAL_MONTHS = 2; public static final int INTERVAL_MONTHS = 2;
private static final int INTERVAL_HOURS = 3; public static final int INTERVAL_HOURS = 3;
private static final int TYPE_DUE_DATE = 0; private static final int TYPE_DUE_DATE = 0;
private static final int TYPE_COMPLETION_DATE = 1; private static final int TYPE_COMPLETION_DATE = 1;
@ -177,7 +177,7 @@ public class RepeatControlSet implements TaskEditControlSet {
String recurrence = task.getValue(Task.RECURRENCE); String recurrence = task.getValue(Task.RECURRENCE);
if(recurrence == null) if(recurrence == null)
recurrence = ""; //$NON-NLS-1$ recurrence = "";
// read recurrence rule // read recurrence rule
if(recurrence.length() > 0) { if(recurrence.length() > 0) {
@ -202,7 +202,7 @@ public class RepeatControlSet implements TaskEditControlSet {
default: default:
// an unhandled recurrence // an unhandled recurrence
exceptionService.reportError("repeat-unhandled-rule", //$NON-NLS-1$ 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 // clear all day of week checks, then update them
@ -219,7 +219,7 @@ public class RepeatControlSet implements TaskEditControlSet {
setInterval = true; setInterval = true;
} catch (ParseException e) { } catch (ParseException e) {
recurrence = ""; //$NON-NLS-1$ recurrence = ""; //$NON-NLS-1$
exceptionService.reportError("repeat-parse-exception", e); //$NON-NLS-1$ exceptionService.reportError("repeat-parse-exception", e);
} }
} }
enabled.setChecked(recurrence.length() > 0); enabled.setChecked(recurrence.length() > 0);
@ -237,7 +237,7 @@ public class RepeatControlSet implements TaskEditControlSet {
public String writeToModel(Task task) { public String writeToModel(Task task) {
String result; String result;
if(!enabled.isChecked()) if(!enabled.isChecked())
result = ""; //$NON-NLS-1$ result = "";
else { else {
RRule rrule = new RRule(); RRule rrule = new RRule();
rrule.setInterval((Integer)value.getTag()); rrule.setInterval((Integer)value.getTag());

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip">
<TimePicker android:id="@+id/timePicker"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout android:id="@+id/snoozePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.todoroo.astrid.ui.NumberPicker android:id="@+id/numberPicker"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Spinner android:id="@+id/numberUnits"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:entries="@array/repeat_interval"/>
</LinearLayout>
</FrameLayout>

@ -28,6 +28,9 @@
<!-- whether astrid nag messages are used --> <!-- whether astrid nag messages are used -->
<string name="p_rmd_nagging">nagging</string> <string name="p_rmd_nagging">nagging</string>
<!-- if true / unset, hh:mm dialog. otherwise, days / hours -->
<string name="p_rmd_snooze_dialog">snooze_dialog</string>
<!-- reminder time when task doesn't have a due time (hour of day) --> <!-- reminder time when task doesn't have a due time (hour of day) -->
<string name="p_rmd_time">reminder_time</string> <string name="p_rmd_time">reminder_time</string>

@ -100,6 +100,13 @@
<!-- Reminder Preference: Nagging Description (false) --> <!-- Reminder Preference: Nagging Description (false) -->
<string name="rmd_EPr_nagging_desc_false">Astrid not give you any encouragement messages</string> <string name="rmd_EPr_nagging_desc_false">Astrid not give you any encouragement messages</string>
<!-- Reminder Preference: Snooze Dialog Title -->
<string name="rmd_EPr_snooze_dialog_title">Snooze Dialog HH:MM</string>
<!-- Reminder Preference: Snooze Dialog Description (true) -->
<string name="rmd_EPr_snooze_dialog_desc_true">Snooze by selecting new snooze time (HH:MM)</string>
<!-- Reminder Preference: Nagging Description (false) -->
<string name="rmd_EPr_snooze_dialog_desc_false">Snooze by selecting # days/hours to snooze</string>
<!-- Reminder Preference: Default Reminders Title --> <!-- Reminder Preference: Default Reminders Title -->
<string name="rmd_EPr_defaultRemind_title">Random Reminders</string> <string name="rmd_EPr_defaultRemind_title">Random Reminders</string>
<!-- Reminder Preference: Default Reminders Setting (disabled) --> <!-- Reminder Preference: Default Reminders Setting (disabled) -->

@ -23,6 +23,10 @@
android:key="@string/p_rmd_nagging" android:key="@string/p_rmd_nagging"
android:title="@string/rmd_EPr_nagging_title" android:title="@string/rmd_EPr_nagging_title"
android:defaultValue="true" /> android:defaultValue="true" />
<CheckBoxPreference
android:key="@string/p_rmd_snooze_dialog"
android:title="@string/rmd_EPr_snooze_dialog_title"
android:defaultValue="true" />
<RingtonePreference <RingtonePreference
android:key="@string/p_rmd_ringtone" android:key="@string/p_rmd_ringtone"
android:title="@string/rmd_EPr_ringtone_title" android:title="@string/rmd_EPr_ringtone_title"

@ -28,7 +28,7 @@ public class Database extends AbstractDatabase {
* Database version number. This variable must be updated when database * Database version number. This variable must be updated when database
* tables are updated, as it determines whether a database needs updating. * tables are updated, as it determines whether a database needs updating.
*/ */
public static final int VERSION = 5; public static final int VERSION = 6;
/** /**
* Database name (must be unique) * Database name (must be unique)
@ -123,6 +123,10 @@ public class Database extends AbstractDatabase {
database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " + database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " +
Task.DETAILS.accept(visitor, null)); Task.DETAILS.accept(visitor, null));
} }
case 5: {
database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " +
Task.REMINDER_SNOOZE.accept(visitor, null));
}
return true; return true;
} }

@ -30,7 +30,7 @@ public final class Constants {
/** /**
* Whether to turn on debugging logging and UI * Whether to turn on debugging logging and UI
*/ */
public static final boolean DEBUG = false; public static final boolean DEBUG = true;
/** /**
* Upgrade time * Upgrade time

Loading…
Cancel
Save