Producteev custom filters.

pull/14/head
Joshua Ball 15 years ago
parent 9bf244812c
commit cb407bbd53

@ -423,6 +423,12 @@
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name="com.todoroo.astrid.producteev.ProducteevCustomFilterCriteriaExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_CUSTOM_FILTER_CRITERIA" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity android:name="com.todoroo.astrid.producteev.ProducteevPreferences" <activity android:name="com.todoroo.astrid.producteev.ProducteevPreferences"
android:label="@string/producteev_PPr_header"> android:label="@string/producteev_PPr_header">
<meta-data android:name="category" <meta-data android:name="category"

@ -295,13 +295,22 @@ public class CustomFilterActivity extends ListActivity {
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) { ContextMenuInfo menuInfo) {
if(menu.hasVisibleItems()) if(menu.hasVisibleItems()) {
/* If it has items already, then the user did not click on the "Add Criteria" button, but instead
long held on a row in the list view, which caused CustomFilterAdapter.onCreateContextMenu
to be invoked before this onCreateContextMenu method was invoked.
*/
return; return;
}
for(int i = 0; i < criteria.size(); i++) { for(int i = 0; i < criteria.size(); i++) {
CustomFilterCriterion item = criteria.get(i); CustomFilterCriterion item = criteria.get(i);
menu.add(CustomFilterActivity.MENU_GROUP_FILTER, try {
i, 0, item.name); menu.add(CustomFilterActivity.MENU_GROUP_FILTER,
i, 0, item.name);
} catch (NullPointerException e) {
throw new NullPointerException("One of the criteria is null. Criteria: " + criteria);
}
} }
} }
}); });

@ -0,0 +1,116 @@
package com.todoroo.astrid.producteev;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import com.timsu.astrid.R;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.CustomFilterCriterion;
import com.todoroo.astrid.api.MultipleSelectCriterion;
import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.StoreObject;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.producteev.sync.ProducteevDashboard;
import com.todoroo.astrid.producteev.sync.ProducteevDataService;
import com.todoroo.astrid.producteev.sync.ProducteevTask;
import com.todoroo.astrid.producteev.sync.ProducteevUser;
import java.util.Set;
import java.util.TreeSet;
public class ProducteevCustomFilterCriteriaExposer extends BroadcastReceiver {
private static final String IDENTIFIER_PRODUCTEEV = "producteev"; // still don't really know what this is
@Override
public void onReceive(Context context, Intent intent) {
// if we aren't logged in, don't expose features
if(!ProducteevUtilities.INSTANCE.isLoggedIn())
return;
Resources r = context.getResources();
StoreObject[] objects = ProducteevDataService.getInstance().getDashboards();
ProducteevDashboard[] dashboards = new ProducteevDashboard[objects.length];
for (int i = 0; i < objects.length; i++) {
dashboards[i] = new ProducteevDashboard(objects[i]);
}
CustomFilterCriterion[] ret = new CustomFilterCriterion[2];
int j = 0;
{
String[] workspaceNames = new String[objects.length];
String[] workspaceIds = new String[objects.length];
for (int i = 0; i < dashboards.length; i++) {
workspaceNames[i] = dashboards[i].getName();
workspaceIds[i] = String.valueOf(dashboards[i].getId());
}
ContentValues values = new ContentValues(2);
values.put(Metadata.KEY.name, ProducteevTask.METADATA_KEY);
values.put(ProducteevTask.DASHBOARD_ID.name, "?");
CustomFilterCriterion criterion = new MultipleSelectCriterion(
IDENTIFIER_PRODUCTEEV,
context.getString(R.string.CFC_producteev_in_workspace_text),
// Todo: abstract these metadata queries
Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner(
Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
MetadataDao.MetadataCriteria.withKey(ProducteevTask.METADATA_KEY),
ProducteevTask.DASHBOARD_ID.eq("?"))).toString(),
values, // what is this?
workspaceNames,
workspaceIds,
((BitmapDrawable)r.getDrawable(R.drawable.silk_folder)).getBitmap(),
context.getString(R.string.CFC_producteev_in_workspace_name));
ret[j++] = criterion;
}
{
Set<ProducteevUser> users = new TreeSet<ProducteevUser>();
for (ProducteevDashboard dashboard : dashboards) {
users.addAll(dashboard.getUsers());
}
int numUsers = users.size();
String[] userNames = new String[numUsers];
String[] userIds = new String[numUsers];
int i = 0;
for (ProducteevUser user : users) {
userNames[i] = user.toString();
userIds[i] = String.valueOf(user.getId());
i++;
}
ContentValues values = new ContentValues(2);
values.put(Metadata.KEY.name, ProducteevTask.METADATA_KEY);
values.put(ProducteevTask.RESPONSIBLE_ID.name, "?");
CustomFilterCriterion criterion = new MultipleSelectCriterion(
IDENTIFIER_PRODUCTEEV, // still not really sure what the point of this identifier is
context.getString(R.string.CFC_producteev_assigned_to_text),
// Todo: abstract these metadata queries, and unify this code with the CustomFilterExposers.
Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner(
Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
MetadataDao.MetadataCriteria.withKey(ProducteevTask.METADATA_KEY),
ProducteevTask.RESPONSIBLE_ID.eq("?"))).toString(),
values, // what is this?
userNames,
userIds,
((BitmapDrawable)r.getDrawable(R.drawable.silk_user_gray)).getBitmap(),
context.getString(R.string.CFC_producteev_assigned_to_name));
ret[j++] = criterion;
}
// transmit filter list
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_CUSTOM_FILTER_CRITERIA);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, ProducteevUtilities.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, ret);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
}

@ -206,31 +206,37 @@ public final class ProducteevDataService {
return cursor; return cursor;
} }
// --- dashboard methods private void readDashboards() {
if (dashboards == null) {
private StoreObject[] dashboards = null; dashboards = readStoreObjects(ProducteevDashboard.TYPE);
}
}
/** /**
* Reads dashboards * Reads store objects.
*/ */
private void readDashboards() { public StoreObject[] readStoreObjects(String type) {
if(dashboards != null) StoreObject[] ret;
return;
TodorooCursor<StoreObject> cursor = storeObjectDao.query(Query.select(StoreObject.PROPERTIES). TodorooCursor<StoreObject> cursor = storeObjectDao.query(Query.select(StoreObject.PROPERTIES).
where(StoreObjectCriteria.byType(ProducteevDashboard.TYPE))); where(StoreObjectCriteria.byType(ProducteevDashboard.TYPE)));
try { try {
dashboards = new StoreObject[cursor.getCount()]; ret = new StoreObject[cursor.getCount()];
for(int i = 0; i < dashboards.length; i++) { for(int i = 0; i < ret.length; i++) {
cursor.moveToNext(); cursor.moveToNext();
StoreObject dashboard = new StoreObject(cursor); StoreObject dashboard = new StoreObject(cursor);
dashboards[i] = dashboard; ret[i] = dashboard;
} }
} finally { } finally {
cursor.close(); cursor.close();
} }
return ret;
} }
// --- dashboard methods
private StoreObject[] dashboards = null;
/** /**
* @return a list of dashboards * @return a list of dashboards
*/ */

@ -8,7 +8,7 @@ import org.json.JSONObject;
* @author Arne Jans <arne.jans@gmail.com> * @author Arne Jans <arne.jans@gmail.com>
*/ */
@SuppressWarnings("nls") @SuppressWarnings("nls")
public class ProducteevUser { public class ProducteevUser implements Comparable<ProducteevUser> {
private final long id; private final long id;
@ -82,4 +82,34 @@ public class ProducteevUser {
displayString += email; displayString += email;
return displayString; return displayString;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProducteevUser that = (ProducteevUser) o;
if (id != that.id) return false;
if (email != null ? !email.equals(that.email) : that.email != null) return false;
if (firstname != null ? !firstname.equals(that.firstname) : that.firstname != null) return false;
if (lastname != null ? !lastname.equals(that.lastname) : that.lastname != null) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (email != null ? email.hashCode() : 0);
result = 31 * result + (firstname != null ? firstname.hashCode() : 0);
result = 31 * result + (lastname != null ? lastname.hashCode() : 0);
return result;
}
@Override
public int compareTo(ProducteevUser o) {
int ret = toString().compareTo(o.toString());
return ret == 0 ? (new Long(id).compareTo(o.id)) : ret;
}
} }

@ -124,4 +124,12 @@
<!-- Spinner-item for default dashboard on taskeditactivity --> <!-- Spinner-item for default dashboard on taskeditactivity -->
<string name="producteev_TEA_dashboard_default">&lt;Default&gt;</string> <string name="producteev_TEA_dashboard_default">&lt;Default&gt;</string>
<string name="CFC_producteev_in_workspace_text">In workspace: ?</string>
<string name="CFC_producteev_in_workspace_name">In workspace...</string>
<string name="CFC_producteev_assigned_to_text">Assigned to: ?</string>
<string name="CFC_producteev_assigned_to_name">Assigned to...</string>
</resources> </resources>
Loading…
Cancel
Save