diff --git a/astrid/libs/todoroo-g.jar b/astrid/libs/todoroo-g.jar index 4978ab38d..fb9d883e7 100644 Binary files a/astrid/libs/todoroo-g.jar and b/astrid/libs/todoroo-g.jar differ diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadataService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadataService.java index 5be214c32..752d7fc88 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadataService.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadataService.java @@ -4,7 +4,10 @@ package com.todoroo.astrid.gtasks; import java.util.ArrayList; +import java.util.HashMap; import java.util.Stack; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; @@ -71,24 +74,25 @@ public final class GtasksMetadataService extends SyncMetadataService cursor = PluginServices.getTaskService().fetchFiltered(filter.sqlQuery, null, Task.ID); - try { - Long[] ids = new Long[cursor.getCount()]; - int order = 0; - int previousIndent = -1; - Stack taskHierarchyStack = new Stack(); - for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - long taskId = cursor.getLong(0); - ids[order] = taskId; + + final ArrayList ids = new ArrayList(); + final Stack taskHierarchyStack = new Stack(); + + final AtomicInteger order = new AtomicInteger(0); + final AtomicInteger previousIndent = new AtomicInteger(-1); + + iterateThroughList(list, new ListIterator() { + @Override + public void processTask(long taskId) { + ids.add(taskId); Metadata metadata = getTaskMetadata(taskId); if(metadata == null) - continue; + return; - metadata.setValue(GtasksMetadata.ORDER, order++); + metadata.setValue(GtasksMetadata.ORDER, order.getAndAdd(1)); int indent = metadata.getValue(GtasksMetadata.INDENT); - for(int i = indent; i <= previousIndent; i++) { + for(int i = indent; i <= previousIndent.get(); i++) { if(!taskHierarchyStack.isEmpty()) taskHierarchyStack.pop(); } @@ -105,10 +109,67 @@ public final class GtasksMetadataService extends SyncMetadataService parents = new HashMap(); + final HashMap siblings = new HashMap(); + + for(StoreObject list : gtasksListService.getLists()) { + final AtomicLong previousTask = new AtomicLong(-1L); + final AtomicInteger previousIndent = new AtomicInteger(-1); + + iterateThroughList(list, new ListIterator() { + @Override + public void processTask(long taskId) { + Metadata metadata = getTaskMetadata(taskId); + if(metadata == null) + return; + + int indent = metadata.getValue(GtasksMetadata.INDENT); + + final long parent, sibling; + if(indent > previousIndent.get()) { + parent = previousTask.get(); + sibling = -1L; + } else if(indent == previousIndent.get()) { + sibling = previousTask.get(); + parent = parents.get(sibling); + } else { + sibling = parents.get(previousTask.get()); + parent = parents.get(sibling); + } + parents.put(taskId, parent); + siblings.put(taskId, sibling); + + previousTask.set(taskId); + previousIndent.set(indent); + } + }); + } + } + + private interface ListIterator { + public void processTask(long taskId); + } + + private void iterateThroughList(StoreObject list, ListIterator iterator) { + Filter filter = GtasksFilterExposer.filterFromList(list); + TodorooCursor cursor = PluginServices.getTaskService().fetchFiltered(filter.sqlQuery, null, Task.ID); + try { + for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { + long taskId = cursor.getLong(0); + iterator.processTask(taskId); } - PluginServices.getTaskService().clearDetails(Task.ID.in(ids)); } finally { cursor.close(); } diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java index 9e764cff0..cb0abb3cf 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java @@ -213,6 +213,8 @@ public class GtasksSyncProvider extends SyncProvider { gtasksListService.updateLists(taskView.getAllLists()); + gtasksMetadataService.createParentSiblingMaps(); + // batched read tasks for each list ArrayList remoteTasks = new ArrayList(); ArrayList getTasksActions = new ArrayList(); @@ -299,14 +301,19 @@ public class GtasksSyncProvider extends SyncProvider { } updateTaskHelper(local, null, createdTask); - String remoteId = createdTask.go(); + String remoteId; + try { + remoteId = createdTask.go(); + } catch (JSONException e) { + throw new GoogleTasksException(e); + } local.gtaskMetadata.setValue(GtasksMetadata.LIST_ID, remoteId); return local; } private void updateTaskHelper(GtasksTaskContainer local, - GtasksTaskContainer remote, TaskBuilder builder) { + GtasksTaskContainer remote, TaskBuilder builder) throws IOException { String idTask = local.gtaskMetadata.getValue(GtasksMetadata.ID); String idList = local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID); @@ -315,22 +322,28 @@ public class GtasksSyncProvider extends SyncProvider { if(remote == null && idTask != null) remote = pull(local); - // moving between lists - if(remote != null && !idList.equals(remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID))) { - a.moveTask(idTask, idList, remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), null); - } + try { + + // moving between lists + if(remote != null && !idList.equals(remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID))) { + a.moveTask(idTask, idList, remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), null); + } - // other properties - if(shouldTransmit(local, Task.TITLE, remote)) - ((TaskModifier)builder).name(local.task.getValue(Task.TITLE)); - if(shouldTransmit(local, Task.DUE_DATE, remote)) - builder.taskDate(local.task.getValue(Task.DUE_DATE)); - if(shouldTransmit(local, Task.COMPLETION_DATE, remote)) - builder.completed(local.task.isCompleted()); - if(shouldTransmit(local, Task.DELETION_DATE, remote)) - builder.deleted(local.task.isDeleted()); - if(shouldTransmit(local, Task.NOTES, remote)) - builder.notes(local.task.getValue(Task.NOTES)); + // other properties + if(shouldTransmit(local, Task.TITLE, remote)) + ((TaskModifier)builder).name(local.task.getValue(Task.TITLE)); + if(shouldTransmit(local, Task.DUE_DATE, remote)) + builder.taskDate(local.task.getValue(Task.DUE_DATE)); + if(shouldTransmit(local, Task.COMPLETION_DATE, remote)) + builder.completed(local.task.isCompleted()); + if(shouldTransmit(local, Task.DELETION_DATE, remote)) + builder.deleted(local.task.isDeleted()); + if(shouldTransmit(local, Task.NOTES, remote)) + builder.notes(local.task.getValue(Task.NOTES)); + + } catch (JSONException e) { + throw new GoogleTasksException(e); + } // TODO indentation } @@ -367,7 +380,12 @@ public class GtasksSyncProvider extends SyncProvider { throw new ApiServiceException("Tried to read an invalid task"); //$NON-NLS-1$ String idToMatch = task.gtaskMetadata.getValue(GtasksMetadata.ID); - List tasks = taskService.getTasks(task.gtaskMetadata.getValue(GtasksMetadata.LIST_ID)); + List tasks; + try { + tasks = taskService.getTasks(task.gtaskMetadata.getValue(GtasksMetadata.LIST_ID)); + } catch (JSONException e) { + throw new GoogleTasksException(e); + } for(GoogleTaskTask remoteTask : tasks) { if(remoteTask.getId().equals(idToMatch)) { return parseRemoteTask(remoteTask); @@ -384,10 +402,14 @@ public class GtasksSyncProvider extends SyncProvider { */ @Override protected void push(GtasksTaskContainer local, GtasksTaskContainer remote) throws IOException { - TaskModifier modifyTask = l.modifyTask(remote.gtaskMetadata.getValue(GtasksMetadata.ID)); - updateTaskHelper(local, remote, modifyTask); - ListAction action = modifyTask.done(); - batch(local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), action); + try { + TaskModifier modifyTask = l.modifyTask(remote.gtaskMetadata.getValue(GtasksMetadata.ID)); + updateTaskHelper(local, remote, modifyTask); + ListAction action = modifyTask.done(); + batch(local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), action); + } catch (JSONException e) { + throw new GoogleTasksException(e); + } } /** add action to batch */ diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java index 22c38431c..6649ba13e 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksTaskContainer.java @@ -19,6 +19,10 @@ public class GtasksTaskContainer extends SyncContainer { public Metadata gtaskMetadata; + // position information + public String parentId = null; + public String priorSiblingId = null; + public GtasksTaskContainer(Task task, ArrayList metadata, Metadata gtaskMetadata) { this.task = task; this.metadata = metadata;