Convert FilterListItems to Kotlin

pull/2549/head
Alex Baker 8 months ago
parent 6664defc16
commit bf6fe02fe3

@ -2,7 +2,7 @@ package com.todoroo.andlib.data
import com.todoroo.andlib.sql.Field
class Property internal constructor(val name: String?, expression: String) : Field(expression) {
class Property internal constructor(val name: String, expression: String) : Field(expression) {
constructor(table: Table, columnName: String) : this(columnName, "${table.name()}.$columnName")
}

@ -1,122 +0,0 @@
package com.todoroo.astrid.api;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.data.Task;
import org.tasks.R;
import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavTask;
import org.tasks.data.TaskDao;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class CaldavFilter extends Filter {
/** Parcelable Creator Object */
public static final Parcelable.Creator<CaldavFilter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public CaldavFilter createFromParcel(Parcel source) {
CaldavFilter item = new CaldavFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public CaldavFilter[] newArray(int size) {
return new CaldavFilter[size];
}
};
private CaldavCalendar calendar;
private CaldavFilter() {
super();
}
public CaldavFilter(CaldavCalendar calendar) {
super(calendar.getName(), queryTemplate(calendar), getValuesForNewTask(calendar));
this.calendar = calendar;
id = calendar.getId();
tint = calendar.getColor();
icon = calendar.getIcon();
order = calendar.getOrder();
}
private static QueryTemplate queryTemplate(CaldavCalendar caldavCalendar) {
return new QueryTemplate()
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(getCriterion(caldavCalendar));
}
private static Criterion getCriterion(CaldavCalendar caldavCalendar) {
return Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
CaldavTask.DELETED.eq(0),
CaldavTask.CALENDAR.eq(caldavCalendar.getUuid()));
}
private static Map<String, Object> getValuesForNewTask(CaldavCalendar caldavCalendar) {
Map<String, Object> result = new HashMap<>();
result.put(CaldavTask.KEY, caldavCalendar.getUuid());
return result;
}
public String getUuid() {
return calendar.getUuid();
}
public String getAccount() {
return calendar.getAccount();
}
public CaldavCalendar getCalendar() {
return calendar;
}
@Override
public boolean isReadOnly() {
return calendar.getAccess() == CaldavCalendar.ACCESS_READ_ONLY;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(calendar, 0);
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
calendar = source.readParcelable(getClass().getClassLoader());
}
@Override
public boolean supportsManualSort() {
return true;
}
@Override
public int getMenu() {
return R.menu.menu_caldav_list_fragment;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other)
&& Objects.equals(calendar, ((CaldavFilter) other).calendar);
}
}

@ -0,0 +1,81 @@
package com.todoroo.astrid.api
import android.os.Parcel
import android.os.Parcelable
import androidx.core.os.ParcelCompat
import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Join.Companion.left
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavTask
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
class CaldavFilter(
val calendar: CaldavCalendar
) : Filter(calendar.name, queryTemplate(calendar), getValuesForNewTask(calendar)) {
init {
id = calendar.id
tint = calendar.color
icon = calendar.getIcon()!!
order = calendar.order
}
val uuid: String
get() = calendar.uuid!!
val account: String
get() = calendar.account!!
override val isReadOnly: Boolean
get() = calendar.access == CaldavCalendar.ACCESS_READ_ONLY
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeParcelable(calendar, 0)
}
override fun supportsManualSort() = true
override val menu = R.menu.menu_caldav_list_fragment
override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && calendar == (other as CaldavFilter).calendar
}
companion object {
@JvmField
val CREATOR = object : Parcelable.Creator<CaldavFilter> {
override fun createFromParcel(source: Parcel): CaldavFilter {
return CaldavFilter(
ParcelCompat.readParcelable(source, javaClass.classLoader, CaldavCalendar::class.java)!!
)
}
override fun newArray(size: Int): Array<CaldavFilter?> {
return arrayOfNulls(size)
}
}
private fun queryTemplate(caldavCalendar: CaldavCalendar): QueryTemplate {
return QueryTemplate()
.join(left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(getCriterion(caldavCalendar))
}
private fun getCriterion(caldavCalendar: CaldavCalendar): Criterion {
return and(
activeAndVisible(),
CaldavTask.DELETED.eq(0),
CaldavTask.CALENDAR.eq(caldavCalendar.uuid)
)
}
private fun getValuesForNewTask(caldavCalendar: CaldavCalendar): Map<String, Any> {
val result: MutableMap<String, Any> = HashMap()
result[CaldavTask.KEY] = caldavCalendar.uuid!!
return result
}
}
}

