From 6e1c31dfdf54e5e51684ab4d724126046c4c6245 Mon Sep 17 00:00:00 2001 From: Arne Jans Date: Thu, 24 Feb 2011 22:52:10 +0100 Subject: [PATCH] rewrite of filters for teammember's tasks, readonly again, modified standard-filters so readonly-tasks dont clutter those filters like Inbox, Recent, Taglists, workspaces, tasks assigned by you/to you. Fixes AST-354 --- api/src/com/todoroo/astrid/data/Task.java | 3 + .../astrid/core/CoreFilterExposer.java | 5 +- .../producteev/ProducteevFilterExposer.java | 70 +++++++++++++++---- .../sync/ProducteevSyncProvider.java | 6 +- .../todoroo/astrid/tags/TagFilterExposer.java | 3 +- .../com/todoroo/astrid/tags/TagService.java | 8 ++- astrid/res/values-de/strings.xml | 7 +- astrid/res/values/strings-producteev.xml | 7 +- .../astrid/activity/TaskListActivity.java | 3 + .../todoroo/astrid/adapter/TaskAdapter.java | 9 ++- .../src/com/todoroo/astrid/dao/TaskDao.java | 5 ++ 11 files changed, 102 insertions(+), 24 deletions(-) diff --git a/api/src/com/todoroo/astrid/data/Task.java b/api/src/com/todoroo/astrid/data/Task.java index 433cd3089..42f1b48eb 100644 --- a/api/src/com/todoroo/astrid/data/Task.java +++ b/api/src/com/todoroo/astrid/data/Task.java @@ -140,6 +140,9 @@ public final class Task extends AbstractModel { /** whether repeat occurs relative to completion date instead of due date */ public static final int FLAG_REPEAT_AFTER_COMPLETION = 1 << 1; + /** whether task is readonly */ + public static final int FLAG_IS_READONLY = 1 << 2; + // --- notification flags /** whether to send a reminder at deadline */ diff --git a/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java index 357442c18..302a26354 100644 --- a/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java @@ -46,7 +46,9 @@ public final class CoreFilterExposer extends BroadcastReceiver { Filter recent = new Filter(r.getString(R.string.BFE_Recent), r.getString(R.string.BFE_Recent), - new QueryTemplate().orderBy(Order.desc(Task.MODIFICATION_DATE)).limit(15), + new QueryTemplate().where( + Criterion.not(TaskCriteria.isReadOnly())).orderBy( + Order.desc(Task.MODIFICATION_DATE)).limit(15), null); recent.listingIcon = ((BitmapDrawable)r.getDrawable(R.drawable.tango_new)).getBitmap(); @@ -68,6 +70,7 @@ public final class CoreFilterExposer extends BroadcastReceiver { Filter inbox = new Filter(r.getString(R.string.BFE_Active), r.getString(R.string.BFE_Active), new QueryTemplate().where( Criterion.and(TaskCriteria.isActive(), TaskCriteria.isVisible(), + Criterion.not(TaskCriteria.isReadOnly()), Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where( Criterion.and(MetadataCriteria.withKey(TagService.KEY), TagService.TAG.like("x_%", "x"))))))), //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java index fcbaf776a..004eb99ec 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java @@ -14,6 +14,7 @@ import com.timsu.astrid.R; import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.QueryTemplate; +import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.FilterCategory; @@ -39,7 +40,7 @@ public class ProducteevFilterExposer extends BroadcastReceiver { /** * @param context */ - public static Filter filterFromList(Context context, ProducteevDashboard dashboard) { + public static Filter filterFromList(Context context, ProducteevDashboard dashboard, long currentUserId) { String dashboardTitle = dashboard.getName(); String title = dashboard.getName(); ContentValues values = new ContentValues(); @@ -48,18 +49,49 @@ public class ProducteevFilterExposer extends BroadcastReceiver { values.put(ProducteevTask.ID.name, 0); values.put(ProducteevTask.CREATOR_ID.name, 0); values.put(ProducteevTask.RESPONSIBLE_ID.name, 0); - Filter filter = new Filter(dashboardTitle, title, new QueryTemplate().join( + Filter filter; + if (currentUserId != -1) + filter = new Filter(dashboardTitle, title, new QueryTemplate().join( + ProducteevDataService.METADATA_JOIN).where(Criterion.and( + MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), + TaskCriteria.isActive(), + TaskCriteria.isVisible(), + Criterion.or(ProducteevTask.CREATOR_ID.eq(currentUserId), + ProducteevTask.RESPONSIBLE_ID.eq(currentUserId)), + ProducteevTask.DASHBOARD_ID.eq(dashboard.getId()))), + values); + else + filter = new Filter(dashboardTitle, title, new QueryTemplate().join( + ProducteevDataService.METADATA_JOIN).where(Criterion.and( + MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), + TaskCriteria.isActive(), + TaskCriteria.isVisible(), + ProducteevTask.DASHBOARD_ID.eq(dashboard.getId()))), + values); + + return filter; + } + + private Filter filterUserAssignedByMe(Context context, ProducteevUser user, long currentUserId) { + String title = context.getString(R.string.producteev_FEx_responsible_title, user.toString()); + ContentValues values = new ContentValues(); + values.put(Metadata.KEY.name, ProducteevTask.METADATA_KEY); + values.put(ProducteevTask.ID.name, 0); + values.put(ProducteevTask.CREATOR_ID.name, currentUserId); + values.put(ProducteevTask.RESPONSIBLE_ID.name, user.getId()); + Filter filter = new Filter(user.toString(), title, new QueryTemplate().join( ProducteevDataService.METADATA_JOIN).where(Criterion.and( MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), TaskCriteria.isActive(), TaskCriteria.isVisible(), - ProducteevTask.DASHBOARD_ID.eq(dashboard.getId()))), - values); + ProducteevTask.CREATOR_ID.eq(currentUserId), + ProducteevTask.RESPONSIBLE_ID.eq(user.getId()))), + values); return filter; } - private Filter filterFromUser(Context context, ProducteevUser user) { + private Filter filterUserAssignedByOthers(Context context, ProducteevUser user, long currentUserId) { String title = context.getString(R.string.producteev_FEx_responsible_title, user.toString()); ContentValues values = new ContentValues(); values.put(Metadata.KEY.name, ProducteevTask.METADATA_KEY); @@ -71,6 +103,7 @@ public class ProducteevFilterExposer extends BroadcastReceiver { MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), TaskCriteria.isActive(), TaskCriteria.isVisible(), + Criterion.not(ProducteevTask.CREATOR_ID.eq(currentUserId)), ProducteevTask.RESPONSIBLE_ID.eq(user.getId()))), values); @@ -92,27 +125,38 @@ public class ProducteevFilterExposer extends BroadcastReceiver { FilterListHeader producteevHeader = new FilterListHeader(context.getString(R.string.producteev_FEx_header)); + long currentUserId = Preferences.getLong(ProducteevUtilities.PREF_USER_ID, -1); + // load dashboards Filter[] dashboardFilters = new Filter[dashboards.length]; for(int i = 0; i < dashboards.length; i++) - dashboardFilters[i] = filterFromList(context, new ProducteevDashboard(dashboards[i])); + dashboardFilters[i] = filterFromList(context, new ProducteevDashboard(dashboards[i]), currentUserId); FilterCategory producteevDashboards = new FilterCategory(context.getString(R.string.producteev_FEx_dashboard), dashboardFilters); - // load responsible people + // load responsible people, assigned by me TreeSet people = loadResponsiblePeople(dashboards); - Filter[] peopleFilters = new Filter[people.size()]; + Filter[] peopleByMeFilters = new Filter[people.size()]; int index = 0; for (ProducteevUser person : people) - peopleFilters[index++] = filterFromUser(context, person); - FilterCategory producteevUsers = new FilterCategory(context.getString(R.string.producteev_FEx_responsible), - peopleFilters); + peopleByMeFilters[index++] = filterUserAssignedByMe(context, person, currentUserId); + FilterCategory producteevUsersByMeCategory = new FilterCategory(context.getString(R.string.producteev_FEx_responsible_byme), + peopleByMeFilters); + + // load responsible people, assigned by others + Filter[] peopleByOthersFilters = new Filter[people.size()]; + index = 0; + for (ProducteevUser person : people) + peopleByOthersFilters[index++] = filterUserAssignedByOthers(context, person, currentUserId); + FilterCategory producteevUsersByOthersCategory = new FilterCategory(context.getString(R.string.producteev_FEx_responsible_byothers), + peopleByOthersFilters); // transmit filter list - FilterListItem[] list = new FilterListItem[3]; + FilterListItem[] list = new FilterListItem[4]; list[0] = producteevHeader; list[1] = producteevDashboards; - list[2] = producteevUsers; + list[2] = producteevUsersByMeCategory; + list[3] = producteevUsersByOthersCategory; Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_FILTERS); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, ProducteevUtilities.IDENTIFIER); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, list); diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java index ce3da5cef..eac03b9d0 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java @@ -238,7 +238,9 @@ public class ProducteevSyncProvider extends SyncProviderArbeitsbereiche - Zugeordnet an + Von mir übertragen an + + + Von anderen übertragen an - Zugeordnet an \'%s\' + Übertragen an \'%s\' von %s diff --git a/astrid/res/values/strings-producteev.xml b/astrid/res/values/strings-producteev.xml index 030df5af9..4577373ed 100644 --- a/astrid/res/values/strings-producteev.xml +++ b/astrid/res/values/strings-producteev.xml @@ -11,9 +11,12 @@ Workspaces - Assigned To + Assigned by me to - + + Assigned by others to + + Assigned To \'%s\' diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java index df9779f1e..4fb73018e 100644 --- a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java @@ -794,6 +794,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener, ContextMenuInfo menuInfo) { AdapterContextMenuInfo adapterInfo = (AdapterContextMenuInfo)menuInfo; Task task = ((ViewHolder)adapterInfo.targetView.getTag()).task; + if (task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) + return; + int id = (int)task.getId(); menu.setHeaderTitle(task.getValue(Task.TITLE)); diff --git a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java index 2f27f5ba5..5a17805b0 100644 --- a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java @@ -88,6 +88,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { public static final Property[] PROPERTIES = new Property[] { Task.ID, Task.TITLE, + Task.FLAGS, Task.IMPORTANCE, Task.DUE_DATE, Task.COMPLETION_DATE, @@ -319,6 +320,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { completedItems.get(task.getId()) ? DateUtilities.now() : 0); } completeBox.setChecked(task.isCompleted()); + // disable checkbox if task is readonly + completeBox.setEnabled(!viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)); } // importance bar @@ -689,7 +692,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable { @Override public void run() { mBarListener.addWithAction(item); - mBar.show(viewHolder.view); + if (!viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) + mBar.show(viewHolder.view); } }); } @@ -831,7 +835,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { Collection actions = taskActionManager.get(taskId); prepareQuickActionBar(viewHolder, actions); //mBarAnchor = v; - if(actions != null) + if(actions != null && !viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)) mBar.show(v); taskActionManager.request(viewHolder); @@ -868,6 +872,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { boolean state = task.isCompleted(); viewHolder.completeBox.setChecked(state); + viewHolder.completeBox.setEnabled(!viewHolder.task.getFlag(Task.FLAGS, Task.FLAG_IS_READONLY)); TextView name = viewHolder.nameView; if(state) { diff --git a/astrid/src/com/todoroo/astrid/dao/TaskDao.java b/astrid/src/com/todoroo/astrid/dao/TaskDao.java index f2aba9818..07bc1b6d1 100644 --- a/astrid/src/com/todoroo/astrid/dao/TaskDao.java +++ b/astrid/src/com/todoroo/astrid/dao/TaskDao.java @@ -13,6 +13,7 @@ import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.sql.Criterion; +import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Functions; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; @@ -64,6 +65,10 @@ public class TaskDao extends DatabaseDao { return Task.DELETION_DATE.neq(0); } + public static Criterion isReadOnly() { + return Field.field(Task.FLAGS.name+" & "+Task.FLAG_IS_READONLY).eq(Task.FLAG_IS_READONLY); + } + /** @return tasks that were not deleted */ public static Criterion notDeleted() { return Task.DELETION_DATE.eq(0);