avoid creating additional subtypes that are the same as a resource subtype

This commit is contained in:
Helium314 2025-03-31 16:31:52 +02:00
parent 8247366bdd
commit 452770566c
4 changed files with 27 additions and 5 deletions

View file

@ -14,11 +14,13 @@ import helium314.keyboard.latin.utils.LayoutType.Companion.toExtraValue
import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.ScriptUtils import helium314.keyboard.latin.utils.ScriptUtils
import helium314.keyboard.latin.utils.ScriptUtils.script import helium314.keyboard.latin.utils.ScriptUtils.script
import helium314.keyboard.latin.utils.SubtypeSettings
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.locale
import java.util.Locale import java.util.Locale
// some kind of intermediate between the string stored in preferences and an InputMethodSubtype // some kind of intermediate between the string stored in preferences and an InputMethodSubtype
// todo: consider using a hashMap or sortedMap instead of a string if we run into comparison issues once again
data class SettingsSubtype(val locale: Locale, val extraValues: String) { data class SettingsSubtype(val locale: Locale, val extraValues: String) {
fun toPref() = locale.toLanguageTag() + Separators.SET + extraValues fun toPref() = locale.toLanguageTag() + Separators.SET + extraValues
@ -70,6 +72,8 @@ data class SettingsSubtype(val locale: Locale, val extraValues: String) {
prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
.split(Separators.SETS).contains(toPref()) .split(Separators.SETS).contains(toPref())
fun isSameAsDefault() = SubtypeSettings.getResourceSubtypesForLocale(locale).any { it.toSettingsSubtype() == this.toPref().toSettingsSubtype() }
companion object { companion object {
fun String.toSettingsSubtype(): SettingsSubtype = fun String.toSettingsSubtype(): SettingsSubtype =
SettingsSubtype( SettingsSubtype(

View file

@ -124,6 +124,10 @@ object SubtypeSettings {
fun getAvailableSubtypeLocales(): List<Locale> = resourceSubtypesByLocale.keys.toList() fun getAvailableSubtypeLocales(): List<Locale> = resourceSubtypesByLocale.keys.toList()
/**
* Update subtypes that contain the layout. If new name is null (layout deleted) and the
* subtype is now identical to a resource subtype, remove the subtype from additional subtypes.
*/
fun onRenameLayout(type: LayoutType, from: String, to: String?, context: Context) { fun onRenameLayout(type: LayoutType, from: String, to: String?, context: Context) {
val prefs = context.prefs() val prefs = context.prefs()
listOf( listOf(
@ -131,10 +135,19 @@ object SubtypeSettings {
Settings.PREF_ENABLED_SUBTYPES to Defaults.PREF_ENABLED_SUBTYPES, Settings.PREF_ENABLED_SUBTYPES to Defaults.PREF_ENABLED_SUBTYPES,
Settings.PREF_SELECTED_SUBTYPE to Defaults.PREF_SELECTED_SUBTYPE Settings.PREF_SELECTED_SUBTYPE to Defaults.PREF_SELECTED_SUBTYPE
).forEach { (key, default) -> ).forEach { (key, default) ->
val new = prefs.getString(key, default)!!.split(Separators.SETS).mapTo(mutableSetOf()) { val new = prefs.getString(key, default)!!.split(Separators.SETS).mapNotNullTo(mutableSetOf()) {
val subtype = it.toSettingsSubtype() val subtype = it.toSettingsSubtype()
if (subtype.layoutName(type) == from) { if (subtype.layoutName(type) == from) {
if (to == null) subtype.withoutLayout(type).toPref() if (to == null) {
val defaultLayout = if (type !== LayoutType.MAIN) null
// if we just delete a main layout, we may end up with something like Hindi (QWERTY)
// so better replace it with a default layout for that locale
else resourceSubtypesByLocale[subtype.locale]?.first()?.mainLayoutName()
val newSubtype = if (defaultLayout == null) subtype.withoutLayout(type)
else subtype.withLayout(type, defaultLayout)
if (newSubtype.isSameAsDefault() && key == Settings.PREF_ADDITIONAL_SUBTYPES) null
else subtype.withoutLayout(type).toPref()
}
else subtype.withLayout(type, to).toPref() else subtype.withLayout(type, to).toPref()
} }
else subtype.toPref() else subtype.toPref()

View file

@ -70,7 +70,7 @@ object SubtypeUtilsAdditional {
val additionalSubtypes = SubtypeSettings.createSettingsSubtypes(prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!) val additionalSubtypes = SubtypeSettings.createSettingsSubtypes(prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!)
.toMutableList() .toMutableList()
additionalSubtypes.remove(from) additionalSubtypes.remove(from)
if (SubtypeSettings.getResourceSubtypesForLocale(to.locale).none { it.toSettingsSubtype() == to }) { if (!to.isSameAsDefault()) {
// We only add the "to" subtype if it's not equal to a resource subtype. // We only add the "to" subtype if it's not equal to a resource subtype.
// This means we make additional subtype disappear as magically as it was added if all settings are default. // This means we make additional subtype disappear as magically as it was added if all settings are default.
// If we don't do this, enabling the base subtype will result in the additional subtype being enabled, // If we don't do this, enabling the base subtype will result in the additional subtype being enabled,

View file

@ -388,8 +388,13 @@ private fun MainLayoutRow(
title = { Text(stringResource(R.string.delete_layout, LayoutUtilsCustom.getDisplayName(it))) }, title = { Text(stringResource(R.string.delete_layout, LayoutUtilsCustom.getDisplayName(it))) },
content = { if (others) Text(stringResource(R.string.layout_in_use)) }, content = { if (others) Text(stringResource(R.string.layout_in_use)) },
onConfirmed = { onConfirmed = {
if (it == currentSubtype.mainLayoutName()) if (it == currentSubtype.mainLayoutName()) {
setCurrentSubtype(currentSubtype.withoutLayout(LayoutType.MAIN)) // similar to what is done in SubtypeSettings.onRenameLayout
val defaultLayout = SubtypeSettings.getResourceSubtypesForLocale(currentSubtype.locale).firstOrNull()?.mainLayoutName()
val newSubtype = if (defaultLayout == null) currentSubtype.withoutLayout(LayoutType.MAIN)
else currentSubtype.withLayout(LayoutType.MAIN, defaultLayout)
setCurrentSubtype(newSubtype)
}
LayoutUtilsCustom.deleteLayout(it, LayoutType.MAIN, ctx) LayoutUtilsCustom.deleteLayout(it, LayoutType.MAIN, ctx)
(ctx.getActivity() as? SettingsActivity)?.prefChanged() (ctx.getActivity() as? SettingsActivity)?.prefChanged()
} }