@ -1,73 +0,0 @@
package com.todoroo.astrid.api;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import org.tasks.R;
import java.util.Objects;
public class CustomFilter extends Filter {
/** Parcelable Creator Object */
public static final Parcelable.Creator<CustomFilter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public CustomFilter createFromParcel(Parcel source) {
return new CustomFilter(source);
}
/** {@inheritDoc} */
@Override
public CustomFilter[] newArray(int size) {
return new CustomFilter[size];
}
};
private String criterion;
public CustomFilter(@NonNull org.tasks.data.Filter filter) {
super(filter.getTitle(), filter.getSql(), filter.getValuesAsMap());
id = filter.getId();
criterion = filter.getCriterion();
tint = filter.getColor();
icon = filter.getIcon();
order = filter.getOrder();
}
private CustomFilter(Parcel parcel) {
readFromParcel(parcel);
}
public String getCriterion() {
return criterion;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(criterion);
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
criterion = source.readString();
}
@Override
public int getMenu() {
return getId() > 0 ? R.menu.menu_custom_filter : 0;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other)
&& Objects.equals(criterion, ((CustomFilter) other).criterion);
}
}

@ -0,0 +1,57 @@
package com.todoroo.astrid.api
import android.os.Parcel
import android.os.Parcelable
import org.tasks.R
class CustomFilter : Filter {
var criterion: String? = null
private set
constructor(filter: org.tasks.data.Filter) : super(
filter.title,
filter.getSql(),
filter.valuesAsMap
) {
id = filter.id
criterion = filter.criterion
tint = filter.getColor()!!
icon = filter.getIcon()!!
order = filter.order
}
private constructor(parcel: Parcel) {
readFromParcel(parcel)
}
/** {@inheritDoc} */
override fun writeToParcel(dest: Parcel, flags: Int) {
super.writeToParcel(dest, flags)
dest.writeString(criterion)
}
override fun readFromParcel(source: Parcel) {
super.readFromParcel(source)
criterion = source.readString()
}
override val menu: Int
get() = if (getId() > 0) R.menu.menu_custom_filter else 0
override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && criterion == (other as CustomFilter).criterion
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<CustomFilter> = object : Parcelable.Creator<CustomFilter> {
override fun createFromParcel(source: Parcel): CustomFilter? {
return CustomFilter(source)
}
override fun newArray(size: Int): Array<CustomFilter?> {
return arrayOfNulls(size)
}
}
}
}

@ -1,247 +0,0 @@
/*
* 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);
}
}

@ -0,0 +1,213 @@
package com.todoroo.astrid.api
import android.os.Parcel
import android.os.Parcelable
import androidx.annotation.MenuRes
import com.todoroo.andlib.sql.QueryTemplate
open class Filter : FilterListItem {
/**
* 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 [PermaSql]
*/
val valuesForNewTasks: MutableMap<String, Any> = HashMap()
/**
* [PermaSql] query for this filter. The query will be appended to the select statement
* after "`SELECT fields FROM table %s`". It is recommended that you use a [ ] to construct your query.
*
*
* Examples:
*
*
* * `"WHERE completionDate = 0"`
* * `"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"`
*
*/
var originalSqlQuery: String? = null
/**
* 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 var filterOverride: String? = null
constructor(listingTitle: String?, sqlQuery: QueryTemplate?) : this(
listingTitle,
sqlQuery,
emptyMap<String, Any>()
)
/**
* 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 [.sqlQuery] for examples).
*/
protected constructor(
listingTitle: String?, sqlQuery: QueryTemplate?, valuesForNewTasks: Map<String, Any>?
) : this(listingTitle, 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 [.sqlQuery] for examples).
*/
internal constructor(
listingTitle: String?,
sqlQuery: String?,
valuesForNewTasks: Map<String, Any>?
) {
this.listingTitle = listingTitle
originalSqlQuery = sqlQuery
filterOverride = null
if (valuesForNewTasks != null) {
this.valuesForNewTasks.putAll(valuesForNewTasks)
}
}
protected constructor()
fun getSqlQuery(): String {
return filterOverride ?: originalSqlQuery!!
}
// --- parcelable
fun setFilterQueryOverride(filterOverride: String?) {
this.filterOverride = filterOverride
}
override fun hashCode(): Int {
val prime = 31
var result = 1
result = prime * result + if (originalSqlQuery == null) 0 else originalSqlQuery.hashCode()
result = prime * result + if (listingTitle == null) 0 else listingTitle.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null) {
return false
}
if (javaClass != other.javaClass) {
return false
}
val filter = other as Filter
if (originalSqlQuery == null) {
if (filter.originalSqlQuery != null) {
return false
}
} else if (originalSqlQuery != filter.originalSqlQuery) {
return false
}
return if (listingTitle == null) {
filter.listingTitle == null
} else listingTitle == filter.listingTitle
}
override fun getItemType(): Type {
return Type.ITEM
}
/** {@inheritDoc} */
override fun writeToParcel(dest: Parcel, flags: Int) {
super.writeToParcel(dest, flags)
dest.writeString("") // old title
dest.writeString(originalSqlQuery)
dest.writeMap(valuesForNewTasks)
}
override fun readFromParcel(source: Parcel) {
super.readFromParcel(source)
source.readString() // old title
originalSqlQuery = source.readString()
source.readMap(valuesForNewTasks, javaClass.classLoader)
}
open fun supportsAstridSorting(): Boolean {
return false
}
open fun supportsManualSort(): Boolean {
return false
}
open fun supportsHiddenTasks(): Boolean {
return true
}
open fun supportsSubtasks(): Boolean {
return true
}
open fun supportsSorting(): Boolean {
return true
}
val isWritable: Boolean
get() = !isReadOnly
open val isReadOnly: Boolean
get() = false
fun hasBeginningMenu(): Boolean {
return beginningMenu != 0
}
@get:MenuRes
open val beginningMenu: Int
get() = 0
fun hasMenu(): Boolean {
return menu != 0
}
@get:MenuRes
open val menu: Int
get() = 0
override fun toString(): String {
return ("Filter{"
+ "sqlQuery='"
+ originalSqlQuery
+ '\''
+ ", filterOverride='"
+ filterOverride
+ '\''
+ ", valuesForNewTasks="
+ valuesForNewTasks
+ '}')
}
override fun areItemsTheSame(other: FilterListItem): Boolean {
return other is Filter && originalSqlQuery == other.originalSqlQuery
}
override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && originalSqlQuery == (other as Filter).originalSqlQuery
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<Filter> = object : Parcelable.Creator<Filter> {
/** {@inheritDoc} */
override fun createFromParcel(source: Parcel): Filter {
val item = Filter()
item.readFromParcel(source)
return item
}
/** {@inheritDoc} */
override fun newArray(size: Int): Array<Filter?> {
return arrayOfNulls(size)
}
}
}
}

@ -1,114 +0,0 @@
package com.todoroo.astrid.api;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.data.Task;
import org.tasks.R;
import org.tasks.data.CaldavCalendar;
import org.tasks.data.CaldavTask;
import org.tasks.data.GoogleTask;
import org.tasks.data.TaskDao;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class GtasksFilter extends Filter {
/** Parcelable Creator Object */
public static final Parcelable.Creator<GtasksFilter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public GtasksFilter createFromParcel(Parcel source) {
GtasksFilter item = new GtasksFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public GtasksFilter[] newArray(int size) {
return new GtasksFilter[size];
}
};
private CaldavCalendar list;
private GtasksFilter() {
super();
}
public GtasksFilter(CaldavCalendar list) {
super(list.getName(), getQueryTemplate(list), getValuesForNewTasks(list));
this.list = list;
id = list.getId();
tint = list.getColor();
icon = list.getIcon();
order = list.getOrder();
}
private static QueryTemplate getQueryTemplate(CaldavCalendar list) {
return new QueryTemplate()
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(
Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
CaldavTask.DELETED.eq(0),
CaldavTask.CALENDAR.eq(list.getUuid())));
}
private static Map<String, Object> getValuesForNewTasks(CaldavCalendar list) {
Map<String, Object> values = new HashMap<>();
values.put(GoogleTask.KEY, list.getUuid());
return values;
}
public String getAccount() {
return list.getAccount();
}
public CaldavCalendar getList() {
return list;
}
@Override
public boolean supportsManualSort() {
return true;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(list, 0);
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
list = source.readParcelable(getClass().getClassLoader());
}
public String getRemoteId() {
return list.getUuid();
}
@Override
public int getMenu() {
return R.menu.menu_gtasks_list_fragment;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other) && Objects.equals(list, ((GtasksFilter) other).list);
}
}

