Calendar event gets updated when you change due dates / roll over a repeating task. (untested).

Also, dates are specified in absolute where appropriate
pull/14/head
Tim Su 16 years ago
parent d1f6853643
commit c6408f488c

@ -56,6 +56,7 @@
<item quantity="other">%d Tags</item>
</plurals>
<!-- Time Constants -->
<string name="dateFormatter">MMM d</string>
<string name="daysVertical">D\na\ny\ns</string>
<string name="hoursVertical">H\no\nu\nr\ns</string>
<plurals name="Ndays">
@ -96,7 +97,8 @@
<string name="addtask_label">New Task</string>
<string name="taskList_hiddenPrefix">H</string>
<string name="taskList_dueIn">Due in</string>
<string name="taskList_dueRelativeTime">Due in</string>
<string name="taskList_dueAbsoluteDate">Due on</string>
<string name="taskList_goalPrefix">Goal</string>
<string name="taskList_overdueBy">Overdue by</string>
<string name="taskList_completedPrefix">Finished</string>

@ -657,12 +657,40 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
protected void onSaveInstanceState(Bundle outState) {
save();
super.onSaveInstanceState(outState);
// save the tag name token for when we rotate the screen
Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey(TAG_NAME_TOKEN))
outState.putString(TAG_NAME_TOKEN,
extras.getString(TAG_NAME_TOKEN));
}
/** Take the values from the model and set the calendar start and end times
* based on these. Sets keys 'dtstart' and 'dtend'.
*
* @param preferred preferred due date or null
* @param definite definite due date or null
* @param estimatedSeconds estimated duration or null
* @param values
*/
public static void createCalendarStartEndTimes(Date preferred, Date definite,
Integer estimatedSeconds, ContentValues values) {
Long deadlineDate = null;
if (preferred != null && preferred.after(new Date()))
deadlineDate = preferred.getTime();
else if (definite != null)
deadlineDate = definite.getTime();
else
deadlineDate = System.currentTimeMillis() + 24*3600*1000L;
int estimatedTime = DEFAULT_CAL_TIME;
if(estimatedSeconds != null && estimatedSeconds > 0) {
estimatedTime = estimatedSeconds;
}
values.put("dtstart", deadlineDate - estimatedTime * 1000L);
values.put("dtend", deadlineDate);
}
@Override
protected void onPause() {
// create calendar event
@ -678,21 +706,9 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
values.put("transparency", 0);
values.put("visibility", 0);
Long deadlineDate = null;
if (model.getPreferredDueDate() != null)
deadlineDate = model.getPreferredDueDate().getTime();
else if (model.getDefiniteDueDate() != null)
deadlineDate = model.getDefiniteDueDate().getTime();
else
deadlineDate = System.currentTimeMillis() + 24*3600*1000L;
int estimatedTime = DEFAULT_CAL_TIME;
if(model.getEstimatedSeconds() != null &&
model.getEstimatedSeconds() > 0) {
estimatedTime = model.getEstimatedSeconds();
}
values.put("dtstart", deadlineDate - estimatedTime * 1000L);
values.put("dtend", deadlineDate);
createCalendarStartEndTimes(model.getPreferredDueDate(),
model.getDefiniteDueDate(), model.getEstimatedSeconds(),
values);
Uri result = cr.insert(uri, values);
if(result != null)
@ -708,22 +724,13 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
Uri result = Uri.parse(model.getCalendarUri());
Intent intent = new Intent(Intent.ACTION_EDIT, result);
// recalculate dates
Long deadlineDate = null;
if (model.getPreferredDueDate() != null)
deadlineDate = model.getPreferredDueDate().getTime();
else if (model.getDefiniteDueDate() != null)
deadlineDate = model.getDefiniteDueDate().getTime();
else
deadlineDate = System.currentTimeMillis() + 24*3600*1000L;
ContentValues values = new ContentValues();
createCalendarStartEndTimes(model.getPreferredDueDate(),
model.getDefiniteDueDate(), model.getEstimatedSeconds(),
values);
int estimatedTime = DEFAULT_CAL_TIME;
if(model.getEstimatedSeconds() != null &&
model.getEstimatedSeconds() > 0) {
estimatedTime = model.getEstimatedSeconds();
}
intent.putExtra("beginTime", deadlineDate - estimatedTime * 1000L);
intent.putExtra("endTime", deadlineDate);
intent.putExtra("beginTime", values.getAsLong("dtstart"));
intent.putExtra("endTime", values.getAsLong("dtend"));
startActivity(intent);
}

