updated indent action to work like google does

pull/14/head
Tim Su 14 years ago
parent 64f8f9e524
commit 04981152a1

@ -3,14 +3,11 @@ package com.todoroo.astrid.gtasks;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.utility.Flags;
@ -40,15 +37,14 @@ abstract public class GtasksIndentAction extends BroadcastReceiver {
metadata = GtasksMetadata.createEmptyMetadata(taskId);
}
int newIndent = Math.max(0, metadata.getValue(GtasksMetadata.INDENT) + getDelta());
metadata.setValue(GtasksMetadata.INDENT, newIndent);
PluginServices.getMetadataService().save(metadata);
if(metadata.getValue(GtasksMetadata.INDENT) + getDelta() < 0)
return;
gtasksTaskListUpdater.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
String listId = metadata.getValue(GtasksMetadata.LIST_ID);
gtasksTaskListUpdater.indent(listId, taskId, getDelta());
gtasksTaskListUpdater.debugPrint(listId);
Flags.set(Flags.REFRESH);
Toast.makeText(context, context.getString(R.string.gtasks_indent_toast, newIndent),
Toast.LENGTH_SHORT).show();
}
public static class GtasksIncreaseIndentAction extends GtasksIndentAction {

@ -39,7 +39,7 @@ abstract public class GtasksOrderAction extends BroadcastReceiver {
if(metadata == null)
return;
gtasksTaskListUpdater.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
gtasksTaskListUpdater.correctMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
metadata = gtasksMetadataService.getTaskMetadata(taskId);
int oldOrder = metadata.getValue(GtasksMetadata.ORDER);

@ -1,8 +1,6 @@
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;
@ -25,6 +23,7 @@ public class GtasksTaskListUpdater {
final HashMap<Long, Long> parents = new HashMap<Long, Long>();
final HashMap<Long, Long> siblings = new HashMap<Long, Long>();
final HashMap<Long, String> localToRemoteIdMap =
new HashMap<Long, String>();
@ -32,54 +31,113 @@ public class GtasksTaskListUpdater {
DependencyInjectionService.getInstance().inject(this);
}
// --- used during normal ui operations
public void debugPrint(String listId) {
StoreObject list = gtasksListService.getList(listId);
if(list == GtasksListService.LIST_NOT_FOUND_OBJECT)
return;
iterateThroughList(list, new ListIterator() {
public void processTask(long taskId, Metadata metadata) {
System.err.format("%d: indent:%d, parent:%d\n", taskId, //$NON-NLS-1$
metadata.getValue(GtasksMetadata.INDENT),
metadata.getValue(GtasksMetadata.PARENT_TASK));
}
});
}
/**
* Indent a task and all its children
*/
public void indent(String listId, final long targetTaskId, final int delta) {
StoreObject list = gtasksListService.getList(listId);
if(list == GtasksListService.LIST_NOT_FOUND_OBJECT)
return;
updateParentSiblingMapsFor(list);
final AtomicInteger targetTaskIndent = new AtomicInteger(-1);
final AtomicInteger previousIndent = new AtomicInteger(-1);
final AtomicLong previousTask = new AtomicLong(-1);
iterateThroughList(list, new ListIterator() {
@Override
public void processTask(long taskId, Metadata metadata) {
int indent = metadata.getValue(GtasksMetadata.INDENT);
if(targetTaskId == taskId) {
// if indenting is warranted, indent me and my children
if(indent + delta <= previousIndent.get() + 1 && indent + delta >= 0) {
targetTaskIndent.set(indent);
metadata.setValue(GtasksMetadata.INDENT, indent + delta);
if(delta > 0)
metadata.setValue(GtasksMetadata.PARENT_TASK, previousTask.get());
else if(parents.containsKey(taskId))
metadata.setValue(GtasksMetadata.PARENT_TASK,
parents.get(parents.get(taskId)));
else
metadata.setValue(GtasksMetadata.PARENT_TASK, Task.NO_ID);
PluginServices.getMetadataService().save(metadata);
}
} else if(targetTaskIndent.get() > -1) {
// found first task that is not beneath target
if(indent <= targetTaskIndent.get())
targetTaskIndent.set(-1);
else {
metadata.setValue(GtasksMetadata.INDENT, indent + delta);
PluginServices.getMetadataService().save(metadata);
}
} else {
previousIndent.set(indent);
previousTask.set(taskId);
}
}
});
}
// --- used during synchronization
/**
* Update order, parent, and indentation fields for all tasks in all lists
*/
public void updateAllMetadata() {
for(StoreObject list : gtasksListService.getLists()) {
correctMetadataForList(list.getValue(GtasksList.REMOTE_ID));
}
}
/**
* Update order and parent fields for all tasks in the given list
* Update order, parent, and indentation fields for all tasks in the given list
* @param listId
*/
public void updateMetadataForList(String listId) {
public void correctMetadataForList(String listId) {
StoreObject list = gtasksListService.getList(listId);
if(list == GtasksListService.LIST_NOT_FOUND_OBJECT)
return;
final ArrayList<Long> ids = new ArrayList<Long>();
final Stack<Long> taskHierarchyStack = new Stack<Long>();
updateParentSiblingMapsFor(list);
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 = gtasksMetadataService.getTaskMetadata(taskId);
if(metadata == null)
return;
public void processTask(long taskId, Metadata metadata) {
metadata.setValue(GtasksMetadata.ORDER, order.getAndAdd(1));
int indent = metadata.getValue(GtasksMetadata.INDENT);
if(indent > previousIndent.get() + 1)
indent = previousIndent.get() + 1;
metadata.setValue(GtasksMetadata.INDENT, indent);
for(int i = indent; i <= previousIndent.get(); i++) {
if(!taskHierarchyStack.isEmpty())
taskHierarchyStack.pop();
}
if(indent > 0) {
if(taskHierarchyStack.isEmpty()) {
metadata.setValue(GtasksMetadata.PARENT_TASK, 0L);
metadata.setValue(GtasksMetadata.INDENT, 0);
} else
metadata.setValue(GtasksMetadata.PARENT_TASK, taskHierarchyStack.peek());
} else {
metadata.setValue(GtasksMetadata.PARENT_TASK, 0L);
}
long parent = parents.get(taskId);
metadata.setValue(GtasksMetadata.PARENT_TASK, parent);
PluginServices.getMetadataService().save(metadata);
taskHierarchyStack.push(taskId);
previousIndent.set(indent);
}
});
PluginServices.getTaskService().clearDetails(Task.ID.in(ids.toArray(new Long[ids.size()])));
}
/**
@ -87,44 +145,50 @@ public class GtasksTaskListUpdater {
*/
public void createParentSiblingMaps() {
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 = gtasksMetadataService.getTaskMetadata(taskId);
if(metadata == null)
return;
int indent = metadata.getValue(GtasksMetadata.INDENT);
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 {
// move up once for each indent
sibling = previousTask.get();
for(int i = indent; i < previousIndent.get(); i++)
sibling = parents.get(sibling);
parent = parents.get(sibling);
}
parents.put(taskId, parent);
siblings.put(taskId, sibling);
updateParentSiblingMapsFor(list);
}
}
previousTask.set(taskId);
previousIndent.set(indent);
if(!TextUtils.isEmpty(metadata.getValue(GtasksMetadata.ID)))
localToRemoteIdMap.put(taskId, metadata.getValue(GtasksMetadata.ID));
private void updateParentSiblingMapsFor(StoreObject list) {
final AtomicLong previousTask = new AtomicLong(-1L);
final AtomicInteger previousIndent = new AtomicInteger(-1);
iterateThroughList(list, new ListIterator() {
@Override
public void processTask(long taskId, Metadata metadata) {
int indent = metadata.getValue(GtasksMetadata.INDENT);
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 {
// move up once for each indent
sibling = previousTask.get();
for(int i = indent; i < previousIndent.get(); i++)
sibling = parents.get(sibling);
parent = parents.get(sibling);
}
});
}
parents.put(taskId, parent);
siblings.put(taskId, sibling);
previousTask.set(taskId);
previousIndent.set(indent);
if(!TextUtils.isEmpty(metadata.getValue(GtasksMetadata.ID)))
localToRemoteIdMap.put(taskId, metadata.getValue(GtasksMetadata.ID));
}
});
}
/**
* Must be called after creating parent and sibling maps. Updates a
* task container's parent and sibling fields.
*
* @param container
*/
public void updateParentAndSibling(GtasksTaskContainer container) {
long taskId = container.task.getId();
if(parents.containsKey(taskId)) {
@ -146,7 +210,7 @@ public class GtasksTaskListUpdater {
// --- private helpers
private interface ListIterator {
public void processTask(long taskId);
public void processTask(long taskId, Metadata metadata);
}
private void iterateThroughList(StoreObject list, ListIterator iterator) {
@ -155,12 +219,16 @@ public class GtasksTaskListUpdater {
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
long taskId = cursor.getLong(0);
iterator.processTask(taskId);
Metadata metadata = gtasksMetadataService.getTaskMetadata(taskId);
if(metadata == null)
continue;
iterator.processTask(taskId, metadata);
}
} finally {
cursor.close();
}
}
}

@ -246,6 +246,8 @@ public class GtasksSyncProvider extends SyncProvider<GtasksTaskContainer> {
syncData.localUpdated.close();
}
gtasksTaskListUpdater.updateAllMetadata();
gtasksPreferenceService.recordSuccessfulSync();
FlurryAgent.onEvent("gtasks-sync-finished"); //$NON-NLS-1$
} catch (IllegalStateException e) {

@ -125,7 +125,7 @@ public class GtasksTaskListUpdaterTest extends DatabaseTestCase {
private void whenCalculatingOrder() {
for(StoreObject list : gtasksListService.getLists())
gtasksTaskListUpdater.updateMetadataForList(list.getValue(GtasksList.REMOTE_ID));
gtasksTaskListUpdater.correctMetadataForList(list.getValue(GtasksList.REMOTE_ID));
}

Loading…
Cancel
Save