@ -0,0 +1,77 @@
package com.todoroo.astrid.api
import android.os.Parcel
import android.os.Parcelable
import androidx.core.os.ParcelCompat
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Join.Companion.left
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavTask
import org.tasks.data.GoogleTask
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
class GtasksFilter(
val list: CaldavCalendar
) : Filter(list.name, getQueryTemplate(list), getValuesForNewTasks(list)) {
init {
id = list.id
tint = list.color
icon = list.getIcon()!!
order = list.order
}
val account: String
get() = list.account!!
override fun supportsManualSort() = true
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeParcelable(list, 0)
}
val remoteId: String
get() = list.uuid!!
override val menu = R.menu.menu_gtasks_list_fragment
override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && list == (other as GtasksFilter).list
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<GtasksFilter> = object : Parcelable.Creator<GtasksFilter> {
override fun createFromParcel(source: Parcel): GtasksFilter {
return GtasksFilter(
ParcelCompat.readParcelable(source, javaClass.classLoader, CaldavCalendar::class.java)!!
)
}
override fun newArray(size: Int): Array<GtasksFilter?> {
return arrayOfNulls(size)
}
}
private fun getQueryTemplate(list: CaldavCalendar): QueryTemplate {
return QueryTemplate()
.join(left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(
and(
activeAndVisible(),
CaldavTask.DELETED.eq(0),
CaldavTask.CALENDAR.eq(list.uuid)
)
)
}
private fun getValuesForNewTasks(list: CaldavCalendar): Map<String, Any> {
val values: MutableMap<String, Any> = HashMap()
values[GoogleTask.KEY] = list.uuid!!
return values
}
}
}

@ -1,104 +0,0 @@
package com.todoroo.astrid.api;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.data.Task;
import org.tasks.R;
import org.tasks.data.Tag;
import org.tasks.data.TagData;
import org.tasks.data.TaskDao;
import java.util.HashMap;
import java.util.Map;
public class TagFilter extends Filter {
/** Parcelable Creator Object */
public static final Parcelable.Creator<TagFilter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public TagFilter createFromParcel(Parcel source) {
TagFilter item = new TagFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public TagFilter[] newArray(int size) {
return new TagFilter[size];
}
};
private TagData tagData;
private TagFilter() {
super();
}
public TagFilter(TagData tagData) {
super(tagData.getName(), queryTemplate(tagData.getRemoteId()), getValuesForNewTask(tagData));
this.tagData = tagData;
id = tagData.getId();
tint = tagData.getColor();
icon = tagData.getIcon();
order = tagData.getOrder();
}
private static QueryTemplate queryTemplate(String uuid) {
return new QueryTemplate()
.join(Join.inner(Tag.TABLE, Task.ID.eq(Tag.TASK)))
.where(Criterion.and(Tag.TAG_UID.eq(uuid), TaskDao.TaskCriteria.activeAndVisible()));
}
private static Map<String, Object> getValuesForNewTask(TagData tagData) {
Map<String, Object> values = new HashMap<>();
values.put(Tag.KEY, tagData.getName());
return values;
}
public String getUuid() {
return tagData.getRemoteId();
}
public TagData getTagData() {
return tagData;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(tagData, 0);
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
tagData = source.readParcelable(getClass().getClassLoader());
}
@Override
public boolean supportsAstridSorting() {
return true;
}
@Override
public int getMenu() {
return R.menu.menu_tag_view_fragment;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return tagData.equals(((TagFilter) other).tagData);
}
}

