From 09fba4073af65fc6b4fb386416758537715c9ccc Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Tue, 20 Oct 2020 14:07:15 -0500 Subject: [PATCH] Add custom filter criteria for recurring tasks --- .../todoroo/astrid/api/BooleanCriterion.kt | 35 +++++++++++++++++++ .../todoroo/astrid/core/CriterionInstance.kt | 5 +++ .../main/java/com/todoroo/astrid/data/Task.kt | 1 + .../activities/FilterSettingsActivity.kt | 8 +++-- .../tasks/filters/FilterCriteriaProvider.kt | 18 +++++++--- 5 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/todoroo/astrid/api/BooleanCriterion.kt diff --git a/app/src/main/java/com/todoroo/astrid/api/BooleanCriterion.kt b/app/src/main/java/com/todoroo/astrid/api/BooleanCriterion.kt new file mode 100644 index 000000000..affc593f1 --- /dev/null +++ b/app/src/main/java/com/todoroo/astrid/api/BooleanCriterion.kt @@ -0,0 +1,35 @@ +package com.todoroo.astrid.api + +import android.os.Parcel +import android.os.Parcelable + +class BooleanCriterion constructor() : CustomFilterCriterion(), Parcelable { + + constructor(identifier: String, title: String, sql: String): this() { + this.identifier = identifier + this.text = title + this.sql = sql + this.name = title + } + + override fun describeContents() = 0 + + override fun writeToParcel(dest: Parcel?, flags: Int) { + writeToParcel(dest) + } + + companion object { + @JvmField + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(source: Parcel?): BooleanCriterion { + val item = BooleanCriterion() + item.readFromParcel(source) + return item + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/todoroo/astrid/core/CriterionInstance.kt b/app/src/main/java/com/todoroo/astrid/core/CriterionInstance.kt index 036318f35..7cd2dc3a6 100644 --- a/app/src/main/java/com/todoroo/astrid/core/CriterionInstance.kt +++ b/app/src/main/java/com/todoroo/astrid/core/CriterionInstance.kt @@ -1,6 +1,7 @@ package com.todoroo.astrid.core import com.todoroo.andlib.utility.AndroidUtilities +import com.todoroo.astrid.api.BooleanCriterion import com.todoroo.astrid.api.CustomFilterCriterion import com.todoroo.astrid.api.MultipleSelectCriterion import com.todoroo.astrid.api.TextInputCriterion @@ -47,6 +48,8 @@ class CriterionInstance { return if (selectedText == null) { criterion.text } else criterion.text.replace("?", selectedText!!) + } else if (criterion is BooleanCriterion) { + return criterion.name } throw UnsupportedOperationException("Unknown criterion type") // $NON-NLS-1$ } @@ -63,6 +66,8 @@ class CriterionInstance { } else criterion.text } else if (criterion is TextInputCriterion) { return selectedText + } else if (criterion is BooleanCriterion) { + return criterion.name } throw UnsupportedOperationException("Unknown criterion type") // $NON-NLS-1$ } diff --git a/app/src/main/java/com/todoroo/astrid/data/Task.kt b/app/src/main/java/com/todoroo/astrid/data/Task.kt index 918ccc552..43f55a92b 100644 --- a/app/src/main/java/com/todoroo/astrid/data/Task.kt +++ b/app/src/main/java/com/todoroo/astrid/data/Task.kt @@ -527,6 +527,7 @@ class Task : Parcelable { @JvmField val NOTES = TABLE.column("notes") @JvmField val TIMER_START = TABLE.column("timerStart") @JvmField val PARENT = TABLE.column("parent") + @JvmField val RECURRENCE = TABLE.column("recurrence") /** constant value for no uuid */ const val NO_UUID = "0" // $NON-NLS-1$ diff --git a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt index 38aba34de..fa3619d74 100644 --- a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt @@ -178,10 +178,10 @@ class FilterSettingsActivity : BaseListSettingsActivity() { .setItems(names) { dialog: DialogInterface, which: Int -> val instance = CriterionInstance() instance.criterion = all[which] - showOptionsFor(instance, Runnable { + showOptionsFor(instance) { criteria.add(instance) updateList() - }) + } dialog.dismiss() } .show() @@ -190,6 +190,10 @@ class FilterSettingsActivity : BaseListSettingsActivity() { /** Show options menu for the given criterioninstance */ private fun showOptionsFor(item: CriterionInstance, onComplete: Runnable?) { + if (item.criterion is BooleanCriterion) { + onComplete?.run() + return + } val dialog = dialogBuilder.newDialog(item.criterion.name) if (item.criterion is MultipleSelectCriterion) { val multiSelectCriterion = item.criterion as MultipleSelectCriterion diff --git a/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt b/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt index 8dd0cece2..7d5c0df0e 100644 --- a/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt +++ b/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt @@ -6,10 +6,7 @@ import com.todoroo.andlib.sql.Criterion.Companion.or import com.todoroo.andlib.sql.Field.Companion.field import com.todoroo.andlib.sql.Join.Companion.inner import com.todoroo.andlib.sql.Query.Companion.select -import com.todoroo.astrid.api.CustomFilterCriterion -import com.todoroo.astrid.api.MultipleSelectCriterion -import com.todoroo.astrid.api.PermaSql -import com.todoroo.astrid.api.TextInputCriterion +import com.todoroo.astrid.api.* import com.todoroo.astrid.data.Task import dagger.hilt.android.qualifiers.ApplicationContext import org.tasks.R @@ -35,6 +32,7 @@ class FilterCriteriaProvider @Inject constructor( IDENTIFIER_CALDAV -> caldavFilterCriteria() IDENTIFIER_TAG_IS -> tagFilter() IDENTIFIER_TAG_CONTAINS -> tagNameContainsFilter + IDENTIFIER_RECUR -> recurringFilter else -> throw RuntimeException("Unknown identifier: $identifier") } } @@ -60,6 +58,7 @@ class FilterCriteriaProvider @Inject constructor( result.add(gtasksFilterCriteria()) } result.add(caldavFilterCriteria()) + result.add(recurringFilter) return result } @@ -87,6 +86,16 @@ class FilterCriteriaProvider @Inject constructor( context.getString(R.string.CFC_tag_name)) } + private val recurringFilter: CustomFilterCriterion + get() = BooleanCriterion( + IDENTIFIER_RECUR, + context.getString(R.string.repeats_single, "").trim(), + select(Task.ID) + .from(Task.TABLE) + .where(field("LENGTH(${Task.RECURRENCE})>0").eq(1)) + .toString() + ) + val tagNameContainsFilter: CustomFilterCriterion get() = TextInputCriterion( IDENTIFIER_TAG_CONTAINS, @@ -229,5 +238,6 @@ class FilterCriteriaProvider @Inject constructor( private const val IDENTIFIER_CALDAV = "caldavlist" private const val IDENTIFIER_TAG_IS = "tag_is" private const val IDENTIFIER_TAG_CONTAINS = "tag_contains" + private const val IDENTIFIER_RECUR = "tag_recur" } } \ No newline at end of file