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 7c6c34b2e..036318f35 100644 --- a/app/src/main/java/com/todoroo/astrid/core/CriterionInstance.kt +++ b/app/src/main/java/com/todoroo/astrid/core/CriterionInstance.kt @@ -1,8 +1,5 @@ package com.todoroo.astrid.core -import com.google.common.base.Joiner -import com.google.common.base.Splitter -import com.google.common.collect.Lists import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.astrid.api.CustomFilterCriterion import com.todoroo.astrid.api.MultipleSelectCriterion @@ -72,14 +69,13 @@ class CriterionInstance { private fun serialize(): String { // criterion|entry|text|type|sql - return Joiner.on(AndroidUtilities.SERIALIZATION_SEPARATOR) - .join( - listOf( - escape(criterion.identifier), - escape(valueFromCriterion), - escape(criterion.text), - type, - if (criterion.sql == null) "" else criterion.sql)) + return listOf( + escape(criterion.identifier), + escape(valueFromCriterion), + escape(criterion.text), + type, + criterion.sql ?: "") + .joinToString(AndroidUtilities.SERIALIZATION_SEPARATOR) } override fun toString(): String { @@ -126,9 +122,10 @@ class CriterionInstance { return emptyList() } val entries: MutableList = ArrayList() - for (row in criterion.split("\n".toRegex()).toTypedArray()) { - val split = Lists.transform( - Splitter.on(AndroidUtilities.SERIALIZATION_SEPARATOR).splitToList(row)) { item: String? -> unescape(item) } + for (row in criterion.trim().split("\n")) { + val split = row + .split(AndroidUtilities.SERIALIZATION_SEPARATOR) + .map { unescape(it) } if (split.size != 4 && split.size != 5) { Timber.e("invalid row: %s", row) return emptyList() @@ -141,7 +138,7 @@ class CriterionInstance { } else if (entry.criterion is MultipleSelectCriterion) { val multipleSelectCriterion = entry.criterion as MultipleSelectCriterion? if (multipleSelectCriterion!!.entryValues != null) { - entry.selectedIndex = listOf(*multipleSelectCriterion.entryValues).indexOf(value) + entry.selectedIndex = multipleSelectCriterion.entryValues.indexOf(value) } } else { Timber.d("Ignored value %s for %s", value, entry.criterion) @@ -167,8 +164,10 @@ class CriterionInstance { AndroidUtilities.SEPARATOR_ESCAPE, AndroidUtilities.SERIALIZATION_SEPARATOR) } - fun serialize(criterion: List?): String { - return Joiner.on("\n").join(Lists.transform(criterion!!) { obj: CriterionInstance? -> obj!!.serialize() }) + fun serialize(criterion: List): String { + return criterion + .joinToString("\n") { it.serialize() } + .trim() } } } \ No newline at end of file diff --git a/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt b/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt index b11edaef8..c3c717e6c 100644 --- a/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt +++ b/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt @@ -69,6 +69,11 @@ class Upgrader @Inject constructor( } run(from, V9_7) { googleTaskListDao.resetOrders() } run(from, V9_7_3) { googleTaskDao.updateParents() } + run(from, V10_0_2) { + filterDao.getAll() + .filter { it.getSql().trim() == "WHERE" } + .forEach { filterDao.delete(it) } + } preferences.setBoolean(R.string.p_just_updated, true) } preferences.setCurrentVersion(to) @@ -315,6 +320,7 @@ class Upgrader @Inject constructor( const val V9_6 = 90600 const val V9_7 = 90700 const val V9_7_3 = 90704 + const val V10_0_2 = 100012 @JvmStatic fun getAndroidColor(context: Context, index: Int): Int { diff --git a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt index a27c4e091..b42068326 100644 --- a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt @@ -91,12 +91,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() { setCriteria(CriterionInstance.fromString( filterCriteriaProvider, intent.getStringExtra(EXTRA_CRITERIA)!!)) } - else -> { - val instance = CriterionInstance() - instance.criterion = filterCriteriaProvider.startingUniverse - instance.type = CriterionInstance.TYPE_UNIVERSE - setCriteria(mutableListOf(instance)) - } + else -> setCriteria(universe()) } recyclerView.layoutManager = LinearLayoutManager(this) ItemTouchHelper( @@ -108,8 +103,15 @@ class FilterSettingsActivity : BaseListSettingsActivity() { updateTheme() } + private fun universe() = listOf(CriterionInstance().apply { + criterion = filterCriteriaProvider.startingUniverse + type = CriterionInstance.TYPE_UNIVERSE + }) + private fun setCriteria(criteria: List) { - this.criteria = criteria.toMutableList() + this.criteria = criteria + .ifEmpty { universe() } + .toMutableList() adapter = CustomFilterAdapter(criteria, locale) { replaceId: String -> onClick(replaceId) } recyclerView.adapter = adapter fab.isExtended = isNew || adapter.itemCount <= 1 @@ -246,6 +248,9 @@ class FilterSettingsActivity : BaseListSettingsActivity() { f.setIcon(selectedIcon) f.values = AndroidUtilities.mapToSerializedString(values) f.criterion = CriterionInstance.serialize(criteria) + if (f.criterion.isNullOrBlank()) { + throw RuntimeException("Criterion cannot be empty") + } f.setSql(sql) if (isNew) { f.id = filterDao.insert(f) @@ -272,7 +277,9 @@ class FilterSettingsActivity : BaseListSettingsActivity() { (!Strings.isNullOrEmpty(newName) || selectedColor != 0 || selectedIcon != -1 || criteria.size > 1) } else newName != filter!!.listingTitle - || selectedColor != filter!!.tint || selectedIcon != filter!!.icon || CriterionInstance.serialize(criteria) != filter!!.criterion + || selectedColor != filter!!.tint + || selectedIcon != filter!!.icon + || CriterionInstance.serialize(criteria) != filter!!.criterion.trim() || values != filter!!.valuesForNewTasks || sql != filter!!.originalSqlQuery } diff --git a/app/src/main/java/org/tasks/data/FilterDao.kt b/app/src/main/java/org/tasks/data/FilterDao.kt index b65b291dd..46b614897 100644 --- a/app/src/main/java/org/tasks/data/FilterDao.kt +++ b/app/src/main/java/org/tasks/data/FilterDao.kt @@ -1,9 +1,6 @@ package org.tasks.data -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.Query -import androidx.room.Update +import androidx.room.* import com.todoroo.astrid.api.FilterListItem.NO_ORDER @Dao @@ -14,6 +11,9 @@ interface FilterDao { @Query("DELETE FROM filters WHERE _id = :id") suspend fun delete(id: Long) + @Delete + suspend fun delete(filter: Filter) + @Query("SELECT * FROM filters WHERE title = :title COLLATE NOCASE LIMIT 1") suspend fun getByName(title: String): Filter?