@ -87,6 +87,9 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
private static final String CACHE_TRUE = "y";
/** Number of seconds after which we display the full date deadline */
private static final int FULL_DATE_THRESHOLD = 7*24*3600;
// alarm date formatter
private static final Format alarmFormat = new SimpleDateFormat(
"MM/dd hh:mm");
@ -309,39 +312,60 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
int secondsLeft = (int)((task.getCompletionDate().getTime() -
System.currentTimeMillis()) / 1000);
label.append(r.getString(R.string.taskList_completedPrefix)).
append(" ").
append(DateUtilities.getDurationString(r, Math.abs(secondsLeft), 1)).
append(" ");
if(secondsLeft < FULL_DATE_THRESHOLD)
label.append(DateUtilities.getDurationString(r,
Math.abs(secondsLeft), 1)).
append(" " + r.getString(R.string.ago_suffix));
else
label.append(DateUtilities.getFormattedDate(r,
task.getCompletionDate()));
}
} else {
boolean taskOverdue = false;
if(task.getDefiniteDueDate() != null) {
long timeLeft = task.getDefiniteDueDate().getTime() -
System.currentTimeMillis();
long timeLeft = (task.getDefiniteDueDate().getTime() -
System.currentTimeMillis())/1000;
if(timeLeft > 0) {
label.append(r.getString(R.string.taskList_dueIn)).append(" ");
if(timeLeft < FULL_DATE_THRESHOLD)
label.append(r.getString(R.string.taskList_dueRelativeTime)).append(" ");
else
label.append(r.getString(R.string.taskList_dueAbsoluteDate)).append(" ");
} else {
taskOverdue = true;
label.append(r.getString(R.string.taskList_overdueBy)).append(" ");
task.putCachedLabel(KEY_OVERDUE, CACHE_TRUE);
}
if(timeLeft < FULL_DATE_THRESHOLD)
label.append(DateUtilities.getDurationString(r,
(int)Math.abs(timeLeft/1000), 1));
else
label.append(DateUtilities.getFormattedDate(r,
task.getDefiniteDueDate()));
}
if(!taskOverdue && task.getPreferredDueDate() != null) {
if(task.getDefiniteDueDate() != null)
label.append(" / ");
long timeLeft = task.getPreferredDueDate().getTime() -
System.currentTimeMillis();
long timeLeft = (task.getPreferredDueDate().getTime() -
System.currentTimeMillis())/1000;
label.append(r.getString(R.string.taskList_goalPrefix)).append(" ");
if(timeLeft > 0) {
label.append(r.getString(R.string.taskList_dueIn)).append(" ");
if(timeLeft < FULL_DATE_THRESHOLD)
label.append(r.getString(R.string.taskList_dueRelativeTime)).append(" ");
else
label.append(r.getString(R.string.taskList_dueAbsoluteDate)).append(" ");
} else {
label.append(r.getString(R.string.taskList_overdueBy)).append(" ");
task.putCachedLabel(KEY_OVERDUE, CACHE_TRUE);
}
if(timeLeft < FULL_DATE_THRESHOLD)
label.append(DateUtilities.getDurationString(r,
(int)Math.abs(timeLeft/1000), 1)).append(" ");
(int)Math.abs(timeLeft/1000), 1));
else
label.append(DateUtilities.getFormattedDate(r,
task.getPreferredDueDate()));
}
}
cachedResult = label.toString();

