Cascading delete, fix a bug with cascading complete.

pull/14/head
Tim Su 14 years ago
parent 2c9afaa3c9
commit b3eb181c17

@ -277,6 +277,55 @@ abstract public class OrderedListUpdater<LIST> {
PluginServices.getTaskService().save(taskContainer); PluginServices.getTaskService().save(taskContainer);
} }
// --- task cascading operations
public interface OrderedListNodeVisitor {
public void visitNode(Node node);
}
/**
* Apply an operation only to the children of the task
*/
public void applyToChildren(Filter filter, LIST list, long targetTaskId,
OrderedListNodeVisitor visitor) {
Node root = buildTreeModel(filter, list);
Node target = findNode(root, targetTaskId);
if(target != null)
for(Node child : target.children)
applyVisitor(child, visitor);
}
private void applyVisitor(Node node, OrderedListNodeVisitor visitor) {
visitor.visitNode(node);
for(Node child : node.children)
applyVisitor(child, visitor);
}
/**
* Removes a task from the order hierarchy and un-indent children
* @param filter
* @param list
* @param targetTaskId
*/
public void onDeleteTask(Filter filter, LIST list, final long targetTaskId) {
if(list == null)
return;
Node root = buildTreeModel(filter, list);
Node target = findNode(root, targetTaskId);
if(target != null && target.parent != null) {
int targetIndex = target.parent.children.indexOf(target);
target.parent.children.remove(targetIndex);
for(Node node : target.children)
target.parent.children.add(targetIndex++, node);
}
traverseTreeAndWriteValues(list, root, new AtomicLong(0), -1);
}
// --- utility // --- utility
public void debugPrint(Filter filter, LIST list) { public void debugPrint(Filter filter, LIST list) {

@ -5,7 +5,6 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import android.app.Activity; import android.app.Activity;
@ -31,10 +30,10 @@ import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.adapter.TaskAdapter.OnCompletedTaskListener; import com.todoroo.astrid.adapter.TaskAdapter.OnCompletedTaskListener;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.subtasks.OrderedListUpdater.OrderedListIterator; import com.todoroo.astrid.subtasks.OrderedListUpdater.Node;
import com.todoroo.astrid.subtasks.OrderedListUpdater.OrderedListNodeVisitor;
import com.todoroo.astrid.ui.DraggableListView; import com.todoroo.astrid.ui.DraggableListView;
public class SubtasksFragmentHelper { public class SubtasksFragmentHelper {
@ -219,61 +218,48 @@ public class SubtasksFragmentHelper {
Collections.synchronizedMap(new HashMap<Long, ArrayList<Long>>()); Collections.synchronizedMap(new HashMap<Long, ArrayList<Long>>());
private void setCompletedForItemAndSubtasks(final Task item, final boolean completedState) { private void setCompletedForItemAndSubtasks(final Task item, final boolean completedState) {
final long itemId = item.getId(); final long itemId = item.getId();
final Task task = new Task(); final Task model = new Task();
task.setValue(Task.COMPLETION_DATE, completedState ? DateUtilities.now() : 0); model.setValue(Task.COMPLETION_DATE, completedState ? DateUtilities.now() : 0);
if(completedState == false) { if(completedState == false) {
ArrayList<Long> chained = chainedCompletions.get(itemId); ArrayList<Long> chained = chainedCompletions.get(itemId);
if(chained != null) { if(chained != null) {
for(Long taskId : chained) { for(Long taskId : chained) {
taskAdapter.getCompletedItems().put(taskId, false); taskAdapter.getCompletedItems().put(taskId, false);
task.setId(taskId); model.setId(taskId);
taskService.save(task); taskService.save(model);
} }
taskAdapter.notifyDataSetInvalidated(); taskAdapter.notifyDataSetInvalidated();
} }
return; return;
} }
final int startIndent = item.getValue(SubtasksMetadata.INDENT);
final AtomicBoolean started = new AtomicBoolean(false);
final AtomicBoolean finished = new AtomicBoolean(false);
final ArrayList<Long> chained = new ArrayList<Long>(); final ArrayList<Long> chained = new ArrayList<Long>();
chainedCompletions.put(itemId, chained); updater.applyToChildren(getFilter(), list, itemId, new OrderedListNodeVisitor() {
updater.iterateThroughList(getFilter(), list, new OrderedListIterator() {
@Override @Override
public void processTask(long taskId, Metadata metadata) { public void visitNode(Node node) {
if(finished.get()) model.setId(node.taskId);
return; taskService.save(model);
taskAdapter.getCompletedItems().put(node.taskId, true);
int indent = metadata.containsNonNullValue(SubtasksMetadata.INDENT) ? chained.add(node.taskId);
metadata.getValue(SubtasksMetadata.INDENT) : 0;
if(taskId == itemId){
started.set(true);
return;
} else if(!started.get())
return;
else if(indent <= startIndent) {
finished.set(true);
return;
}
taskAdapter.getCompletedItems().put(taskId, true);
task.setId(taskId);
taskService.save(task);
chained.add(taskId);
} }
}); });
taskAdapter.notifyDataSetInvalidated();
if(chained.size() > 0) {
chainedCompletions.put(itemId, chained);
taskAdapter.notifyDataSetInvalidated();
}
} }
public void setList(String list) { public void setList(String list) {
this.list = list; this.list = list;
} }
public void onDeleteTask(Task task) {
updater.onDeleteTask(getFilter(), list, task.getId());
taskAdapter.notifyDataSetInvalidated();
}
} }

@ -58,6 +58,11 @@ public class SubtasksListFragment extends TaskListFragment {
return true; return true;
} }
@Override
protected void onTaskDelete(Task task) {
helper.onDeleteTask(task);
}
@Override @Override
protected TaskAdapter createTaskAdapter(TodorooCursor<Task> cursor) { protected TaskAdapter createTaskAdapter(TodorooCursor<Task> cursor) {
return helper.createTaskAdapter(cursor, sqlQueryTemplate); return helper.createTaskAdapter(cursor, sqlQueryTemplate);

@ -25,9 +25,6 @@ public class SubtasksTagListFragment extends TagViewFragment {
helper.setList(list); helper.setList(list);
} }
/* (non-Javadoc)
* @see com.todoroo.astrid.activity.TaskListActivity#getListBody(android.view.ViewGroup)
*/
@Override @Override
protected View getListBody(ViewGroup root) { protected View getListBody(ViewGroup root) {
ViewGroup parent = (ViewGroup) getActivity().getLayoutInflater().inflate( ViewGroup parent = (ViewGroup) getActivity().getLayoutInflater().inflate(
@ -67,6 +64,11 @@ public class SubtasksTagListFragment extends TagViewFragment {
return true; return true;
} }
@Override
protected void onTaskDelete(Task task) {
helper.onDeleteTask(task);
}
@Override @Override
protected TaskAdapter createTaskAdapter(TodorooCursor<Task> cursor) { protected TaskAdapter createTaskAdapter(TodorooCursor<Task> cursor) {
return helper.createTaskAdapter(cursor, sqlQueryTemplate); return helper.createTaskAdapter(cursor, sqlQueryTemplate);

@ -141,4 +141,7 @@ public class SubtasksUpdater extends OrderedListUpdater<String> {
} }
}); });
} }
} }

@ -1022,12 +1022,17 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
android.R.drawable.ic_dialog_alert).setPositiveButton( android.R.drawable.ic_dialog_alert).setPositiveButton(
android.R.string.ok, new DialogInterface.OnClickListener() { android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
onTaskDelete(task);
taskService.delete(task); taskService.delete(task);
loadTaskListContent(true); loadTaskListContent(true);
} }
}).setNegativeButton(android.R.string.cancel, null).show(); }).setNegativeButton(android.R.string.cancel, null).show();
} }
protected void onTaskDelete(@SuppressWarnings("unused") Task task) {
// hook
}
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id); super.onListItemClick(l, v, position, id);

@ -336,6 +336,9 @@ public class DraggableListView extends ListView {
public void run() { public void run() {
stopDragging(); stopDragging();
dragThread = null; dragThread = null;
Vibrator v = (Vibrator) getContext().getSystemService(
Context.VIBRATOR_SERVICE);
v.vibrate(50);
mClickListener.onLongClick(viewAtPosition()); mClickListener.onLongClick(viewAtPosition());
} }
}); });

Loading…
Cancel
Save