You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/app/src/main/java/com/todoroo/astrid/api/Filter.java

248 lines
6.5 KiB
Java

/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.MenuRes;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.QueryTemplate;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 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 {
/** Parcelable Creator Object */
public static final Parcelable.Creator<Filter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public Filter createFromParcel(Parcel source) {
Filter item = new Filter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public Filter[] newArray(int size) {
return new Filter[size];
}
};
/**
* 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 final Map<String, Object> valuesForNewTasks = new HashMap<>();
/**
* {@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>
*/
public 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.
*/
private String filterOverride;
public Filter(String listingTitle, QueryTemplate sqlQuery) {
this(listingTitle, sqlQuery, Collections.emptyMap());
}
/**
* Utility constructor for creating a Filter object
*
* @param listingTitle Title of this item as displayed on the lists page, e.g. Inbox
* @param sqlQuery SQL query for this list (see {@link #sqlQuery} for examples).
*/
protected Filter(
String listingTitle, QueryTemplate sqlQuery, Map<String, Object> valuesForNewTasks) {
this(listingTitle, 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 sqlQuery SQL query for this list (see {@link #sqlQuery} for examples).
*/
Filter(String listingTitle, String sqlQuery, Map<String, Object> valuesForNewTasks) {
this.listingTitle = listingTitle;
this.sqlQuery = sqlQuery;
this.filterOverride = null;
if (valuesForNewTasks != null) {
this.valuesForNewTasks.putAll(valuesForNewTasks);
}
}
protected Filter() {}
public String getOriginalSqlQuery() {
return sqlQuery;
}
public String getSqlQuery() {
if (filterOverride != null) {
return filterOverride;
}
return sqlQuery;
}
// --- parcelable
public void setFilterQueryOverride(String filterOverride) {
this.filterOverride = filterOverride;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((sqlQuery == null) ? 0 : sqlQuery.hashCode());
result = prime * result + ((listingTitle == null) ? 0 : listingTitle.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 (listingTitle == null) {
return other.listingTitle == null;
} else return listingTitle.equals(other.listingTitle);
}
@Override
public Type getItemType() {
return Type.ITEM;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(""); // old title
dest.writeString(sqlQuery);
dest.writeMap(valuesForNewTasks);
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
source.readString(); // old title
sqlQuery = source.readString();
source.readMap(valuesForNewTasks, getClass().getClassLoader());
}
public boolean supportsAstridSorting() {
return false;
}
public boolean supportsManualSort() {
return false;
}
public boolean supportsHiddenTasks() {
return true;
}
public boolean supportsSubtasks() {
return true;
}
public boolean supportsSorting() {
return true;
}
public boolean isWritable() {
return !isReadOnly();
}
public boolean isReadOnly() {
return false;
}
public boolean hasBeginningMenu() {
return getBeginningMenu() != 0;
}
public @MenuRes int getBeginningMenu() {
return 0;
}
public boolean hasMenu() {
return getMenu() != 0;
}
public @MenuRes int getMenu() {
return 0;
}
@Override
public String toString() {
return "Filter{"
+ "sqlQuery='"
+ sqlQuery
+ '\''
+ ", filterOverride='"
+ filterOverride
+ '\''
+ ", valuesForNewTasks="
+ valuesForNewTasks
+ '}';
}
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof Filter && Objects.equals(sqlQuery, ((Filter) other).sqlQuery);
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other)
&& Objects.equals(sqlQuery, ((Filter) other).sqlQuery);
}
}