/** * Copyright (c) 2012 Todoroo Inc * * See the file "LICENSE" for the full license governing this code. */ package com.todoroo.astrid.api; import android.content.ContentValues; import android.os.Parcel; import android.os.Parcelable; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.QueryTemplate; /** * A <code>FilterListFilter</code> allows users to display tasks that have * something in common. * <p> * A plug-in can expose new <code>FilterListFilter</code>s to the system by * responding to the <code>com.todoroo.astrid.GET_FILTERS</code> broadcast * intent. * * @author Tim Su <tim@todoroo.com> * */ public class Filter extends FilterListItem { // --- constants /** Constant for valuesForNewTasks to indicate the value should be replaced * with the current time as long */ public static final long VALUE_NOW = Long.MIN_VALUE + 1; // --- instance variables /** * Expanded title of this filter. This is displayed at the top * of the screen when user is viewing this filter. * <p> * e.g "Tasks With Notes" */ public String title; /** * {@link PermaSql} query for this filter. The query will be appended to the select * statement after "<code>SELECT fields FROM table %s</code>". It is * recommended that you use a {@link QueryTemplate} to construct your * query. * <p> * Examples: * <ul> * <li><code>"WHERE completionDate = 0"</code> * <li><code>"INNER JOIN " + * Constants.TABLE_METADATA + " ON metadata.task = tasks.id WHERE * metadata.namespace = " + NAMESPACE + " AND metadata.key = 'a' AND * metadata.value = 'b' GROUP BY tasks.id ORDER BY tasks.title"</code> * </ul> */ protected String sqlQuery; /** * Field for holding a modified sqlQuery based on sqlQuery. Useful for adjusting * query for sort/subtasks without breaking the equality checking based on sqlQuery. */ protected String filterOverride; /** * Values to apply to a task when quick-adding a task from this filter. * For example, when a user views tasks tagged 'ABC', the * tasks they create should also be tagged 'ABC'. If set to null, no * additional values will be stored for a task. Can use {@link PermaSql} */ public ContentValues valuesForNewTasks = null; /** * Utility constructor for creating a Filter object * @param listingTitle * Title of this item as displayed on the lists page, e.g. Inbox * @param title * Expanded title of this filter when user is viewing this * filter, e.g. Inbox (20 tasks) * @param sqlQuery * SQL query for this list (see {@link #sqlQuery} for examples). * @param valuesForNewTasks * see {@link #sqlForNewTasks} */ public Filter(String listingTitle, String title, QueryTemplate sqlQuery, ContentValues valuesForNewTasks) { this(listingTitle, title, sqlQuery == null ? null : sqlQuery.toString(), valuesForNewTasks); } /** * Utility constructor for creating a Filter object * @param listingTitle * Title of this item as displayed on the lists page, e.g. Inbox * @param title * Expanded title of this filter when user is viewing this * filter, e.g. Inbox (20 tasks) * @param sqlQuery * SQL query for this list (see {@link #sqlQuery} for examples). * @param valuesForNewTasks * see {@link #sqlForNewTasks} */ public Filter(String listingTitle, String title, String sqlQuery, ContentValues valuesForNewTasks) { this.listingTitle = listingTitle; this.title = title; this.sqlQuery = sqlQuery; this.filterOverride = null; this.valuesForNewTasks = valuesForNewTasks; } public String getSqlQuery() { if (filterOverride != null) return filterOverride; return sqlQuery; } public void setSqlQuery(String sqlQuery) { this.sqlQuery = sqlQuery; } public void setFilterQueryOverride(String filterOverride) { this.filterOverride = filterOverride; } /** * Utility constructor * * @param plugin * {@link Addon} identifier that encompasses object */ protected Filter() { // do nothing } // --- parcelable /** * {@inheritDoc} */ public int describeContents() { return 0; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((sqlQuery == null) ? 0 : sqlQuery.hashCode()); result = prime * result + ((title == null) ? 0 : title.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Filter other = (Filter) obj; if (sqlQuery == null) { if (other.sqlQuery != null) return false; } else if (!sqlQuery.equals(other.sqlQuery)) return false; if (title == null) { if (other.title != null) return false; } else if (!title.equals(other.title)) return false; return true; } /** * {@inheritDoc} */ @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(title); dest.writeString(sqlQuery); dest.writeParcelable(valuesForNewTasks, 0); } @Override public void readFromParcel(Parcel source) { super.readFromParcel(source); title = source.readString(); sqlQuery = source.readString(); valuesForNewTasks = source.readParcelable(ContentValues.class.getClassLoader()); } /** * Parcelable Creator Object */ public static final Parcelable.Creator<Filter> CREATOR = new Parcelable.Creator<Filter>() { /** * {@inheritDoc} */ public Filter createFromParcel(Parcel source) { Filter item = new Filter(); item.readFromParcel(source); return item; } /** * {@inheritDoc} */ public Filter[] newArray(int size) { return new Filter[size]; } }; /** * @param title * @return a filter that matches nothing */ public static Filter emptyFilter(String title) { return new Filter(title, title, new QueryTemplate().where(Criterion.none), null); } }