From fa5739f499abd8f70ef93f8bd2a85cdfb04252ac Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Tue, 30 Oct 2012 17:12:07 -0700 Subject: [PATCH] Started implementing in-memory management of sort and subtasks --- .../subtasks/NewOrderedListUpdater.java | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 astrid/plugin-src/com/todoroo/astrid/subtasks/NewOrderedListUpdater.java diff --git a/astrid/plugin-src/com/todoroo/astrid/subtasks/NewOrderedListUpdater.java b/astrid/plugin-src/com/todoroo/astrid/subtasks/NewOrderedListUpdater.java new file mode 100644 index 000000000..1a6644785 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/subtasks/NewOrderedListUpdater.java @@ -0,0 +1,142 @@ +package com.todoroo.astrid.subtasks; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Log; + +import com.todoroo.andlib.service.DependencyInjectionService; +import com.todoroo.astrid.api.Filter; + +public abstract class NewOrderedListUpdater { + + public NewOrderedListUpdater() { + DependencyInjectionService.getInstance().inject(this); + idToNode = new HashMap(); + } + + public interface OrderedListIterator { + public void processTask(Node node); + } + + protected static class Node { + public final long taskId; + public Node parent; + public final ArrayList children = new ArrayList(); + + public Node(long taskId, Node parent) { + this.taskId = taskId; + this.parent = parent; + } + } + + private Node treeRoot; + + private final HashMap idToNode; + + protected abstract String getSerializedTree(); + + protected void initialize(LIST list, Filter filter) { + treeRoot = buildTreeModel(getSerializedTree()); + } + + public void indent(long targetTaskId, int delta) { + Node node = idToNode.get(targetTaskId); + indentHelper(node, delta); + } + + private void indentHelper(Node node, int delta) { + if (node == null) + return; + if (delta == 0) + return; + Node parent = node.parent; + if (parent == null) + return; + + if (delta > 0) { + ArrayList siblings = parent.children; + int index = siblings.indexOf(node); + if (index <= 0) // Can't indent first child + return; + Node newParent = siblings.get(index - 1); + siblings.remove(index); + node.parent = newParent; + newParent.children.add(node); + } else if (delta < 0) { + if (parent == treeRoot) // Can't deindent a top level item + return; + + ArrayList siblings = parent.children; + int index = siblings.indexOf(node); + if (index < 0) + return; + + Node newParent = parent.parent; + ArrayList newSiblings = newParent.children; + int insertAfter = newSiblings.indexOf(parent); + siblings.remove(index); + node.parent = newParent; + newSiblings.add(insertAfter + 1, node); + } + } + + private Node buildTreeModel(String serializedTree) { + Node root = new Node(-1, null); + try { + JSONArray tree = new JSONArray(serializedTree); + recursivelyBuildChildren(root, tree); + } catch (JSONException e) { + Log.e("OrderedListUpdater", "Error building tree model", e); //$NON-NLS-1$//$NON-NLS-2$ + } + return root; + } + + private void recursivelyBuildChildren(Node node, JSONArray children) throws JSONException { + for (int i = 0; i < children.length(); i++) { + JSONObject childObj = children.getJSONObject(i); + JSONArray keys = childObj.names(); + if (keys == null) + continue; + + Long id = keys.getLong(0); + if (id <= 0) + continue; + + JSONArray childsChildren = childObj.getJSONArray(Long.toString(id)); + Node child = new Node(id, node); + recursivelyBuildChildren(child, childsChildren); + node.children.add(child); + idToNode.put(id, child); + } + } + + protected String serializeTree() { + JSONArray tree = new JSONArray(); + if (treeRoot == null) { + return tree.toString(); + } + + try { + recursivelySerializeChildren(treeRoot, tree); + } catch (JSONException e) { + Log.e("OrderedListUpdater", "Error serializing tree model", e); //$NON-NLS-1$//$NON-NLS-2$ + } + return tree.toString(); + } + + private void recursivelySerializeChildren(Node node, JSONArray serializeTo) throws JSONException { + ArrayList children = node.children; + for (Node child : children) { + JSONObject childObj = new JSONObject(); + JSONArray childsChildren = new JSONArray(); + recursivelySerializeChildren(child, childsChildren); + childObj.put(Long.toString(child.taskId), childsChildren); + serializeTo.put(childObj); + } + } +}