From ce6812fcf5204d32350ad6e75a27abd2cd166511 Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Wed, 11 Jul 2012 12:29:58 -0700 Subject: [PATCH] Introduced ability to repeat a task until a specified date --- .../astrid/api/AstridApiConstants.java | 8 ++ api/src/com/todoroo/astrid/data/Task.java | 4 + .../astrid/alarms/AlarmControlSet.java | 5 +- .../astrid/repeats/RepeatControlSet.java | 74 ++++++++++++++----- .../repeats/RepeatTaskCompleteListener.java | 13 +++- .../layout/control_set_deadline_display.xml | 39 ++++++++++ astrid/res/layout/control_set_repeat.xml | 4 + astrid/res/layout/repeat_until_dialog.xml | 37 ++++++++++ astrid/res/values/attrs.xml | 4 + astrid/res/values/strings-repeat.xml | 22 ++++++ .../astrid/activity/TaskEditFragment.java | 7 +- .../src/com/todoroo/astrid/dao/Database.java | 9 ++- .../todoroo/astrid/ui/DateAndTimeDialog.java | 16 ++-- .../todoroo/astrid/ui/DateAndTimePicker.java | 29 ++++++-- .../todoroo/astrid/ui/DeadlineControlSet.java | 2 +- .../astrid/ui/HideUntilControlSet.java | 2 +- 16 files changed, 234 insertions(+), 41 deletions(-) create mode 100644 astrid/res/layout/control_set_deadline_display.xml create mode 100644 astrid/res/layout/repeat_until_dialog.xml diff --git a/api/src/com/todoroo/astrid/api/AstridApiConstants.java b/api/src/com/todoroo/astrid/api/AstridApiConstants.java index c61601977..663c5012e 100644 --- a/api/src/com/todoroo/astrid/api/AstridApiConstants.java +++ b/api/src/com/todoroo/astrid/api/AstridApiConstants.java @@ -246,6 +246,14 @@ public class AstridApiConstants { */ public static final String BROADCAST_EVENT_TASK_REPEATED = PACKAGE + ".TASK_REPEATED"; + /** + * Action name for broadcast intent notifying that a repeating task has passed its repeat_until value + *
  • EXTRAS_TASK_ID id of the task + *
  • EXTRAS_OLD_DUE_DATE task old due date (could be 0) + *
  • EXTRAS_NEW_DUE_DATE task new due date (will not be 0) + */ + public static final String BROADCAST_EVENT_TASK_REPEAT_FINISHED = PACKAGE + ".TASK_REPEAT_FINISHED"; + /** * Action name for broadcast intent notifying that tag was deleted */ diff --git a/api/src/com/todoroo/astrid/data/Task.java b/api/src/com/todoroo/astrid/data/Task.java index 382643b98..30646a3d2 100644 --- a/api/src/com/todoroo/astrid/data/Task.java +++ b/api/src/com/todoroo/astrid/data/Task.java @@ -128,6 +128,9 @@ public final class Task extends RemoteModel { public static final StringProperty RECURRENCE = new StringProperty( TABLE, "recurrence"); + public static final LongProperty REPEAT_UNTIL = new LongProperty( + TABLE, "repeatUntil"); + public static final StringProperty CALENDAR_URI = new StringProperty( TABLE, "calendarUri"); @@ -241,6 +244,7 @@ public final class Task extends RemoteModel { defaultValues.put(CALENDAR_URI.name, ""); defaultValues.put(RECURRENCE.name, ""); + defaultValues.put(REPEAT_UNTIL.name, 0); defaultValues.put(REMINDER_PERIOD.name, 0); defaultValues.put(REMINDER_FLAGS.name, 0); defaultValues.put(REMINDER_LAST.name, 0); diff --git a/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmControlSet.java b/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmControlSet.java index 5a03ac905..d03d45a2a 100644 --- a/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmControlSet.java +++ b/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmControlSet.java @@ -19,6 +19,7 @@ import com.todoroo.astrid.data.Task; import com.todoroo.astrid.helper.TaskEditControlSet; import com.todoroo.astrid.ui.DateAndTimeDialog; import com.todoroo.astrid.ui.DateAndTimeDialog.DateAndTimeDialogListener; +import com.todoroo.astrid.ui.DateAndTimePicker; /** * Control set to manage adding and removing tags @@ -100,7 +101,7 @@ public final class AlarmControlSet extends TaskEditControlSet { } v.setTag(date); TextView label = (TextView) v.findViewById(R.id.alarm_string); - label.setText(pickerDialog.getDisplayString(activity, date)); + label.setText(DateAndTimePicker.getDisplayString(activity, date)); } } @@ -115,7 +116,7 @@ public final class AlarmControlSet extends TaskEditControlSet { alertItem.setTag(alert.getTime()); TextView display = (TextView) alertItem.findViewById(R.id.alarm_string); - display.setText(pickerDialog.getDisplayString(activity, alert.getTime())); + display.setText(DateAndTimePicker.getDisplayString(activity, alert.getTime())); ImageButton reminderRemoveButton; reminderRemoveButton = (ImageButton)alertItem.findViewById(R.id.button1); diff --git a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java index aea9c78bc..5f8d416ef 100644 --- a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java +++ b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java @@ -37,6 +37,9 @@ import com.todoroo.astrid.data.Task; import com.todoroo.astrid.service.StatisticsConstants; import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.TaskService; +import com.todoroo.astrid.ui.DateAndTimeDialog; +import com.todoroo.astrid.ui.DateAndTimeDialog.DateAndTimeDialogListener; +import com.todoroo.astrid.ui.DateAndTimePicker; import com.todoroo.astrid.ui.NumberPicker; import com.todoroo.astrid.ui.NumberPickerDialog; import com.todoroo.astrid.ui.NumberPickerDialog.OnNumberPickedListener; @@ -67,12 +70,14 @@ public class RepeatControlSet extends PopupControlSet { private Button value; private Spinner interval; private Spinner type; + private Button repeatUntil; private LinearLayout daysOfWeekContainer; private final CompoundButton[] daysOfWeek = new CompoundButton[7]; private String recurrence; private int repeatValue; private int intervalValue; + private long repeatUntilValue; private final List listeners = new LinkedList(); @@ -99,26 +104,45 @@ public class RepeatControlSet extends PopupControlSet { value.setText(activity.getString(R.string.repeat_every, newValue)); } + private void setRepeatUntilValue(long newValue) { + repeatUntilValue = newValue; + + if (newValue == 0) + repeatUntil.setText(activity.getString(R.string.repeat_forever)); + else + repeatUntil.setText(activity.getString(R.string.repeat_until, DateAndTimePicker.getDisplayString(activity, newValue))); + } + protected void repeatValueClick() { + int dialogValue = repeatValue; + if(dialogValue == 0) + dialogValue = 1; - final Runnable openDialogRunnable = new Runnable() { - public void run() { - int dialogValue = repeatValue; - if(dialogValue == 0) - dialogValue = 1; - - new NumberPickerDialog(activity, new OnNumberPickedListener() { - @Override - public void onNumberPicked(NumberPicker view, - int number) { - setRepeatValue(number); - } - }, activity.getResources().getString(R.string.repeat_interval_prompt), - dialogValue, 1, 1, 365).show(); + new NumberPickerDialog(activity, new OnNumberPickedListener() { + @Override + public void onNumberPicked(NumberPicker view, + int number) { + setRepeatValue(number); } - }; + }, activity.getResources().getString(R.string.repeat_interval_prompt), + dialogValue, 1, 1, 365).show(); + } - openDialogRunnable.run(); + private void repeatUntilClick() { + DateAndTimeDialog d = new DateAndTimeDialog(activity, repeatUntilValue, + R.layout.repeat_until_dialog, R.string.repeat_until_title); + d.setDateAndTimeDialogListener(new DateAndTimeDialogListener() { + @Override + public void onDateAndTimeSelected(long date) { + setRepeatUntilValue(date); + } + + @Override + public void onDateAndTimeCancelled() { + // + } + }); + d.show(); } @@ -139,6 +163,8 @@ public class RepeatControlSet extends PopupControlSet { if(recurrence == null) recurrence = ""; + repeatUntilValue = model.getValue(Task.REPEAT_UNTIL); + if(recurrence.length() > 0) { try { RRule rrule = new RRule(recurrence); @@ -196,6 +222,7 @@ public class RepeatControlSet extends PopupControlSet { RRule rrule = new RRule(recurrence); setRepeatValue(rrule.getInterval()); + setRepeatUntilValue(model.getValue(Task.REPEAT_UNTIL)); interval.setSelection(intervalValue); // clear all day of week checks, then update them @@ -233,7 +260,9 @@ public class RepeatControlSet extends PopupControlSet { interval = (Spinner) getView().findViewById(R.id.repeatInterval); type = (Spinner) getView().findViewById(R.id.repeatType); daysOfWeekContainer = (LinearLayout) getView().findViewById(R.id.repeatDayOfWeekContainer); + repeatUntil = (Button) getView().findViewById(R.id.repeatUntil); setRepeatValue(1); + setRepeatUntilValue(0); // set up days of week DateFormatSymbols dfs = new DateFormatSymbols(); @@ -280,6 +309,13 @@ public class RepeatControlSet extends PopupControlSet { // } }); + + repeatUntil.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + repeatUntilClick(); + } + }); daysOfWeekContainer.setVisibility(View.GONE); } @@ -329,6 +365,7 @@ public class RepeatControlSet extends PopupControlSet { if (!result.equals(task.getValue(Task.RECURRENCE))) task.putTransitory(TaskService.TRANS_REPEAT_CHANGED, true); task.setValue(Task.RECURRENCE, result); + task.setValue(Task.REPEAT_UNTIL, repeatUntilValue); switch(type.getSelectedItemPosition()) { case TYPE_DUE_DATE: @@ -385,7 +422,10 @@ public class RepeatControlSet extends PopupControlSet { String[] dates = activity.getResources().getStringArray( arrayResource); String date = String.format("%s %s", repeatValue, dates[intervalValue]); //$NON-NLS-1$ - return String.format(activity.getString(R.string.repeat_detail_duedate), date); // Every freq int + if (repeatUntilValue > 0) + return activity.getString(R.string.repeat_detail_duedate_until, date, DateAndTimePicker.getDisplayString(activity, repeatUntilValue, false, useAbbrev, useAbbrev)); + else + return activity.getString(R.string.repeat_detail_duedate, date); // Every freq int } @Override diff --git a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatTaskCompleteListener.java b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatTaskCompleteListener.java index 87a92238a..76f3bef57 100644 --- a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatTaskCompleteListener.java +++ b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatTaskCompleteListener.java @@ -63,15 +63,26 @@ public class RepeatTaskCompleteListener extends BroadcastReceiver { return; } + StatisticsService.reportEvent(StatisticsConstants.V2_TASK_REPEAT); + long oldDueDate = task.getValue(Task.DUE_DATE); + long repeatUntil = task.getValue(Task.REPEAT_UNTIL); + if (repeatUntil > 0 && newDueDate >= repeatUntil) { + Intent repeatFinished = new Intent(AstridApiConstants.BROADCAST_EVENT_TASK_REPEAT_FINISHED); + repeatFinished.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId()); + repeatFinished.putExtra(AstridApiConstants.EXTRAS_OLD_DUE_DATE, oldDueDate); + repeatFinished.putExtra(AstridApiConstants.EXTRAS_NEW_DUE_DATE, newDueDate); + context.sendOrderedBroadcast(repeatFinished, null); + return; + } + long hideUntil = task.getValue(Task.HIDE_UNTIL); if(hideUntil > 0 && task.getValue(Task.DUE_DATE) > 0) { hideUntil += newDueDate - task.getValue(Task.DUE_DATE); } // update repeat time when it repeats on the server - long oldDueDate = task.getValue(Task.DUE_DATE); task.setValue(Task.COMPLETION_DATE, 0L); task.setValue(Task.DUE_DATE, newDueDate); task.setValue(Task.HIDE_UNTIL, hideUntil); diff --git a/astrid/res/layout/control_set_deadline_display.xml b/astrid/res/layout/control_set_deadline_display.xml new file mode 100644 index 000000000..4163b6c99 --- /dev/null +++ b/astrid/res/layout/control_set_deadline_display.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + diff --git a/astrid/res/layout/control_set_repeat.xml b/astrid/res/layout/control_set_repeat.xml index 296997105..1a0c57f65 100644 --- a/astrid/res/layout/control_set_repeat.xml +++ b/astrid/res/layout/control_set_repeat.xml @@ -44,6 +44,10 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center"/> + +