@ -0,0 +1,67 @@
package com.todoroo.astrid.api
import android.os.Parcel
import android.os.Parcelable
import androidx.core.os.ParcelCompat
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Join.Companion.inner
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.data.Tag
import org.tasks.data.TagData
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
class TagFilter(
val tagData: TagData
) : Filter(tagData.name, queryTemplate(tagData.remoteId), getValuesForNewTask(tagData)) {
init {
id = tagData.id!!
tint = tagData.getColor()!!
icon = tagData.getIcon()!!
order = tagData.order
}
val uuid: String
get() = tagData.remoteId!!
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeParcelable(tagData, 0)
}
override fun supportsAstridSorting() = true
override val menu = R.menu.menu_tag_view_fragment
override fun areContentsTheSame(other: FilterListItem): Boolean {
return tagData == (other as TagFilter).tagData
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<TagFilter> = object : Parcelable.Creator<TagFilter> {
override fun createFromParcel(source: Parcel): TagFilter {
return TagFilter(
ParcelCompat.readParcelable(source, javaClass.classLoader, TagData::class.java)!!
)
}
override fun newArray(size: Int): Array<TagFilter?> {
return arrayOfNulls(size)
}
}
private fun queryTemplate(uuid: String?): QueryTemplate {
return QueryTemplate()
.join(inner(Tag.TABLE, Task.ID.eq(Tag.TASK)))
.where(and(Tag.TAG_UID.eq(uuid), activeAndVisible()))
}
private fun getValuesForNewTask(tagData: TagData): Map<String, Any> {
val values: MutableMap<String, Any> = HashMap()
values[Tag.KEY] = tagData.name!!
return values
}
}
}