@ -63,11 +63,11 @@ public abstract class AbstractTagModel extends AbstractModel {
static {
defaultValues.put(NAME, "");
defaultValues.put(NOTES, "");
defaultValues.put(ICON, (Integer)null);
defaultValues.put(PARENT, (Long)null);
defaultValues.put(FLAGS, (Integer)0);
defaultValues.put(LOCATION_LAT, (Integer)null);
defaultValues.put(LOCATION_LONG, (Integer)null);
defaultValues.put(ICON, 0);
defaultValues.put(PARENT, 0);
defaultValues.put(FLAGS, 0);
defaultValues.put(LOCATION_LAT, 0);
defaultValues.put(LOCATION_LONG, 0);
defaultValues.put(NOTIFICATIONS, 0);
}
@ -92,11 +92,11 @@ public abstract class AbstractTagModel extends AbstractModel {
String sql = new StringBuilder().
append("CREATE TABLE ").append(tableName).append(" (").
append(AbstractController.KEY_ROWID).append(" integer primary key autoincrement, ").
append(NAME).append(" text unique not null,").
append(NOTES).append(" text not null,").
append(NAME).append(" text unique,").
append(NOTES).append(" text,").
append(ICON).append(" integer,").
append(PARENT).append(" integer,").
append(FLAGS).append(" integer not null,").
append(FLAGS).append(" integer,").
append(LOCATION_LAT).append(" integer,").
append(LOCATION_LONG).append(" integer,").
append(NOTIFICATIONS).append(" integer,").

@ -35,6 +35,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;
import com.timsu.astrid.activities.TaskEdit;
import com.timsu.astrid.data.AbstractController;
import com.timsu.astrid.data.sync.SyncDataController;
import com.timsu.astrid.data.task.AbstractTaskModel.RepeatInfo;
@ -204,7 +205,7 @@ public class TaskController extends AbstractController {
if(taskId == null)
throw new UnsupportedOperationException("Cannot delete uncreated task!");
long id = taskId.getId();
cleanupTask(taskId);
cleanupTask(taskId, false);
return database.delete(TASK_TABLE_NAME, KEY_ROWID + "=" + id, null) > 0;
}
@ -255,7 +256,7 @@ public class TaskController extends AbstractController {
onTaskSetCompleted(task, values);
}
// task timer was updated
// task timer was updated, update notification bar
if(values.containsKey(AbstractTaskModel.TIMER_START)) {
// show notification bar if timer was started
if(values.get(AbstractTaskModel.TIMER_START) != null) {
@ -265,6 +266,41 @@ public class TaskController extends AbstractController {
Notifications.clearAllNotifications(context, task.getTaskIdentifier());
}
}
// due date was updated, update calendar event
if(values.containsKey(AbstractTaskModel.DEFINITE_DUE_DATE) ||
values.containsKey(AbstractTaskModel.PREFERRED_DUE_DATE)) {
try {
Cursor cursor = fetchTaskCursor(task.getTaskIdentifier(),
new String[] { AbstractTaskModel.CALENDAR_URI });
cursor.moveToFirst();
String uriAsString = cursor.getString(0);
cursor.close();
if(uriAsString != null && uriAsString.length() > 0) {
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.parse(uriAsString);
Integer estimated = null;
if(values.containsKey(AbstractTaskModel.ESTIMATED_SECONDS))
estimated = values.getAsInteger(AbstractTaskModel.ESTIMATED_SECONDS);
else { // read from event
Cursor event = cr.query(uri, new String[] {"dtstart", "dtend"},
null, null, null);
event.moveToFirst();
estimated = (event.getInt(1) - event.getInt(0))/1000;
}
// create new start and end date for this event
ContentValues newValues = new ContentValues();
TaskEdit.createCalendarStartEndTimes(task.getPreferredDueDate(),
task.getDefiniteDueDate(), estimated, newValues);
cr.update(uri, newValues, null, null);
}
} catch (Exception e) {
// ignore calendar event - event could be deleted or whatever
Log.e("astrid", "Error moving calendar event", e);
}
}
}
@ -286,15 +322,16 @@ public class TaskController extends AbstractController {
repeatModel.repeatTaskBy(context, this, repeatInfo);
cursor.close();
cleanupTask(task.getTaskIdentifier());
cleanupTask(task.getTaskIdentifier(), repeatInfo != null);
}
/** Clean up state from a task. Called when deleting or completing it */
private void cleanupTask(TaskIdentifier taskId) {
private void cleanupTask(TaskIdentifier taskId, boolean isRepeating) {
// delete notifications & alarms
Notifications.deleteAlarm(context, null, taskId.getId());
// delete calendar event
// delete calendar event if not repeating
if(!isRepeating) {
try {
Cursor cursor = fetchTaskCursor(taskId, new String[] {
AbstractTaskModel.CALENDAR_URI });
@ -313,6 +350,7 @@ public class TaskController extends AbstractController {
Log.e("astrid", "Error deleting calendar event", e);
}
}
}
/** Set last notification date */
public boolean setLastNotificationTime(TaskIdentifier taskId, Date date) {

@ -19,12 +19,22 @@
*/
package com.timsu.astrid.utilities;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.res.Resources;
import com.timsu.astrid.R;
public class DateUtilities {
/** Format a time into a medium length absolute format */
public static String getFormattedDate(Resources r, Date date) {
SimpleDateFormat format = new SimpleDateFormat(r.getString(R.string.dateFormatter));
return format.format(date);
}
/**
* Format a time into the format: 5 days, 3 hours, 2 minutes
*

Loading…
Cancel
Save