Better calendar integration: precreating events and then opening them up for edit, and also deleting them when you complete / delete your task.

pull/14/head
Tim Su 16 years ago
parent c4db48e97e
commit d1f6853643

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.timsu.astrid"
android:versionCode="84"
android:versionName="2.3.3">
android:versionCode="86"
android:versionName="2.3.5">
<meta-data android:name="com.a0soft.gphone.aTrackDog.webURL"
android:value="http://www.weloveastrid.com" />
@ -11,6 +11,7 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<application android:icon="@drawable/icon" android:label="@string/app_name">

@ -40,10 +40,10 @@
android:layout_height="fill_parent">
<CheckBox android:id="@+id/cb1"
android:paddingBottom="5px"
android:paddingBottom="5px"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_width="48px"
android:layout_height="52px"
android:scaleType="center" />
<ImageView android:id="@+id/imageLeft"

@ -159,6 +159,7 @@
<string name="definiteDueDate_label">Absolute Deadline</string>
<string name="preferredDueDate_label">Goal Deadline</string>
<string name="addToCalendar_label">Add Task To Calendar</string>
<string name="showCalendar_label">Open Calendar Event</string>
<string name="hiddenUntil_label">Hide Until This Date</string>
<string name="repeat_label">Repeat Every</string>
<string name="repeat_value_unset">No Repeat Set</string>

@ -28,10 +28,13 @@ import java.util.Map;
import java.util.Set;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
@ -207,6 +210,8 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
if(reminder != null)
notification.setTimeDuration(24*3600*reminder);
}
if(model.getCalendarUri() != null)
addToCalendar.setText(r.getString(R.string.showCalendar_label));
// tags
tags = tagController.getAllTags(this);
@ -660,37 +665,69 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
@Override
protected void onPause() {
// create calendar event
if(addToCalendar.isChecked() && model.getCalendarUri() == null) {
Uri uri = Uri.parse("content://calendar/events");
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put("title", name.getText().toString());
values.put("calendar_id", 1);
values.put("description", notes.getText().toString());
values.put("hasAlarm", 0);
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);
Uri result = cr.insert(uri, values);
if(result != null)
model.setCalendarUri(result.toString());
else
Log.e("astrid", "Error creating calendar event!");
}
if(shouldSaveState)
save();
// create calendar event
if(addToCalendar.isChecked()) {
addToCalendar.setChecked(false);
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("title", name.getText());
if(addToCalendar.isChecked() && model.getCalendarUri() != null) {
Uri result = Uri.parse(model.getCalendarUri());
Intent intent = new Intent(Intent.ACTION_EDIT, result);
// recalculate dates
Long deadlineDate = null;
if(model.getPreferredDueDate() != null)
if (model.getPreferredDueDate() != null)
deadlineDate = model.getPreferredDueDate().getTime();
else if(model.getDefiniteDueDate() != null)
else if (model.getDefiniteDueDate() != null)
deadlineDate = model.getDefiniteDueDate().getTime();
else
deadlineDate = System.currentTimeMillis() + 24*3600*1000L;
if(deadlineDate != null) {
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);
} else {
intent.putExtra("allDay", true);
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);
startActivity(intent);
}
super.onPause();
}