@ -87,7 +87,7 @@ class BuiltInFilterExposer @Inject constructor(
fun getTodayFilter(r: Resources): Filter {
val todayTitle = AndroidUtilities.capitalize(r.getString(R.string.today))
val todayValues: MutableMap<String?, Any> = HashMap()
val todayValues: MutableMap<String, Any> = HashMap()
todayValues[Task.DUE_DATE.name] = PermaSql.VALUE_NOON
return SortableFilter(
todayTitle,

@ -45,7 +45,7 @@ class TaskDeleter @Inject constructor(
suspend fun clearCompleted(filter: Filter): Int {
val deleteFilter = Filter(null, null)
deleteFilter.setFilterQueryOverride(
QueryUtils.removeOrder(QueryUtils.showHiddenAndCompleted(filter.originalSqlQuery)))
QueryUtils.removeOrder(QueryUtils.showHiddenAndCompleted(filter.originalSqlQuery!!)))
val completed = taskDao.fetchTasks(preferences, deleteFilter)
.filter(TaskContainer::isCompleted)
.filterNot(TaskContainer::isReadOnly)

@ -38,25 +38,25 @@ class TaskMover @Inject constructor(
val googleTaskLists = googleTaskDao.getLists(tasks)
if (caldavCalendars.isEmpty()) {
if (googleTaskLists.size == 1) {
return GtasksFilter(googleTaskListDao.getByRemoteId(googleTaskLists[0]))
return googleTaskListDao.getByRemoteId(googleTaskLists[0])?.let { GtasksFilter(it) }
}
} else if (googleTaskLists.isEmpty()) {
if (caldavCalendars.size == 1) {
return CaldavFilter(caldavDao.getCalendar(caldavCalendars[0]))
return caldavDao.getCalendar(caldavCalendars[0])?.let { CaldavFilter(it) }
}
}
return null
}
suspend fun move(task: Long, list: Long) {
val list = caldavDao.getCalendarById(list) ?: return
val account = list.account?.let { caldavDao.getAccountByUuid(it) } ?: return
val calendar = caldavDao.getCalendarById(list) ?: return
val account = calendar.account?.let { caldavDao.getAccountByUuid(it) } ?: return
move(
ids = listOf(task),
selectedList = if (account.accountType == CaldavAccount.TYPE_GOOGLE_TASKS)
GtasksFilter(list)
GtasksFilter(calendar)
else
CaldavFilter(list))
CaldavFilter(calendar))
}
suspend fun move(ids: List<Long>, selectedList: Filter) {

@ -274,7 +274,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
} else newName != filter!!.listingTitle
|| selectedColor != filter!!.tint
|| selectedIcon != filter!!.icon
|| CriterionInstance.serialize(criteria) != filter!!.criterion.trim()
|| CriterionInstance.serialize(criteria) != filter!!.criterion!!.trim()
|| criteria.values != filter!!.valuesForNewTasks
|| criteria.sql != filter!!.originalSqlQuery
}

@ -181,7 +181,7 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() {
setResult(
Activity.RESULT_OK,
Intent(TaskListFragment.ACTION_RELOAD)
.putExtra(MainActivity.OPEN_FILTER, CaldavFilter(caldavCalendar)))
.putExtra(MainActivity.OPEN_FILTER, CaldavFilter(caldavCalendar!!)))
finish()
}

@ -1,6 +1,11 @@
package org.tasks.data
import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.RawQuery
import androidx.room.Update
import androidx.room.withTransaction
import androidx.sqlite.db.SimpleSQLiteQuery
import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Field
@ -210,7 +215,7 @@ FROM recursive_tasks
}
suspend fun count(filter: Filter): Int {
val query = getQuery(filter.sqlQuery, Field.COUNT)
val query = getQuery(filter.originalSqlQuery!!, Field.COUNT)
val start = if (BuildConfig.DEBUG) now() else 0
val count = count(query)
Timber.v("%sms: %s", now() - start, query.sql)

@ -1,114 +0,0 @@
package org.tasks.filters;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.data.Table;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.data.Task;
import org.tasks.R;
import org.tasks.data.Geofence;
import org.tasks.data.Place;
import org.tasks.data.TaskDao;
import org.tasks.themes.CustomIcons;
import java.util.HashMap;
import java.util.Map;
public class PlaceFilter extends Filter {
public static final Parcelable.Creator<PlaceFilter> CREATOR =
new Parcelable.Creator<>() {
@Override
public PlaceFilter createFromParcel(Parcel source) {
return new PlaceFilter(source);
}
/** {@inheritDoc} */
@Override
public PlaceFilter[] newArray(int size) {
return new PlaceFilter[size];
}
};
private final Place place;
private static final Table G2 = Geofence.TABLE.as("G2");
private static final Field G2_PLACE = Field.field("G2.place");
private static final Field G2_TASK = Field.field("G2.task");
private static final Table P2 = Place.TABLE.as("P2");
private static final Field P2_UID = Field.field("P2.uid");
private PlaceFilter(Parcel source) {
super();
readFromParcel(source);
place = source.readParcelable(getClass().getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(place, 0);
}
public PlaceFilter(Place place) {
super(place.getDisplayName(), queryTemplate(place), getValuesForNewTask(place));
this.place = place;
id = place.getId();
tint = place.getColor();
icon = place.getIcon();
if (icon == -1) {
icon = CustomIcons.PLACE;
}
order = place.getOrder();
}
public Place getPlace() {
return place;
}
public String getUid() {
return place.getUid();
}
private static QueryTemplate queryTemplate(Place place) {
return new QueryTemplate()
.join(Join.inner(G2, Task.ID.eq(G2_TASK)))
.join(Join.inner(P2, P2_UID.eq(G2_PLACE)))
.where(Criterion.and(TaskDao.TaskCriteria.activeAndVisible(), G2_PLACE.eq(place.getUid())));
}
private static Map<String, Object> getValuesForNewTask(Place place) {
Map<String, Object> result = new HashMap<>();
result.put(Place.KEY, place.getUid());
return result;
}
@Override
public int getBeginningMenu() {
return R.menu.menu_location_actions;
}
@Override
public int getMenu() {
return R.menu.menu_location_list_fragment;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return place.equals(((PlaceFilter) other).getPlace()) && count == other.count;
}
public void openMap(Context context) {
place.open(context);
}
}

@ -0,0 +1,85 @@
package org.tasks.filters
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import androidx.core.os.ParcelCompat
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Field.Companion.field
import com.todoroo.andlib.sql.Join.Companion.inner
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.data.Geofence
import org.tasks.data.Place
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import org.tasks.themes.CustomIcons
class PlaceFilter(
val place: Place
) : Filter(place.displayName, queryTemplate(place), getValuesForNewTask(place)) {
init {
id = place.id
tint = place.color
icon = place.icon
if (icon == -1) {
icon = CustomIcons.PLACE
}
order = place.order
}
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeParcelable(place, 0)
}
val uid: String
get() = place.uid!!
override val beginningMenu = R.menu.menu_location_actions
override val menu = R.menu.menu_location_list_fragment
override fun areContentsTheSame(other: FilterListItem): Boolean {
return place == (other as PlaceFilter).place && count == other.count
}
fun openMap(context: Context?) {
place.open(context)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<PlaceFilter> = object : Parcelable.Creator<PlaceFilter> {
override fun createFromParcel(source: Parcel): PlaceFilter {
return PlaceFilter(
ParcelCompat.readParcelable(source, javaClass.classLoader, Place::class.java)!!
)
}
/** {@inheritDoc} */
override fun newArray(size: Int): Array<PlaceFilter?> {
return arrayOfNulls(size)
}
}
private val G2 = Geofence.TABLE.`as`("G2")
private val G2_PLACE = field("G2.place")
private val G2_TASK = field("G2.task")
private val P2 = Place.TABLE.`as`("P2")
private val P2_UID = field("P2.uid")
private fun queryTemplate(place: Place): QueryTemplate {
return QueryTemplate()
.join(inner(G2, Task.ID.eq(G2_TASK)))
.join(inner(P2, P2_UID.eq(G2_PLACE)))
.where(and(activeAndVisible(), G2_PLACE.eq(place.uid)))
}
private fun getValuesForNewTask(place: Place): Map<String, Any> {
val result: MutableMap<String, Any> = HashMap()
result[Place.KEY] = place.uid!!
return result
}
}
}

@ -1,62 +0,0 @@
package org.tasks.filters;
import android.os.Parcel;
import android.os.Parcelable;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.data.Task;
import org.tasks.time.DateTime;
public class RecentlyModifiedFilter extends Filter {
public static final Parcelable.Creator<RecentlyModifiedFilter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public RecentlyModifiedFilter createFromParcel(Parcel source) {
RecentlyModifiedFilter item = new RecentlyModifiedFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public RecentlyModifiedFilter[] newArray(int size) {
return new RecentlyModifiedFilter[size];
}
};
public RecentlyModifiedFilter(String listingTitle) {
super(listingTitle, getQueryTemplate());
}
private RecentlyModifiedFilter() {}
private static QueryTemplate getQueryTemplate() {
return new QueryTemplate()
.where(
Criterion.and(
Task.DELETION_DATE.lte(0),
Task.MODIFICATION_DATE.gt(
new DateTime().minusDays(1).startOfMinute().getMillis())))
.orderBy(Order.desc(Task.MODIFICATION_DATE));
}
@Override
public boolean supportsHiddenTasks() {
return false;
}
@Override
public boolean supportsSubtasks() {
return false;
}
@Override
public boolean supportsSorting() {
return false;
}
}

@ -0,0 +1,48 @@
package org.tasks.filters
import android.os.Parcel
import android.os.Parcelable
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Order.Companion.desc
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.data.Task
import org.tasks.time.DateTime
class RecentlyModifiedFilter : Filter {
constructor(listingTitle: String?) : super(listingTitle, queryTemplate)
private constructor()
override fun supportsHiddenTasks() = false
override fun supportsSubtasks() = false
override fun supportsSorting() = false
companion object {
@JvmField
val CREATOR: Parcelable.Creator<RecentlyModifiedFilter> =
object : Parcelable.Creator<RecentlyModifiedFilter> {
override fun createFromParcel(source: Parcel): RecentlyModifiedFilter? {
val item = RecentlyModifiedFilter()
item.readFromParcel(source)
return item
}
override fun newArray(size: Int): Array<RecentlyModifiedFilter?> {
return arrayOfNulls(size)
}
}
private val queryTemplate: QueryTemplate
get() = QueryTemplate()
.where(
and(
Task.DELETION_DATE.lte(0),
Task.MODIFICATION_DATE.gt(
DateTime().minusDays(1).startOfMinute().millis
)
)
)
.orderBy(desc(Task.MODIFICATION_DATE))
}
}

@ -1,51 +0,0 @@
package org.tasks.filters;
import static org.tasks.data.Alarm.TYPE_SNOOZE;
import android.os.Parcel;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.data.Task;
import org.tasks.data.Alarm;
public class SnoozedFilter extends Filter {
public static final Creator<SnoozedFilter> CREATOR =
new Creator<>() {
/** {@inheritDoc} */
@Override
public SnoozedFilter createFromParcel(Parcel source) {
SnoozedFilter item = new SnoozedFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public SnoozedFilter[] newArray(int size) {
return new SnoozedFilter[size];
}
};
public SnoozedFilter(String listingTitle) {
super(listingTitle, getQueryTemplate());
}
private SnoozedFilter() {}
private static QueryTemplate getQueryTemplate() {
return new QueryTemplate()
.join(Join.inner(Alarm.TABLE, Task.ID.eq(Alarm.TASK)))
.where(Criterion.and(Task.DELETION_DATE.lte(0), Alarm.TYPE.eq(TYPE_SNOOZE)));
}
@Override
public boolean supportsHiddenTasks() {
return false;
}
}

@ -0,0 +1,39 @@
package org.tasks.filters
import android.os.Parcel
import android.os.Parcelable
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Join.Companion.inner
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.data.Task
import org.tasks.data.Alarm
class SnoozedFilter : Filter {
constructor(listingTitle: String?) : super(listingTitle, queryTemplate)
private constructor()
override fun supportsHiddenTasks(): Boolean {
return false
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<SnoozedFilter> =
object : Parcelable.Creator<SnoozedFilter> {
override fun createFromParcel(source: Parcel): SnoozedFilter {
val item = SnoozedFilter()
item.readFromParcel(source)
return item
}
override fun newArray(size: Int): Array<SnoozedFilter?> {
return arrayOfNulls(size)
}
}
private val queryTemplate: QueryTemplate
get() = QueryTemplate()
.join(inner(Alarm.TABLE, Task.ID.eq(Alarm.TASK)))
.where(and(Task.DELETION_DATE.lte(0), Alarm.TYPE.eq(Alarm.TYPE_SNOOZE)))
}
}

@ -1,44 +0,0 @@
package org.tasks.filters;
import android.os.Parcel;
import android.os.Parcelable;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.api.Filter;
import java.util.Map;
public class SortableFilter extends Filter {
public static final Parcelable.Creator<SortableFilter> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public SortableFilter createFromParcel(Parcel source) {
SortableFilter item = new SortableFilter();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public SortableFilter[] newArray(int size) {
return new SortableFilter[size];
}
};
public SortableFilter(String listingTitle, QueryTemplate sqlQuery) {
super(listingTitle, sqlQuery);
}
public SortableFilter(
String listingTitle, QueryTemplate sqlQuery, Map<String, Object> valuesForNewTasks) {
super(listingTitle, sqlQuery, valuesForNewTasks);
}
private SortableFilter() {}
@Override
public boolean supportsAstridSorting() {
return true;
}
}

@ -0,0 +1,37 @@
package org.tasks.filters
import android.os.Parcel
import android.os.Parcelable
import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.api.Filter
class SortableFilter : Filter {
constructor(listingTitle: String?, sqlQuery: QueryTemplate?) : super(listingTitle, sqlQuery)
constructor(
listingTitle: String?, sqlQuery: QueryTemplate?, valuesForNewTasks: Map<String, Any>?
) : super(listingTitle, sqlQuery, valuesForNewTasks)
private constructor()
override fun supportsAstridSorting(): Boolean {
return true
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<SortableFilter> =
object : Parcelable.Creator<SortableFilter> {
/** {@inheritDoc} */
override fun createFromParcel(source: Parcel): SortableFilter {
val item = SortableFilter()
item.readFromParcel(source)
return item
}
/** {@inheritDoc} */
override fun newArray(size: Int): Array<SortableFilter?> {
return arrayOfNulls(size)
}
}
}
}

@ -198,14 +198,13 @@ class GoogleTaskSynchronizer @Inject constructor(
val defaultRemoteList = defaultFilterProvider.defaultList
var listId = if (defaultRemoteList is GtasksFilter) defaultRemoteList.remoteId else DEFAULT_LIST
if (isNullOrEmpty(gtasksMetadata.remoteId)) { // Create case
val selectedList = gtasksMetadata.calendar
if (!isNullOrEmpty(selectedList)) {
listId = selectedList
gtasksMetadata.calendar?.takeIf { it.isNotBlank() }?.let {
listId = it
}
newlyCreated = true
} else { // update case
remoteId = gtasksMetadata.remoteId
listId = gtasksMetadata.calendar
listId = gtasksMetadata.calendar!!
remoteModel.id = remoteId
}

Loading…
Cancel
Save