mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-10 16:39:35 +00:00
compose PersonalDictionariesScreen
This commit is contained in:
parent
52c887e941
commit
86f15e11d8
6 changed files with 450 additions and 8 deletions
|
@ -186,6 +186,10 @@ object LocaleUtils {
|
|||
return getLocaleDisplayNameInLocale(locale, context.resources, context.resources.configuration.locale())
|
||||
}
|
||||
|
||||
// todo: use this instead of getLocaleDisplayNameInSystemLocale in .kt files
|
||||
fun Locale.localizedDisplayName(context: Context) =
|
||||
getLocaleDisplayNameInLocale(this, context.resources, context.resources.configuration.locale())
|
||||
|
||||
@JvmStatic
|
||||
fun getLocaleDisplayNameInLocale(locale: Locale, resources: Resources, displayLocale: Locale): String {
|
||||
val languageTag = locale.toLanguageTag()
|
||||
|
|
|
@ -103,7 +103,7 @@ fun SearchSettingsScreen(
|
|||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun <T: Any> SearchScreen(
|
||||
fun <T: Any?> SearchScreen(
|
||||
onClickBack: () -> Unit,
|
||||
title: @Composable () -> Unit,
|
||||
filteredItems: (String) -> List<T>,
|
||||
|
|
|
@ -10,6 +10,8 @@ import androidx.compose.ui.unit.LayoutDirection
|
|||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
import helium314.keyboard.settings.screens.AboutScreen
|
||||
import helium314.keyboard.settings.screens.AdvancedSettingsScreen
|
||||
import helium314.keyboard.settings.screens.AppearanceScreen
|
||||
|
@ -19,6 +21,8 @@ import helium314.keyboard.settings.screens.DictionaryScreen
|
|||
import helium314.keyboard.settings.screens.GestureTypingScreen
|
||||
import helium314.keyboard.settings.screens.LanguageScreen
|
||||
import helium314.keyboard.settings.screens.MainSettingsScreen
|
||||
import helium314.keyboard.settings.screens.PersonalDictionariesScreen
|
||||
import helium314.keyboard.settings.screens.PersonalDictionaryScreen
|
||||
import helium314.keyboard.settings.screens.PreferencesScreen
|
||||
import helium314.keyboard.settings.screens.SecondaryLayoutScreen
|
||||
import helium314.keyboard.settings.screens.TextCorrectionScreen
|
||||
|
@ -28,6 +32,7 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun SettingsNavHost(
|
||||
|
@ -89,10 +94,15 @@ fun SettingsNavHost(
|
|||
composable(SettingsDestination.Appearance) {
|
||||
AppearanceScreen(onClickBack = ::goBack)
|
||||
}
|
||||
composable(SettingsDestination.PersonalDictionary) {
|
||||
// PersonalDictionarySettingsScreen(
|
||||
// onClickBack = ::goBack
|
||||
// )
|
||||
composable(SettingsDestination.PersonalDictionary + "{locale}") {
|
||||
val locale = it.arguments?.getString("locale")?.takeIf { it.isNotBlank() }?.constructLocale()
|
||||
PersonalDictionaryScreen(
|
||||
onClickBack = ::goBack,
|
||||
locale = locale
|
||||
)
|
||||
}
|
||||
composable(SettingsDestination.PersonalDictionaries) {
|
||||
PersonalDictionariesScreen(onClickBack = ::goBack)
|
||||
}
|
||||
composable(SettingsDestination.Languages) {
|
||||
LanguageScreen(onClickBack = ::goBack)
|
||||
|
@ -126,7 +136,8 @@ object SettingsDestination {
|
|||
const val Appearance = "appearance"
|
||||
const val Colors = "colors"
|
||||
const val ColorsNight = "colors_night"
|
||||
const val PersonalDictionary = "personal_dictionary"
|
||||
const val PersonalDictionaries = "personal_dictionaries"
|
||||
const val PersonalDictionary = "personal_dictionary/"
|
||||
const val Languages = "languages"
|
||||
const val Layouts = "layouts"
|
||||
const val Dictionaries = "dictionaries"
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
package helium314.keyboard.settings.screens
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.common.splitOnWhitespace
|
||||
import helium314.keyboard.latin.settings.Defaults
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.SubtypeLocaleUtils
|
||||
import helium314.keyboard.latin.utils.SubtypeSettings.getEnabledSubtypes
|
||||
import helium314.keyboard.latin.utils.SubtypeSettings.getSystemLocales
|
||||
import helium314.keyboard.latin.utils.getSecondaryLocales
|
||||
import helium314.keyboard.latin.utils.locale
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.SearchScreen
|
||||
import helium314.keyboard.settings.SettingsDestination
|
||||
import java.util.Locale
|
||||
import java.util.TreeSet
|
||||
|
||||
@Composable
|
||||
fun PersonalDictionariesScreen(
|
||||
onClickBack: () -> Unit,
|
||||
) {
|
||||
// todo: consider adding "add word" button like old settings (requires additional navigation parameter, should not be hard)
|
||||
val ctx = LocalContext.current
|
||||
val locales: MutableList<Locale?> = getSortedDictionaryLocales(LocalContext.current).toMutableList()
|
||||
locales.add(0, null)
|
||||
SearchScreen(
|
||||
onClickBack = onClickBack,
|
||||
title = { Text(stringResource(R.string.edit_personal_dictionary)) },
|
||||
filteredItems = { term ->
|
||||
locales.filter {
|
||||
it.getLocaleDisplayNameForUserDictSettings(ctx).replace("(", "")
|
||||
.splitOnWhitespace().any { it.startsWith(term, true) }
|
||||
}
|
||||
},
|
||||
itemContent = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
SettingsDestination.navigateTo(SettingsDestination.PersonalDictionary + (it?.toLanguageTag() ?: ""))
|
||||
}
|
||||
.heightIn(min = 44.dp)
|
||||
.padding(12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(it.getLocaleDisplayNameForUserDictSettings(ctx), style = MaterialTheme.typography.bodyLarge)
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_arrow_left),
|
||||
modifier = Modifier.scale(-1f, 1f),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun getSortedDictionaryLocales(context: Context): TreeSet<Locale> {
|
||||
val prefs = context.prefs()
|
||||
val localeSystemOnly = prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)
|
||||
val sortedLocales = sortedSetOf<Locale>(compareBy { it.toLanguageTag().lowercase() })
|
||||
|
||||
// Add the main language selected in the "Language and Layouts" setting except "No language"
|
||||
for (mainSubtype in getEnabledSubtypes(prefs, true)) {
|
||||
val mainLocale = mainSubtype.locale()
|
||||
if (mainLocale.toLanguageTag() != SubtypeLocaleUtils.NO_LANGUAGE) {
|
||||
sortedLocales.add(mainLocale)
|
||||
}
|
||||
// Secondary language is added only if main language is selected and if system language is not enabled
|
||||
if (!localeSystemOnly) {
|
||||
val enabled = getEnabledSubtypes(prefs, false)
|
||||
for (subtype in enabled) {
|
||||
if (subtype.locale() == mainLocale) sortedLocales.addAll(getSecondaryLocales(subtype.extraValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sortedLocales.addAll(getSystemLocales())
|
||||
return sortedLocales
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
package helium314.keyboard.settings.screens
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.provider.UserDictionary
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.common.LocaleUtils.localizedDisplayName
|
||||
import helium314.keyboard.settings.SearchScreen
|
||||
import helium314.keyboard.settings.dialogs.DropDownField
|
||||
import helium314.keyboard.settings.dialogs.ThreeButtonAlertDialog
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun PersonalDictionaryScreen(
|
||||
onClickBack: () -> Unit,
|
||||
locale: Locale?
|
||||
) {
|
||||
val ctx = LocalContext.current
|
||||
val words = getAll(locale, ctx)
|
||||
var selectedWord: Word? by remember { mutableStateOf(null) }
|
||||
SearchScreen(
|
||||
onClickBack = onClickBack,
|
||||
title = {
|
||||
Column {
|
||||
Text(stringResource(R.string.edit_personal_dictionary))
|
||||
Text(
|
||||
locale.getLocaleDisplayNameForUserDictSettings(ctx),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
},
|
||||
filteredItems = { term ->
|
||||
// we could maybe to this using a query and getting items by position
|
||||
// requires adjusting the SearchScreen, likely not worth the effort
|
||||
words.filter { it.word.startsWith(term, true) || it.shortcut?.startsWith(term, true) == true }
|
||||
},
|
||||
itemContent = {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { selectedWord = it }
|
||||
.padding(vertical = 6.dp, horizontal = 16.dp)
|
||||
) {
|
||||
Column {
|
||||
Text(it.word, style = MaterialTheme.typography.bodyLarge)
|
||||
val details = if (it.shortcut == null) it.weight.toString() else "${it.weight} | ${it.shortcut}"
|
||||
Text(details, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.user_dict_settings_edit_dialog_title))
|
||||
}
|
||||
}
|
||||
)
|
||||
if (selectedWord != null) {
|
||||
val selWord = selectedWord!!
|
||||
var newWord by remember { mutableStateOf(selWord) }
|
||||
var newLocale by remember { mutableStateOf(locale) }
|
||||
val wordValid = (newWord.word == selWord.word && locale == newLocale) || !doesWordExist(newWord.word, newLocale, ctx)
|
||||
ThreeButtonAlertDialog(
|
||||
onDismissRequest = { selectedWord = null },
|
||||
onConfirmed = {
|
||||
if (newWord != selWord || locale != newLocale) {
|
||||
deleteWord(selWord, locale, ctx.contentResolver)
|
||||
val saveWeight = newWord.weight ?: WEIGHT_FOR_USER_DICTIONARY_ADDS
|
||||
UserDictionary.Words.addWord(ctx, newWord.word, saveWeight, newWord.shortcut, newLocale)
|
||||
}
|
||||
},
|
||||
checkOk = { newWord.word.isNotBlank() && wordValid },
|
||||
confirmButtonText = stringResource(R.string.save),
|
||||
neutralButtonText = stringResource(R.string.delete),
|
||||
onNeutral = {
|
||||
deleteWord(selWord, locale, ctx.contentResolver) // delete the originally selected word
|
||||
selectedWord = null
|
||||
},
|
||||
title = {
|
||||
Column {
|
||||
Text(stringResource(R.string.user_dict_settings_edit_dialog_title))
|
||||
Text(
|
||||
locale.getLocaleDisplayNameForUserDictSettings(ctx),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
},
|
||||
text = {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
TextField(
|
||||
value = newWord.word,
|
||||
onValueChange = { newWord = newWord.copy(word = it) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(stringResource(R.string.user_dict_settings_add_shortcut_option_name), Modifier.fillMaxWidth(0.3f))
|
||||
TextField(
|
||||
value = newWord.shortcut ?: "",
|
||||
onValueChange = { newWord = newWord.copy(shortcut = it.ifBlank { null }) },
|
||||
label = { Text(stringResource(R.string.user_dict_settings_add_shortcut_hint))},
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true
|
||||
)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(stringResource(R.string.user_dict_settings_add_weight_value), Modifier.fillMaxWidth(0.3f))
|
||||
TextField(
|
||||
newWord.weight?.toString() ?: "",
|
||||
{
|
||||
if (it.isBlank())
|
||||
newWord = newWord.copy(weight = null)
|
||||
else if ((it.toIntOrNull() ?: -1) in 0..255)
|
||||
newWord = newWord.copy(weight = it.toInt())
|
||||
},
|
||||
label = { Text(WEIGHT_FOR_USER_DICTIONARY_ADDS.toString()) },
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true
|
||||
)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(stringResource(R.string.user_dict_settings_add_locale_option_name), Modifier.fillMaxWidth(0.3f))
|
||||
DropDownField(
|
||||
items = getSpecificallySortedLocales(ctx, locale),
|
||||
selectedItem = newLocale,
|
||||
onSelected = { newLocale = it },
|
||||
) {
|
||||
Text(it.getLocaleDisplayNameForUserDictSettings(ctx))
|
||||
}
|
||||
}
|
||||
if (!wordValid)
|
||||
Text(
|
||||
stringResource(R.string.user_dict_word_already_present, newLocale.getLocaleDisplayNameForUserDictSettings(ctx)),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
ExtendedFloatingActionButton(
|
||||
onClick = { selectedWord = Word("", null, null) },
|
||||
text = { Text(stringResource(R.string.user_dict_add_word_button)) },
|
||||
icon = { Icon(painter = painterResource(R.drawable.ic_edit), stringResource(R.string.user_dict_add_word_button)) },
|
||||
modifier = Modifier.wrapContentSize(Alignment.BottomEnd).padding(all = 12.dp)
|
||||
)
|
||||
}
|
||||
|
||||
private fun deleteWord(wordDetails: Word, locale: Locale?, resolver: ContentResolver) {
|
||||
val (word, shortcut, weightInt) = wordDetails
|
||||
val weight = weightInt.toString()
|
||||
if (shortcut.isNullOrBlank()) {
|
||||
if (locale == null) {
|
||||
resolver.delete(
|
||||
UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITHOUT_SHORTCUT_AND_WITH_ALL_LOCALES,
|
||||
arrayOf(word, weight)
|
||||
)
|
||||
} else {
|
||||
resolver.delete( // requires use of locale string for interaction with Android system
|
||||
UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITHOUT_SHORTCUT_AND_WITH_LOCALE,
|
||||
arrayOf(word, weight, locale.toString())
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (locale == null) {
|
||||
resolver.delete(
|
||||
UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITH_SHORTCUT_AND_WITH_ALL_LOCALES,
|
||||
arrayOf(word, shortcut, weight)
|
||||
)
|
||||
} else {
|
||||
resolver.delete( // requires use of locale string for interaction with Android system
|
||||
UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITH_SHORTCUT_AND_WITH_LOCALE,
|
||||
arrayOf(word, shortcut, weight, locale.toString())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun doesWordExist(word: String, locale: Locale?, context: Context): Boolean {
|
||||
val hasWordProjection = arrayOf(UserDictionary.Words.WORD, UserDictionary.Words.LOCALE)
|
||||
|
||||
val select: String
|
||||
val selectArgs: Array<String>?
|
||||
if (locale == null) {
|
||||
select = "${UserDictionary.Words.WORD}=? AND ${UserDictionary.Words.LOCALE} is null"
|
||||
selectArgs = arrayOf(word)
|
||||
} else {
|
||||
select = "${UserDictionary.Words.WORD}=? AND ${UserDictionary.Words.LOCALE}=?"
|
||||
// requires use of locale string (as opposed to more useful language tag) for interaction with Android system
|
||||
selectArgs = arrayOf(word, locale.toString())
|
||||
}
|
||||
val cursor = context.contentResolver.query(UserDictionary.Words.CONTENT_URI, hasWordProjection, select, selectArgs, null)
|
||||
cursor.use {
|
||||
if (null == it) return false
|
||||
return it.count > 0
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSpecificallySortedLocales(context: Context, firstLocale: Locale?): List<Locale?> {
|
||||
val list: MutableList<Locale?> = getSortedDictionaryLocales(context).toMutableList()
|
||||
list.remove(firstLocale)
|
||||
list.remove(null)
|
||||
list.add(0, firstLocale)
|
||||
if (firstLocale != null)
|
||||
list.add(null)
|
||||
return list
|
||||
}
|
||||
|
||||
fun Locale?.getLocaleDisplayNameForUserDictSettings(context: Context) =
|
||||
this?.localizedDisplayName(context) ?: context.resources.getString(R.string.user_dict_settings_all_languages)
|
||||
|
||||
// weight is frequency but different name towards user
|
||||
private data class Word(val word: String, val shortcut: String?, val weight: Int?)
|
||||
|
||||
// getting all words instead of reading directly cursor, because filteredItems expects a list
|
||||
private fun getAll(locale: Locale?, context: Context): List<Word> {
|
||||
val cursor = createCursor(locale, context) ?: return emptyList()
|
||||
|
||||
if (!cursor.moveToFirst()) return emptyList()
|
||||
val result = mutableListOf<Word>()
|
||||
val wordIndex = cursor.getColumnIndexOrThrow(UserDictionary.Words.WORD)
|
||||
val shortcutIndex = cursor.getColumnIndexOrThrow(UserDictionary.Words.SHORTCUT)
|
||||
val frequencyIndex = cursor.getColumnIndexOrThrow(UserDictionary.Words.FREQUENCY)
|
||||
while (!cursor.isAfterLast) {
|
||||
result.add(Word(cursor.getString(wordIndex), cursor.getString(shortcutIndex), cursor.getInt(frequencyIndex)))
|
||||
cursor.moveToNext()
|
||||
}
|
||||
cursor.close()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createCursor(locale: Locale?, context: Context): Cursor? {
|
||||
// locale can be any of:
|
||||
// - An actual locale, for use of Locale#toString()
|
||||
// - The emptyLocale. This means we want a cursor returning words valid for all locales.
|
||||
|
||||
// Note that this contrasts with the data inside the database, where NULL means "all
|
||||
// locales" and there should never be an empty string.
|
||||
// The confusion is called by the historical use of null for "all locales".
|
||||
|
||||
val select: String
|
||||
val selectArgs: Array<String>?
|
||||
if (locale == null) {
|
||||
select = QUERY_SELECTION_ALL_LOCALES
|
||||
selectArgs = null
|
||||
} else {
|
||||
select = QUERY_SELECTION
|
||||
// requires use of locale string (as opposed to more useful language tag) for interaction with Android system
|
||||
selectArgs = arrayOf(locale.toString())
|
||||
}
|
||||
|
||||
return context.contentResolver.query(
|
||||
UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, select, selectArgs, SORT_ORDER
|
||||
)
|
||||
}
|
||||
|
||||
private val QUERY_PROJECTION =
|
||||
arrayOf(UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT, UserDictionary.Words.FREQUENCY)
|
||||
// Case-insensitive sort
|
||||
private const val SORT_ORDER = "UPPER(" + UserDictionary.Words.WORD + ")"
|
||||
|
||||
// Either the locale is empty (means the word is applicable to all locales)
|
||||
// or the word equals our current locale
|
||||
private const val QUERY_SELECTION = UserDictionary.Words.LOCALE + "=?"
|
||||
private const val QUERY_SELECTION_ALL_LOCALES = UserDictionary.Words.LOCALE + " is null"
|
||||
|
||||
private const val DELETE_SELECTION_WITH_SHORTCUT_AND_WITH_LOCALE = (UserDictionary.Words.WORD + "=? AND "
|
||||
+ UserDictionary.Words.SHORTCUT + "=? AND "
|
||||
+ UserDictionary.Words.FREQUENCY + "=? AND "
|
||||
+ UserDictionary.Words.LOCALE + "=?")
|
||||
|
||||
private const val DELETE_SELECTION_WITH_SHORTCUT_AND_WITH_ALL_LOCALES = (UserDictionary.Words.WORD + "=? AND "
|
||||
+ UserDictionary.Words.SHORTCUT + "=? AND "
|
||||
+ UserDictionary.Words.FREQUENCY + "=? AND "
|
||||
+ UserDictionary.Words.LOCALE + " is null")
|
||||
|
||||
private const val DELETE_SELECTION_WITHOUT_SHORTCUT_AND_WITH_LOCALE = (UserDictionary.Words.WORD + "=? AND "
|
||||
+ UserDictionary.Words.SHORTCUT + " is null AND "
|
||||
+ UserDictionary.Words.FREQUENCY + "=? AND "
|
||||
+ UserDictionary.Words.LOCALE + "=? OR "
|
||||
|
||||
+ UserDictionary.Words.SHORTCUT + "='' AND "
|
||||
+ UserDictionary.Words.FREQUENCY + "=? AND "
|
||||
+ UserDictionary.Words.LOCALE + "=?")
|
||||
|
||||
private const val DELETE_SELECTION_WITHOUT_SHORTCUT_AND_WITH_ALL_LOCALES = (UserDictionary.Words.WORD + "=? AND "
|
||||
+ UserDictionary.Words.SHORTCUT + " is null AND "
|
||||
+ UserDictionary.Words.FREQUENCY + "=? AND "
|
||||
+ UserDictionary.Words.LOCALE + " is null OR "
|
||||
|
||||
+ UserDictionary.Words.SHORTCUT + "='' AND "
|
||||
+ UserDictionary.Words.FREQUENCY + "=? AND "
|
||||
+ UserDictionary.Words.LOCALE + " is null")
|
||||
|
||||
private const val WEIGHT_FOR_USER_DICTIONARY_ADDS = 250
|
|
@ -37,6 +37,8 @@ import helium314.keyboard.settings.Setting
|
|||
import helium314.keyboard.settings.preferences.Preference
|
||||
import helium314.keyboard.settings.SearchSettingsScreen
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.SettingsDestination
|
||||
import helium314.keyboard.settings.SettingsNavHost
|
||||
import helium314.keyboard.settings.preferences.SwitchPreference
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.dialogs.ConfirmationDialog
|
||||
|
@ -83,10 +85,9 @@ fun TextCorrectionScreen(
|
|||
|
||||
fun createCorrectionSettings(context: Context) = listOf(
|
||||
Setting(context, SettingsWithoutKey.EDIT_PERSONAL_DICTIONARY, R.string.edit_personal_dictionary) {
|
||||
val ctx = LocalContext.current
|
||||
Preference(
|
||||
name = stringResource(R.string.edit_personal_dictionary),
|
||||
onClick = { ctx.getActivity()?.switchTo(UserDictionaryListFragment()) },
|
||||
onClick = { SettingsDestination.navigateTo(SettingsDestination.PersonalDictionaries) },
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_arrow_left),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue