mirror of https://github.com/tasks/tasks
Made lots of changes in an attempt to clean stuff up
parent
c537ea95c8
commit
c43ff1aea6
@ -1,184 +0,0 @@
|
|||||||
/**
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.api;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants for interfacing with Astrid's Content Providers.
|
|
||||||
*
|
|
||||||
* @author Tim Su <tim@todoroo.com>
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("nls")
|
|
||||||
public class AstridContentProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Content Provider
|
|
||||||
*/
|
|
||||||
public static final String PROVIDER = "com.todoroo.astrid.provider";
|
|
||||||
|
|
||||||
// --- methods for generating URI's for accessing Astrid data
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URI for:
|
|
||||||
* <ul>
|
|
||||||
* <li>Queries on multiple tasks
|
|
||||||
* <li>Inserting new tasks
|
|
||||||
* <li>Deleting multiple tasks at a time
|
|
||||||
* <li>Updating multiple tasks at a time
|
|
||||||
* </ul>
|
|
||||||
* If your selection clause contains metadata columns, you need to use
|
|
||||||
* <code>allItemsWithMetadataUri</code> instead of this one.
|
|
||||||
*/
|
|
||||||
public static Uri allItemsUri() {
|
|
||||||
return Uri.parse("content://" + PROVIDER + "/items");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URI for:
|
|
||||||
* <ul>
|
|
||||||
* <li>Querying on tasks with metadata columns in selection
|
|
||||||
* <li>Deleting multiple tasks with metadata columns in selection
|
|
||||||
* <li>Updating multiple tasks with metadata columns in selection
|
|
||||||
* </ul>
|
|
||||||
* If, for example, you have defined metadata key 'tag' and wish to delete
|
|
||||||
* all tasks where 'tag' = 'deleteme', you would use this URI. For querying
|
|
||||||
* or insertion, use <code>allItemsUri</code>.
|
|
||||||
* <p>
|
|
||||||
* For queries, <code>allItemsUri</code> will be more efficient, but will
|
|
||||||
* not work if your selection clause contains columns not mentioned in your
|
|
||||||
* projection
|
|
||||||
*
|
|
||||||
* @param metadata
|
|
||||||
* array of metadata columns you wish to select using
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static Uri allItemsWithMetadataUri(String[] metadata) {
|
|
||||||
if(metadata == null || metadata.length == 0)
|
|
||||||
throw new IllegalArgumentException("You must provide metadata");
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for(int i = 0; i < metadata.length; i++)
|
|
||||||
builder.append(escapeUriSubComponent(metadata[i])).append(
|
|
||||||
SUB_COMPONENT_SEPARATOR);
|
|
||||||
|
|
||||||
return Uri.parse("content://" + PROVIDER + "/itemsWith/" +
|
|
||||||
escapeUriComponent(builder.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URI for:
|
|
||||||
* <ul>
|
|
||||||
* <li>Queries on a single task
|
|
||||||
* <li>Updating fields for a single task
|
|
||||||
* <li>Deleting a single task
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* id of task to fetch
|
|
||||||
*/
|
|
||||||
public static Uri singleItemUri(long id) {
|
|
||||||
return Uri.parse("content://" + PROVIDER + "/" + id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URI for:
|
|
||||||
* <ul>
|
|
||||||
* <li>Queries on multiple tasks, grouped by column
|
|
||||||
* </ul>
|
|
||||||
* @param groupBy
|
|
||||||
* column name to group by
|
|
||||||
*/
|
|
||||||
public static Uri groupByUri(String groupBy) {
|
|
||||||
groupBy = escapeUriComponent(groupBy);
|
|
||||||
return Uri.parse("content://" + PROVIDER + "/groupby/" + groupBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- task built-in columns and constnats
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A task in Astrid represents a single item in a user's task list
|
|
||||||
*
|
|
||||||
* @author Tim Su <tim@todoroo.com>
|
|
||||||
*/
|
|
||||||
public static class AstridTask {
|
|
||||||
|
|
||||||
// --- columns
|
|
||||||
|
|
||||||
/** long: Task id */
|
|
||||||
public static final String ID = "_id";
|
|
||||||
|
|
||||||
/** String: name of Task */
|
|
||||||
public static final String TITLE = "title";
|
|
||||||
|
|
||||||
/** int: Task Urgency setting (see <code>Task.URGENCY_*</code>) */
|
|
||||||
public static final String URGENCY = "urgency";
|
|
||||||
|
|
||||||
/** int: Task Importance setting (see <code>Task.IMPORTANCE_*</code>) */
|
|
||||||
public static final String IMPORTANCE = "importance";
|
|
||||||
|
|
||||||
/** int: unixtime Task is due, 0 if not set */
|
|
||||||
public static final String DUE_DATE = "dueDate";
|
|
||||||
|
|
||||||
/** int: unixtime Task should be hidden until, 0 if not set */
|
|
||||||
public static final String HIDDEN_UNTIL = "hiddenUntil";
|
|
||||||
|
|
||||||
/** int: unixtime Task was created */
|
|
||||||
public static final String CREATION_DATE = "creationDate";
|
|
||||||
|
|
||||||
/** int: unixtime Task was completed, 0 if task not completed */
|
|
||||||
public static final String COMPLETION_DATE = "completionDate";
|
|
||||||
|
|
||||||
/** int: unixtime Task was deleted, 0 if task not deleted */
|
|
||||||
public static final String DELETION_DATE = "deletionDate";
|
|
||||||
|
|
||||||
/** int: unixtime Task was modified */
|
|
||||||
public static final String MODIFICATION_DATE = "modificationDate";
|
|
||||||
|
|
||||||
// --- urgency settings
|
|
||||||
|
|
||||||
public static final int URGENCY_NONE = 0;
|
|
||||||
public static final int URGENCY_TODAY = 1;
|
|
||||||
public static final int URGENCY_THIS_WEEK = 2;
|
|
||||||
public static final int URGENCY_THIS_MONTH = 3;
|
|
||||||
public static final int URGENCY_WITHIN_THREE_MONTHS = 4;
|
|
||||||
public static final int URGENCY_WITHIN_SIX_MONTHS = 5;
|
|
||||||
public static final int URGENCY_WITHIN_A_YEAR = 6;
|
|
||||||
public static final int URGENCY_SPECIFIC_DAY = 7;
|
|
||||||
public static final int URGENCY_SPECIFIC_DAY_TIME = 8;
|
|
||||||
|
|
||||||
// --- importance settings
|
|
||||||
|
|
||||||
public static final int IMPORTANCE_DO_OR_DIE = 0;
|
|
||||||
public static final int IMPORTANCE_MUST_DO = 1;
|
|
||||||
public static final int IMPORTANCE_SHOULD_DO = 2;
|
|
||||||
public static final int IMPORTANCE_NONE = 3;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- internal methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Escapes a string for use in a URI. Used internally to pass extra data
|
|
||||||
* to the content provider.
|
|
||||||
* @param component
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String escapeUriComponent(String component) {
|
|
||||||
return component.replace("%", "%o").replace("/", "%s");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String SUB_COMPONENT_SEPARATOR = "|";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Escapes a string for use as part of a URI string. Used internally to pass extra data
|
|
||||||
* to the content provider.
|
|
||||||
* @param component
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String escapeUriSubComponent(String component) {
|
|
||||||
return component.replace("$", "$o").replace(SUB_COMPONENT_SEPARATOR, "$s");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* See the file "LICENSE" for the full license governing this code.
|
||||||
|
*/
|
||||||
|
package com.todoroo.astrid.api;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a plug-in for Astrid. Users can enable or disable plug-ins,
|
||||||
|
* which affect all other extension points that share the same identifier.
|
||||||
|
*
|
||||||
|
* @author Tim Su <tim@todoroo.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Plugin implements Parcelable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug-in Identifier
|
||||||
|
*/
|
||||||
|
public String plugin = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug-in Title
|
||||||
|
*/
|
||||||
|
public String title = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug-in Author
|
||||||
|
*/
|
||||||
|
public String author = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug-in Description
|
||||||
|
*/
|
||||||
|
public String description = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience constructor to generate a plug-in object
|
||||||
|
*
|
||||||
|
* @param plugin
|
||||||
|
* @param title
|
||||||
|
* @param author
|
||||||
|
* @param description
|
||||||
|
*/
|
||||||
|
public Plugin(String plugin, String title, String author, String description) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- parcelable helpers
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(plugin);
|
||||||
|
dest.writeString(title);
|
||||||
|
dest.writeString(author);
|
||||||
|
dest.writeString(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parcelable creator
|
||||||
|
*/
|
||||||
|
public static final Parcelable.Creator<Plugin> CREATOR = new Parcelable.Creator<Plugin>() {
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Plugin createFromParcel(Parcel source) {
|
||||||
|
return new Plugin(source.readString(), source.readString(),
|
||||||
|
source.readString(), source.readString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Plugin[] newArray(int size) {
|
||||||
|
return new Plugin[size];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
|
||||||
|
|
||||||
public enum OrderType {
|
|
||||||
DESC, ASC
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
@SuppressWarnings("nls")
|
@SuppressWarnings("nls")
|
||||||
public class Constants {
|
public final class Constants {
|
||||||
static final String SELECT = "SELECT";
|
static final String SELECT = "SELECT";
|
||||||
static final String SPACE = " ";
|
static final String SPACE = " ";
|
||||||
static final String AS = "AS";
|
static final String AS = "AS";
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.AND;
|
import static com.todoroo.andlib.sql.Constants.AND;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.EXISTS;
|
import static com.todoroo.andlib.sql.Constants.EXISTS;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.LEFT_PARENTHESIS;
|
import static com.todoroo.andlib.sql.Constants.LEFT_PARENTHESIS;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.NOT;
|
import static com.todoroo.andlib.sql.Constants.NOT;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.OR;
|
import static com.todoroo.andlib.sql.Constants.OR;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.RIGHT_PARENTHESIS;
|
import static com.todoroo.andlib.sql.Constants.RIGHT_PARENTHESIS;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
public abstract class Criterion {
|
public abstract class Criterion {
|
||||||
protected final Operator operator;
|
protected final Operator operator;
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.AS;
|
import static com.todoroo.andlib.sql.Constants.AS;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
public abstract class DBObject<T extends DBObject<?>> implements Cloneable {
|
public abstract class DBObject<T extends DBObject<?>> implements Cloneable {
|
||||||
protected String alias;
|
protected String alias;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
public class EqCriterion extends UnaryCriterion {
|
public class EqCriterion extends UnaryCriterion {
|
||||||
EqCriterion(Field field, Object value) {
|
EqCriterion(Field field, Object value) {
|
||||||
@ -1,11 +1,11 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.AND;
|
import static com.todoroo.andlib.sql.Constants.AND;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.BETWEEN;
|
import static com.todoroo.andlib.sql.Constants.BETWEEN;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.COMMA;
|
import static com.todoroo.andlib.sql.Constants.COMMA;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.LEFT_PARENTHESIS;
|
import static com.todoroo.andlib.sql.Constants.LEFT_PARENTHESIS;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.RIGHT_PARENTHESIS;
|
import static com.todoroo.andlib.sql.Constants.RIGHT_PARENTHESIS;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
public class Field extends DBObject<Field> {
|
public class Field extends DBObject<Field> {
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public final class Functions {
|
||||||
|
|
||||||
|
public static String caseStatement(Criterion when, Object ifTrue, Object ifFalse) {
|
||||||
|
return new StringBuilder("CASE WHEN ").
|
||||||
|
append(when.toString()).append(" THEN ").append(value(ifTrue)).
|
||||||
|
append(" ELSE ").append(value(ifFalse)).append(" END").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String value(Object value) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -1,33 +1,33 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.JOIN;
|
import static com.todoroo.andlib.sql.Constants.JOIN;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.ON;
|
import static com.todoroo.andlib.sql.Constants.ON;
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
public class Join {
|
public class Join {
|
||||||
private final Table joinTable;
|
private final SqlTable joinTable;
|
||||||
private final JoinType joinType;
|
private final JoinType joinType;
|
||||||
private final Criterion[] criterions;
|
private final Criterion[] criterions;
|
||||||
|
|
||||||
private Join(Table table, JoinType joinType, Criterion... criterions) {
|
private Join(SqlTable table, JoinType joinType, Criterion... criterions) {
|
||||||
joinTable = table;
|
joinTable = table;
|
||||||
this.joinType = joinType;
|
this.joinType = joinType;
|
||||||
this.criterions = criterions;
|
this.criterions = criterions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Join inner(Table expression, Criterion... criterions) {
|
public static Join inner(SqlTable expression, Criterion... criterions) {
|
||||||
return new Join(expression, JoinType.INNER, criterions);
|
return new Join(expression, JoinType.INNER, criterions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Join left(Table table, Criterion... criterions) {
|
public static Join left(SqlTable table, Criterion... criterions) {
|
||||||
return new Join(table, JoinType.LEFT, criterions);
|
return new Join(table, JoinType.LEFT, criterions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Join right(Table table, Criterion... criterions) {
|
public static Join right(SqlTable table, Criterion... criterions) {
|
||||||
return new Join(table, JoinType.RIGHT, criterions);
|
return new Join(table, JoinType.RIGHT, criterions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Join out(Table table, Criterion... criterions) {
|
public static Join out(SqlTable table, Criterion... criterions) {
|
||||||
return new Join(table, JoinType.OUT, criterions);
|
return new Join(table, JoinType.OUT, criterions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
public enum JoinType {
|
public enum JoinType {
|
||||||
INNER, LEFT, RIGHT, OUT
|
INNER, LEFT, RIGHT, OUT
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -1,25 +1,25 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
public class Order {
|
public class Order {
|
||||||
private final Field expression;
|
private final Object expression;
|
||||||
private final OrderType orderType;
|
private final OrderType orderType;
|
||||||
|
|
||||||
private Order(Field expression) {
|
private Order(Object expression) {
|
||||||
this(expression, OrderType.ASC);
|
this(expression, OrderType.ASC);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Order(Field expression, OrderType orderType) {
|
private Order(Object expression, OrderType orderType) {
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
this.orderType = orderType;
|
this.orderType = orderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Order asc(Field expression) {
|
public static Order asc(Object expression) {
|
||||||
return new Order(expression);
|
return new Order(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Order desc(Field expression) {
|
public static Order desc(Object expression) {
|
||||||
return new Order(expression, OrderType.DESC);
|
return new Order(expression, OrderType.DESC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
|
public enum OrderType {
|
||||||
|
DESC, ASC
|
||||||
|
}
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
|
import static com.todoroo.andlib.sql.Constants.COMMA;
|
||||||
|
import static com.todoroo.andlib.sql.Constants.GROUP_BY;
|
||||||
|
import static com.todoroo.andlib.sql.Constants.ORDER_BY;
|
||||||
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
import static com.todoroo.andlib.sql.Constants.WHERE;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query Template returns a bunch of criteria that allows a query to be
|
||||||
|
* constructed
|
||||||
|
*
|
||||||
|
* @author Tim Su <tim@todoroo.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class QueryTemplate {
|
||||||
|
|
||||||
|
private final ArrayList<Criterion> criterions = new ArrayList<Criterion>();
|
||||||
|
private final ArrayList<Join> joins = new ArrayList<Join>();
|
||||||
|
private final ArrayList<Field> groupBies = new ArrayList<Field>();
|
||||||
|
private final ArrayList<Order> orders = new ArrayList<Order>();
|
||||||
|
private final ArrayList<Criterion> havings = new ArrayList<Criterion>();
|
||||||
|
|
||||||
|
public QueryTemplate join(Join... join) {
|
||||||
|
joins.addAll(asList(join));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryTemplate where(Criterion criterion) {
|
||||||
|
criterions.add(criterion);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryTemplate groupBy(Field... groupBy) {
|
||||||
|
groupBies.addAll(asList(groupBy));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryTemplate orderBy(Order... order) {
|
||||||
|
orders.addAll(asList(order));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
visitJoinClause(sql);
|
||||||
|
visitWhereClause(sql);
|
||||||
|
visitGroupByClause(sql);
|
||||||
|
visitOrderByClause(sql);
|
||||||
|
return sql.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitOrderByClause(StringBuilder sql) {
|
||||||
|
if (orders.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sql.append(ORDER_BY);
|
||||||
|
for (Order order : orders) {
|
||||||
|
sql.append(SPACE).append(order).append(COMMA);
|
||||||
|
}
|
||||||
|
sql.deleteCharAt(sql.length() - 1).append(SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
private void visitGroupByClause(StringBuilder sql) {
|
||||||
|
if (groupBies.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sql.append(GROUP_BY);
|
||||||
|
for (Field groupBy : groupBies) {
|
||||||
|
sql.append(SPACE).append(groupBy).append(COMMA);
|
||||||
|
}
|
||||||
|
sql.deleteCharAt(sql.length() - 1).append(SPACE);
|
||||||
|
if (havings.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sql.append("HAVING");
|
||||||
|
for (Criterion havingCriterion : havings) {
|
||||||
|
sql.append(SPACE).append(havingCriterion).append(COMMA);
|
||||||
|
}
|
||||||
|
sql.deleteCharAt(sql.length() - 1).append(SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitWhereClause(StringBuilder sql) {
|
||||||
|
if (criterions.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sql.append(WHERE);
|
||||||
|
for (Criterion criterion : criterions) {
|
||||||
|
sql.append(SPACE).append(criterion).append(SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitJoinClause(StringBuilder sql) {
|
||||||
|
for (Join join : joins) {
|
||||||
|
sql.append(join).append(SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryTemplate having(Criterion criterion) {
|
||||||
|
this.havings.add(criterion);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,13 +1,13 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
public class Table extends DBObject<Table> {
|
public class SqlTable extends DBObject<SqlTable> {
|
||||||
|
|
||||||
protected Table(String expression) {
|
protected SqlTable(String expression) {
|
||||||
super(expression);
|
super(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Table table(String table) {
|
public static SqlTable table(String table) {
|
||||||
return new Table(table);
|
return new SqlTable(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("nls")
|
@SuppressWarnings("nls")
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.todoroo.andlib.data.sql;
|
package com.todoroo.andlib.sql;
|
||||||
|
|
||||||
import static com.todoroo.andlib.data.sql.Constants.SPACE;
|
import static com.todoroo.andlib.sql.Constants.SPACE;
|
||||||
|
|
||||||
public class UnaryCriterion extends Criterion {
|
public class UnaryCriterion extends Criterion {
|
||||||
protected final Field expression;
|
protected final Field expression;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.todoroo.astrid.filters;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.api.AstridApiConstants;
|
||||||
|
import com.todoroo.astrid.api.Plugin;
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class CorePlugin extends BroadcastReceiver {
|
||||||
|
|
||||||
|
static final String pluginIdentifier = "core";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Plugin plugin = new Plugin(pluginIdentifier, "Core Filters", "Todoroo",
|
||||||
|
"Provides 'Inbox' and 'All Tasks' Filters");
|
||||||
|
|
||||||
|
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_PLUGINS);
|
||||||
|
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_PLUGIN, plugin);
|
||||||
|
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* See the file "LICENSE" for the full license governing this code.
|
||||||
|
*/
|
||||||
|
package com.todoroo.astrid.filters;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
|
||||||
|
import com.todoroo.andlib.sql.Criterion;
|
||||||
|
import com.todoroo.andlib.sql.Order;
|
||||||
|
import com.todoroo.andlib.sql.QueryTemplate;
|
||||||
|
import com.todoroo.andlib.utility.DateUtilities;
|
||||||
|
import com.todoroo.astrid.activity.FilterListActivity;
|
||||||
|
import com.todoroo.astrid.api.AstridApiConstants;
|
||||||
|
import com.todoroo.astrid.api.Filter;
|
||||||
|
import com.todoroo.astrid.api.FilterListItem;
|
||||||
|
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
|
||||||
|
import com.todoroo.astrid.model.Task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes Astrid's built in filters to the {@link FilterListActivity}
|
||||||
|
*
|
||||||
|
* @author Tim Su <tim@todoroo.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class ExtendedFilterExposer extends BroadcastReceiver {
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Resources r = context.getResources();
|
||||||
|
|
||||||
|
// build filters
|
||||||
|
ContentValues hiddenValues = new ContentValues();
|
||||||
|
hiddenValues.put(Task.HIDE_UNTIL, DateUtilities.now() + DateUtilities.ONE_DAY);
|
||||||
|
Filter hidden = new Filter(ExtendedPlugin.pluginIdentifier, "Hidden Tasks",
|
||||||
|
"Hidden Tasks",
|
||||||
|
new QueryTemplate().where(Criterion.and(TaskCriteria.isActive(),
|
||||||
|
Criterion.not(TaskCriteria.isVisible(DateUtilities.now())))).
|
||||||
|
orderBy(Order.asc(Task.HIDE_UNTIL)),
|
||||||
|
hiddenValues);
|
||||||
|
|
||||||
|
Filter alphabetical = new Filter(ExtendedPlugin.pluginIdentifier,
|
||||||
|
"Inbox (sorted by name)",
|
||||||
|
"Inbox (sorted by name)",
|
||||||
|
new QueryTemplate().orderBy(Order.asc(Task.TITLE)),
|
||||||
|
null);
|
||||||
|
|
||||||
|
// transmit filter list
|
||||||
|
FilterListItem[] list = new FilterListItem[2];
|
||||||
|
list[0] = inbox;
|
||||||
|
list[1] = all;
|
||||||
|
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_FILTERS);
|
||||||
|
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, list);
|
||||||
|
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.todoroo.astrid.filters;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.api.AstridApiConstants;
|
||||||
|
import com.todoroo.astrid.api.Plugin;
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class ExtendedPlugin extends BroadcastReceiver {
|
||||||
|
|
||||||
|
static final String pluginIdentifier = "extended";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Plugin plugin = new Plugin(pluginIdentifier, "Extended Filters", "Todoroo",
|
||||||
|
"Provides extended filters for viewing subsets of your tasks");
|
||||||
|
|
||||||
|
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_PLUGINS);
|
||||||
|
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_PLUGIN, plugin);
|
||||||
|
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* See the file "LICENSE" for the full license governing this code.
|
||||||
|
*/
|
||||||
|
package com.todoroo.astrid.tags;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.R;
|
||||||
|
import com.todoroo.astrid.api.AstridApiConstants;
|
||||||
|
import com.todoroo.astrid.api.Filter;
|
||||||
|
import com.todoroo.astrid.api.FilterCategory;
|
||||||
|
import com.todoroo.astrid.api.FilterListHeader;
|
||||||
|
import com.todoroo.astrid.api.FilterListItem;
|
||||||
|
import com.todoroo.astrid.tags.DataService.Tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes filters based on tags
|
||||||
|
*
|
||||||
|
* @author Tim Su <tim@todoroo.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FilterExposer extends BroadcastReceiver {
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
private Filter filterFromTag(Context context, Tag tag, DataService tagService) {
|
||||||
|
String listTitle = context.getString(R.string.tag_FEx_tag_w_size).
|
||||||
|
replace("$T", tag.tag).replace("$C", Integer.toString(tag.count));
|
||||||
|
String title = context.getString(R.string.tag_FEx_name, tag.tag);
|
||||||
|
Filter filter = new Filter(listTitle, title,
|
||||||
|
tagService.getQuery(tag.tag),
|
||||||
|
tagService.getNewTaskSql(tag.tag));
|
||||||
|
|
||||||
|
// filters[0].contextMenuLabels = new String[] {
|
||||||
|
// "Rename Tag",
|
||||||
|
// "Delete Tag"
|
||||||
|
// };
|
||||||
|
// filters[0].contextMenuIntents = new Intent[] {
|
||||||
|
// new Intent(),
|
||||||
|
// new Intent()
|
||||||
|
// };
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
DataService tagService = new DataService(context);
|
||||||
|
Tag[] tagsByAlpha = tagService.getGroupedTags(DataService.GROUPED_TAGS_BY_ALPHA);
|
||||||
|
|
||||||
|
// If user does not have any tags, don't show this section at all
|
||||||
|
if(tagsByAlpha.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tag[] tagsBySize = tagService.getGroupedTags(DataService.GROUPED_TAGS_BY_SIZE);
|
||||||
|
Filter[] filtersByAlpha = new Filter[tagsByAlpha.length];
|
||||||
|
for(int i = 0; i < tagsByAlpha.length; i++)
|
||||||
|
filtersByAlpha[i] = filterFromTag(context, tagsByAlpha[i], tagService);
|
||||||
|
|
||||||
|
Filter[] filtersBySize = new Filter[tagsBySize.length];
|
||||||
|
for(int i = 0; i < tagsBySize.length; i++)
|
||||||
|
filtersBySize[i] = filterFromTag(context, tagsBySize[i], tagService);
|
||||||
|
|
||||||
|
FilterListHeader tagsHeader = new FilterListHeader(context.getString(R.string.tag_FEx_header));
|
||||||
|
FilterCategory tagsCategoryBySize = new FilterCategory(
|
||||||
|
context.getString(R.string.tag_FEx_by_size), filtersBySize);
|
||||||
|
FilterCategory tagsCategoryByAlpha = new FilterCategory(context.getString(R.string.tag_FEx_alpha), filtersByAlpha);
|
||||||
|
|
||||||
|
// transmit filter list
|
||||||
|
FilterListItem[] list = new FilterListItem[3];
|
||||||
|
list[0] = tagsHeader;
|
||||||
|
list[1] = tagsCategoryBySize;
|
||||||
|
list[2] = tagsCategoryByAlpha;
|
||||||
|
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_FILTERS);
|
||||||
|
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, list);
|
||||||
|
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- See the file "LICENSE" for the full license governing this code. -->
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Resources for built-in tag plug-in -->
|
||||||
|
|
||||||
|
<string name="tag_EOE_button">Add Tags</string>
|
||||||
|
<string name="tag_EOE_button_w_tags">Tags: %s</string>
|
||||||
|
|
||||||
|
<string name="tag_TLA_detail">Tags: %s</string>
|
||||||
|
|
||||||
|
<string name="tag_FEx_header">Tags</string>
|
||||||
|
<string name="tag_FEx_by_size">By Size</string>
|
||||||
|
<string name="tag_FEx_alpha">Alphabetical</string>
|
||||||
|
|
||||||
|
<!-- $T => tag, $C => count -->
|
||||||
|
<string name="tag_FEx_tag_w_size">$T ($C)</string>
|
||||||
|
<!-- %s => tag name -->
|
||||||
|
<string name="tag_FEx_name">Tagged \'%s\'</string>
|
||||||
|
|
||||||
|
<string name="tag_TEA_hint">Type In a Tag</string>
|
||||||
|
<string name="tag_TEA_title">Edit Tags</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
Loading…
Reference in New Issue