diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml
index a491a72ee..393440d45 100644
--- a/astrid/AndroidManifest.xml
+++ b/astrid/AndroidManifest.xml
@@ -465,6 +465,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksIndentAction.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksIndentAction.java
new file mode 100644
index 000000000..b949ebec2
--- /dev/null
+++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksIndentAction.java
@@ -0,0 +1,57 @@
+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;
+
+abstract public class GtasksIndentAction extends BroadcastReceiver {
+
+ @Autowired private GtasksMetadataService gtasksMetadataService;
+
+ abstract int getDelta();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ContextManager.setContext(context);
+ DependencyInjectionService.getInstance().inject(this);
+
+ long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1);
+ if(taskId == -1)
+ return;
+
+ Metadata metadata = gtasksMetadataService.getTaskMetadata(taskId);
+ if(metadata == null)
+ metadata = GtasksMetadata.createEmptyMetadata();
+
+ int newIndent = Math.max(0, metadata.getValue(GtasksMetadata.INDENTATION) + getDelta());
+ metadata.setValue(GtasksMetadata.INDENTATION, newIndent);
+ PluginServices.getMetadataService().save(metadata);
+
+ Toast.makeText(context, context.getString(R.string.gtasks_indent_toast, newIndent),
+ Toast.LENGTH_SHORT).show();
+ }
+
+ public static class GtasksIncreaseIndentAction extends GtasksIndentAction {
+ @Override
+ public int getDelta() {
+ return 1;
+ }
+ }
+
+ public static class GtasksDecreaseIndentAction extends GtasksIndentAction {
+ @Override
+ public int getDelta() {
+ return -1;
+ }
+ }
+
+}
diff --git a/astrid/res/values/strings-gtasks.xml b/astrid/res/values/strings-gtasks.xml
index f10f718a2..3280cecf1 100644
--- a/astrid/res/values/strings-gtasks.xml
+++ b/astrid/res/values/strings-gtasks.xml
@@ -2,13 +2,22 @@
-
+
Google Tasks
By List
+
+
+ New Indentation: %d
+
+
+ Move Right
+
+
+ Move Left
diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java
index f87af25fa..8c56e1668 100644
--- a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java
+++ b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java
@@ -58,7 +58,6 @@ import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.utility.AndroidUtilities;
-import com.todoroo.andlib.utility.Pair;
import com.todoroo.andlib.widget.GestureService;
import com.todoroo.andlib.widget.GestureService.GestureInterface;
import com.todoroo.astrid.activity.SortSelectionActivity.OnSortSelectedListener;
@@ -76,6 +75,8 @@ import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
+import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader;
+import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader.ContextMenuItem;
import com.todoroo.astrid.reminders.Notifications;
import com.todoroo.astrid.reminders.ReminderService;
import com.todoroo.astrid.reminders.ReminderService.AlarmScheduler;
@@ -161,6 +162,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
private Timer backgroundTimer;
private final LinkedHashSet syncActions = new LinkedHashSet();
+
+ private final TaskListContextMenuExtensionLoader contextMenuExtensionLoader = new TaskListContextMenuExtensionLoader();
+
/* ======================================================================
* ======================================================= initialization
* ====================================================================== */
@@ -210,12 +214,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
if(Constants.DEBUG)
setTitle("[D] " + filter.title); //$NON-NLS-1$
- // perform caching
- new Thread(new Runnable() {
- public void run() {
- loadContextMenuIntents();
- }
- }).start();
+ contextMenuExtensionLoader.loadInNewThread(this);
}
/**
@@ -746,24 +745,6 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
return task;
}
- protected Pair[] contextMenuItemCache = null;
-
- protected void loadContextMenuIntents() {
- Intent queryIntent = new Intent(AstridApiConstants.ACTION_TASK_CONTEXT_MENU);
- PackageManager pm = getPackageManager();
- List resolveInfoList = pm.queryIntentActivities(queryIntent, 0);
- int length = resolveInfoList.size();
- contextMenuItemCache = new Pair[length];
- for(int i = 0; i < length; i++) {
- ResolveInfo resolveInfo = resolveInfoList.get(i);
- Intent intent = new Intent(AstridApiConstants.ACTION_TASK_CONTEXT_MENU);
- intent.setClassName(resolveInfo.activityInfo.packageName,
- resolveInfo.activityInfo.name);
- CharSequence title = resolveInfo.loadLabel(pm);
- contextMenuItemCache[i] = Pair.create(title, intent);
- }
- }
-
@SuppressWarnings("nls")
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
@@ -785,25 +766,20 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
menu.add(id, CONTEXT_MENU_DELETE_TASK_ID, Menu.NONE,
R.string.TAd_contextDeleteTask);
+ long taskId = task.getId();
+ for(ContextMenuItem item : contextMenuExtensionLoader.getList()) {
+ MenuItem menuItem = menu.add(id, CONTEXT_MENU_ADDON_INTENT_ID, Menu.NONE,
+ item.title);
+ item.intent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
+ menuItem.setIntent(item.intent);
+ }
+
if(Constants.DEBUG) {
menu.add("--- debug ---");
menu.add(id, CONTEXT_MENU_DEBUG, Menu.NONE,
- "when alarm?");
+ "when alarm?");
menu.add(id, CONTEXT_MENU_DEBUG + 1, Menu.NONE,
- "make notification");
- }
-
- if(contextMenuItemCache == null)
- return;
-
- // ask about plug-ins
- long taskId = task.getId();
- for(int i = 0; i < contextMenuItemCache.length; i++) {
- Intent intent = contextMenuItemCache[i].getRight();
- MenuItem item = menu.add(id, CONTEXT_MENU_ADDON_INTENT_ID, Menu.NONE,
- contextMenuItemCache[i].getLeft());
- intent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
- item.setIntent(intent);
+ "make notification");
}
}
}
diff --git a/astrid/src/com/todoroo/astrid/helper/TaskListContextMenuExtensionLoader.java b/astrid/src/com/todoroo/astrid/helper/TaskListContextMenuExtensionLoader.java
new file mode 100644
index 000000000..7abc7cdc5
--- /dev/null
+++ b/astrid/src/com/todoroo/astrid/helper/TaskListContextMenuExtensionLoader.java
@@ -0,0 +1,55 @@
+package com.todoroo.astrid.helper;
+
+import java.util.List;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+
+import com.todoroo.astrid.api.AstridApiConstants;
+
+public class TaskListContextMenuExtensionLoader {
+
+ public static class ContextMenuItem {
+ public CharSequence title;
+ public Intent intent;
+ }
+
+ private ContextMenuItem[] contextMenuItemCache = new ContextMenuItem[0];
+
+ public void loadContextMenuIntents(Context context) {
+ Intent queryIntent = new Intent(AstridApiConstants.ACTION_TASK_CONTEXT_MENU);
+ PackageManager pm = context.getPackageManager();
+ List resolveInfoList = pm.queryBroadcastReceivers(queryIntent,
+ PackageManager.GET_META_DATA);
+
+ int length = resolveInfoList.size();
+ contextMenuItemCache = new ContextMenuItem[length];
+ for(int i = 0; i < length; i++) {
+ ResolveInfo resolveInfo = resolveInfoList.get(i);
+
+ ContextMenuItem item = new ContextMenuItem();
+
+ item.intent = new Intent(AstridApiConstants.ACTION_TASK_CONTEXT_MENU);
+ item.intent.setClassName(resolveInfo.activityInfo.packageName,
+ resolveInfo.activityInfo.name);
+ item.title = resolveInfo.loadLabel(pm);
+ contextMenuItemCache[i] = item;
+ }
+ }
+
+ public void loadInNewThread(final Context context) {
+ new Thread(new Runnable() {
+ public void run() {
+ loadContextMenuIntents(context);
+ }
+ }).start();
+ }
+
+ public ContextMenuItem[] getList() {
+ return contextMenuItemCache;
+ }
+
+
+}
\ No newline at end of file
diff --git a/tests/src/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java b/tests/src/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java
new file mode 100644
index 000000000..37569717d
--- /dev/null
+++ b/tests/src/com/todoroo/astrid/gtasks/GtasksIndentActionTest.java
@@ -0,0 +1,100 @@
+package com.todoroo.astrid.gtasks;
+
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+
+import com.todoroo.andlib.service.Autowired;
+import com.todoroo.astrid.api.AstridApiConstants;
+import com.todoroo.astrid.core.PluginServices;
+import com.todoroo.astrid.data.Metadata;
+import com.todoroo.astrid.data.Task;
+import com.todoroo.astrid.gtasks.GtasksIndentAction.GtasksDecreaseIndentAction;
+import com.todoroo.astrid.gtasks.GtasksIndentAction.GtasksIncreaseIndentAction;
+import com.todoroo.astrid.test.DatabaseTestCase;
+
+public class GtasksIndentActionTest extends DatabaseTestCase {
+
+ @Autowired private GtasksMetadataService gtasksMetadataService;
+
+ private Task task;
+
+ public void testIndentWithoutMetadata() {
+ givenTask(taskWithoutMetadata());
+
+ whenTrigger(new GtasksIncreaseIndentAction());
+
+ thenExpectIndentationLevel(1);
+ }
+
+ public void testIndentWithMetadata() {
+ givenTask(taskWithMetadata(0));
+
+ whenTrigger(new GtasksIncreaseIndentAction());
+
+ thenExpectIndentationLevel(1);
+ }
+
+ public void testDeindentWithMetadata() {
+ givenTask(taskWithMetadata(1));
+
+ whenTrigger(new GtasksDecreaseIndentAction());
+
+ thenExpectIndentationLevel(0);
+ }
+
+ public void testDeindentWithoutMetadata() {
+ givenTask(taskWithoutMetadata());
+
+ whenTrigger(new GtasksDecreaseIndentAction());
+
+ thenExpectIndentationLevel(0);
+ }
+
+ public void testDeindentWhenAlreadyZero() {
+ givenTask(taskWithMetadata(0));
+
+ whenTrigger(new GtasksDecreaseIndentAction());
+
+ thenExpectIndentationLevel(0);
+ }
+
+ // --- helpers
+
+ private Task taskWithMetadata(int indentation) {
+ Task task = new Task();
+ PluginServices.getTaskService().save(task);
+ Metadata metadata = GtasksMetadata.createEmptyMetadata();
+ metadata.setValue(GtasksMetadata.INDENTATION, indentation);
+ metadata.setValue(Metadata.TASK, task.getId());
+ PluginServices.getMetadataService().save(metadata);
+ return task;
+ }
+
+ private void thenExpectIndentationLevel(int expected) {
+ Metadata metadata = gtasksMetadataService.getTaskMetadata(task.getId());
+ assertNotNull(metadata);
+ int indentation = metadata.getValue(GtasksMetadata.INDENTATION);
+ assertTrue("indentation: " + indentation,
+ indentation == expected);
+ }
+
+
+ private void whenTrigger(BroadcastReceiver action) {
+ Intent intent = new Intent(AstridApiConstants.ACTION_TASK_CONTEXT_MENU);
+ intent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId());
+ action.onReceive(getContext(), intent);
+ }
+
+
+ private void givenTask(Task taskToTest) {
+ task = taskToTest;
+ }
+
+
+ private Task taskWithoutMetadata() {
+ Task task = new Task();
+ PluginServices.getTaskService().save(task);
+ return task;
+ }
+
+}