diff --git a/app/src/androidTest/java/com/todoroo/astrid/data/TaskTest.java b/app/src/androidTest/java/com/todoroo/astrid/data/TaskTest.java index ed8db65df..2e42d59dd 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/data/TaskTest.java +++ b/app/src/androidTest/java/com/todoroo/astrid/data/TaskTest.java @@ -12,10 +12,6 @@ import org.tasks.time.DateTime; import java.util.ArrayList; import java.util.TreeSet; -import static com.todoroo.astrid.data.Task.COMPLETION_DATE; -import static com.todoroo.astrid.data.Task.DELETION_DATE; -import static com.todoroo.astrid.data.Task.DUE_DATE; -import static com.todoroo.astrid.data.Task.HIDE_UNTIL; import static com.todoroo.astrid.data.Task.URGENCY_DAY_AFTER; import static com.todoroo.astrid.data.Task.URGENCY_IN_TWO_WEEKS; import static com.todoroo.astrid.data.Task.URGENCY_NEXT_MONTH; @@ -115,7 +111,7 @@ public class TaskTest { @Test public void testTaskHasDueTime() { Task task = new Task(); - task.setValue(DUE_DATE, 1388516076000L); + task.setDueDate(1388516076000L); assertTrue(task.hasDueTime()); assertTrue(task.hasDueDate()); } @@ -123,7 +119,7 @@ public class TaskTest { @Test public void testTaskHasDueDate() { Task task = new Task(); - task.setValue(DUE_DATE, 1388469600000L); + task.setDueDate(1388469600000L); assertFalse(task.hasDueTime()); assertTrue(task.hasDueDate()); } @@ -175,7 +171,7 @@ public class TaskTest { @Test public void testTaskIsCompleted() { Task task = new Task(); - task.setValue(COMPLETION_DATE, 1L); + task.setCompletionDate(1L); assertTrue(task.isCompleted()); } @@ -184,7 +180,7 @@ public class TaskTest { final long now = currentTimeMillis(); freezeAt(now).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(HIDE_UNTIL, now); + task.setHideUntil(now); assertFalse(task.isHidden()); }}); } @@ -194,7 +190,7 @@ public class TaskTest { final long now = currentTimeMillis(); freezeAt(now).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(HIDE_UNTIL, now + 1); + task.setHideUntil(now + 1); assertTrue(task.isHidden()); }}); } @@ -202,7 +198,7 @@ public class TaskTest { @Test public void testTaskIsDeleted() { Task task = new Task(); - task.setValue(DELETION_DATE, 1L); + task.setDeletionDate(1L); assertTrue(task.isDeleted()); } @@ -216,7 +212,7 @@ public class TaskTest { final long now = currentTimeMillis(); freezeAt(now).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(DUE_DATE, now); + task.setDueDate(now); assertFalse(task.isOverdue()); }}); } @@ -226,7 +222,7 @@ public class TaskTest { final long dueDate = currentTimeMillis(); freezeAt(dueDate + 1).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(DUE_DATE, dueDate); + task.setDueDate(dueDate); assertTrue(task.isOverdue()); }}); } @@ -236,7 +232,7 @@ public class TaskTest { final DateTime dueDate = new DateTime().startOfDay(); freezeAt(dueDate.plusHours(12).minusMillis(1)).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(DUE_DATE, dueDate.getMillis()); + task.setDueDate(dueDate.getMillis()); assertFalse(task.hasDueTime()); assertFalse(task.isOverdue()); }}); @@ -247,7 +243,7 @@ public class TaskTest { final DateTime dueDate = new DateTime().startOfDay(); freezeAt(dueDate.plusHours(12)).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(DUE_DATE, dueDate.getMillis()); + task.setDueDate(dueDate.getMillis()); assertFalse(task.hasDueTime()); assertFalse(task.isOverdue()); }}); @@ -258,7 +254,7 @@ public class TaskTest { final DateTime dueDate = new DateTime().startOfDay(); freezeAt(dueDate.plusDays(1)).thawAfter(new Snippet() {{ Task task = new Task(); - task.setValue(DUE_DATE, dueDate.getMillis()); + task.setDueDate(dueDate.getMillis()); assertFalse(task.hasDueTime()); assertTrue(task.isOverdue()); }}); diff --git a/app/src/androidTest/java/com/todoroo/astrid/service/QuickAddMarkupTest.java b/app/src/androidTest/java/com/todoroo/astrid/service/QuickAddMarkupTest.java index e4233773e..60a778b79 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/service/QuickAddMarkupTest.java +++ b/app/src/androidTest/java/com/todoroo/astrid/service/QuickAddMarkupTest.java @@ -8,6 +8,8 @@ package com.todoroo.astrid.service; import android.support.test.runner.AndroidJUnit4; import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.tags.TagService; +import com.todoroo.astrid.utility.TitleParser; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,7 +27,7 @@ import static junit.framework.Assert.assertEquals; @RunWith(AndroidJUnit4.class) public class QuickAddMarkupTest extends InjectingTestCase { - @Inject TaskCreator taskCreator; + @Inject TagService tagService; @Override protected void inject(TestComponent component) { @@ -102,7 +104,7 @@ public class QuickAddMarkupTest extends InjectingTestCase { task = new Task(); task.setTitle(title); tags.clear(); - taskCreator.parseQuickAddMarkup(task, tags); + TitleParser.parse(tagService, task, tags); } private void assertImportanceIs(int importance) { diff --git a/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java b/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java index 27f8312f4..c56b4f3a9 100644 --- a/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java +++ b/app/src/googleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java @@ -31,7 +31,6 @@ import com.google.api.services.tasks.model.TaskList; import com.google.api.services.tasks.model.TaskLists; import com.google.api.services.tasks.model.Tasks; import com.google.common.base.Strings; -import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Join; @@ -74,7 +73,6 @@ import javax.inject.Inject; import timber.log.Timber; -import static com.todoroo.andlib.data.AbstractModel.NO_ID; import static com.todoroo.astrid.data.Task.NO_UUID; import static org.tasks.date.DateTimeUtils.newDateTime; @@ -297,7 +295,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter task.setModificationDate(DateUtilities.now()); gtasksMetadata.setLastSync(DateUtilities.now() + 1000L); - if (gtasksMetadata.getId() == NO_ID) { + if (gtasksMetadata.getId() == Task.NO_ID) { googleTaskDao.insert(gtasksMetadata); } else { googleTaskDao.update(gtasksMetadata); @@ -357,7 +355,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter private long localIdForGtasksId(String gtasksId) { GoogleTask metadata = getMetadataByGtaskId(gtasksId); - return metadata == null ? AbstractModel.NO_ID : metadata.getTask(); + return metadata == null ? Task.NO_ID : metadata.getTask(); } private GoogleTask getMetadataByGtaskId(String gtaskId) { @@ -370,15 +368,15 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter if(task.task.isSaved()) { Task local = taskDao.fetch(task.task.getId()); if (local == null) { - task.task.setId(NO_ID); + task.task.setId(Task.NO_ID); task.task.setUuid(NO_UUID); } else { mergeDates(task.task, local); } } else { // Set default importance and reminders for remotely created tasks task.task.setImportance(preferences.getIntegerFromString( - R.string.p_default_importance_key, Task.IMPORTANCE_SHOULD_DO)); - TaskCreator.setDefaultReminders(preferences, task.task); + R.string.p_default_importance_key, Task.IMPORTANCE_SHOULD_DO)); // TODO: can probably remove this + TaskCreator.setDefaultReminders(preferences, task.task); // TODO: can probably remove this too task.task.setUuid(UUIDHelper.newUUID()); taskDao.createNew(task.task); } diff --git a/app/src/googleplay/java/org/tasks/receivers/GoogleTaskPusher.java b/app/src/googleplay/java/org/tasks/receivers/GoogleTaskPusher.java index bc34baeb3..c82bfca79 100644 --- a/app/src/googleplay/java/org/tasks/receivers/GoogleTaskPusher.java +++ b/app/src/googleplay/java/org/tasks/receivers/GoogleTaskPusher.java @@ -1,20 +1,15 @@ package org.tasks.receivers; -import com.todoroo.andlib.data.Property; +import com.google.common.base.Strings; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; import org.tasks.gtasks.SyncAdapterHelper; -import java.util.ArrayList; - import javax.inject.Inject; public class GoogleTaskPusher { - private static final Property[] GOOGLE_TASK_PROPERTIES = { Task.ID, Task.TITLE, - Task.NOTES, Task.DUE_DATE, Task.COMPLETION_DATE, Task.DELETION_DATE }; - private final SyncAdapterHelper syncAdapterHelper; @Inject @@ -22,7 +17,7 @@ public class GoogleTaskPusher { this.syncAdapterHelper = syncAdapterHelper; } - void push(Task task, ArrayList modifiedValues) { + void push(Task task, Task original) { if(!syncAdapterHelper.isEnabled()) { return; } @@ -31,20 +26,16 @@ public class GoogleTaskPusher { return; } - if (checkValuesForProperties(modifiedValues, GOOGLE_TASK_PROPERTIES) || task.checkTransitory(SyncFlags.FORCE_SYNC)) { + if (original == null || + !task.getTitle().equals(original.getTitle()) || + (Strings.isNullOrEmpty(task.getNotes()) + ? !Strings.isNullOrEmpty(original.getNotes()) + : !task.getNotes().equals(original.getNotes())) || + !task.getDueDate().equals(original.getDueDate()) || + !task.getCompletionDate().equals(original.getCompletionDate()) || + !task.getDeletionDate().equals(original.getDeletionDate()) || + task.checkAndClearTransitory(SyncFlags.FORCE_SYNC)) { syncAdapterHelper.requestSynchronization(); } } - - private boolean checkValuesForProperties(ArrayList values, Property[] properties) { - if (values == null) { - return false; - } - for (Property property : properties) { - if (property != Task.ID && values.contains(property.name)) { - return true; - } - } - return false; - } } diff --git a/app/src/googleplay/java/org/tasks/receivers/PushReceiver.java b/app/src/googleplay/java/org/tasks/receivers/PushReceiver.java index f787cbea5..edcc7f6b0 100644 --- a/app/src/googleplay/java/org/tasks/receivers/PushReceiver.java +++ b/app/src/googleplay/java/org/tasks/receivers/PushReceiver.java @@ -15,10 +15,10 @@ import javax.inject.Inject; public class PushReceiver extends InjectingBroadcastReceiver { - public static void broadcast(Context context, Task task, ArrayList values) { + public static void broadcast(Context context, Task task, Task original) { Intent intent = new Intent(context, PushReceiver.class); intent.putExtra(AstridApiConstants.EXTRAS_TASK, task); - intent.putStringArrayListExtra(AstridApiConstants.EXTRAS_VALUES, values); + intent.putExtra(AstridApiConstants.EXTRAS_ORIGINAL, original); context.sendBroadcast(intent); } @@ -30,7 +30,7 @@ public class PushReceiver extends InjectingBroadcastReceiver { googleTaskPusher.push( intent.getParcelableExtra(AstridApiConstants.EXTRAS_TASK), - intent.getStringArrayListExtra(AstridApiConstants.EXTRAS_VALUES)); + intent.getParcelableExtra(AstridApiConstants.EXTRAS_ORIGINAL)); } @Override diff --git a/app/src/main/java/com/todoroo/andlib/data/AbstractModel.java b/app/src/main/java/com/todoroo/andlib/data/AbstractModel.java deleted file mode 100644 index 0c11edca0..000000000 --- a/app/src/main/java/com/todoroo/andlib/data/AbstractModel.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.andlib.data; - -import android.arch.persistence.room.Ignore; -import android.content.ContentValues; - -import com.todoroo.andlib.data.Property.LongProperty; -import com.todoroo.astrid.data.Task; - -import org.tasks.data.Tag; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map.Entry; -import java.util.Set; - -import static com.google.common.collect.Sets.newHashSet; - -/** - * AbstractModel represents a row in a database. - *

- * A single database can be represented by multiple AbstractModels - * corresponding to different queries that return a different set of columns. - * Each model exposes a set of properties that it contains. - * - * @author Tim Su - * - */ -public abstract class AbstractModel { - - /** id property common to all models */ - protected static final String ID_PROPERTY_NAME = "_id"; //$NON-NLS-1$ - - /** id field common to all models */ - public static final LongProperty ID_PROPERTY = new LongProperty(null, ID_PROPERTY_NAME); - - /** sentinel for objects without an id */ - public static final long NO_ID = 0; - - // --- abstract methods - - public interface ValueWriter { - void setValue(Task instance, TYPE value); - } - - // --- data store variables and management - - /* Data Source Ordering: - * - * In order to return the best data, we want to check first what the user - * has explicitly set (setValues), then the values we have read out of - * the database (values), then defaults (getRoomGetters) - */ - - /** User set values */ - @Ignore - protected final Set setValues = new HashSet<>(); - - /** Transitory Metadata (not saved in database) */ - @Ignore - protected HashMap transitoryData = null; - - /** Get the user-set values for this object */ - public Set getSetValues() { - return newHashSet(setValues); - } - - /** - * Transfers all set values into values. This occurs when a task is - * saved - future saves will not need to write all the data as before. - */ - public void markSaved() { - setValues.clear(); - } - - private void setValue(String columnName, Object value) { - ValueWriter writer = Task.roomSetters.get(columnName); - if (writer == null) { - throw new RuntimeException(); - } - writer.setValue((Task) this, value); - setValues.add(columnName); - } - - - /** - * Utility method to get the identifier of the model, if it exists. - * - * @return {@value #NO_ID} if this model was not added to the database - */ - abstract public long getId(); - - public void setId(long id) { - setValue(ID_PROPERTY, id); - } - - /** - * @return true if this model has found Jesus (i.e. the database) - */ - public boolean isSaved() { - return getId() != NO_ID; - } - - /** - * @return true if setValues or values contains this property - */ - public boolean isModified(Property property) { - return setValues.contains(property.getColumnName()); - } - - // --- data storage - - /** - * Sets the given property. Make sure this model has this property! - */ - public synchronized void setValue(Property property, TYPE value) { - setValue(property.getColumnName(), value); - } - - /** - * Merges set values with those coming from another source, - * keeping the existing value if one already exists - */ - public synchronized void mergeWithoutReplacement(ContentValues other) { - for (Entry item : other.valueSet()) { - String columnName = item.getKey(); - if (setValues.add(columnName)) { - setValue(columnName, item.getValue()); - } - } - } - - // --- setting and retrieving flags - - public synchronized void putTransitory(String key, Object value) { - if(transitoryData == null) { - transitoryData = new HashMap<>(); - } - transitoryData.put(key, value); - } - - public void setTags(ArrayList tags) { - if (transitoryData == null) { - transitoryData = new HashMap<>(); - } - transitoryData.put(Tag.KEY, tags); - } - - public ArrayList getTags() { - Object tags = getTransitory(Tag.KEY); - return tags == null ? new ArrayList<>() : (ArrayList) tags; - } - - public T getTransitory(String key) { - if(transitoryData == null) { - return null; - } - return (T) transitoryData.get(key); - } - - private Object clearTransitory(String key) { - if (transitoryData == null) { - return null; - } - return transitoryData.remove(key); - } - - // --- Convenience wrappers for using transitories as flags - public boolean checkTransitory(String flag) { - Object trans = getTransitory(flag); - return trans != null; - } - - public boolean checkAndClearTransitory(String flag) { - Object trans = clearTransitory(flag); - return trans != null; - } -} diff --git a/app/src/main/java/com/todoroo/andlib/data/Table.java b/app/src/main/java/com/todoroo/andlib/data/Table.java index be658bbc1..9cf1b74d4 100644 --- a/app/src/main/java/com/todoroo/andlib/data/Table.java +++ b/app/src/main/java/com/todoroo/andlib/data/Table.java @@ -16,17 +16,15 @@ import com.todoroo.andlib.sql.SqlTable; */ public final class Table extends SqlTable { public final String name; - private final Class modelClass; - public Table(String name, Class modelClass) { - this(name, modelClass, null); + public Table(String name) { + this(name, null); } - private Table(String name, Class modelClass, String alias) { + private Table(String name, String alias) { super(name); this.name = name; this.alias = alias; - this.modelClass = modelClass; } /** @@ -34,7 +32,7 @@ public final class Table extends SqlTable { */ @Override public Table as(String newAlias) { - return new Table(name, modelClass, newAlias); + return new Table(name, newAlias); } @Override diff --git a/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java b/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java index 9d76fbb41..79e94f95a 100644 --- a/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java +++ b/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java @@ -6,7 +6,6 @@ package com.todoroo.andlib.utility; import android.app.Activity; -import android.content.ContentValues; import android.content.Context; import android.os.Build; import android.text.InputType; @@ -51,32 +50,6 @@ public class AndroidUtilities { }); } - /** - * Put an arbitrary object into a {@link ContentValues} - */ - public static void putInto(ContentValues target, String key, Object value) { - if (value instanceof Boolean) { - target.put(key, (Boolean) value); - } else if (value instanceof Byte) { - target.put(key, (Byte) value); - } else if (value instanceof Double) { - target.put(key, (Double) value); - } else if (value instanceof Float) { - target.put(key, (Float) value); - } else if (value instanceof Integer) { - target.put(key, (Integer) value); - } else if (value instanceof Long) { - target.put(key, (Long) value); - } else if (value instanceof Short) { - target.put(key, (Short) value); - } else if (value instanceof String) { - target.put(key, (String) value); - } else { - throw new UnsupportedOperationException("Could not handle type " + //$NON-NLS-1$ - value.getClass()); - } - } - // --- serialization /** diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java index 30075766d..12e0b5da0 100755 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java @@ -206,7 +206,7 @@ public final class TaskEditFragment extends InjectingFragment implements Toolbar for (TaskEditControlFragment fragment : fragments) { fragment.apply(model); } - taskDao.save(model); + taskDao.save(model, null); if (Flags.checkAndClear(Flags.TAGS_CHANGED)) { localBroadcastManager.broadcastRefreshList(); diff --git a/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java b/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java index e8f30507a..3487a816b 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java @@ -25,8 +25,6 @@ import org.tasks.data.TaskAttachment; import java.util.ArrayList; import java.util.List; -import static com.todoroo.andlib.data.AbstractModel.NO_ID; - /** * Adapter for displaying a user's tasks as a list * @@ -107,7 +105,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { return c.get(Task.ID); } } - return NO_ID; + return Task.NO_ID; } public Task getTask(int position) { diff --git a/app/src/main/java/com/todoroo/astrid/api/AstridApiConstants.java b/app/src/main/java/com/todoroo/astrid/api/AstridApiConstants.java index 1a115701e..164eda059 100644 --- a/app/src/main/java/com/todoroo/astrid/api/AstridApiConstants.java +++ b/app/src/main/java/com/todoroo/astrid/api/AstridApiConstants.java @@ -23,7 +23,7 @@ public class AstridApiConstants { public static final String EXTRAS_TASK_ID = "task_id"; public static final String EXTRAS_TASK = "task"; - public static final String EXTRAS_VALUES = "values"; + public static final String EXTRAS_ORIGINAL = "original"; /** * Extras name for old task due date */ diff --git a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java index ceddc744c..8edfbb98c 100755 --- a/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java +++ b/app/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java @@ -13,9 +13,6 @@ import android.support.annotation.Nullable; import android.util.Xml; import android.widget.Toast; -import com.todoroo.andlib.data.AbstractModel; -import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.data.Property.PropertyVisitor; import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DateUtilities; diff --git a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java index 53f4aca1f..291578c72 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java +++ b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.java @@ -18,16 +18,12 @@ import com.todoroo.andlib.sql.Functions; import com.todoroo.andlib.sql.Query; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.PermaSql; -import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.data.TaskApiDao; import org.tasks.BuildConfig; import org.tasks.jobs.AfterSaveIntentService; -import org.tasks.receivers.PushReceiver; import java.util.List; -import java.util.Set; import timber.log.Timber; @@ -131,9 +127,6 @@ public abstract class TaskDao { } } - @android.arch.persistence.room.Query("SELECT remoteId FROM tasks WHERE _id = :localId") - public abstract String uuidFromLocalId(long localId); - @android.arch.persistence.room.Query("UPDATE tasks SET calendarUri = '' " + "WHERE calendarUri NOT NULL AND calendarUri != ''") public abstract void clearAllCalendarEvents(); @@ -156,11 +149,13 @@ public abstract class TaskDao { * */ public void save(Task task) { - Set modifiedValues = saveExisting(task); - if (modifiedValues != null) { - AfterSaveIntentService.enqueue(context, task.getId(), modifiedValues); - } else if (task.checkTransitory(SyncFlags.FORCE_SYNC)) { - PushReceiver.broadcast(context, task, null); + save(task, fetch(task.getId())); + } + + // TODO: get rid of this super-hack + public void save(Task task, Task original) { + if (saveExisting(task, original)) { + AfterSaveIntentService.enqueue(context, task.getId(), original); } } @@ -177,23 +172,16 @@ public abstract class TaskDao { task.setId(insert); } - private Set saveExisting(Task item) { - Set values = item.getSetValues(); - if (values == null || values.size() == 0) { - return null; - } - if (!TaskApiDao.insignificantChange(values)) { - if (!values.contains(Task.MODIFICATION_DATE.name)) { - item.setModificationDate(now()); - } + private boolean saveExisting(Task item, Task original) { + if (!item.insignificantChange(original)) { + item.setModificationDate(now()); } int updated = update(item); if (updated == 1) { - item.markSaved(); database.onDatabaseUpdated(); - return values; + return true; } - return null; + return false; } /** diff --git a/app/src/main/java/com/todoroo/astrid/data/Task.java b/app/src/main/java/com/todoroo/astrid/data/Task.java index 04e14945f..dd03010f5 100644 --- a/app/src/main/java/com/todoroo/astrid/data/Task.java +++ b/app/src/main/java/com/todoroo/astrid/data/Task.java @@ -12,32 +12,30 @@ import android.arch.persistence.room.Ignore; import android.arch.persistence.room.Index; import android.arch.persistence.room.PrimaryKey; import android.content.ContentValues; +import android.database.Cursor; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import com.google.common.base.Strings; import com.google.ical.values.RRule; -import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.Property.IntegerProperty; import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.StringProperty; import com.todoroo.andlib.data.Table; -import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.utility.DateUtilities; import org.tasks.backup.XmlReader; import org.tasks.backup.XmlWriter; -import org.tasks.data.GoogleTask; +import org.tasks.data.Tag; import org.tasks.time.DateTime; +import java.util.ArrayList; import java.util.HashMap; -import java.util.Map; import timber.log.Timber; -import static com.google.common.collect.Lists.newArrayList; import static org.tasks.date.DateTimeUtils.newDateTime; /** @@ -48,12 +46,14 @@ import static org.tasks.date.DateTimeUtils.newDateTime; */ @Entity(tableName = "tasks", indices = @Index(name = "t_rid", value = "remoteId", unique = true)) -public class Task extends AbstractModel implements Parcelable { +public class Task implements Parcelable { // --- table and uri /** table for this model */ - public static final Table TABLE = new Table("tasks", Task.class); + public static final Table TABLE = new Table("tasks"); + + public static final long NO_ID = 0; // --- properties @@ -62,7 +62,7 @@ public class Task extends AbstractModel implements Parcelable { @ColumnInfo(name = "_id") public Long id = NO_ID; public static final LongProperty ID = new LongProperty( - TABLE, ID_PROPERTY_NAME); + TABLE, "_id"); /** Name of Task */ @ColumnInfo(name = "title") @@ -121,13 +121,9 @@ public class Task extends AbstractModel implements Parcelable { @ColumnInfo(name = "estimatedSeconds") public Integer estimatedSeconds = 0; - public static final IntegerProperty ESTIMATED_SECONDS = new IntegerProperty( - TABLE, "estimatedSeconds"); @ColumnInfo(name = "elapsedSeconds") public Integer elapsedSeconds = 0; - public static final IntegerProperty ELAPSED_SECONDS = new IntegerProperty( - TABLE, "elapsedSeconds"); @ColumnInfo(name = "timerStart") public Long timerStart = 0L; @@ -149,14 +145,10 @@ public class Task extends AbstractModel implements Parcelable { /** Unixtime the last reminder was triggered */ @ColumnInfo(name = "lastNotified") public Long lastNotified = 0L; - public static final LongProperty REMINDER_LAST = new LongProperty( - TABLE, "lastNotified"); /** Unixtime snooze is set (0 -> no snooze) */ @ColumnInfo(name = "snoozeTime") public Long snoozeTime = 0L; - public static final LongProperty REMINDER_SNOOZE = new LongProperty( - TABLE, "snoozeTime"); @ColumnInfo(name = "recurrence") public String recurrence = ""; @@ -165,8 +157,6 @@ public class Task extends AbstractModel implements Parcelable { @ColumnInfo(name = "repeatUntil") public Long repeatUntil = 0L; - public static final LongProperty REPEAT_UNTIL = new LongProperty( - TABLE, "repeatUntil"); @ColumnInfo(name = "calendarUri") public String calendarUri = ""; @@ -191,8 +181,8 @@ public class Task extends AbstractModel implements Parcelable { CREATION_DATE, DELETION_DATE, DUE_DATE, - ELAPSED_SECONDS, - ESTIMATED_SECONDS, + new IntegerProperty(TABLE, "elapsedSeconds"), + new IntegerProperty(TABLE, "estimatedSeconds"), HIDE_UNTIL, ID, IMPORTANCE, @@ -200,10 +190,10 @@ public class Task extends AbstractModel implements Parcelable { NOTES, RECURRENCE, REMINDER_FLAGS, - REMINDER_LAST, + new LongProperty(TABLE, "lastNotified"), REMINDER_PERIOD, - REMINDER_SNOOZE, - REPEAT_UNTIL, + new LongProperty(TABLE, "snoozeTime"), + new LongProperty(TABLE, "repeatUntil"), TIMER_START, TITLE, UUID @@ -230,54 +220,128 @@ public class Task extends AbstractModel implements Parcelable { public static final int IMPORTANCE_SHOULD_DO = 2; public static final int IMPORTANCE_NONE = 3; - public static final Map> roomSetters = new HashMap<>(); - - static { - roomSetters.put(CALENDAR_URI.name, (t, v) -> t.calendarUri = (String) v); - roomSetters.put(COMPLETION_DATE.name, (t, v) -> t.completed = (Long) v); - roomSetters.put(CREATION_DATE.name, (t, v) -> t.created = (Long) v); - roomSetters.put(DELETION_DATE.name, (t, v) -> t.deleted = (Long) v); - roomSetters.put(DUE_DATE.name, (t, v) -> t.dueDate = v instanceof String ? Long.valueOf((String) v) : (Long) v); - roomSetters.put(ELAPSED_SECONDS.name, (t, v) -> t.elapsedSeconds = (Integer) v); - roomSetters.put(ESTIMATED_SECONDS.name, (t, v) -> t.estimatedSeconds = (Integer) v); - roomSetters.put(HIDE_UNTIL.name, (t, v) -> t.hideUntil = (Long) v); - roomSetters.put(ID.name, (t, v) -> t.id = (Long) v); - roomSetters.put(IMPORTANCE.name, (t, v) -> t.importance = v instanceof String ? Integer.valueOf((String) v) : (Integer) v); - roomSetters.put(MODIFICATION_DATE.name, (t, v) -> t.modified = (Long) v); - roomSetters.put(NOTES.name, (t, v) -> t.notes = (String) v); - roomSetters.put(RECURRENCE.name, (t, v) -> t.recurrence = (String) v); - roomSetters.put(REMINDER_FLAGS.name, (t, v) -> t.notificationFlags = (Integer) v); - roomSetters.put(REMINDER_LAST.name, (t, v) -> t.lastNotified = (Long) v); - roomSetters.put(REMINDER_PERIOD.name, (t, v) -> t.notifications = (Long) v); - roomSetters.put(REMINDER_SNOOZE.name, (t, v) -> t.snoozeTime = (Long) v); - roomSetters.put(REPEAT_UNTIL.name, (t, v) -> t.repeatUntil = (Long) v); - roomSetters.put(TIMER_START.name, (t, v) -> t.timerStart = (Long) v); - roomSetters.put(TITLE.name, (t, v) -> t.title = (String) v); - roomSetters.put(UUID.name, (t, v) -> t.remoteId = (String) v); - roomSetters.put(GoogleTask.INDENT.name, (t, v) -> t.googleTaskIndent = (Integer) v); - } - @Ignore private int googleTaskIndent; + @Ignore + private HashMap transitoryData = null; + // --- data access boilerplate public Task() { - super(); } @Ignore - public Task(TodorooCursor cursor) { - for (Property property : cursor.getProperties()) { - try { - ValueWriter writer = roomSetters.get(property.getColumnName()); - if (writer != null) { - writer.setValue(this, cursor.get(property)); - } - } catch (IllegalArgumentException e) { - // underlying cursor may have changed, suppress - Timber.e(e, e.getMessage()); - } + public Task(Cursor _cursor) { + final int _cursorIndexOfId = _cursor.getColumnIndexOrThrow("_id"); + final int _cursorIndexOfTitle = _cursor.getColumnIndexOrThrow("title"); + final int _cursorIndexOfImportance = _cursor.getColumnIndexOrThrow("importance"); + final int _cursorIndexOfDueDate = _cursor.getColumnIndexOrThrow("dueDate"); + final int _cursorIndexOfHideUntil = _cursor.getColumnIndexOrThrow("hideUntil"); + final int _cursorIndexOfCreated = _cursor.getColumnIndexOrThrow("created"); + final int _cursorIndexOfModified = _cursor.getColumnIndexOrThrow("modified"); + final int _cursorIndexOfCompleted = _cursor.getColumnIndexOrThrow("completed"); + final int _cursorIndexOfDeleted = _cursor.getColumnIndexOrThrow("deleted"); + final int _cursorIndexOfNotes = _cursor.getColumnIndexOrThrow("notes"); + final int _cursorIndexOfEstimatedSeconds = _cursor.getColumnIndexOrThrow("estimatedSeconds"); + final int _cursorIndexOfElapsedSeconds = _cursor.getColumnIndexOrThrow("elapsedSeconds"); + final int _cursorIndexOfTimerStart = _cursor.getColumnIndexOrThrow("timerStart"); + final int _cursorIndexOfNotificationFlags = _cursor.getColumnIndexOrThrow("notificationFlags"); + final int _cursorIndexOfNotifications = _cursor.getColumnIndexOrThrow("notifications"); + final int _cursorIndexOfLastNotified = _cursor.getColumnIndexOrThrow("lastNotified"); + final int _cursorIndexOfSnoozeTime = _cursor.getColumnIndexOrThrow("snoozeTime"); + final int _cursorIndexOfRecurrence = _cursor.getColumnIndexOrThrow("recurrence"); + final int _cursorIndexOfRepeatUntil = _cursor.getColumnIndexOrThrow("repeatUntil"); + final int _cursorIndexOfCalendarUri = _cursor.getColumnIndexOrThrow("calendarUri"); + final int _cursorIndexOfRemoteId = _cursor.getColumnIndexOrThrow("remoteId"); + final int _cursorIndexOfIndent = _cursor.getColumnIndex("index"); + if (_cursor.isNull(_cursorIndexOfId)) { + id = null; + } else { + id = _cursor.getLong(_cursorIndexOfId); + } + title = _cursor.getString(_cursorIndexOfTitle); + if (_cursor.isNull(_cursorIndexOfImportance)) { + importance = null; + } else { + importance = _cursor.getInt(_cursorIndexOfImportance); + } + if (_cursor.isNull(_cursorIndexOfDueDate)) { + dueDate = null; + } else { + dueDate = _cursor.getLong(_cursorIndexOfDueDate); + } + if (_cursor.isNull(_cursorIndexOfHideUntil)) { + hideUntil = null; + } else { + hideUntil = _cursor.getLong(_cursorIndexOfHideUntil); + } + if (_cursor.isNull(_cursorIndexOfCreated)) { + created = null; + } else { + created = _cursor.getLong(_cursorIndexOfCreated); + } + if (_cursor.isNull(_cursorIndexOfModified)) { + modified = null; + } else { + modified = _cursor.getLong(_cursorIndexOfModified); + } + if (_cursor.isNull(_cursorIndexOfCompleted)) { + completed = null; + } else { + completed = _cursor.getLong(_cursorIndexOfCompleted); + } + if (_cursor.isNull(_cursorIndexOfDeleted)) { + deleted = null; + } else { + deleted = _cursor.getLong(_cursorIndexOfDeleted); + } + notes = _cursor.getString(_cursorIndexOfNotes); + if (_cursor.isNull(_cursorIndexOfEstimatedSeconds)) { + estimatedSeconds = null; + } else { + estimatedSeconds = _cursor.getInt(_cursorIndexOfEstimatedSeconds); + } + if (_cursor.isNull(_cursorIndexOfElapsedSeconds)) { + elapsedSeconds = null; + } else { + elapsedSeconds = _cursor.getInt(_cursorIndexOfElapsedSeconds); + } + if (_cursor.isNull(_cursorIndexOfTimerStart)) { + timerStart = null; + } else { + timerStart = _cursor.getLong(_cursorIndexOfTimerStart); + } + if (_cursor.isNull(_cursorIndexOfNotificationFlags)) { + notificationFlags = null; + } else { + notificationFlags = _cursor.getInt(_cursorIndexOfNotificationFlags); + } + if (_cursor.isNull(_cursorIndexOfNotifications)) { + notifications = null; + } else { + notifications = _cursor.getLong(_cursorIndexOfNotifications); + } + if (_cursor.isNull(_cursorIndexOfLastNotified)) { + lastNotified = null; + } else { + lastNotified = _cursor.getLong(_cursorIndexOfLastNotified); + } + if (_cursor.isNull(_cursorIndexOfSnoozeTime)) { + snoozeTime = null; + } else { + snoozeTime = _cursor.getLong(_cursorIndexOfSnoozeTime); + } + recurrence = _cursor.getString(_cursorIndexOfRecurrence); + if (_cursor.isNull(_cursorIndexOfRepeatUntil)) { + repeatUntil = null; + } else { + repeatUntil = _cursor.getLong(_cursorIndexOfRepeatUntil); + } + calendarUri = _cursor.getString(_cursorIndexOfCalendarUri); + remoteId = _cursor.getString(_cursorIndexOfRemoteId); + if (_cursorIndexOfIndent >= 0) { + googleTaskIndent = _cursor.getInt(_cursorIndexOfIndent); } } @@ -351,11 +415,9 @@ public class Task extends AbstractModel implements Parcelable { timerStart = parcel.readLong(); title = parcel.readString(); remoteId = parcel.readString(); - setValues.addAll(parcel.readArrayList(getClass().getClassLoader())); transitoryData = parcel.readHashMap(ContentValues.class.getClassLoader()); } - @Override public long getId() { return id == null ? NO_ID : id; } @@ -570,18 +632,16 @@ public class Task extends AbstractModel implements Parcelable { } public void setDueDate(Long dueDate) { - setValue(DUE_DATE, dueDate); + this.dueDate = dueDate; } - public void setDueDateAdjustingHideUntil(Long dueDate) { - long oldDueDate = dueDate; - if (oldDueDate > 0) { - long hideUntil = this.hideUntil; + public void setDueDateAdjustingHideUntil(Long newDueDate) { + if (dueDate > 0) { if (hideUntil > 0) { - setHideUntil(dueDate > 0 ? hideUntil + dueDate - oldDueDate : 0); + setHideUntil(newDueDate > 0 ? hideUntil + newDueDate - dueDate : 0); } } - setDueDate(dueDate); + setDueDate(newDueDate); } public String getRecurrence() { @@ -589,7 +649,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setRecurrence(String recurrence) { - setValue(RECURRENCE, recurrence); + this.recurrence = recurrence; } public void setRecurrence(RRule rrule, boolean afterCompletion) { @@ -601,7 +661,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setCreationDate(Long creationDate) { - setValue(CREATION_DATE, creationDate); + created = creationDate; } public String getTitle() { @@ -609,7 +669,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setTitle(String title) { - setValue(TITLE, title); + this.title = title; } public Long getDeletionDate() { @@ -617,7 +677,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setDeletionDate(Long deletionDate) { - setValue(DELETION_DATE, deletionDate); + deleted = deletionDate; } public Long getHideUntil() { @@ -625,7 +685,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setHideUntil(Long hideUntil) { - setValue(HIDE_UNTIL, hideUntil); + this.hideUntil = hideUntil; } public Long getReminderLast() { @@ -633,7 +693,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setReminderLast(Long reminderLast) { - setValue(REMINDER_LAST, reminderLast); + lastNotified = reminderLast; } public Long getReminderSnooze() { @@ -641,7 +701,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setReminderSnooze(Long reminderSnooze) { - setValue(REMINDER_SNOOZE, reminderSnooze); + snoozeTime = reminderSnooze; } public Integer getElapsedSeconds() { @@ -653,7 +713,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setTimerStart(Long timerStart) { - setValue(TIMER_START, timerStart); + this.timerStart = timerStart; } public Long getRepeatUntil() { @@ -661,7 +721,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setRepeatUntil(Long repeatUntil) { - setValue(REPEAT_UNTIL, repeatUntil); + this.repeatUntil = repeatUntil; } public String getCalendarURI() { @@ -673,7 +733,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setImportance(Integer importance) { - setValue(IMPORTANCE, importance); + this.importance = importance; } public Long getCompletionDate() { @@ -681,7 +741,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setCompletionDate(Long completionDate) { - setValue(COMPLETION_DATE, completionDate); + completed = completionDate; } public String getNotes() { @@ -693,11 +753,11 @@ public class Task extends AbstractModel implements Parcelable { } public void setNotes(String notes) { - setValue(NOTES, notes); + this.notes = notes; } public void setModificationDate(Long modificationDate) { - setValue(MODIFICATION_DATE, modificationDate); + modified = modificationDate; } public Integer getReminderFlags() { @@ -705,7 +765,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setReminderFlags(Integer reminderFlags) { - setValue(REMINDER_FLAGS, reminderFlags); + notificationFlags = reminderFlags; } public Long getReminderPeriod() { @@ -713,7 +773,7 @@ public class Task extends AbstractModel implements Parcelable { } public void setReminderPeriod(Long reminderPeriod) { - setValue(REMINDER_PERIOD, reminderPeriod); + notifications = reminderPeriod; } public Integer getEstimatedSeconds() { @@ -721,15 +781,15 @@ public class Task extends AbstractModel implements Parcelable { } public void setElapsedSeconds(Integer elapsedSeconds) { - setValue(ELAPSED_SECONDS, elapsedSeconds); + this.elapsedSeconds = elapsedSeconds; } public void setEstimatedSeconds(Integer estimatedSeconds) { - setValue(ESTIMATED_SECONDS, estimatedSeconds); + this.estimatedSeconds = estimatedSeconds; } public void setCalendarUri(String calendarUri) { - setValue(CALENDAR_URI, calendarUri); + this.calendarUri = calendarUri; } public boolean isNotifyModeNonstop() { @@ -766,8 +826,12 @@ public class Task extends AbstractModel implements Parcelable { } } + public void setId(long id) { + this.id = id; + } + public void setUuid(String uuid) { - setValue(UUID, uuid); + remoteId = uuid; } public static boolean isUuidEmpty(String uuid) { @@ -808,7 +872,6 @@ public class Task extends AbstractModel implements Parcelable { dest.writeLong(timerStart); dest.writeString(title); dest.writeString(remoteId); - dest.writeList(newArrayList(setValues)); dest.writeMap(transitoryData); } @@ -818,7 +881,6 @@ public class Task extends AbstractModel implements Parcelable { "id=" + id + ", title='" + title + '\'' + ", importance=" + importance + - ", setValues=" + setValues + ", dueDate=" + dueDate + ", transitoryData=" + transitoryData + ", hideUntil=" + hideUntil + @@ -844,4 +906,87 @@ public class Task extends AbstractModel implements Parcelable { public int getGoogleTaskIndent() { return googleTaskIndent; } + + public boolean insignificantChange(Task task) { + if (this == task) return true; + if (task == null) return false; + + if (id != null ? !id.equals(task.id) : task.id != null) return false; + if (title != null ? !title.equals(task.title) : task.title != null) return false; + if (importance != null ? !importance.equals(task.importance) : task.importance != null) + return false; + if (dueDate != null ? !dueDate.equals(task.dueDate) : task.dueDate != null) return false; + if (hideUntil != null ? !hideUntil.equals(task.hideUntil) : task.hideUntil != null) + return false; + if (created != null ? !created.equals(task.created) : task.created != null) return false; + if (modified != null ? !modified.equals(task.modified) : task.modified != null) + return false; + if (completed != null ? !completed.equals(task.completed) : task.completed != null) + return false; + if (deleted != null ? !deleted.equals(task.deleted) : task.deleted != null) return false; + if (notes != null ? !notes.equals(task.notes) : task.notes != null) return false; + if (estimatedSeconds != null ? !estimatedSeconds.equals(task.estimatedSeconds) : task.estimatedSeconds != null) + return false; + if (elapsedSeconds != null ? !elapsedSeconds.equals(task.elapsedSeconds) : task.elapsedSeconds != null) + return false; + if (notificationFlags != null ? !notificationFlags.equals(task.notificationFlags) : task.notificationFlags != null) + return false; + if (notifications != null ? !notifications.equals(task.notifications) : task.notifications != null) + return false; + if (recurrence != null ? !recurrence.equals(task.recurrence) : task.recurrence != null) + return false; + if (repeatUntil != null ? !repeatUntil.equals(task.repeatUntil) : task.repeatUntil != null) + return false; + if (calendarUri != null ? !calendarUri.equals(task.calendarUri) : task.calendarUri != null) + return false; + return remoteId != null ? remoteId.equals(task.remoteId) : task.remoteId == null; + } + + public boolean isSaved() { + return getId() != NO_ID; + } + + public synchronized void putTransitory(String key, Object value) { + if(transitoryData == null) { + transitoryData = new HashMap<>(); + } + transitoryData.put(key, value); + } + + public void setTags(ArrayList tags) { + if (transitoryData == null) { + transitoryData = new HashMap<>(); + } + transitoryData.put(Tag.KEY, tags); + } + + public ArrayList getTags() { + Object tags = getTransitory(Tag.KEY); + return tags == null ? new ArrayList<>() : (ArrayList) tags; + } + + public T getTransitory(String key) { + if(transitoryData == null) { + return null; + } + return (T) transitoryData.get(key); + } + + private Object clearTransitory(String key) { + if (transitoryData == null) { + return null; + } + return transitoryData.remove(key); + } + + // --- Convenience wrappers for using transitories as flags + public boolean checkTransitory(String flag) { + Object trans = getTransitory(flag); + return trans != null; + } + + public boolean checkAndClearTransitory(String flag) { + Object trans = clearTransitory(flag); + return trans != null; + } } diff --git a/app/src/main/java/com/todoroo/astrid/data/TaskApiDao.java b/app/src/main/java/com/todoroo/astrid/data/TaskApiDao.java deleted file mode 100644 index 207cc0916..000000000 --- a/app/src/main/java/com/todoroo/astrid/data/TaskApiDao.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.data; - -import java.util.Collection; -import java.util.Set; - -/** - * Data access object for accessing Astrid's {@link Task} table. If you - * are looking to store extended information about a Task, you probably - * want to use the MetadataApiDao object. - * - * @author Tim Su - * - */ -public class TaskApiDao { - - /** @return true if task change shouldn't be broadcast */ - public static boolean insignificantChange(Collection values) { - if(values == null || values.size() == 0) { - return true; - } - - if(values.contains(Task.REMINDER_LAST.name) && - values.size() <= 2) { - return true; - } - - if(values.contains(Task.REMINDER_SNOOZE.name) && - values.size() <= 2) { - return true; - } - - if(values.contains(Task.TIMER_START.name) && - values.size() <= 2) { - return true; - } - - return false; - } - -} diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java b/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java index 49e306048..fa76e0339 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java +++ b/app/src/main/java/com/todoroo/astrid/service/TaskCreator.java @@ -5,7 +5,6 @@ import android.net.Uri; import android.text.TextUtils; import com.google.common.base.Strings; -import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.dao.TaskDao; @@ -72,7 +71,7 @@ public class TaskCreator { googleTaskDao.insert(new GoogleTask(task.getId(), googleTaskList)); } - taskDao.save(task); + taskDao.save(task, null); return task; } @@ -88,15 +87,17 @@ public class TaskCreator { task.setUuid(UUIDHelper.newUUID()); + task.setImportance(preferences.getIntegerFromString(R.string.p_default_importance_key, Task.IMPORTANCE_SHOULD_DO)); + task.setDueDate(Task.createDueDate( + preferences.getIntegerFromString(R.string.p_default_urgency_key, Task.URGENCY_NONE), 0)); + int setting = preferences.getIntegerFromString(R.string.p_default_hideUntil_key, + Task.HIDE_UNTIL_NONE); + task.setHideUntil(task.createHideUntil(setting, 0)); + setDefaultReminders(preferences, task); + ArrayList tags = new ArrayList<>(); - try { - parseQuickAddMarkup(task, tags); - } catch (Throwable e) { - Timber.e(e, e.getMessage()); - } if (values != null && values.size() > 0) { - ContentValues forTask = new ContentValues(); for (Map.Entry item : values.entrySet()) { String key = item.getKey(); Object value = item.getValue(); @@ -104,49 +105,37 @@ public class TaskCreator { tags.add((String) value); } else if (key.equals(GoogleTask.KEY)) { task.putTransitory(key, value); - } else { - if (value instanceof String) { - value = PermaSql.replacePlaceholders((String) value); + } else if (value instanceof String) { + value = PermaSql.replacePlaceholders((String) value); + if (key.equals("dueDate")) { + task.setDueDate(Long.valueOf((String) value)); + } else if (key.equals("importance")) { + task.setImportance(Integer.valueOf((String) value)); + } else { + throw new RuntimeException("Unhandled key: " + key); } - - AndroidUtilities.putInto(forTask, key, value); + } else { + throw new RuntimeException("Unhandled key: " + key); } } - task.mergeWithoutReplacement(forTask); - } - - if (!task.isModified(Task.IMPORTANCE)) { - task.setImportance(preferences.getIntegerFromString(R.string.p_default_importance_key, Task.IMPORTANCE_SHOULD_DO)); - } - - if(!task.isModified(Task.DUE_DATE)) { - task.setDueDate(Task.createDueDate( - preferences.getIntegerFromString(R.string.p_default_urgency_key, Task.URGENCY_NONE), 0)); } - if(!task.isModified(Task.HIDE_UNTIL)) { - int setting = preferences.getIntegerFromString(R.string.p_default_hideUntil_key, - Task.HIDE_UNTIL_NONE); - task.setHideUntil(task.createHideUntil(setting, 0)); + try { + TitleParser.parse(tagService, task, tags); + } catch (Throwable e) { + Timber.e(e, e.getMessage()); } - setDefaultReminders(preferences, task); - task.setTags(tags); return task; } public static void setDefaultReminders(Preferences preferences, Task task) { - if(!task.isModified(Task.REMINDER_PERIOD)) { - task.setReminderPeriod(DateUtilities.ONE_HOUR * - preferences.getIntegerFromString(R.string.p_rmd_default_random_hours, - 0)); - } - - if(!task.isModified(Task.REMINDER_FLAGS)) { - task.setReminderFlags(preferences.getDefaultReminders() | preferences.getDefaultRingMode()); - } + task.setReminderPeriod(DateUtilities.ONE_HOUR * + preferences.getIntegerFromString(R.string.p_rmd_default_random_hours, + 0)); + task.setReminderFlags(preferences.getDefaultReminders() | preferences.getDefaultRingMode()); } public void createTags(Task task) { @@ -161,12 +150,4 @@ public class TaskCreator { tagDao.insert(link); } } - - /** - * Parse quick add markup for the given task - * @param tags an empty array to apply tags to - */ - void parseQuickAddMarkup(Task task, ArrayList tags) { - TitleParser.parse(tagService, task, tags); - } } diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java b/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java index c4fed2fb6..eeb1676bb 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java +++ b/app/src/main/java/com/todoroo/astrid/service/TaskDuplicator.java @@ -73,7 +73,7 @@ public class TaskDuplicator { gcalHelper.createTaskEventIfEnabled(clone); - taskDao.save(clone); // TODO: delete me + taskDao.save(clone, null); // TODO: delete me return clone; } diff --git a/app/src/main/java/com/todoroo/astrid/utility/TitleParser.java b/app/src/main/java/com/todoroo/astrid/utility/TitleParser.java index 5ebd70e49..2069572d3 100644 --- a/app/src/main/java/com/todoroo/astrid/utility/TitleParser.java +++ b/app/src/main/java/com/todoroo/astrid/utility/TitleParser.java @@ -166,9 +166,6 @@ public class TitleParser { //Day of week (e.g. Monday, Tuesday,..) is overridden by a set date (e.g. October 23 2013). //Vague times (e.g. breakfast, night) are overridden by a set time (9 am, at 10, 17:00) private static boolean dayHelper(Task task ) { - if (task.getDueDate() > 0) { - return false; - } String inputText = task.getTitle(); Calendar cal = null; Boolean containsSpecificTime = false; @@ -373,9 +370,6 @@ public class TitleParser { //Parses through the text and sets the frequency of the task. private static boolean repeatHelper(Task task) { - if (!Strings.isNullOrEmpty(task.getRecurrence())) { - return false; - } String inputText = task.getTitle(); HashMap repeatTimes = new HashMap<>(); repeatTimes.put("(?i)\\bevery ?\\w{0,6} days?\\b" , Frequency.DAILY); diff --git a/app/src/main/java/org/tasks/data/GoogleTask.java b/app/src/main/java/org/tasks/data/GoogleTask.java index 54df20276..6ca01f42c 100644 --- a/app/src/main/java/org/tasks/data/GoogleTask.java +++ b/app/src/main/java/org/tasks/data/GoogleTask.java @@ -18,7 +18,7 @@ public class GoogleTask { public static final String KEY = "gtasks"; //$NON-NLS-1$ @Deprecated - public static final Table TABLE = new Table("google_tasks", null); + public static final Table TABLE = new Table("google_tasks"); @Deprecated public static final Property.IntegerProperty INDENT = new Property.IntegerProperty(GoogleTask.TABLE, "indent"); diff --git a/app/src/main/java/org/tasks/data/Tag.java b/app/src/main/java/org/tasks/data/Tag.java index 5f57ed39b..a0f75f595 100644 --- a/app/src/main/java/org/tasks/data/Tag.java +++ b/app/src/main/java/org/tasks/data/Tag.java @@ -17,7 +17,7 @@ public class Tag { public static final String KEY = "tags-tag"; //$NON-NLS-1$ @Deprecated - public static final Table TABLE = new Table("tags", null); + public static final Table TABLE = new Table("tags"); @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "_id") diff --git a/app/src/main/java/org/tasks/data/TaskAttachment.java b/app/src/main/java/org/tasks/data/TaskAttachment.java index 65ae80bd4..0e26c83fd 100644 --- a/app/src/main/java/org/tasks/data/TaskAttachment.java +++ b/app/src/main/java/org/tasks/data/TaskAttachment.java @@ -13,7 +13,7 @@ import com.todoroo.astrid.data.Task; public final class TaskAttachment { @Deprecated - public static final Table TABLE = new Table("task_attachments", null); + public static final Table TABLE = new Table("task_attachments"); @Deprecated public static final Property.LongProperty ID = new Property.LongProperty( diff --git a/app/src/main/java/org/tasks/jobs/AfterSaveIntentService.java b/app/src/main/java/org/tasks/jobs/AfterSaveIntentService.java index 8b7aa850c..21b7d9b2c 100644 --- a/app/src/main/java/org/tasks/jobs/AfterSaveIntentService.java +++ b/app/src/main/java/org/tasks/jobs/AfterSaveIntentService.java @@ -11,7 +11,6 @@ import android.text.TextUtils; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.data.TaskApiDao; import com.todoroo.astrid.reminders.ReminderService; import com.todoroo.astrid.repeats.RepeatTaskHelper; import com.todoroo.astrid.timers.TimerPlugin; @@ -26,9 +25,6 @@ import org.tasks.notifications.NotificationManager; import org.tasks.receivers.PushReceiver; import org.tasks.scheduling.RefreshScheduler; -import java.util.ArrayList; -import java.util.Set; - import javax.inject.Inject; import timber.log.Timber; @@ -40,12 +36,12 @@ import static com.todoroo.astrid.dao.TaskDao.TRANS_SUPPRESS_REFRESH; public class AfterSaveIntentService extends InjectingJobIntentService { private static final String EXTRA_TASK_ID = "extra_task_id"; - private static final String EXTRA_MODIFIED_VALUES = "extra_modified_values"; + private static final String EXTRA_ORIGINAL = "extra_original"; - public static void enqueue(Context context, long taskId, Set modifiedValues) { + public static void enqueue(Context context, long taskId, Task original) { Intent intent = new Intent(); intent.putExtra(EXTRA_TASK_ID, taskId); - intent.putStringArrayListExtra(EXTRA_MODIFIED_VALUES, newArrayList(modifiedValues)); + intent.putExtra(EXTRA_ORIGINAL, original); AfterSaveIntentService.enqueueWork(context, AfterSaveIntentService.class, JobManager.JOB_ID_TASK_STATUS_CHANGE, intent); } @@ -64,10 +60,10 @@ public class AfterSaveIntentService extends InjectingJobIntentService { super.onHandleWork(intent); long taskId = intent.getLongExtra(EXTRA_TASK_ID, -1); - ArrayList modifiedValues = intent.getStringArrayListExtra(EXTRA_MODIFIED_VALUES); + Task original = intent.getParcelableExtra(EXTRA_ORIGINAL); - if (taskId == -1 || modifiedValues == null) { - Timber.e("Invalid extras, taskId=%s modifiedValues=%s", taskId, modifiedValues); + if (taskId == -1) { + Timber.e("Invalid taskId=%s", taskId); return; } @@ -77,20 +73,17 @@ public class AfterSaveIntentService extends InjectingJobIntentService { return; } - if(modifiedValues.contains(Task.DUE_DATE.name) || - modifiedValues.contains(Task.REMINDER_FLAGS.name) || - modifiedValues.contains(Task.REMINDER_PERIOD.name) || - modifiedValues.contains(Task.REMINDER_LAST.name) || - modifiedValues.contains(Task.REMINDER_SNOOZE.name)) { + if(original == null || + !task.getDueDate().equals(original.getDueDate()) || + !task.getReminderFlags().equals(original.getReminderFlags()) || + !task.getReminderPeriod().equals(original.getReminderPeriod()) || + !task.getReminderLast().equals(original.getReminderLast()) || + !task.getReminderSnooze().equals(original.getReminderSnooze())) { reminderService.scheduleAlarm(task); } - if(TaskApiDao.insignificantChange(modifiedValues)) { - return; - } - - boolean completionDateModified = modifiedValues.contains(Task.COMPLETION_DATE.name); - boolean deletionDateModified = modifiedValues.contains(Task.DELETION_DATE.name); + boolean completionDateModified = original == null || !task.getCompletionDate().equals(original.getCompletionDate()); + boolean deletionDateModified = original != null && !task.getDeletionDate().equals(original.getDeletionDate()); boolean justCompleted = completionDateModified && task.isCompleted(); boolean justDeleted = deletionDateModified && task.isDeleted(); @@ -110,7 +103,7 @@ public class AfterSaveIntentService extends InjectingJobIntentService { } } - PushReceiver.broadcast(context, task, modifiedValues); + PushReceiver.broadcast(context, task, original); refreshScheduler.scheduleRefresh(task); if (!task.checkAndClearTransitory(TRANS_SUPPRESS_REFRESH)) { localBroadcastManager.broadcastRefresh(); diff --git a/app/src/main/java/org/tasks/locale/receiver/TaskerTaskCreator.java b/app/src/main/java/org/tasks/locale/receiver/TaskerTaskCreator.java index bd7ed8900..b1254b761 100644 --- a/app/src/main/java/org/tasks/locale/receiver/TaskerTaskCreator.java +++ b/app/src/main/java/org/tasks/locale/receiver/TaskerTaskCreator.java @@ -72,7 +72,7 @@ public class TaskerTaskCreator { task.setNotes(bundle.getDescription()); taskDao.createNew(task); - taskDao.save(task); // TODO: delete me + taskDao.save(task, null); // TODO: delete me taskCreator.createTags(task); } diff --git a/app/src/main/java/org/tasks/ui/CalendarControlSet.java b/app/src/main/java/org/tasks/ui/CalendarControlSet.java index 212776011..b48e9ff27 100644 --- a/app/src/main/java/org/tasks/ui/CalendarControlSet.java +++ b/app/src/main/java/org/tasks/ui/CalendarControlSet.java @@ -161,15 +161,9 @@ public class CalendarControlSet extends TaskEditControlFragment { ContentValues updateValues = new ContentValues(); // check if we need to update the item - if(task.isModified(Task.TITLE)) { - updateValues.put(CalendarContract.Events.TITLE, task.getTitle()); - } - if(task.isModified(Task.NOTES)) { - updateValues.put(CalendarContract.Events.DESCRIPTION, task.getNotes()); - } - if(task.isModified(Task.DUE_DATE) || task.isModified(Task.ESTIMATED_SECONDS)) { - gcalHelper.createStartAndEndDate(task, updateValues); - } + updateValues.put(CalendarContract.Events.TITLE, task.getTitle()); + updateValues.put(CalendarContract.Events.DESCRIPTION, task.getNotes()); + gcalHelper.createStartAndEndDate(task, updateValues); cr.update(Uri.parse(task.getCalendarURI()), updateValues, null, null); } catch (Exception e) { diff --git a/app/src/main/java/org/tasks/widget/ScrollableViewsFactory.java b/app/src/main/java/org/tasks/widget/ScrollableViewsFactory.java index 8a45c1874..8624f1e8c 100644 --- a/app/src/main/java/org/tasks/widget/ScrollableViewsFactory.java +++ b/app/src/main/java/org/tasks/widget/ScrollableViewsFactory.java @@ -204,7 +204,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory { private TodorooCursor getCursor() { String query = getQuery(); - return taskDao.fetchFiltered(query, Task.ID, Task.TITLE, Task.DUE_DATE, Task.COMPLETION_DATE, Task.IMPORTANCE, Task.RECURRENCE); + return taskDao.fetchFiltered(query, Task.PROPERTIES); } private Task getTask(int position) {