diff --git a/api/src/com/todoroo/andlib/data/AbstractModel.java b/api/src/com/todoroo/andlib/data/AbstractModel.java index 650dabd62..1d41d88eb 100644 --- a/api/src/com/todoroo/andlib/data/AbstractModel.java +++ b/api/src/com/todoroo/andlib/data/AbstractModel.java @@ -10,6 +10,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import android.content.ContentValues; import android.os.Parcel; @@ -67,6 +68,9 @@ public abstract class AbstractModel implements Parcelable, Cloneable { /** Values from database */ protected ContentValues values = null; + /** Model Flags(not saved in database) */ + protected HashSet modelFlags = null; + /** Get database-read values for this object */ public ContentValues getDatabaseValues() { return values; @@ -160,6 +164,7 @@ public abstract class AbstractModel implements Parcelable, Cloneable { // clears user-set values setValues = null; + modelFlags = null; for (Property property : cursor.getProperties()) { try { @@ -345,6 +350,21 @@ public abstract class AbstractModel implements Parcelable, Cloneable { return (getValue(property) & flag) > 0; } + + // --- setting and retrieving flags + + public synchronized void setModelFlag(String flag) { + if(modelFlags == null) + modelFlags = new HashSet(); + modelFlags.add(flag); + } + + public boolean checkModelFlag(String flag) { + if(modelFlags == null) + return false; + return modelFlags.contains(flag); + } + // --- property management /** diff --git a/api/src/com/todoroo/astrid/data/Task.java b/api/src/com/todoroo/astrid/data/Task.java index 5fecd82ae..da79064ef 100644 --- a/api/src/com/todoroo/astrid/data/Task.java +++ b/api/src/com/todoroo/astrid/data/Task.java @@ -171,6 +171,17 @@ public final class Task extends RemoteModel { /** whether task is read-only */ public static final int FLAG_IS_READONLY = 1 << 2; + // --- user id special values + + /** user id = read user email value */ + public static final long USER_ID_EMAIL = -2L; + + /** user id = unassigned */ + public static final long USER_ID_UNASSIGNED = -1L; + + /** user id = myself */ + public static final long USER_ID_SELF = 0L; + // --- notification flags /** whether to send a reminder at deadline */ diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleControlSet.java b/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleControlSet.java index 36ada3f73..6b29ad946 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleControlSet.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/EditPeopleControlSet.java @@ -498,11 +498,11 @@ public class EditPeopleControlSet extends PopupControlSet { activity.getString(R.string.actfm_EPA_invalid_email, userJson.optString("email"))); } - if(userJson == null || userJson.optLong("id", -2) == 0) { - dirty = task.getValue(Task.USER_ID) == 0L ? dirty : true; - task.setValue(Task.USER_ID, 0L); + if(userJson == null || userJson.optLong("id", Task.USER_ID_EMAIL) == Task.USER_ID_SELF) { + dirty = task.getValue(Task.USER_ID) == Task.USER_ID_SELF ? dirty : true; + task.setValue(Task.USER_ID, Task.USER_ID_SELF); if(!TextUtils.isEmpty(task.getValue(Task.USER))) - task.setValue(Task.USER, "{}"); + task.setValue(Task.USER, ""); } else { String user = userJson.toString(); @@ -510,20 +510,20 @@ public class EditPeopleControlSet extends PopupControlSet { String taskUserEmail = ""; try { JSONObject taskUser = new JSONObject(task.getValue(Task.USER)); - taskUserId = taskUser.optLong("id", -2); + taskUserId = taskUser.optLong("id", Task.USER_ID_EMAIL); taskUserEmail = taskUser.optString("email"); } catch (JSONException e) { // sad times } - long userId = userJson.optLong("id", -2); + long userId = userJson.optLong("id", Task.USER_ID_EMAIL); String userEmail = userJson.optString("email"); - boolean match = (userId == taskUserId && userId != -2); + boolean match = (userId == taskUserId && userId != Task.USER_ID_EMAIL); match = match || (userEmail.equals(taskUserEmail) && !TextUtils.isEmpty(userEmail)); dirty = match ? dirty : true; - task.setValue(Task.USER_ID, userJson.optLong("id", -2)); + task.setValue(Task.USER_ID, userJson.optLong("id", Task.USER_ID_EMAIL)); task.setValue(Task.USER, user); } @@ -543,7 +543,7 @@ public class EditPeopleControlSet extends PopupControlSet { public void onClick(DialogInterface d, int which) { makePrivateTask(); AssignedToUser me = (AssignedToUser) assignedList.getAdapter().getItem(0); - task.setValue(Task.USER_ID, me.user.optLong("id", -2)); + task.setValue(Task.USER_ID, me.user.optLong("id", Task.USER_ID_EMAIL)); task.setValue(Task.USER, me.user.toString()); } }; @@ -557,14 +557,8 @@ public class EditPeopleControlSet extends PopupControlSet { if(!TextUtils.isEmpty(task.getValue(Task.SHARED_WITH)) || sharedWith.length() != 0) task.setValue(Task.SHARED_WITH, sharedWith.toString()); - if(dirty) - taskService.save(task); - - - if(dirty) - shareTask(sharedWith); - else - showSaveToast(); + task.setModelFlag("task-assigned"); + showSaveToast(); return true; } catch (JSONException e) { @@ -582,13 +576,12 @@ public class EditPeopleControlSet extends PopupControlSet { private void makePrivateTask() { assignToMe(); sharedWithContainer.removeAllViews(); - sharedWithContainer.addPerson(""); + sharedWithContainer.addPerson(""); //$NON-NLS-1$ refreshDisplayView(); } private void showSaveToast() { - int length = saveToast.indexOf('\n') > -1 ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT; - Toast.makeText(activity, saveToast, length).show(); + Toast.makeText(activity, saveToast, Toast.LENGTH_LONG).show(); } private class ParseSharedException extends Exception { diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java index fe6618a78..e8fcabe6d 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java @@ -319,7 +319,7 @@ public final class ActFmSyncService { if(values.containsKey(Task.DELETION_DATE.name)) { params.add("deleted_at"); params.add(task.getValue(Task.DELETION_DATE) / 1000L); } - if(Flags.checkAndClear(Flags.ACTFM_REPEATED_TASK)) { + if(task.checkModelFlag("repeat-complete")) { params.add("completed"); params.add(DateUtilities.now() / 1000L); } else if(values.containsKey(Task.COMPLETION_DATE.name)) { params.add("completed"); params.add(task.getValue(Task.COMPLETION_DATE) / 1000L); @@ -334,14 +334,25 @@ public final class ActFmSyncService { recurrence = recurrence + ";FROM=COMPLETION"; params.add("repeat"); params.add(recurrence); } - long userId = task.getValue(Task.USER_ID); - if(values.containsKey(Task.USER_ID.name) && userId >= 0 || userId == -1) { - params.add("user_id"); - if(task.getValue(Task.USER_ID) == 0) - params.add(ActFmPreferenceService.userId()); - else - params.add(task.getValue(Task.USER_ID)); + + if(values.containsKey(Task.USER_ID.name) && task.checkModelFlag("task-assigned")) { + if(task.getValue(Task.USER_ID) == Task.USER_ID_EMAIL) { + try { + JSONObject user = new JSONObject(task.getValue(Task.USER)); + params.add("user_email"); + params.add(user.get("email")); + } catch (JSONException e) { + Log.e("Error parsing user", task.getValue(Task.USER), e); + } + } else { + params.add("user_id"); + if(task.getValue(Task.USER_ID) == Task.USER_ID_SELF) + params.add(ActFmPreferenceService.userId()); + else + params.add(task.getValue(Task.USER_ID)); + } } + if(Flags.checkAndClear(Flags.TAGS_CHANGED) || newlyCreated) { TodorooCursor cursor = TagService.getInstance().getTags(task.getId()); try { diff --git a/astrid/src-legacy/com/timsu/astrid/data/AbstractModel.java b/astrid/src-legacy/com/timsu/astrid/data/AbstractModel.java index 40dc3d911..38aad297e 100644 --- a/astrid/src-legacy/com/timsu/astrid/data/AbstractModel.java +++ b/astrid/src-legacy/com/timsu/astrid/data/AbstractModel.java @@ -41,10 +41,10 @@ public abstract class AbstractModel { protected ContentValues setValues = new ContentValues(); /** Cached values from database */ - private final ContentValues values = new ContentValues(); + private final ContentValues values = new ContentValues(); /** Cursor into the database */ - private Cursor cursor = null; + private Cursor cursor = null; // --- constructors diff --git a/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java index 578716d05..ea9e61fd0 100755 --- a/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java @@ -651,13 +651,14 @@ public final class TaskEditActivity extends Activity { } } - taskService.save(model); String processedToast = addDueTimeToToast(toast.toString()); - if(!onPause && peopleControlSet != null && !peopleControlSet.saveSharingSettings(processedToast)) - return; + boolean cancelFinish = !onPause && peopleControlSet != null && + !peopleControlSet.saveSharingSettings(processedToast); + + taskService.save(model); - if (!onPause) { // Saving during on pause could cause a double finish + if (!onPause && !cancelFinish) { shouldSaveState = false; finish(); }