|
|
|
|
@ -8,7 +8,6 @@ package com.todoroo.astrid.subtasks;
|
|
|
|
|
import com.todoroo.andlib.data.Property.IntegerProperty;
|
|
|
|
|
import com.todoroo.andlib.data.Property.LongProperty;
|
|
|
|
|
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
|
|
|
import com.todoroo.astrid.api.Filter;
|
|
|
|
|
import com.todoroo.astrid.core.PluginServices;
|
|
|
|
|
import com.todoroo.astrid.data.Metadata;
|
|
|
|
|
import com.todoroo.astrid.data.Task;
|
|
|
|
|
@ -31,7 +30,7 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
|
|
|
|
|
// --- abstract and empty
|
|
|
|
|
|
|
|
|
|
abstract protected Metadata getTaskMetadata(LIST list, long taskId);
|
|
|
|
|
abstract protected Metadata getTaskMetadata(long taskId);
|
|
|
|
|
|
|
|
|
|
abstract protected IntegerProperty indentProperty();
|
|
|
|
|
|
|
|
|
|
@ -39,15 +38,11 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
|
|
|
|
|
abstract protected LongProperty parentProperty();
|
|
|
|
|
|
|
|
|
|
abstract protected void iterateThroughList(Filter filter, LIST list, OrderedListIterator iterator);
|
|
|
|
|
abstract protected void iterateThroughList(LIST list, OrderedListIterator iterator);
|
|
|
|
|
|
|
|
|
|
abstract protected Metadata createEmptyMetadata(LIST list, long taskId);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param list
|
|
|
|
|
* @param filter
|
|
|
|
|
*/
|
|
|
|
|
protected void initialize(LIST list, Filter filter) {
|
|
|
|
|
protected void initialize() {
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -65,23 +60,12 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param list
|
|
|
|
|
* @param taskId
|
|
|
|
|
* @param metadata
|
|
|
|
|
* @param indent
|
|
|
|
|
* @param order
|
|
|
|
|
*/
|
|
|
|
|
protected void beforeSaveIndent(LIST list, long taskId, Metadata metadata, int indent, int order) {
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- task indenting
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Indent a task and all its children
|
|
|
|
|
*/
|
|
|
|
|
public void indent(final Filter filter, final LIST list, final long targetTaskId, final int delta) {
|
|
|
|
|
public void indent(final LIST list, final long targetTaskId, final int delta) {
|
|
|
|
|
if (list == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -93,7 +77,7 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
final AtomicLong previousTask = new AtomicLong(Task.NO_ID);
|
|
|
|
|
final AtomicLong globalOrder = new AtomicLong(-1);
|
|
|
|
|
|
|
|
|
|
iterateThroughList(filter, list, new OrderedListIterator() {
|
|
|
|
|
iterateThroughList(list, new OrderedListIterator() {
|
|
|
|
|
@Override
|
|
|
|
|
public void processTask(long taskId, Metadata metadata) {
|
|
|
|
|
if (!metadata.isSaved()) {
|
|
|
|
|
@ -112,8 +96,7 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
metadata.setValue(indentProperty(), indent + delta);
|
|
|
|
|
|
|
|
|
|
if (parentProperty() != null) {
|
|
|
|
|
long newParent = computeNewParent(filter, list,
|
|
|
|
|
taskId, indent + delta - 1);
|
|
|
|
|
long newParent = computeNewParent(list, taskId, indent + delta - 1);
|
|
|
|
|
if (newParent == taskId) {
|
|
|
|
|
metadata.setValue(parentProperty(), Task.NO_ID);
|
|
|
|
|
} else {
|
|
|
|
|
@ -141,7 +124,7 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
onMovedOrIndented(getTaskMetadata(list, targetTaskId));
|
|
|
|
|
onMovedOrIndented(getTaskMetadata(targetTaskId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -153,13 +136,13 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
* @param newIndent
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private long computeNewParent(Filter filter, LIST list, long targetTaskId, int targetParentIndent) {
|
|
|
|
|
private long computeNewParent(LIST list, long targetTaskId, int targetParentIndent) {
|
|
|
|
|
final AtomicInteger desiredParentIndent = new AtomicInteger(targetParentIndent);
|
|
|
|
|
final AtomicLong targetTask = new AtomicLong(targetTaskId);
|
|
|
|
|
final AtomicLong lastPotentialParent = new AtomicLong(Task.NO_ID);
|
|
|
|
|
final AtomicBoolean computedParent = new AtomicBoolean(false);
|
|
|
|
|
|
|
|
|
|
iterateThroughList(filter, list, new OrderedListIterator() {
|
|
|
|
|
iterateThroughList(list, new OrderedListIterator() {
|
|
|
|
|
@Override
|
|
|
|
|
public void processTask(long taskId, Metadata metadata) {
|
|
|
|
|
if (targetTask.get() == taskId) {
|
|
|
|
|
@ -187,13 +170,13 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
*
|
|
|
|
|
* @param newTaskId task we will move above. if -1, moves to end of list
|
|
|
|
|
*/
|
|
|
|
|
public void moveTo(Filter filter, LIST list, final long targetTaskId,
|
|
|
|
|
public void moveTo(LIST list, final long targetTaskId,
|
|
|
|
|
final long moveBeforeTaskId) {
|
|
|
|
|
if (list == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node root = buildTreeModel(filter, list);
|
|
|
|
|
Node root = buildTreeModel(list);
|
|
|
|
|
Node target = findNode(root, targetTaskId);
|
|
|
|
|
|
|
|
|
|
if (target != null && target.parent != null) {
|
|
|
|
|
@ -219,7 +202,7 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
traverseTreeAndWriteValues(list, root, new AtomicLong(0), -1);
|
|
|
|
|
onMovedOrIndented(getTaskMetadata(list, targetTaskId));
|
|
|
|
|
onMovedOrIndented(getTaskMetadata(targetTaskId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean ancestorOf(Node ancestor, Node descendant) {
|
|
|
|
|
@ -245,7 +228,7 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
|
|
|
|
|
protected void traverseTreeAndWriteValues(LIST list, Node node, AtomicLong order, int indent) {
|
|
|
|
|
if (node.taskId != Task.NO_ID) {
|
|
|
|
|
Metadata metadata = getTaskMetadata(list, node.taskId);
|
|
|
|
|
Metadata metadata = getTaskMetadata(node.taskId);
|
|
|
|
|
if (metadata == null) {
|
|
|
|
|
metadata = createEmptyMetadata(list, node.taskId);
|
|
|
|
|
}
|
|
|
|
|
@ -281,12 +264,12 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected Node buildTreeModel(Filter filter, LIST list) {
|
|
|
|
|
protected Node buildTreeModel(LIST list) {
|
|
|
|
|
final Node root = new Node(Task.NO_ID, null);
|
|
|
|
|
final AtomicInteger previoustIndent = new AtomicInteger(-1);
|
|
|
|
|
final AtomicReference<Node> currentNode = new AtomicReference<Node>(root);
|
|
|
|
|
|
|
|
|
|
iterateThroughList(filter, list, new OrderedListIterator() {
|
|
|
|
|
iterateThroughList(list, new OrderedListIterator() {
|
|
|
|
|
@Override
|
|
|
|
|
public void processTask(long taskId, Metadata metadata) {
|
|
|
|
|
int indent = metadata.getValue(indentProperty());
|
|
|
|
|
@ -335,10 +318,10 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
/**
|
|
|
|
|
* Apply an operation only to the children of the task
|
|
|
|
|
*/
|
|
|
|
|
public void applyToChildren(Filter filter, LIST list, long targetTaskId,
|
|
|
|
|
public void applyToChildren(LIST list, long targetTaskId,
|
|
|
|
|
OrderedListNodeVisitor visitor) {
|
|
|
|
|
|
|
|
|
|
Node root = buildTreeModel(filter, list);
|
|
|
|
|
Node root = buildTreeModel(list);
|
|
|
|
|
Node target = findNode(root, targetTaskId);
|
|
|
|
|
|
|
|
|
|
if (target != null) {
|
|
|
|
|
@ -362,12 +345,12 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
* @param list
|
|
|
|
|
* @param targetTaskId
|
|
|
|
|
*/
|
|
|
|
|
public void onDeleteTask(Filter filter, LIST list, final long targetTaskId) {
|
|
|
|
|
public void onDeleteTask(LIST list, final long targetTaskId) {
|
|
|
|
|
if (list == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node root = buildTreeModel(filter, list);
|
|
|
|
|
Node root = buildTreeModel(list);
|
|
|
|
|
Node target = findNode(root, targetTaskId);
|
|
|
|
|
|
|
|
|
|
if (target != null && target.parent != null) {
|
|
|
|
|
@ -384,8 +367,8 @@ abstract public class OrderedMetadataListUpdater<LIST> {
|
|
|
|
|
|
|
|
|
|
// --- utility
|
|
|
|
|
|
|
|
|
|
public void debugPrint(Filter filter, LIST list) {
|
|
|
|
|
iterateThroughList(filter, list, new OrderedListIterator() {
|
|
|
|
|
public void debugPrint(LIST list) {
|
|
|
|
|
iterateThroughList(list, new OrderedListIterator() {
|
|
|
|
|
@Override
|
|
|
|
|
public void processTask(long taskId, Metadata metadata) {
|
|
|
|
|
System.err.format("id %d: order %d, indent:%d, parent:%d\n", taskId, //$NON-NLS-1$
|
|
|
|
|
|