diff --git a/astrid/.classpath b/astrid/.classpath index c7efb1be2..e7b64bf23 100644 --- a/astrid/.classpath +++ b/astrid/.classpath @@ -22,7 +22,7 @@ - + diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksFilterExposer.java index 99927d4d6..e4386815b 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksFilterExposer.java @@ -62,7 +62,7 @@ public class GtasksFilterExposer extends BroadcastReceiver { ContextManager.getString(R.string.gtasks_FEx_title, listName), new QueryTemplate().join( Join.left(Metadata.TABLE, Task.ID.eq(Metadata.TASK))).where(Criterion.and( MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), - TaskCriteria.activeAndVisible(), + TaskCriteria.notDeleted(), GtasksMetadata.LIST_ID.eq(list.getValue(GtasksList.REMOTE_ID)))).orderBy( Order.asc(Functions.cast(GtasksMetadata.ORDER, "LONG"))).groupBy(Task.ID), //$NON-NLS-1$ values); diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListActivity.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListActivity.java index 8d951b973..4a0bf130f 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListActivity.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListActivity.java @@ -1,20 +1,29 @@ package com.todoroo.astrid.gtasks; +import android.app.ProgressDialog; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; import com.commonsware.cwac.tlv.TouchListView; import com.commonsware.cwac.tlv.TouchListView.DropListener; import com.commonsware.cwac.tlv.TouchListView.SwipeListener; import com.timsu.astrid.R; import com.todoroo.andlib.data.Property.IntegerProperty; +import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; +import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.activity.DraggableTaskListActivity; +import com.todoroo.astrid.adapter.TaskAdapter.OnCompletedTaskListener; +import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.sync.GtasksSyncOnSaveService; public class GtasksListActivity extends DraggableTaskListActivity { + protected static final int MENU_CLEAR_COMPLETED_ID = MENU_ADDON_INTENT_ID + 1; + @Autowired private GtasksTaskListUpdater gtasksTaskListUpdater; @Autowired private GtasksSyncOnSaveService gtasksSyncOnSaveService; @@ -40,6 +49,13 @@ public class GtasksListActivity extends DraggableTaskListActivity { android.R.drawable.ic_dialog_info, getString(R.string.gtasks_help_body), null); } + + taskAdapter.addOnCompletedTaskListener(new OnCompletedTaskListener() { + @Override + public void onCompletedTask(Task item, boolean newState) { + setCompletedForItemAndSubtasks(item, newState); + } + }); } private final TouchListView.DropListener dropListener = new DropListener() { @@ -75,4 +91,101 @@ public class GtasksListActivity extends DraggableTaskListActivity { } }; + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item = menu.add(Menu.NONE, MENU_CLEAR_COMPLETED_ID, Menu.FIRST, this.getString(R.string.gtasks_GTA_clear_completed)); + item.setIcon(android.R.drawable.ic_input_delete); // Needs new icon + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, final MenuItem item) { + if (item.getItemId() == MENU_CLEAR_COMPLETED_ID) { + clearCompletedTasks(); + return true; + } else { + return super.onMenuItemSelected(featureId, item); + } + } + + private void clearCompletedTasks() { + + final ProgressDialog pd = new ProgressDialog(this); + final TodorooCursor tasks = taskService.fetchFiltered(filter.sqlQuery, null, Task.ID, Task.COMPLETION_DATE); + pd.setMessage(this.getString(R.string.gtasks_GTA_clearing)); + pd.show(); + + new Thread() { + @Override + public void run() { + String listId = null; + try { + for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) { + Task t = new Task(tasks); + if (t.isCompleted()) { + if (listId == null) { + listId = gtasksMetadataService.getTaskMetadata(t.getId()).getValue(GtasksMetadata.LIST_ID); + } + t.setValue(Task.DELETION_DATE, DateUtilities.now()); + taskService.save(t); + } + } + } finally { + tasks.close(); + DialogUtilities.dismissDialog(GtasksListActivity.this, pd); + } + if (listId != null) { + gtasksTaskListUpdater.correctMetadataForList(listId); + } + GtasksListActivity.this.runOnUiThread(new Runnable() { + public void run() { + loadTaskListContent(true); + } + }); + } + }.start(); + } + + private void setCompletedForItemAndSubtasks(Task item, boolean completedState) { + final TodorooCursor tasks = taskService.fetchFiltered(filter.sqlQuery, null, Task.ID, Task.COMPLETION_DATE); + final long itemId = item.getId(); + final boolean completed = completedState; + + new Thread() { + @Override + public void run() { + try { + for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) { + Task curr = new Task(tasks); + if (curr.getId() == itemId) { + int itemIndent = gtasksMetadataService.getTaskMetadata(curr.getId()).getValue(GtasksMetadata.INDENT); + tasks.moveToNext(); + while (!tasks.isAfterLast()) { + Task next = new Task(tasks); + int currIndent = gtasksMetadataService.getTaskMetadata(next.getId()).getValue(GtasksMetadata.INDENT); + if (currIndent > itemIndent) { + if (completed) + next.setValue(Task.COMPLETION_DATE, DateUtilities.now()); + else + next.setValue(Task.COMPLETION_DATE, 0L); + taskService.save(next); + } else break; + + tasks.moveToNext(); + } + break; + } + } + } finally { + tasks.close(); + } + GtasksListActivity.this.runOnUiThread(new Runnable() { + public void run() { + loadTaskListContent(true); + } + }); + } + }.start(); + } } diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/api/GtasksService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/api/GtasksService.java index b5cdd8ea5..5b52a59f9 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/api/GtasksService.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/api/GtasksService.java @@ -160,14 +160,15 @@ public class GtasksService { } } - public com.google.api.services.tasks.v1.model.Tasks getAllGtasksFromTaskList(TaskList list, boolean includeDeleted) throws IOException { - return getAllGtasksFromListId(list.id, includeDeleted); + public com.google.api.services.tasks.v1.model.Tasks getAllGtasksFromTaskList(TaskList list, boolean includeDeleted, boolean includeHidden) throws IOException { + return getAllGtasksFromListId(list.id, includeDeleted, includeHidden); } - public com.google.api.services.tasks.v1.model.Tasks getAllGtasksFromListId(String listId, boolean includeDeleted) throws IOException { + public com.google.api.services.tasks.v1.model.Tasks getAllGtasksFromListId(String listId, boolean includeDeleted, boolean includeHidden) throws IOException { com.google.api.services.tasks.v1.model.Tasks toReturn = null; List request = service.tasks.list(listId); request.showDeleted = includeDeleted; + request.showHidden = includeHidden; try { toReturn = request.execute(); } catch (IOException e) { diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksLegacyMigrator.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksLegacyMigrator.java index a27ddfb54..d3586d855 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksLegacyMigrator.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksLegacyMigrator.java @@ -73,7 +73,7 @@ public class GtasksLegacyMigrator { defaultListId = list.id; } - Tasks allTasks = gtasksService.getAllGtasksFromListId(list.id, false); + Tasks allTasks = gtasksService.getAllGtasksFromListId(list.id, false, false); if (allTasks.items != null) { for (com.google.api.services.tasks.v1.model.Task t : allTasks.items) { diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java index fd4a48bcd..0b96f4782 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java @@ -245,7 +245,7 @@ public class GtasksSyncProvider extends SyncProvider { // first, pull all tasks. then we can write them // include deleted tasks so we can delete them in astrid - data.remoteUpdated = readAllRemoteTasks(true); + data.remoteUpdated = readAllRemoteTasks(true, true); for(GtasksTaskContainer remote : data.remoteUpdated) { if(remote.task.getId() < 1) { @@ -300,7 +300,7 @@ public class GtasksSyncProvider extends SyncProvider { private SyncData populateSyncData() throws IOException { // fetch remote tasks - ArrayList remoteTasks = readAllRemoteTasks(false); + ArrayList remoteTasks = readAllRemoteTasks(false, false); // fetch locally created tasks TodorooCursor localCreated = gtasksMetadataService.getLocallyCreated(PROPERTIES); @@ -315,7 +315,7 @@ public class GtasksSyncProvider extends SyncProvider { // ------------------------------------------------- create / push / pull // ---------------------------------------------------------------------- - private ArrayList readAllRemoteTasks(final boolean includeDeleted) { + private ArrayList readAllRemoteTasks(final boolean includeDeleted, final boolean includeHidden) { final ArrayList list = new ArrayList(); final Semaphore listsFinished = new Semaphore(0); @@ -329,7 +329,7 @@ public class GtasksSyncProvider extends SyncProvider { String listId = dashboard.getValue(GtasksList.REMOTE_ID); if(Constants.DEBUG) Log.e("gtasks-debug", "ACTION: getTasks, " + listId); - List remoteTasks = taskService.getAllGtasksFromListId(listId, includeDeleted).items; + List remoteTasks = taskService.getAllGtasksFromListId(listId, includeDeleted, includeHidden).items; addRemoteTasksToList(remoteTasks, list); } catch (Exception e) { handleException("read-remotes", e, false); @@ -530,7 +530,9 @@ public class GtasksSyncProvider extends SyncProvider { task.setValue(Task.COMPLETION_DATE, GtasksApiUtilities.gtasksCompletedTimeToUnixTime(remoteTask.completed, 0)); if (remoteTask.deleted == null || !remoteTask.deleted.booleanValue()) task.setValue(Task.DELETION_DATE, 0L); - else if (remoteTask.deleted) + else if (remoteTask.deleted.booleanValue()) + task.setValue(Task.DELETION_DATE, DateUtilities.now()); + if (remoteTask.hidden != null && remoteTask.hidden.booleanValue()) task.setValue(Task.DELETION_DATE, DateUtilities.now()); long dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.due, 0); diff --git a/astrid/res/values/strings-gtasks.xml b/astrid/res/values/strings-gtasks.xml index 94549a768..746020d1d 100644 --- a/astrid/res/values/strings-gtasks.xml +++ b/astrid/res/values/strings-gtasks.xml @@ -29,6 +29,12 @@ In List: ? In GTasks List... + + + Clearing completed tasks... + + + Clear Completed @@ -70,7 +76,7 @@ You may have encountered a captcha. Try logging in from the browser, then come back to try again: - + diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java index 437883ee5..4253a4c7f 100644 --- a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java @@ -152,7 +152,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, @Autowired ExceptionService exceptionService; - @Autowired TaskService taskService; + @Autowired protected TaskService taskService; @Autowired MetadataService metadataService;