diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index 647c0eea6..36ecb334f 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -86,7 +86,7 @@ import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.StatsUtils; import helium314.keyboard.latin.utils.StatsUtilsManager; import helium314.keyboard.latin.utils.SubtypeLocaleUtils; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.ViewLayoutUtils; import helium314.keyboard.settings.SettingsActivity; import helium314.keyboard.settings.SettingsActivityKt; @@ -572,7 +572,7 @@ public class LatinIME extends InputMethodService implements public void onCreate() { Settings.init(this); DebugFlags.init(this); - SubtypeSettingsKt.init(this); + SubtypeSettings.INSTANCE.init(this); KeyboardIconsSet.Companion.getInstance().loadIcons(this); RichInputMethodManager.init(this); mRichImm = RichInputMethodManager.getInstance(); @@ -745,7 +745,7 @@ public class LatinIME extends InputMethodService implements public void onConfigurationChanged(final Configuration conf) { SettingsValues settingsValues = mSettings.getCurrent(); Log.i(TAG, "onConfigurationChanged"); - SubtypeSettingsKt.reloadSystemLocales(this); + SubtypeSettings.INSTANCE.reloadSystemLocales(this); if (settingsValues.mDisplayOrientation != conf.orientation) { mHandler.startOrientationChanging(); mInputLogic.onOrientationChange(mSettings.getCurrent()); diff --git a/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java b/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java index ad28f8255..914d34408 100644 --- a/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java +++ b/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java @@ -23,7 +23,7 @@ import helium314.keyboard.latin.utils.LanguageOnSpacebarUtils; import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.ScriptUtils; import helium314.keyboard.latin.utils.SubtypeLocaleUtils; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsKt; import java.util.Collections; @@ -171,7 +171,7 @@ public class RichInputMethodManager { if (imi == getInputMethodOfThisIme()) { // allowsImplicitlySelectedSubtypes means system should choose if nothing is enabled, // use it to fall back to system locales or en_US to avoid returning an empty list - result = SubtypeSettingsKt.getEnabledSubtypes(KtxKt.prefs(sInstance.mContext), allowsImplicitlySelectedSubtypes); + result = SubtypeSettings.INSTANCE.getEnabledSubtypes(KtxKt.prefs(sInstance.mContext), allowsImplicitlySelectedSubtypes); } else { result = mImm.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes); } @@ -351,12 +351,12 @@ public class RichInputMethodManager { public void refreshSubtypeCaches() { mInputMethodInfoCache.clear(); SharedPreferences prefs = KtxKt.prefs(mContext); - updateCurrentSubtype(SubtypeSettingsKt.getSelectedSubtype(prefs)); + updateCurrentSubtype(SubtypeSettings.INSTANCE.getSelectedSubtype(prefs)); updateShortcutIme(); } private void updateCurrentSubtype(final InputMethodSubtype subtype) { - SubtypeSettingsKt.setSelectedSubtype(KtxKt.prefs(mContext), subtype); + SubtypeSettings.INSTANCE.setSelectedSubtype(KtxKt.prefs(mContext), subtype); mCurrentRichInputMethodSubtype = RichInputMethodSubtype.Companion.get(subtype); } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt index 99b3b373e..d3e4168fb 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt @@ -49,10 +49,9 @@ import helium314.keyboard.latin.utils.DeviceProtectedUtils import helium314.keyboard.latin.utils.ExecutorUtils import helium314.keyboard.latin.utils.JniUtils import helium314.keyboard.latin.utils.ResourceUtils +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.infoDialog -import helium314.keyboard.latin.utils.reloadEnabledSubtypes -import helium314.keyboard.latin.utils.updateAdditionalSubtypes import java.io.File import java.io.FileInputStream import java.io.FileOutputStream @@ -410,8 +409,8 @@ class AdvancedSettingsFragment : SubScreenFragment() { checkVersionUpgrade(requireContext()) Settings.getInstance().startListener() val additionalSubtypes = sharedPreferences.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! - updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) - reloadEnabledSubtypes(requireContext()) + SubtypeSettings.updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) + SubtypeSettings.reloadEnabledSubtypes(requireContext()) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) activity?.sendBroadcast(newDictBroadcast) // reload current prefs screen diff --git a/app/src/main/java/helium314/keyboard/latin/settings/LanguageFilterList.kt b/app/src/main/java/helium314/keyboard/latin/settings/LanguageFilterList.kt index 87ca72d1d..b9bf30280 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/LanguageFilterList.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/LanguageFilterList.kt @@ -22,12 +22,10 @@ import androidx.recyclerview.widget.RecyclerView import helium314.keyboard.latin.R import helium314.keyboard.latin.common.LocaleUtils import helium314.keyboard.latin.utils.SubtypeLocaleUtils -import helium314.keyboard.latin.utils.addEnabledSubtype +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.displayName -import helium314.keyboard.latin.utils.isAdditionalSubtype import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.prefs -import helium314.keyboard.latin.utils.removeEnabledSubtype import helium314.keyboard.latin.utils.showMissingDictionaryDialog class LanguageFilterList(searchField: EditText, recyclerView: RecyclerView) { @@ -125,10 +123,10 @@ private class LanguageAdapter(list: List> = listOf(), c if (b) { if (!infos.first().hasDictionary) showMissingDictionaryDialog(context, infos.first().subtype.locale()) - addEnabledSubtype(prefs, infos.first().subtype) + SubtypeSettings.addEnabledSubtype(prefs, infos.first().subtype) infos.first().isEnabled = true } else { - removeEnabledSubtype(prefs, infos.first().subtype) + SubtypeSettings.removeEnabledSubtype(prefs, infos.first().subtype) infos.first().isEnabled = false } } @@ -154,7 +152,7 @@ private class LanguageAdapter(list: List> = listOf(), c private fun sort(infos: MutableList) { if (infos.size <= 1) return - infos.sortWith(compareBy({ isAdditionalSubtype(it.subtype) }, { it.displayName })) + infos.sortWith(compareBy({ SubtypeSettings.isAdditionalSubtype(it.subtype) }, { it.displayName })) } } } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsDialog.kt b/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsDialog.kt index f805bc081..8fed8ea1f 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsDialog.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsDialog.kt @@ -104,7 +104,7 @@ class LanguageSettingsDialog( val newSubtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(mainLocale, name, infos.first().subtype.isAsciiCapable) val newSubtypeInfo = newSubtype.toSubtypeInfo(mainLocale, context, true, infos.first().hasDictionary) // enabled by default val displayName = SubtypeLocaleUtils.getMainLayoutDisplayName(newSubtype) - val old = infos.firstOrNull { isAdditionalSubtype(it.subtype) && displayName == SubtypeLocaleUtils.getMainLayoutDisplayName(it.subtype) } + val old = infos.firstOrNull { SubtypeSettings.isAdditionalSubtype(it.subtype) && displayName == SubtypeLocaleUtils.getMainLayoutDisplayName(it.subtype) } if (old != null) { KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context) reloadSetting() @@ -112,7 +112,7 @@ class LanguageSettingsDialog( } SubtypeUtilsAdditional.addAdditionalSubtype(prefs, newSubtype) - addEnabledSubtype(prefs, newSubtype) + SubtypeSettings.addEnabledSubtype(prefs, newSubtype) addSubtypeToView(newSubtypeInfo) KeyboardLayoutSet.onKeyboardThemeChanged() infos.add(newSubtypeInfo) @@ -185,15 +185,15 @@ class LanguageSettingsDialog( if (b) { if (!infos.first().hasDictionary) showMissingDictionaryDialog(context, mainLocale) - addEnabledSubtype(prefs, subtype.subtype) + SubtypeSettings.addEnabledSubtype(prefs, subtype.subtype) } else - removeEnabledSubtype(prefs, subtype.subtype) + SubtypeSettings.removeEnabledSubtype(prefs, subtype.subtype) subtype.isEnabled = b reloadSetting() } } - if (isAdditionalSubtype(subtype.subtype)) { + if (SubtypeSettings.isAdditionalSubtype(subtype.subtype)) { row.findViewById(R.id.language_switch).isEnabled = true row.findViewById(R.id.delete_button).apply { isVisible = true @@ -205,7 +205,7 @@ class LanguageSettingsDialog( //if (isCustom) // LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context) SubtypeUtilsAdditional.removeAdditionalSubtype(prefs, subtype.subtype) - removeEnabledSubtype(prefs, subtype.subtype) + SubtypeSettings.removeEnabledSubtype(prefs, subtype.subtype) reloadSetting() } if (isCustom) { diff --git a/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsFragment.kt index fbec0c8cd..7002ca1c4 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsFragment.kt @@ -23,10 +23,8 @@ import helium314.keyboard.latin.common.LocaleUtils.constructLocale import helium314.keyboard.latin.utils.DictionaryInfoUtils import helium314.keyboard.latin.utils.ScriptUtils.script import helium314.keyboard.latin.utils.SubtypeLocaleUtils -import helium314.keyboard.latin.utils.getAllAvailableSubtypes +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.getDictionaryLocales -import helium314.keyboard.latin.utils.getEnabledSubtypes -import helium314.keyboard.latin.utils.getSystemLocales import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.prefs import java.util.* @@ -60,8 +58,8 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) { SubtypeLocaleUtils.init(requireContext()) - enabledSubtypes.addAll(getEnabledSubtypes(prefs)) - systemLocales.addAll(getSystemLocales()) + enabledSubtypes.addAll(SubtypeSettings.getEnabledSubtypes(prefs)) + systemLocales.addAll(SubtypeSettings.getSystemLocales()) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -71,7 +69,7 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) { systemOnlySwitch.setOnCheckedChangeListener { _, b -> prefs.edit { putBoolean(Settings.PREF_USE_SYSTEM_LOCALES, b) } enabledSubtypes.clear() - enabledSubtypes.addAll(getEnabledSubtypes(prefs)) + enabledSubtypes.addAll(SubtypeSettings.getEnabledSubtypes(prefs)) loadSubtypes(b) } languageFilterList = LanguageFilterList(view.findViewById(R.id.search_field), view.findViewById(R.id.language_list)) @@ -97,7 +95,7 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) { private fun loadSubtypes(systemOnly: Boolean) { sortedSubtypesByDisplayName.clear() // list of all subtypes, any subtype added to sortedSubtypes will be removed to avoid duplicates - val allSubtypes = getAllAvailableSubtypes().toMutableList() + val allSubtypes = SubtypeSettings.getAllAvailableSubtypes().toMutableList() fun List.sortedAddToSubtypesAndRemoveFromAllSubtypes() { val subtypesToAdd = mutableListOf() forEach { locale -> diff --git a/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java b/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java index bc56de40d..cc5a4402c 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java @@ -22,7 +22,7 @@ import helium314.keyboard.latin.R; import helium314.keyboard.latin.RichInputMethodManager; import helium314.keyboard.latin.utils.DialogUtilsKt; import helium314.keyboard.latin.utils.PopupKeysUtilsKt; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsKt; import kotlin.collections.ArraysKt; @@ -106,7 +106,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment { if (pref == null) return; // locales that have a number row defined (not good to have it hardcoded, but reading a bunch of files may be noticeably slow) final String[] numberRowLocales = new String[] { "ar", "bn", "fa", "gu", "hi", "kn", "mr", "ne", "ur" }; - for (final InputMethodSubtype subtype : SubtypeSettingsKt.getEnabledSubtypes(getSharedPreferences(), true)) { + for (final InputMethodSubtype subtype : SubtypeSettings.INSTANCE.getEnabledSubtypes(getSharedPreferences(), true)) { if (ArraysKt.any(numberRowLocales, (l) -> l.equals(SubtypeUtilsKt.locale(subtype).getLanguage()))) { pref.setVisible(true); return; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 6b1e30ab7..b27b40ddb 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -37,7 +37,7 @@ import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.ResourceUtils; import helium314.keyboard.latin.utils.RunInLocaleKt; import helium314.keyboard.latin.utils.StatsUtils; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsAdditional; import helium314.keyboard.latin.utils.ToolbarKey; import helium314.keyboard.latin.utils.ToolbarUtilsKt; @@ -243,7 +243,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang } if (PREF_ADDITIONAL_SUBTYPES.equals(key)) { final String additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES); - SubtypeSettingsKt.updateAdditionalSubtypes(SubtypeUtilsAdditional.INSTANCE.createAdditionalSubtypes(additionalSubtypes)); + SubtypeSettings.INSTANCE.updateAdditionalSubtypes(SubtypeUtilsAdditional.INSTANCE.createAdditionalSubtypes(additionalSubtypes)); } } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsFragment.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsFragment.java index 944050d00..f5c1f49e9 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsFragment.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsFragment.java @@ -29,7 +29,7 @@ import helium314.keyboard.latin.utils.DictionaryUtilsKt; import helium314.keyboard.latin.utils.ExecutorUtils; import helium314.keyboard.latin.utils.JniUtils; import helium314.keyboard.latin.utils.KtxKt; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsKt; import java.util.List; @@ -77,7 +77,7 @@ public final class SettingsFragment extends PreferenceFragmentCompat { // sometimes wrong languages are returned when not initializing on creation of LatinIME // this might be a bug, at least it's not documented // but anyway, here is really rare (LatinIme should be loaded when the settings are opened) - SubtypeSettingsKt.init(getActivity()); + SubtypeSettings.INSTANCE.init(getActivity()); findPreference("screen_languages").setSummary(getEnabledSubtypesLabel()); if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED) @@ -85,7 +85,7 @@ public final class SettingsFragment extends PreferenceFragmentCompat { } private String getEnabledSubtypesLabel() { - final List subtypes = SubtypeSettingsKt.getEnabledSubtypes(KtxKt.prefs(getActivity()), true); + final List subtypes = SubtypeSettings.INSTANCE.getEnabledSubtypes(KtxKt.prefs(getActivity()), true); final StringBuilder sb = new StringBuilder(); for (final InputMethodSubtype subtype : subtypes) { if (sb.length() > 0) diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 2cc1bc6f7..cfb1ff250 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -30,7 +30,7 @@ import helium314.keyboard.latin.utils.JniUtils; import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.PopupKeysUtilsKt; import helium314.keyboard.latin.utils.ScriptUtils; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import java.util.Arrays; import java.util.List; @@ -247,7 +247,7 @@ public class SettingsValues { mOneHandedModeScale = 1 - (1 - baseScale) * extraScale; } else mOneHandedModeScale = 1f; - final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs); + final InputMethodSubtype selectedSubtype = SubtypeSettings.INSTANCE.getSelectedSubtype(prefs); mSecondaryLocales = Settings.getSecondaryLocales(prefs, mLocale); mShowMorePopupKeys = selectedSubtype.isAsciiCapable() ? Settings.readMorePopupKeysPref(prefs) diff --git a/app/src/main/java/helium314/keyboard/latin/settings/UserDictionaryListFragment.java b/app/src/main/java/helium314/keyboard/latin/settings/UserDictionaryListFragment.java index 62d82aa8a..98d073c35 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/UserDictionaryListFragment.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/UserDictionaryListFragment.java @@ -26,7 +26,7 @@ import androidx.preference.PreferenceGroup; import helium314.keyboard.latin.R; import helium314.keyboard.latin.utils.KtxKt; import helium314.keyboard.latin.utils.SubtypeLocaleUtils; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsKt; import java.util.Comparator; @@ -110,7 +110,7 @@ public class UserDictionaryListFragment extends SubScreenFragment { final TreeSet sortedLocales = new TreeSet<>(new LocaleComparator()); // Add the main language selected in the "Language and Layouts" setting except "No language" - for (InputMethodSubtype mainSubtype : SubtypeSettingsKt.getEnabledSubtypes(prefs, true)) { + for (InputMethodSubtype mainSubtype : SubtypeSettings.INSTANCE.getEnabledSubtypes(prefs, true)) { final Locale mainLocale = SubtypeUtilsKt.locale(mainSubtype); if (!mainLocale.toLanguageTag().equals(SubtypeLocaleUtils.NO_LANGUAGE)) { sortedLocales.add(mainLocale); @@ -121,7 +121,7 @@ public class UserDictionaryListFragment extends SubScreenFragment { } } - sortedLocales.addAll(SubtypeSettingsKt.getSystemLocales()); + sortedLocales.addAll(SubtypeSettings.INSTANCE.getSystemLocales()); return sortedLocales; } diff --git a/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java b/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java index c553a683e..d7f99a201 100644 --- a/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java +++ b/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java @@ -31,7 +31,7 @@ import helium314.keyboard.latin.settings.Defaults; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.SettingsValuesForSuggestion; import helium314.keyboard.latin.utils.KtxKt; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsAdditional; import helium314.keyboard.latin.utils.SuggestionResults; @@ -85,7 +85,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService onSharedPreferenceChanged(prefs, Settings.PREF_USE_CONTACTS); final boolean blockOffensive = prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, Defaults.PREF_BLOCK_POTENTIALLY_OFFENSIVE); mSettingsValuesForSuggestion = new SettingsValuesForSuggestion(blockOffensive, false); - SubtypeSettingsKt.init(this); + SubtypeSettings.INSTANCE.init(this); } public float getRecommendedThreshold() { @@ -199,7 +199,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService editorInfo.inputType = InputType.TYPE_CLASS_TEXT; Settings.getInstance().loadSettings(this, locale, new InputAttributes(editorInfo, false, getPackageName())); } - final String mainLayoutName = SubtypeSettingsKt.getMatchingMainLayoutNameForLocale(locale); + final String mainLayoutName = SubtypeSettings.INSTANCE.getMatchingMainLayoutNameForLocale(locale); final InputMethodSubtype subtype = SubtypeUtilsAdditional.INSTANCE.createDummyAdditionalSubtype(locale, mainLayoutName); final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype); return keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); diff --git a/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index df285ef84..1487ddd4e 100644 --- a/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -34,7 +34,7 @@ import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; import helium314.keyboard.latin.utils.ScriptUtils; import helium314.keyboard.latin.utils.StatsUtils; -import helium314.keyboard.latin.utils.SubtypeSettingsKt; +import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SuggestionResults; import java.util.ArrayList; @@ -153,9 +153,9 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { } // localeString for this app is always empty, get it from settings if possible // and we're sure this app is used - if (SubtypeSettingsKt.getInitialized() && "dummy".equals(currentInputMethodSubtype.getExtraValue())) { + if (SubtypeSettings.INSTANCE.getInitialized() && "dummy".equals(currentInputMethodSubtype.getExtraValue())) { final SharedPreferences prefs = KtxKt.prefs(mService); - return SubtypeSettingsKt.getSelectedSubtype(prefs).getLocale(); + return SubtypeSettings.INSTANCE.getSelectedSubtype(prefs).getLocale(); } } } diff --git a/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt index b4e34a0da..c80b49ed3 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt @@ -102,7 +102,7 @@ fun cleanUnusedMainDicts(context: Context) { val dirs = dictionaryDir.listFiles() ?: return val prefs = context.prefs() val usedLocaleLanguageTags = hashSetOf() - getEnabledSubtypes(prefs).forEach { subtype -> + SubtypeSettings.getEnabledSubtypes(prefs).forEach { subtype -> val locale = subtype.locale() usedLocaleLanguageTags.add(locale.toLanguageTag()) Settings.getSecondaryLocales(prefs, locale).forEach { usedLocaleLanguageTags.add(it.toLanguageTag()) } diff --git a/app/src/main/java/helium314/keyboard/latin/utils/LayoutUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/LayoutUtils.kt index 7dd81831f..0ac9b258b 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/LayoutUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/LayoutUtils.kt @@ -12,11 +12,11 @@ object LayoutUtils { if (layoutType != LayoutType.MAIN) return context.assets.list(layoutType.folder)?.map { it.substringBefore(".") }.orEmpty() if (locale == null) - return getAllAvailableSubtypes().mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" } + return SubtypeSettings.getAllAvailableSubtypes().mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" } if (locale.script() == ScriptUtils.SCRIPT_LATIN) - return getAllAvailableSubtypes().filter { it.isAsciiCapable && !LayoutUtilsCustom.isCustomLayout(it.mainLayoutName() ?: "qwerty") } + return SubtypeSettings.getAllAvailableSubtypes().filter { it.isAsciiCapable && !LayoutUtilsCustom.isCustomLayout(it.mainLayoutName() ?: "qwerty") } .mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" } - return getSubtypesForLocale(locale).mapNotNullTo(HashSet()) { it.mainLayoutName() } + return SubtypeSettings.getSubtypesForLocale(locale).mapNotNullTo(HashSet()) { it.mainLayoutName() } } fun getLMainLayoutsForLocales(locales: List, context: Context): Collection = diff --git a/app/src/main/java/helium314/keyboard/latin/utils/NewDictionaryAdder.kt b/app/src/main/java/helium314/keyboard/latin/utils/NewDictionaryAdder.kt index c7343c9fa..7ace57bed 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/NewDictionaryAdder.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/NewDictionaryAdder.kt @@ -56,7 +56,7 @@ class NewDictionaryAdder(private val context: Context, private val onAdded: ((Bo .setMessage(message) .setNeutralButton(android.R.string.cancel) { _, _ -> cachedDictionaryFile.delete() } .setNegativeButton(R.string.button_select_language) { _, _ -> selectLocaleForDictionary(newHeader, locale) } - if (hasMatchingSubtypeForLocale(locale)) { + if (SubtypeSettings.hasMatchingSubtypeForLocale(locale)) { val buttonText = context.getString(R.string.button_add_to_language, localeName) b.setPositiveButton(buttonText) { _, _ -> addDictAndAskToReplace(newHeader, locale) @@ -90,7 +90,7 @@ class NewDictionaryAdder(private val context: Context, private val onAdded: ((Bo } private fun selectLocaleForDictionary(newHeader: DictionaryHeader, dictLocale: Locale) { - val locales = getAvailableSubtypeLocales().sortedBy { it.language != dictLocale.language } // matching languages should show first + val locales = SubtypeSettings.getAvailableSubtypeLocales().sortedBy { it.language != dictLocale.language } // matching languages should show first val displayNamesArray = locales.map { LocaleUtils.getLocaleDisplayNameInSystemLocale(it, context) }.toTypedArray() AlertDialog.Builder(context) .setTitle(R.string.button_select_language) diff --git a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeSettings.kt b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeSettings.kt index 9594da4c5..8b7b51215 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeSettings.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeSettings.kt @@ -20,257 +20,259 @@ import helium314.keyboard.latin.utils.ScriptUtils.script import helium314.keyboard.latin.utils.SettingsSubtype.Companion.toSettingsSubtype import java.util.Locale -/** @return enabled subtypes. If no subtypes are enabled, but a contextForFallback is provided, - * subtypes for system locales will be returned, or en-US if none found. */ -fun getEnabledSubtypes(prefs: SharedPreferences, fallback: Boolean = false): List { - require(initialized) - if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) - return getDefaultEnabledSubtypes() - if (fallback && enabledSubtypes.isEmpty()) - return getDefaultEnabledSubtypes() - return enabledSubtypes -} - -fun getAllAvailableSubtypes(): List { - require(initialized) - return resourceSubtypesByLocale.values.flatten() + additionalSubtypes -} - -fun getMatchingMainLayoutNameForLocale(locale: Locale): String { - val subtypes = resourceSubtypesByLocale.values.flatten() - val name = LocaleUtils.getBestMatch(locale, subtypes) { it.locale() }?.mainLayoutName() - if (name != null) return name - return when (locale.script()) { - ScriptUtils.SCRIPT_LATIN -> "qwerty" - ScriptUtils.SCRIPT_ARMENIAN -> "armenian_phonetic" - ScriptUtils.SCRIPT_CYRILLIC -> "ru" - ScriptUtils.SCRIPT_GREEK -> "greek" - ScriptUtils.SCRIPT_HEBREW -> "hebrew" - ScriptUtils.SCRIPT_GEORGIAN -> "georgian" - ScriptUtils.SCRIPT_BENGALI -> "bengali_unijoy" - else -> throw RuntimeException("Wrong script supplied: ${locale.script()}") +object SubtypeSettings { + /** @return enabled subtypes. If no subtypes are enabled, but a contextForFallback is provided, + * subtypes for system locales will be returned, or en-US if none found. */ + fun getEnabledSubtypes(prefs: SharedPreferences, fallback: Boolean = false): List { + require(initialized) + if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) + return getDefaultEnabledSubtypes() + if (fallback && enabledSubtypes.isEmpty()) + return getDefaultEnabledSubtypes() + return enabledSubtypes } -} -fun addEnabledSubtype(prefs: SharedPreferences, newSubtype: InputMethodSubtype) { - require(initialized) - val subtypeString = newSubtype.toSettingsSubtype().toPref() - val oldSubtypeStrings = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!!.split(Separators.SETS) - val newString = (oldSubtypeStrings + subtypeString).filter { it.isNotBlank() }.toSortedSet().joinToString(Separators.SETS) - prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) } + fun getAllAvailableSubtypes(): List { + require(initialized) + return resourceSubtypesByLocale.values.flatten() + additionalSubtypes + } - if (newSubtype !in enabledSubtypes) { - enabledSubtypes.add(newSubtype) - enabledSubtypes.sortBy { it.locale().toLanguageTag() } // for consistent order + fun getMatchingMainLayoutNameForLocale(locale: Locale): String { + val subtypes = resourceSubtypesByLocale.values.flatten() + val name = LocaleUtils.getBestMatch(locale, subtypes) { it.locale() }?.mainLayoutName() + if (name != null) return name + return when (locale.script()) { + ScriptUtils.SCRIPT_LATIN -> "qwerty" + ScriptUtils.SCRIPT_ARMENIAN -> "armenian_phonetic" + ScriptUtils.SCRIPT_CYRILLIC -> "ru" + ScriptUtils.SCRIPT_GREEK -> "greek" + ScriptUtils.SCRIPT_HEBREW -> "hebrew" + ScriptUtils.SCRIPT_GEORGIAN -> "georgian" + ScriptUtils.SCRIPT_BENGALI -> "bengali_unijoy" + else -> throw RuntimeException("Wrong script supplied: ${locale.script()}") + } + } + + fun addEnabledSubtype(prefs: SharedPreferences, newSubtype: InputMethodSubtype) { + require(initialized) + val subtypeString = newSubtype.toSettingsSubtype().toPref() + val oldSubtypeStrings = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!!.split(Separators.SETS) + val newString = (oldSubtypeStrings + subtypeString).filter { it.isNotBlank() }.toSortedSet().joinToString(Separators.SETS) + prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) } + + if (newSubtype !in enabledSubtypes) { + enabledSubtypes.add(newSubtype) + enabledSubtypes.sortBy { it.locale().toLanguageTag() } // for consistent order + RichInputMethodManager.getInstance().refreshSubtypeCaches() + } + } + + /** returns whether subtype was actually removed, does not remove last subtype */ + fun removeEnabledSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) { + require(initialized) + removeEnabledSubtype(prefs, subtype.toSettingsSubtype().toPref()) + enabledSubtypes.remove(subtype) RichInputMethodManager.getInstance().refreshSubtypeCaches() } -} -/** returns whether subtype was actually removed, does not remove last subtype */ -fun removeEnabledSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) { - require(initialized) - removeEnabledSubtype(prefs, subtype.toSettingsSubtype().toPref()) - enabledSubtypes.remove(subtype) - RichInputMethodManager.getInstance().refreshSubtypeCaches() -} - -fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype { - require(initialized) - val selectedSubtype = prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)!!.toSettingsSubtype() - val selectedAdditionalSubtype = selectedSubtype.toAdditionalSubtype() - if (selectedAdditionalSubtype != null && additionalSubtypes.contains(selectedAdditionalSubtype)) - return selectedAdditionalSubtype // don't even care whether it's enabled - // no additional subtype, must be a resource subtype - val subtypes = if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) getDefaultEnabledSubtypes() + fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype { + require(initialized) + val selectedSubtype = prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)!!.toSettingsSubtype() + val selectedAdditionalSubtype = selectedSubtype.toAdditionalSubtype() + if (selectedAdditionalSubtype != null && additionalSubtypes.contains(selectedAdditionalSubtype)) + return selectedAdditionalSubtype // don't even care whether it's enabled + // no additional subtype, must be a resource subtype + val subtypes = if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) getDefaultEnabledSubtypes() else enabledSubtypes - val subtype = subtypes.firstOrNull { it.toSettingsSubtype() == selectedSubtype } - if (subtype != null) { - return subtype - } else { - Log.w(TAG, "selected subtype $selectedSubtype / ${prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)} not found") + val subtype = subtypes.firstOrNull { it.toSettingsSubtype() == selectedSubtype } + if (subtype != null) { + return subtype + } else { + Log.w(TAG, "selected subtype $selectedSubtype / ${prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)} not found") + } + if (subtypes.isNotEmpty()) + return subtypes.first() + val defaultSubtypes = getDefaultEnabledSubtypes() + return defaultSubtypes.firstOrNull { it.locale() == selectedSubtype.locale && it.mainLayoutName() == it.mainLayoutName() } + ?: defaultSubtypes.firstOrNull { it.locale().language == selectedSubtype.locale.language } + ?: defaultSubtypes.first() } - if (subtypes.isNotEmpty()) - return subtypes.first() - val defaultSubtypes = getDefaultEnabledSubtypes() - return defaultSubtypes.firstOrNull { it.locale() == selectedSubtype.locale && it.mainLayoutName() == it.mainLayoutName() } - ?: defaultSubtypes.firstOrNull { it.locale().language == selectedSubtype.locale.language } - ?: defaultSubtypes.first() -} -fun setSelectedSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) { - val subtypeString = subtype.toSettingsSubtype().toPref() - if (subtype.locale().toLanguageTag().isEmpty() || prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE) == subtypeString) - return - prefs.edit { putString(Settings.PREF_SELECTED_SUBTYPE, subtypeString) } -} - -// todo: use this or the version in SubtypeUtilsAdditional? -fun isAdditionalSubtype(subtype: InputMethodSubtype): Boolean { - return subtype in additionalSubtypes -} - -fun updateAdditionalSubtypes(subtypes: List) { - additionalSubtypes.clear() - additionalSubtypes.addAll(subtypes) - RichInputMethodManager.getInstance().refreshSubtypeCaches() -} - -fun reloadSystemLocales(context: Context) { - systemLocales.clear() - val localeList = LocaleManagerCompat.getSystemLocales(context) - (0 until localeList.size()).forEach { - val locale = localeList[it] - if (locale != null) systemLocales.add(locale) + fun setSelectedSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) { + val subtypeString = subtype.toSettingsSubtype().toPref() + if (subtype.locale().toLanguageTag().isEmpty() || prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE) == subtypeString) + return + prefs.edit { putString(Settings.PREF_SELECTED_SUBTYPE, subtypeString) } } - systemSubtypes.clear() -} -fun getSystemLocales(): List { - require(initialized) - return systemLocales -} + // todo: use this or the version in SubtypeUtilsAdditional? + fun isAdditionalSubtype(subtype: InputMethodSubtype): Boolean { + return subtype in additionalSubtypes + } -fun hasMatchingSubtypeForLocale(locale: Locale): Boolean { - require(initialized) - return !resourceSubtypesByLocale[locale].isNullOrEmpty() -} + fun updateAdditionalSubtypes(subtypes: List) { + additionalSubtypes.clear() + additionalSubtypes.addAll(subtypes) + RichInputMethodManager.getInstance().refreshSubtypeCaches() + } -fun getSubtypesForLocale(locale: Locale): List = resourceSubtypesByLocale[locale].orEmpty() + fun reloadSystemLocales(context: Context) { + systemLocales.clear() + val localeList = LocaleManagerCompat.getSystemLocales(context) + (0 until localeList.size()).forEach { + val locale = localeList[it] + if (locale != null) systemLocales.add(locale) + } + systemSubtypes.clear() + } -fun getAvailableSubtypeLocales(): Collection { - require(initialized) - return resourceSubtypesByLocale.keys -} + fun getSystemLocales(): List { + require(initialized) + return systemLocales + } -fun reloadEnabledSubtypes(context: Context) { - require(initialized) - enabledSubtypes.clear() - removeInvalidCustomSubtypes(context) - loadEnabledSubtypes(context) -} + fun hasMatchingSubtypeForLocale(locale: Locale): Boolean { + require(initialized) + return !resourceSubtypesByLocale[locale].isNullOrEmpty() + } -fun init(context: Context) { - if (initialized) return - SubtypeLocaleUtils.init(context) // necessary to get the correct getKeyboardLayoutSetName + fun getSubtypesForLocale(locale: Locale): List = resourceSubtypesByLocale[locale].orEmpty() - // necessary to set system locales at start, because for some weird reason (bug?) - // LocaleManagerCompat.getSystemLocales(context) sometimes doesn't return all system locales - reloadSystemLocales(context) + fun getAvailableSubtypeLocales(): Collection { + require(initialized) + return resourceSubtypesByLocale.keys + } - loadResourceSubtypes(context.resources) - removeInvalidCustomSubtypes(context) - loadAdditionalSubtypes(context.prefs()) - loadEnabledSubtypes(context) - initialized = true -} + fun reloadEnabledSubtypes(context: Context) { + require(initialized) + enabledSubtypes.clear() + removeInvalidCustomSubtypes(context) + loadEnabledSubtypes(context) + } -private fun getDefaultEnabledSubtypes(): List { - if (systemSubtypes.isNotEmpty()) return systemSubtypes - val subtypes = systemLocales.mapNotNull { locale -> - val subtypesOfLocale = resourceSubtypesByLocale[locale] + fun init(context: Context) { + if (initialized) return + SubtypeLocaleUtils.init(context) // necessary to get the correct getKeyboardLayoutSetName + + // necessary to set system locales at start, because for some weird reason (bug?) + // LocaleManagerCompat.getSystemLocales(context) sometimes doesn't return all system locales + reloadSystemLocales(context) + + loadResourceSubtypes(context.resources) + removeInvalidCustomSubtypes(context) + loadAdditionalSubtypes(context.prefs()) + loadEnabledSubtypes(context) + initialized = true + } + + private fun getDefaultEnabledSubtypes(): List { + if (systemSubtypes.isNotEmpty()) return systemSubtypes + val subtypes = systemLocales.mapNotNull { locale -> + val subtypesOfLocale = resourceSubtypesByLocale[locale] // get best match - ?: LocaleUtils.getBestMatch(locale, resourceSubtypesByLocale.keys) {it}?.let { resourceSubtypesByLocale[it] } - subtypesOfLocale?.firstOrNull() - } - if (subtypes.isEmpty()) { - // hardcoded fallback to en-US for weird cases - systemSubtypes.add(resourceSubtypesByLocale[Locale.US]!!.first()) - } else { - systemSubtypes.addAll(subtypes) - } - return systemSubtypes -} - -private fun loadResourceSubtypes(resources: Resources) { - getResourceSubtypes(resources).forEach { - resourceSubtypesByLocale.getOrPut(it.locale()) { ArrayList(2) }.add(it) - } -} - -// remove custom subtypes without a layout file -private fun removeInvalidCustomSubtypes(context: Context) { // todo: new layout structure! - val prefs = context.prefs() - val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(";") - val customSubtypeFiles by lazy { LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, context).map { it.name } } - val subtypesToRemove = mutableListOf() - additionalSubtypes.forEach { - val name = it.substringAfter(":").substringBefore(":") - if (!LayoutUtilsCustom.isCustomLayout(name)) return@forEach - if (name !in customSubtypeFiles) - subtypesToRemove.add(it) - } - if (subtypesToRemove.isEmpty()) return - Log.w(TAG, "removing custom subtypes without files: $subtypesToRemove") - Settings.writePrefAdditionalSubtypes(prefs, additionalSubtypes.filterNot { it in subtypesToRemove }.joinToString(";")) -} - -private fun loadAdditionalSubtypes(prefs: SharedPreferences) { - val additionalSubtypeString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! - val subtypes = SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypeString) - additionalSubtypes.addAll(subtypes) -} - -// requires loadResourceSubtypes to be called before -private fun loadEnabledSubtypes(context: Context) { - val prefs = context.prefs() - val settingsSubtypes = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!! - .split(Separators.SETS).filter { it.isNotEmpty() }.map { it.toSettingsSubtype() } - for (settingsSubtype in settingsSubtypes) { - val additionalSubtype = settingsSubtype.toAdditionalSubtype() - if (additionalSubtype != null && additionalSubtypes.contains(additionalSubtype)) { - enabledSubtypes.add(additionalSubtype) - continue + ?: LocaleUtils.getBestMatch(locale, resourceSubtypesByLocale.keys) {it}?.let { resourceSubtypesByLocale[it] } + subtypesOfLocale?.firstOrNull() } - val subtypesForLocale = resourceSubtypesByLocale[settingsSubtype.locale] - if (subtypesForLocale == null) { - val message = "no resource subtype for $settingsSubtype" - Log.w(TAG, message) - if (DebugFlags.DEBUG_ENABLED) - Toast.makeText(context, message, Toast.LENGTH_LONG).show() - else // don't remove in debug mode - removeEnabledSubtype(prefs, settingsSubtype.toPref()) - continue + if (subtypes.isEmpty()) { + // hardcoded fallback to en-US for weird cases + systemSubtypes.add(resourceSubtypesByLocale[Locale.US]!!.first()) + } else { + systemSubtypes.addAll(subtypes) } + return systemSubtypes + } - val subtype = subtypesForLocale.firstOrNull { SubtypeLocaleUtils.getMainLayoutName(it) == (settingsSubtype.mainLayoutName() ?: "qwerty") } - if (subtype == null) { - val message = "subtype $settingsSubtype could not be loaded" - Log.w(TAG, message) - if (DebugFlags.DEBUG_ENABLED) - Toast.makeText(context, message, Toast.LENGTH_LONG).show() - else // don't remove in debug mode - removeEnabledSubtype(prefs, settingsSubtype.toPref()) - continue + private fun loadResourceSubtypes(resources: Resources) { + getResourceSubtypes(resources).forEach { + resourceSubtypesByLocale.getOrPut(it.locale()) { ArrayList(2) }.add(it) } - - enabledSubtypes.add(subtype) } -} -private fun removeEnabledSubtype(prefs: SharedPreferences, subtypeString: String) { - val oldSubtypeString = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!! - val newString = (oldSubtypeString.split(Separators.SETS) - subtypeString).joinToString(Separators.SETS) - if (newString == oldSubtypeString) - return // already removed - prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) } - if (subtypeString == prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)) { - // switch subtype if the currently used one has been disabled - try { - val nextSubtype = RichInputMethodManager.getInstance().getNextSubtypeInThisIme(true) - if (subtypeString == nextSubtype?.toSettingsSubtype()?.toPref()) - KeyboardSwitcher.getInstance().switchToSubtype(getDefaultEnabledSubtypes().first()) - else - KeyboardSwitcher.getInstance().switchToSubtype(nextSubtype) - } catch (_: Exception) { } // do nothing if RichInputMethodManager isn't initialized + // remove custom subtypes without a layout file + private fun removeInvalidCustomSubtypes(context: Context) { // todo: new layout structure! + val prefs = context.prefs() + val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(";") + val customSubtypeFiles by lazy { LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, context).map { it.name } } + val subtypesToRemove = mutableListOf() + additionalSubtypes.forEach { + val name = it.substringAfter(":").substringBefore(":") + if (!LayoutUtilsCustom.isCustomLayout(name)) return@forEach + if (name !in customSubtypeFiles) + subtypesToRemove.add(it) + } + if (subtypesToRemove.isEmpty()) return + Log.w(TAG, "removing custom subtypes without files: $subtypesToRemove") + Settings.writePrefAdditionalSubtypes(prefs, additionalSubtypes.filterNot { it in subtypesToRemove }.joinToString(";")) } -} -var initialized = false - private set -private val enabledSubtypes = mutableListOf() -private val resourceSubtypesByLocale = LinkedHashMap>(100) -private val additionalSubtypes = mutableListOf() -private val systemLocales = mutableListOf() -private val systemSubtypes = mutableListOf() -private const val TAG = "SubtypeSettings" + private fun loadAdditionalSubtypes(prefs: SharedPreferences) { + val additionalSubtypeString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! + val subtypes = SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypeString) + additionalSubtypes.addAll(subtypes) + } + + // requires loadResourceSubtypes to be called before + private fun loadEnabledSubtypes(context: Context) { + val prefs = context.prefs() + val settingsSubtypes = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!! + .split(Separators.SETS).filter { it.isNotEmpty() }.map { it.toSettingsSubtype() } + for (settingsSubtype in settingsSubtypes) { + val additionalSubtype = settingsSubtype.toAdditionalSubtype() + if (additionalSubtype != null && additionalSubtypes.contains(additionalSubtype)) { + enabledSubtypes.add(additionalSubtype) + continue + } + val subtypesForLocale = resourceSubtypesByLocale[settingsSubtype.locale] + if (subtypesForLocale == null) { + val message = "no resource subtype for $settingsSubtype" + Log.w(TAG, message) + if (DebugFlags.DEBUG_ENABLED) + Toast.makeText(context, message, Toast.LENGTH_LONG).show() + else // don't remove in debug mode + removeEnabledSubtype(prefs, settingsSubtype.toPref()) + continue + } + + val subtype = subtypesForLocale.firstOrNull { SubtypeLocaleUtils.getMainLayoutName(it) == (settingsSubtype.mainLayoutName() ?: "qwerty") } + if (subtype == null) { + val message = "subtype $settingsSubtype could not be loaded" + Log.w(TAG, message) + if (DebugFlags.DEBUG_ENABLED) + Toast.makeText(context, message, Toast.LENGTH_LONG).show() + else // don't remove in debug mode + removeEnabledSubtype(prefs, settingsSubtype.toPref()) + continue + } + + enabledSubtypes.add(subtype) + } + } + + private fun removeEnabledSubtype(prefs: SharedPreferences, subtypeString: String) { + val oldSubtypeString = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!! + val newString = (oldSubtypeString.split(Separators.SETS) - subtypeString).joinToString(Separators.SETS) + if (newString == oldSubtypeString) + return // already removed + prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) } + if (subtypeString == prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)) { + // switch subtype if the currently used one has been disabled + try { + val nextSubtype = RichInputMethodManager.getInstance().getNextSubtypeInThisIme(true) + if (subtypeString == nextSubtype?.toSettingsSubtype()?.toPref()) + KeyboardSwitcher.getInstance().switchToSubtype(getDefaultEnabledSubtypes().first()) + else + KeyboardSwitcher.getInstance().switchToSubtype(nextSubtype) + } catch (_: Exception) { } // do nothing if RichInputMethodManager isn't initialized + } + } + + var initialized = false + private set + private val enabledSubtypes = mutableListOf() + private val resourceSubtypesByLocale = LinkedHashMap>(100) + private val additionalSubtypes = mutableListOf() + private val systemLocales = mutableListOf() + private val systemSubtypes = mutableListOf() + private const val TAG = "SubtypeSettings" +} diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt b/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt index 556fcc1a6..8359a0b8f 100644 --- a/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt +++ b/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt @@ -21,8 +21,8 @@ import helium314.keyboard.latin.common.FileUtils import helium314.keyboard.latin.define.DebugFlags import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.ExecutorUtils +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.cleanUnusedMainDicts -import helium314.keyboard.latin.utils.init import helium314.keyboard.latin.utils.prefs import kotlinx.coroutines.flow.MutableStateFlow import java.io.BufferedOutputStream @@ -45,7 +45,7 @@ class SettingsActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferen super.onCreate(savedInstanceState) if (Settings.getInstance().current == null) Settings.init(this) - init(this) // todo: move into object so it's clear what is initialized + SubtypeSettings.init(this) ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute { cleanUnusedMainDicts(this) } if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED) askAboutCrashReports() diff --git a/app/src/main/java/helium314/keyboard/settings/preferences/BackupRestorePreference.kt b/app/src/main/java/helium314/keyboard/settings/preferences/BackupRestorePreference.kt index 1eaa8cc34..54ae66196 100644 --- a/app/src/main/java/helium314/keyboard/settings/preferences/BackupRestorePreference.kt +++ b/app/src/main/java/helium314/keyboard/settings/preferences/BackupRestorePreference.kt @@ -34,12 +34,11 @@ import helium314.keyboard.latin.utils.DeviceProtectedUtils import helium314.keyboard.latin.utils.ExecutorUtils import helium314.keyboard.latin.utils.LayoutUtilsCustom import helium314.keyboard.latin.utils.Log +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.protectedPrefs -import helium314.keyboard.latin.utils.reloadEnabledSubtypes -import helium314.keyboard.latin.utils.updateAdditionalSubtypes import helium314.keyboard.settings.Setting import helium314.keyboard.settings.SettingsActivity import helium314.keyboard.settings.dialogs.ConfirmationDialog @@ -176,8 +175,8 @@ fun BackupRestorePreference(setting: Setting) { checkVersionUpgrade(ctx) Settings.getInstance().startListener() val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! - updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) - reloadEnabledSubtypes(ctx) + SubtypeSettings.updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) + SubtypeSettings.reloadEnabledSubtypes(ctx) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) ctx.getActivity()?.sendBroadcast(newDictBroadcast) LayoutUtilsCustom.onLayoutFileChanged() diff --git a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt index 3f6fe916a..a8df5aec4 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt @@ -15,8 +15,8 @@ import helium314.keyboard.latin.R import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.Log +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.getActivity -import helium314.keyboard.latin.utils.getEnabledSubtypes import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.prefs import helium314.keyboard.settings.SettingsContainer @@ -57,7 +57,7 @@ fun PreferencesScreen( Settings.PREF_KEYPRESS_SOUND_VOLUME else null, R.string.settings_category_additional_keys, Settings.PREF_SHOW_NUMBER_ROW, - if (getEnabledSubtypes(prefs, true).any { it.locale().language in localesWithLocalizedNumberRow }) + if (SubtypeSettings.getEnabledSubtypes(prefs, true).any { it.locale().language in localesWithLocalizedNumberRow }) Settings.PREF_LOCALIZED_NUMBER_ROW else null, if (prefs.getBoolean(Settings.PREF_SHOW_HINTS, Defaults.PREF_SHOW_HINTS) && prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, Defaults.PREF_SHOW_NUMBER_ROW))