From 0dc4ef880585c83cf5d0c61920c1987dd4f17b23 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 27 Aug 2023 09:41:23 +0200 Subject: [PATCH] fix issues with language settings don't show subtypes when using system locales this may not be ideal, but avoids dealing with many edge cases and is consistent with old behavior don't return a selected subtype when it's not enabled --- .../keyboard/KeyboardSwitcher.java | 1 - .../settings/LanguageFilterListPreference.kt | 19 +++++---- .../latin/settings/LanguageSettingsDialog.kt | 22 +++++------ .../settings/LanguageSettingsFragment.kt | 17 ++++---- .../latin/settings/SubtypeSettings.kt | 39 +++++++++++++++---- 5 files changed, 59 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardSwitcher.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardSwitcher.java index 0f9e7ba37..071bab618 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardSwitcher.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardSwitcher.java @@ -604,7 +604,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { } public void switchToSubtype(InputMethodSubtype subtype) { - Log.i("test1", "switch to "+subtype.getLocale()); mLatinIME.switchToSubtype(subtype); } } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageFilterListPreference.kt b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageFilterListPreference.kt index 7c6cad015..c1eecc60e 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageFilterListPreference.kt +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageFilterListPreference.kt @@ -48,10 +48,10 @@ class LanguageFilterListPreference(context: Context, attrs: AttributeSet) : Pref } } - fun setLanguages(list: Collection>, disableSwitches: Boolean) { + fun setLanguages(list: Collection>, onlySystemLocales: Boolean) { sortedSubtypes.clear() sortedSubtypes.addAll(list) - adapter.disableSwitches = disableSwitches + adapter.onlySystemLocales = onlySystemLocales adapter.list = sortedSubtypes } @@ -60,7 +60,7 @@ class LanguageFilterListPreference(context: Context, attrs: AttributeSet) : Pref @Suppress("Deprecation") class LanguageAdapter(list: List> = listOf(), context: Context) : RecyclerView.Adapter() { - var disableSwitches = false + var onlySystemLocales = false private val prefs = DeviceProtectedUtils.getSharedPreferences(context) var fragment: LanguageSettingsFragment? = null @@ -105,31 +105,31 @@ class LanguageAdapter(list: List> = listOf(), context: }) } text = sb.toString() - if (text.isBlank()) isGone = true + if (onlySystemLocales || text.isBlank()) isGone = true else isVisible = true } view.findViewById(R.id.language_switch).apply { - isEnabled = !disableSwitches && infos.size == 1 + isEnabled = !onlySystemLocales && infos.size == 1 // take care: isChecked changes if the language is scrolled out of view and comes back! // disable the change listener when setting the checked status on scroll // so it's only triggered on user interactions setOnCheckedChangeListener(null) - isChecked = disableSwitches || infos.any { it.isEnabled } + isChecked = onlySystemLocales || infos.any { it.isEnabled } setOnCheckedChangeListener { _, b -> if (b) { if (infos.size == 1) { addEnabledSubtype(prefs, infos.first().subtype) infos.single().isEnabled = true } else { - LanguageSettingsDialog(view.context, infos, fragment, disableSwitches, { setupDetailsTextAndSwitch() }).show() + LanguageSettingsDialog(view.context, infos, fragment, onlySystemLocales, { setupDetailsTextAndSwitch() }).show() } } else { if (infos.size == 1) { removeEnabledSubtype(prefs, infos.first().subtype) infos.single().isEnabled = false } else { - LanguageSettingsDialog(view.context, infos, fragment, disableSwitches, { setupDetailsTextAndSwitch() }).show() + LanguageSettingsDialog(view.context, infos, fragment, onlySystemLocales, { setupDetailsTextAndSwitch() }).show() } } } @@ -138,10 +138,9 @@ class LanguageAdapter(list: List> = listOf(), context: view.findViewById(R.id.language_name).text = infos.first().displayName view.findViewById(R.id.language_text).setOnClickListener { - LanguageSettingsDialog(view.context, infos, fragment, disableSwitches, { setupDetailsTextAndSwitch() }).show() + LanguageSettingsDialog(view.context, infos, fragment, onlySystemLocales, { setupDetailsTextAndSwitch() }).show() } setupDetailsTextAndSwitch() } } } - diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsDialog.kt b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsDialog.kt index 31d050a83..be25984c7 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsDialog.kt +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsDialog.kt @@ -29,7 +29,7 @@ class LanguageSettingsDialog( context: Context, private val subtypes: MutableList, private val fragment: LanguageSettingsFragment?, - private val disableSwitches: Boolean, + private val onlySystemLocales: Boolean, private val onSubtypesChanged: () -> Unit ) : AlertDialog(ContextThemeWrapper(context, R.style.platformDialogTheme)), LanguageSettingsFragment.Listener { private val context = ContextThemeWrapper(context, R.style.platformDialogTheme) @@ -46,7 +46,10 @@ class LanguageSettingsDialog( dismiss() } - fillSubtypesView(view.findViewById(R.id.subtypes)) + if (onlySystemLocales) + view.findViewById(R.id.subtypes).isGone = true + else + fillSubtypesView(view.findViewById(R.id.subtypes)) fillSecondaryLocaleView(view.findViewById(R.id.secondary_languages)) fillDictionariesView(view.findViewById(R.id.dictionaries)) } @@ -73,12 +76,9 @@ class LanguageSettingsDialog( di.dismiss() val newSubtype = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(mainLocaleString, layouts[i]) val newSubtypeInfo = newSubtype.toSubtypeInfo(mainLocale, context.resources, true) // enabled by default, because why else add them - addSubtypeToView(newSubtypeInfo, subtypesView) - val oldAdditionalSubtypesString = Settings.readPrefAdditionalSubtypes(prefs, context.resources) - val oldAdditionalSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(oldAdditionalSubtypesString).toHashSet() - val newAdditionalSubtypesString = AdditionalSubtypeUtils.createPrefSubtypes((oldAdditionalSubtypes + newSubtype).toTypedArray()) - Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString) + addAdditionalSubtype(prefs, context.resources, newSubtype) addEnabledSubtype(prefs, newSubtype) + addSubtypeToView(newSubtypeInfo, subtypesView) subtypes.add(newSubtypeInfo) onSubtypesChanged() } @@ -102,7 +102,7 @@ class LanguageSettingsDialog( row.findViewById(R.id.language_details).isGone = true row.findViewById(R.id.language_switch).apply { isChecked = subtype.isEnabled - isEnabled = !disableSwitches + isEnabled = !onlySystemLocales setOnCheckedChangeListener { _, b -> if (b) addEnabledSubtype(prefs, subtype.subtype) @@ -121,11 +121,7 @@ class LanguageSettingsDialog( subtypesView.removeView(row) subtypes.remove(subtype) - val oldAdditionalSubtypesString = Settings.readPrefAdditionalSubtypes(prefs, context.resources) - val oldAdditionalSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(oldAdditionalSubtypesString) - val newAdditionalSubtypes = oldAdditionalSubtypes.filter { it != subtype.subtype } - val newAdditionalSubtypesString = AdditionalSubtypeUtils.createPrefSubtypes(newAdditionalSubtypes.toTypedArray()) - Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString) + removeAdditionalSubtype(prefs, context.resources, subtype.subtype) removeEnabledSubtype(prefs, subtype.subtype) onSubtypesChanged() } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsFragment.kt b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsFragment.kt index 188ded44c..48d250e59 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsFragment.kt +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/LanguageSettingsFragment.kt @@ -2,6 +2,7 @@ package org.dslul.openboard.inputmethod.latin.settings import android.app.Activity import android.content.Intent +import android.content.SharedPreferences import android.content.res.Resources import android.net.Uri import android.os.Bundle @@ -29,12 +30,13 @@ class LanguageSettingsFragment : SubScreenFragment() { enabledSubtypes.addAll(getExplicitlyEnabledSubtypes()) systemLocales.addAll(getSystemLocales()) - val systemLocalesSwitch = findPreference(Settings.PREF_USE_SYSTEM_LOCALES) as TwoStatePreference - systemLocalesSwitch.setOnPreferenceChangeListener { _, b -> - loadSubtypes(b as Boolean) - true - } - loadSubtypes(systemLocalesSwitch.isChecked) + loadSubtypes() + } + + override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String) { + super.onSharedPreferenceChanged(prefs, key) + if (key == Settings.PREF_USE_SYSTEM_LOCALES) + loadSubtypes() } override fun onResume() { @@ -47,7 +49,8 @@ class LanguageSettingsFragment : SubScreenFragment() { languageFilterListPreference.setSettingsFragment(null) } - private fun loadSubtypes(systemOnly: Boolean) { + private fun loadSubtypes() { + val systemOnly = (findPreference(Settings.PREF_USE_SYSTEM_LOCALES) as TwoStatePreference).isChecked sortedSubtypes.clear() val allSubtypes = getAllAvailableSubtypes().toMutableList() // maybe make use of the map used by SubtypeSettings for performance reasons? diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SubtypeSettings.kt b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SubtypeSettings.kt index e074bccb6..7e155da53 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SubtypeSettings.kt +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SubtypeSettings.kt @@ -75,11 +75,28 @@ fun removeEnabledSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) RichInputMethodManager.getInstance().refreshSubtypeCaches() } +fun addAdditionalSubtype(prefs: SharedPreferences, resources: Resources, subtype: InputMethodSubtype) { + val oldAdditionalSubtypesString = Settings.readPrefAdditionalSubtypes(prefs, resources) + val oldAdditionalSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(oldAdditionalSubtypesString).toSet() + val newAdditionalSubtypesString = AdditionalSubtypeUtils.createPrefSubtypes((oldAdditionalSubtypes + subtype).toTypedArray()) + Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString) +} + +fun removeAdditionalSubtype(prefs: SharedPreferences, resources: Resources, subtype: InputMethodSubtype) { + val oldAdditionalSubtypesString = Settings.readPrefAdditionalSubtypes(prefs, resources) + val oldAdditionalSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(oldAdditionalSubtypesString) + val newAdditionalSubtypes = oldAdditionalSubtypes.filter { it != subtype } + val newAdditionalSubtypesString = AdditionalSubtypeUtils.createPrefSubtypes(newAdditionalSubtypes.toTypedArray()) + Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString) +} + fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype { require(initialized) val subtypeString = prefs.getString(Settings.PREF_SELECTED_INPUT_STYLE, "")!!.split(LOCALE_LAYOUT_SEPARATOR) - val subtype = enabledSubtypes.firstOrNull { subtypeString.first() == it.locale && subtypeString.last() == SubtypeLocaleUtils.getKeyboardLayoutSetName(it) } - ?: enabledSubtypes.firstOrNull() + val subtypes = if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, true)) getDefaultEnabledSubtypes() + else enabledSubtypes + val subtype = subtypes.firstOrNull { subtypeString.first() == it.locale && subtypeString.last() == SubtypeLocaleUtils.getKeyboardLayoutSetName(it) } + ?: subtypes.firstOrNull() if (subtype == null) { val defaultSubtypes = getDefaultEnabledSubtypes() return defaultSubtypes.firstOrNull { subtypeString.first() == it.locale && subtypeString.last() == SubtypeLocaleUtils.getKeyboardLayoutSetName(it) } @@ -113,6 +130,7 @@ fun reloadSystemLocales(context: Context) { val locale = localeList[it] if (locale != null) systemLocales.add(locale) } + systemSubtypes.clear() } fun getSystemLocales(): List { @@ -135,16 +153,20 @@ fun init(context: Context) { } private fun getDefaultEnabledSubtypes(): List { - val inputMethodSubtypes = systemLocales.mapNotNull { locale -> + if (systemSubtypes.isNotEmpty()) return systemSubtypes + val subtypes = systemLocales.mapNotNull { locale -> val localeString = locale.toString() - val subtypes = resourceSubtypesByLocale[localeString] + val subtypesOfLocale = resourceSubtypesByLocale[localeString] ?: resourceSubtypesByLocale[localeString.substringBefore("_")] // fall back to language match - subtypes?.firstOrNull() // todo: maybe set default for some languages with multiple resource subtypes? + subtypesOfLocale?.firstOrNull() } - if (inputMethodSubtypes.isEmpty()) + if (subtypes.isEmpty()) { // hardcoded fallback for weird cases - return listOf(resourceSubtypesByLocale["en_US"]!!.first()) - return inputMethodSubtypes + systemSubtypes.add(resourceSubtypesByLocale["en_US"]!!.first()) + } else { + systemSubtypes.addAll(subtypes) + } + return systemSubtypes } private fun InputMethodSubtype.prefString() = @@ -219,6 +241,7 @@ private val enabledSubtypes = mutableListOf() private val resourceSubtypesByLocale = LinkedHashMap>(100) private val additionalSubtypes = mutableListOf() private val systemLocales = mutableListOf() +private val systemSubtypes = mutableListOf() private const val SUBTYPE_SEPARATOR = ";" private const val LOCALE_LAYOUT_SEPARATOR = ":"