@ -45,7 +45,7 @@ import com.timsu.astrid.utilities.Preferences;
public abstract class AbstractTaskModel extends AbstractModel {
/** Version number of this model */
static final int VERSION = 3;
static final int VERSION = 4;
public static final int COMPLETE_PERCENTAGE = 100;
@ -67,6 +67,7 @@ public abstract class AbstractTaskModel extends AbstractModel {
static final String REPEAT = "repeat";
static final String CREATION_DATE = "creationDate";
static final String COMPLETION_DATE = "completionDate";
static final String CALENDAR_URI = "calendarUri";
// reserved fields ---
static final String BLOCKING_ON = "blockingOn";
@ -99,6 +100,7 @@ public abstract class AbstractTaskModel extends AbstractModel {
defaultValues.put(LAST_NOTIFIED, (Long)null);
defaultValues.put(REPEAT, 0);
defaultValues.put(COMPLETION_DATE, (Long)null);
defaultValues.put(CALENDAR_URI, (String)null);
}
// --- database helper
@ -133,7 +135,8 @@ public abstract class AbstractTaskModel extends AbstractModel {
append(LAST_NOTIFIED).append(" integer,").
append(REPEAT).append(" integer,").
append(CREATION_DATE).append(" integer,").
append(COMPLETION_DATE).append(" integer").
append(COMPLETION_DATE).append(" integer,").
append(CALENDAR_URI).append(" text").
append(");").toString();
db.execSQL(sql);
}
@ -176,6 +179,16 @@ public abstract class AbstractTaskModel extends AbstractModel {
Log.e("astrid", "Error updating table!", e);
}
case 3:
sql = new StringBuilder().append("ALTER TABLE ").
append(tableName).append(" ADD COLUMN ").
append(CALENDAR_URI).append(" text").toString();
try {
db.execSQL(sql);
} catch (Exception e) {
Log.e("astrid", "Error updating table!", e);
}
break;
default:
// we don't know how to handle it... do the unfortunate thing
@ -410,6 +423,14 @@ public abstract class AbstractTaskModel extends AbstractModel {
return new RepeatInfo(interval, value);
}
protected String getCalendarUri() {
String uri = retrieveString(CALENDAR_URI);
if(uri != null && uri.length() == 0)
return null;
else
return uri;
}
// --- setters
protected void setName(String name) {
@ -493,6 +514,10 @@ public abstract class AbstractTaskModel extends AbstractModel {
putIfChangedFromDatabase(REPEAT, repeat);
}
protected void setCalendarUri(String uri) {
putIfChangedFromDatabase(CALENDAR_URI, uri);
}
// --- utility methods
protected void putDate(String fieldName, Date date) {

@ -25,12 +25,15 @@ import java.util.HashSet;
import java.util.List;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;
import com.timsu.astrid.data.AbstractController;
import com.timsu.astrid.data.sync.SyncDataController;
@ -201,7 +204,7 @@ public class TaskController extends AbstractController {
if(taskId == null)
throw new UnsupportedOperationException("Cannot delete uncreated task!");
long id = taskId.getId();
Notifications.deleteAlarm(context, null, id);
cleanupTask(taskId);
return database.delete(TASK_TABLE_NAME, KEY_ROWID + "=" + id, null) > 0;
}
@ -283,7 +286,32 @@ public class TaskController extends AbstractController {
repeatModel.repeatTaskBy(context, this, repeatInfo);
cursor.close();
Notifications.deleteAlarm(context, null, task.getTaskIdentifier().getId());
cleanupTask(task.getTaskIdentifier());
}
/** Clean up state from a task. Called when deleting or completing it */
private void cleanupTask(TaskIdentifier taskId) {
// delete notifications & alarms
Notifications.deleteAlarm(context, null, taskId.getId());
// delete calendar event
try {
Cursor cursor = fetchTaskCursor(taskId, new String[] {
AbstractTaskModel.CALENDAR_URI });
cursor.moveToFirst();
String uri = cursor.getString(0);
cursor.close();
if(uri != null && uri.length() > 0) {
ContentResolver cr = context.getContentResolver();
cr.delete(Uri.parse(uri), null, null);
ContentValues values = new ContentValues();
values.put(AbstractTaskModel.CALENDAR_URI, (String)null);
database.update(TASK_TABLE_NAME, values, KEY_ROWID + "=" +
taskId.getId(), null);
}
} catch (Exception e) {
Log.e("astrid", "Error deleting calendar event", e);
}
}
/** Set last notification date */

@ -46,6 +46,7 @@ public class TaskModelForEdit extends AbstractTaskModel implements Notifiable {
PROGRESS_PERCENTAGE,
NOTES,
REPEAT,
CALENDAR_URI,
};
// --- constructors
@ -136,6 +137,11 @@ public class TaskModelForEdit extends AbstractTaskModel implements Notifiable {
return super.getRepeat();
}
@Override
public String getCalendarUri() {
return super.getCalendarUri();
}
@Override
public void setDefiniteDueDate(Date definiteDueDate) {
super.setDefiniteDueDate(definiteDueDate);
@ -190,4 +196,9 @@ public class TaskModelForEdit extends AbstractTaskModel implements Notifiable {
public void setRepeat(RepeatInfo taskRepeat) {
super.setRepeat(taskRepeat);
}
@Override
public void setCalendarUri(String uri) {
super.setCalendarUri(uri);
}
}

Loading…
Cancel
Save