change subtypeSettings to object, so it's clear which init is called

This commit is contained in:
Helium314 2025-02-16 12:49:19 +01:00
parent 6e77437ea9
commit 2c1d6a5f4c
20 changed files with 283 additions and 287 deletions

View file

@ -86,7 +86,7 @@ import helium314.keyboard.latin.utils.Log;
import helium314.keyboard.latin.utils.StatsUtils; import helium314.keyboard.latin.utils.StatsUtils;
import helium314.keyboard.latin.utils.StatsUtilsManager; import helium314.keyboard.latin.utils.StatsUtilsManager;
import helium314.keyboard.latin.utils.SubtypeLocaleUtils; 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.latin.utils.ViewLayoutUtils;
import helium314.keyboard.settings.SettingsActivity; import helium314.keyboard.settings.SettingsActivity;
import helium314.keyboard.settings.SettingsActivityKt; import helium314.keyboard.settings.SettingsActivityKt;
@ -572,7 +572,7 @@ public class LatinIME extends InputMethodService implements
public void onCreate() { public void onCreate() {
Settings.init(this); Settings.init(this);
DebugFlags.init(this); DebugFlags.init(this);
SubtypeSettingsKt.init(this); SubtypeSettings.INSTANCE.init(this);
KeyboardIconsSet.Companion.getInstance().loadIcons(this); KeyboardIconsSet.Companion.getInstance().loadIcons(this);
RichInputMethodManager.init(this); RichInputMethodManager.init(this);
mRichImm = RichInputMethodManager.getInstance(); mRichImm = RichInputMethodManager.getInstance();
@ -745,7 +745,7 @@ public class LatinIME extends InputMethodService implements
public void onConfigurationChanged(final Configuration conf) { public void onConfigurationChanged(final Configuration conf) {
SettingsValues settingsValues = mSettings.getCurrent(); SettingsValues settingsValues = mSettings.getCurrent();
Log.i(TAG, "onConfigurationChanged"); Log.i(TAG, "onConfigurationChanged");
SubtypeSettingsKt.reloadSystemLocales(this); SubtypeSettings.INSTANCE.reloadSystemLocales(this);
if (settingsValues.mDisplayOrientation != conf.orientation) { if (settingsValues.mDisplayOrientation != conf.orientation) {
mHandler.startOrientationChanging(); mHandler.startOrientationChanging();
mInputLogic.onOrientationChange(mSettings.getCurrent()); mInputLogic.onOrientationChange(mSettings.getCurrent());

View file

@ -23,7 +23,7 @@ import helium314.keyboard.latin.utils.LanguageOnSpacebarUtils;
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.SubtypeLocaleUtils; 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 helium314.keyboard.latin.utils.SubtypeUtilsKt;
import java.util.Collections; import java.util.Collections;
@ -171,7 +171,7 @@ public class RichInputMethodManager {
if (imi == getInputMethodOfThisIme()) { if (imi == getInputMethodOfThisIme()) {
// allowsImplicitlySelectedSubtypes means system should choose if nothing is enabled, // 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 // 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 { } else {
result = mImm.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes); result = mImm.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes);
} }
@ -351,12 +351,12 @@ public class RichInputMethodManager {
public void refreshSubtypeCaches() { public void refreshSubtypeCaches() {
mInputMethodInfoCache.clear(); mInputMethodInfoCache.clear();
SharedPreferences prefs = KtxKt.prefs(mContext); SharedPreferences prefs = KtxKt.prefs(mContext);
updateCurrentSubtype(SubtypeSettingsKt.getSelectedSubtype(prefs)); updateCurrentSubtype(SubtypeSettings.INSTANCE.getSelectedSubtype(prefs));
updateShortcutIme(); updateShortcutIme();
} }
private void updateCurrentSubtype(final InputMethodSubtype subtype) { private void updateCurrentSubtype(final InputMethodSubtype subtype) {
SubtypeSettingsKt.setSelectedSubtype(KtxKt.prefs(mContext), subtype); SubtypeSettings.INSTANCE.setSelectedSubtype(KtxKt.prefs(mContext), subtype);
mCurrentRichInputMethodSubtype = RichInputMethodSubtype.Companion.get(subtype); mCurrentRichInputMethodSubtype = RichInputMethodSubtype.Companion.get(subtype);
} }

View file

@ -49,10 +49,9 @@ import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.ExecutorUtils import helium314.keyboard.latin.utils.ExecutorUtils
import helium314.keyboard.latin.utils.JniUtils import helium314.keyboard.latin.utils.JniUtils
import helium314.keyboard.latin.utils.ResourceUtils import helium314.keyboard.latin.utils.ResourceUtils
import helium314.keyboard.latin.utils.SubtypeSettings
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
import helium314.keyboard.latin.utils.infoDialog 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.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
@ -410,8 +409,8 @@ class AdvancedSettingsFragment : SubScreenFragment() {
checkVersionUpgrade(requireContext()) checkVersionUpgrade(requireContext())
Settings.getInstance().startListener() Settings.getInstance().startListener()
val additionalSubtypes = sharedPreferences.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! val additionalSubtypes = sharedPreferences.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) SubtypeSettings.updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes))
reloadEnabledSubtypes(requireContext()) SubtypeSettings.reloadEnabledSubtypes(requireContext())
val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)
activity?.sendBroadcast(newDictBroadcast) activity?.sendBroadcast(newDictBroadcast)
// reload current prefs screen // reload current prefs screen

View file

@ -22,12 +22,10 @@ import androidx.recyclerview.widget.RecyclerView
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.LocaleUtils import helium314.keyboard.latin.common.LocaleUtils
import helium314.keyboard.latin.utils.SubtypeLocaleUtils 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.displayName
import helium314.keyboard.latin.utils.isAdditionalSubtype
import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.locale
import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.prefs
import helium314.keyboard.latin.utils.removeEnabledSubtype
import helium314.keyboard.latin.utils.showMissingDictionaryDialog import helium314.keyboard.latin.utils.showMissingDictionaryDialog
class LanguageFilterList(searchField: EditText, recyclerView: RecyclerView) { class LanguageFilterList(searchField: EditText, recyclerView: RecyclerView) {
@ -125,10 +123,10 @@ private class LanguageAdapter(list: List<MutableList<SubtypeInfo>> = listOf(), c
if (b) { if (b) {
if (!infos.first().hasDictionary) if (!infos.first().hasDictionary)
showMissingDictionaryDialog(context, infos.first().subtype.locale()) showMissingDictionaryDialog(context, infos.first().subtype.locale())
addEnabledSubtype(prefs, infos.first().subtype) SubtypeSettings.addEnabledSubtype(prefs, infos.first().subtype)
infos.first().isEnabled = true infos.first().isEnabled = true
} else { } else {
removeEnabledSubtype(prefs, infos.first().subtype) SubtypeSettings.removeEnabledSubtype(prefs, infos.first().subtype)
infos.first().isEnabled = false infos.first().isEnabled = false
} }
} }
@ -154,7 +152,7 @@ private class LanguageAdapter(list: List<MutableList<SubtypeInfo>> = listOf(), c
private fun sort(infos: MutableList<SubtypeInfo>) { private fun sort(infos: MutableList<SubtypeInfo>) {
if (infos.size <= 1) return if (infos.size <= 1) return
infos.sortWith(compareBy({ isAdditionalSubtype(it.subtype) }, { it.displayName })) infos.sortWith(compareBy({ SubtypeSettings.isAdditionalSubtype(it.subtype) }, { it.displayName }))
} }
} }
} }

View file

@ -104,7 +104,7 @@ class LanguageSettingsDialog(
val newSubtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(mainLocale, name, infos.first().subtype.isAsciiCapable) val newSubtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(mainLocale, name, infos.first().subtype.isAsciiCapable)
val newSubtypeInfo = newSubtype.toSubtypeInfo(mainLocale, context, true, infos.first().hasDictionary) // enabled by default val newSubtypeInfo = newSubtype.toSubtypeInfo(mainLocale, context, true, infos.first().hasDictionary) // enabled by default
val displayName = SubtypeLocaleUtils.getMainLayoutDisplayName(newSubtype) 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) { if (old != null) {
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context) KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
reloadSetting() reloadSetting()
@ -112,7 +112,7 @@ class LanguageSettingsDialog(
} }
SubtypeUtilsAdditional.addAdditionalSubtype(prefs, newSubtype) SubtypeUtilsAdditional.addAdditionalSubtype(prefs, newSubtype)
addEnabledSubtype(prefs, newSubtype) SubtypeSettings.addEnabledSubtype(prefs, newSubtype)
addSubtypeToView(newSubtypeInfo) addSubtypeToView(newSubtypeInfo)
KeyboardLayoutSet.onKeyboardThemeChanged() KeyboardLayoutSet.onKeyboardThemeChanged()
infos.add(newSubtypeInfo) infos.add(newSubtypeInfo)
@ -185,15 +185,15 @@ class LanguageSettingsDialog(
if (b) { if (b) {
if (!infos.first().hasDictionary) if (!infos.first().hasDictionary)
showMissingDictionaryDialog(context, mainLocale) showMissingDictionaryDialog(context, mainLocale)
addEnabledSubtype(prefs, subtype.subtype) SubtypeSettings.addEnabledSubtype(prefs, subtype.subtype)
} }
else else
removeEnabledSubtype(prefs, subtype.subtype) SubtypeSettings.removeEnabledSubtype(prefs, subtype.subtype)
subtype.isEnabled = b subtype.isEnabled = b
reloadSetting() reloadSetting()
} }
} }
if (isAdditionalSubtype(subtype.subtype)) { if (SubtypeSettings.isAdditionalSubtype(subtype.subtype)) {
row.findViewById<Switch>(R.id.language_switch).isEnabled = true row.findViewById<Switch>(R.id.language_switch).isEnabled = true
row.findViewById<ImageView>(R.id.delete_button).apply { row.findViewById<ImageView>(R.id.delete_button).apply {
isVisible = true isVisible = true
@ -205,7 +205,7 @@ class LanguageSettingsDialog(
//if (isCustom) //if (isCustom)
// LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context) // LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context)
SubtypeUtilsAdditional.removeAdditionalSubtype(prefs, subtype.subtype) SubtypeUtilsAdditional.removeAdditionalSubtype(prefs, subtype.subtype)
removeEnabledSubtype(prefs, subtype.subtype) SubtypeSettings.removeEnabledSubtype(prefs, subtype.subtype)
reloadSetting() reloadSetting()
} }
if (isCustom) { if (isCustom) {

View file

@ -23,10 +23,8 @@ import helium314.keyboard.latin.common.LocaleUtils.constructLocale
import helium314.keyboard.latin.utils.DictionaryInfoUtils import helium314.keyboard.latin.utils.DictionaryInfoUtils
import helium314.keyboard.latin.utils.ScriptUtils.script import helium314.keyboard.latin.utils.ScriptUtils.script
import helium314.keyboard.latin.utils.SubtypeLocaleUtils 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.getDictionaryLocales
import helium314.keyboard.latin.utils.getEnabledSubtypes
import helium314.keyboard.latin.utils.getSystemLocales
import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.locale
import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.prefs
import java.util.* import java.util.*
@ -60,8 +58,8 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) {
SubtypeLocaleUtils.init(requireContext()) SubtypeLocaleUtils.init(requireContext())
enabledSubtypes.addAll(getEnabledSubtypes(prefs)) enabledSubtypes.addAll(SubtypeSettings.getEnabledSubtypes(prefs))
systemLocales.addAll(getSystemLocales()) systemLocales.addAll(SubtypeSettings.getSystemLocales())
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -71,7 +69,7 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) {
systemOnlySwitch.setOnCheckedChangeListener { _, b -> systemOnlySwitch.setOnCheckedChangeListener { _, b ->
prefs.edit { putBoolean(Settings.PREF_USE_SYSTEM_LOCALES, b) } prefs.edit { putBoolean(Settings.PREF_USE_SYSTEM_LOCALES, b) }
enabledSubtypes.clear() enabledSubtypes.clear()
enabledSubtypes.addAll(getEnabledSubtypes(prefs)) enabledSubtypes.addAll(SubtypeSettings.getEnabledSubtypes(prefs))
loadSubtypes(b) loadSubtypes(b)
} }
languageFilterList = LanguageFilterList(view.findViewById(R.id.search_field), view.findViewById(R.id.language_list)) 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) { private fun loadSubtypes(systemOnly: Boolean) {
sortedSubtypesByDisplayName.clear() sortedSubtypesByDisplayName.clear()
// list of all subtypes, any subtype added to sortedSubtypes will be removed to avoid duplicates // 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<Locale>.sortedAddToSubtypesAndRemoveFromAllSubtypes() { fun List<Locale>.sortedAddToSubtypesAndRemoveFromAllSubtypes() {
val subtypesToAdd = mutableListOf<SubtypeInfo>() val subtypesToAdd = mutableListOf<SubtypeInfo>()
forEach { locale -> forEach { locale ->

View file

@ -22,7 +22,7 @@ import helium314.keyboard.latin.R;
import helium314.keyboard.latin.RichInputMethodManager; import helium314.keyboard.latin.RichInputMethodManager;
import helium314.keyboard.latin.utils.DialogUtilsKt; import helium314.keyboard.latin.utils.DialogUtilsKt;
import helium314.keyboard.latin.utils.PopupKeysUtilsKt; 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 helium314.keyboard.latin.utils.SubtypeUtilsKt;
import kotlin.collections.ArraysKt; import kotlin.collections.ArraysKt;
@ -106,7 +106,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
if (pref == null) return; 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) // 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" }; 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()))) { if (ArraysKt.any(numberRowLocales, (l) -> l.equals(SubtypeUtilsKt.locale(subtype).getLanguage()))) {
pref.setVisible(true); pref.setVisible(true);
return; return;

View file

@ -37,7 +37,7 @@ import helium314.keyboard.latin.utils.Log;
import helium314.keyboard.latin.utils.ResourceUtils; import helium314.keyboard.latin.utils.ResourceUtils;
import helium314.keyboard.latin.utils.RunInLocaleKt; import helium314.keyboard.latin.utils.RunInLocaleKt;
import helium314.keyboard.latin.utils.StatsUtils; 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.SubtypeUtilsAdditional;
import helium314.keyboard.latin.utils.ToolbarKey; import helium314.keyboard.latin.utils.ToolbarKey;
import helium314.keyboard.latin.utils.ToolbarUtilsKt; import helium314.keyboard.latin.utils.ToolbarUtilsKt;
@ -243,7 +243,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
} }
if (PREF_ADDITIONAL_SUBTYPES.equals(key)) { if (PREF_ADDITIONAL_SUBTYPES.equals(key)) {
final String additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES); 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));
} }
} }

View file

@ -29,7 +29,7 @@ import helium314.keyboard.latin.utils.DictionaryUtilsKt;
import helium314.keyboard.latin.utils.ExecutorUtils; import helium314.keyboard.latin.utils.ExecutorUtils;
import helium314.keyboard.latin.utils.JniUtils; import helium314.keyboard.latin.utils.JniUtils;
import helium314.keyboard.latin.utils.KtxKt; 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 helium314.keyboard.latin.utils.SubtypeUtilsKt;
import java.util.List; 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 // sometimes wrong languages are returned when not initializing on creation of LatinIME
// this might be a bug, at least it's not documented // 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) // 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()); findPreference("screen_languages").setSummary(getEnabledSubtypesLabel());
if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED) if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED)
@ -85,7 +85,7 @@ public final class SettingsFragment extends PreferenceFragmentCompat {
} }
private String getEnabledSubtypesLabel() { private String getEnabledSubtypesLabel() {
final List<InputMethodSubtype> subtypes = SubtypeSettingsKt.getEnabledSubtypes(KtxKt.prefs(getActivity()), true); final List<InputMethodSubtype> subtypes = SubtypeSettings.INSTANCE.getEnabledSubtypes(KtxKt.prefs(getActivity()), true);
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
for (final InputMethodSubtype subtype : subtypes) { for (final InputMethodSubtype subtype : subtypes) {
if (sb.length() > 0) if (sb.length() > 0)

View file

@ -30,7 +30,7 @@ import helium314.keyboard.latin.utils.JniUtils;
import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.Log;
import helium314.keyboard.latin.utils.PopupKeysUtilsKt; import helium314.keyboard.latin.utils.PopupKeysUtilsKt;
import helium314.keyboard.latin.utils.ScriptUtils; 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.Arrays;
import java.util.List; import java.util.List;
@ -247,7 +247,7 @@ public class SettingsValues {
mOneHandedModeScale = 1 - (1 - baseScale) * extraScale; mOneHandedModeScale = 1 - (1 - baseScale) * extraScale;
} else } else
mOneHandedModeScale = 1f; mOneHandedModeScale = 1f;
final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs); final InputMethodSubtype selectedSubtype = SubtypeSettings.INSTANCE.getSelectedSubtype(prefs);
mSecondaryLocales = Settings.getSecondaryLocales(prefs, mLocale); mSecondaryLocales = Settings.getSecondaryLocales(prefs, mLocale);
mShowMorePopupKeys = selectedSubtype.isAsciiCapable() mShowMorePopupKeys = selectedSubtype.isAsciiCapable()
? Settings.readMorePopupKeysPref(prefs) ? Settings.readMorePopupKeysPref(prefs)

View file

@ -26,7 +26,7 @@ import androidx.preference.PreferenceGroup;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.utils.KtxKt; import helium314.keyboard.latin.utils.KtxKt;
import helium314.keyboard.latin.utils.SubtypeLocaleUtils; 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 helium314.keyboard.latin.utils.SubtypeUtilsKt;
import java.util.Comparator; import java.util.Comparator;
@ -110,7 +110,7 @@ public class UserDictionaryListFragment extends SubScreenFragment {
final TreeSet<Locale> sortedLocales = new TreeSet<>(new LocaleComparator()); final TreeSet<Locale> sortedLocales = new TreeSet<>(new LocaleComparator());
// Add the main language selected in the "Language and Layouts" setting except "No language" // 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); final Locale mainLocale = SubtypeUtilsKt.locale(mainSubtype);
if (!mainLocale.toLanguageTag().equals(SubtypeLocaleUtils.NO_LANGUAGE)) { if (!mainLocale.toLanguageTag().equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
sortedLocales.add(mainLocale); sortedLocales.add(mainLocale);
@ -121,7 +121,7 @@ public class UserDictionaryListFragment extends SubScreenFragment {
} }
} }
sortedLocales.addAll(SubtypeSettingsKt.getSystemLocales()); sortedLocales.addAll(SubtypeSettings.INSTANCE.getSystemLocales());
return sortedLocales; return sortedLocales;
} }

View file

@ -31,7 +31,7 @@ import helium314.keyboard.latin.settings.Defaults;
import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.Settings;
import helium314.keyboard.latin.settings.SettingsValuesForSuggestion; import helium314.keyboard.latin.settings.SettingsValuesForSuggestion;
import helium314.keyboard.latin.utils.KtxKt; 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.SubtypeUtilsAdditional;
import helium314.keyboard.latin.utils.SuggestionResults; import helium314.keyboard.latin.utils.SuggestionResults;
@ -85,7 +85,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
onSharedPreferenceChanged(prefs, Settings.PREF_USE_CONTACTS); onSharedPreferenceChanged(prefs, Settings.PREF_USE_CONTACTS);
final boolean blockOffensive = prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, Defaults.PREF_BLOCK_POTENTIALLY_OFFENSIVE); final boolean blockOffensive = prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, Defaults.PREF_BLOCK_POTENTIALLY_OFFENSIVE);
mSettingsValuesForSuggestion = new SettingsValuesForSuggestion(blockOffensive, false); mSettingsValuesForSuggestion = new SettingsValuesForSuggestion(blockOffensive, false);
SubtypeSettingsKt.init(this); SubtypeSettings.INSTANCE.init(this);
} }
public float getRecommendedThreshold() { public float getRecommendedThreshold() {
@ -199,7 +199,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
editorInfo.inputType = InputType.TYPE_CLASS_TEXT; editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
Settings.getInstance().loadSettings(this, locale, new InputAttributes(editorInfo, false, getPackageName())); 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 InputMethodSubtype subtype = SubtypeUtilsAdditional.INSTANCE.createDummyAdditionalSubtype(locale, mainLayoutName);
final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype); final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype);
return keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); return keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);

View file

@ -34,7 +34,7 @@ import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import helium314.keyboard.latin.utils.ScriptUtils; import helium314.keyboard.latin.utils.ScriptUtils;
import helium314.keyboard.latin.utils.StatsUtils; 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 helium314.keyboard.latin.utils.SuggestionResults;
import java.util.ArrayList; 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 // localeString for this app is always empty, get it from settings if possible
// and we're sure this app is used // 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); final SharedPreferences prefs = KtxKt.prefs(mService);
return SubtypeSettingsKt.getSelectedSubtype(prefs).getLocale(); return SubtypeSettings.INSTANCE.getSelectedSubtype(prefs).getLocale();
} }
} }
} }

View file

@ -102,7 +102,7 @@ fun cleanUnusedMainDicts(context: Context) {
val dirs = dictionaryDir.listFiles() ?: return val dirs = dictionaryDir.listFiles() ?: return
val prefs = context.prefs() val prefs = context.prefs()
val usedLocaleLanguageTags = hashSetOf<String>() val usedLocaleLanguageTags = hashSetOf<String>()
getEnabledSubtypes(prefs).forEach { subtype -> SubtypeSettings.getEnabledSubtypes(prefs).forEach { subtype ->
val locale = subtype.locale() val locale = subtype.locale()
usedLocaleLanguageTags.add(locale.toLanguageTag()) usedLocaleLanguageTags.add(locale.toLanguageTag())
Settings.getSecondaryLocales(prefs, locale).forEach { usedLocaleLanguageTags.add(it.toLanguageTag()) } Settings.getSecondaryLocales(prefs, locale).forEach { usedLocaleLanguageTags.add(it.toLanguageTag()) }

View file

@ -12,11 +12,11 @@ object LayoutUtils {
if (layoutType != LayoutType.MAIN) if (layoutType != LayoutType.MAIN)
return context.assets.list(layoutType.folder)?.map { it.substringBefore(".") }.orEmpty() return context.assets.list(layoutType.folder)?.map { it.substringBefore(".") }.orEmpty()
if (locale == null) 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) 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" } .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<Locale>, context: Context): Collection<String> = fun getLMainLayoutsForLocales(locales: List<Locale>, context: Context): Collection<String> =

View file

@ -56,7 +56,7 @@ class NewDictionaryAdder(private val context: Context, private val onAdded: ((Bo
.setMessage(message) .setMessage(message)
.setNeutralButton(android.R.string.cancel) { _, _ -> cachedDictionaryFile.delete() } .setNeutralButton(android.R.string.cancel) { _, _ -> cachedDictionaryFile.delete() }
.setNegativeButton(R.string.button_select_language) { _, _ -> selectLocaleForDictionary(newHeader, locale) } .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) val buttonText = context.getString(R.string.button_add_to_language, localeName)
b.setPositiveButton(buttonText) { _, _ -> b.setPositiveButton(buttonText) { _, _ ->
addDictAndAskToReplace(newHeader, locale) addDictAndAskToReplace(newHeader, locale)
@ -90,7 +90,7 @@ class NewDictionaryAdder(private val context: Context, private val onAdded: ((Bo
} }
private fun selectLocaleForDictionary(newHeader: DictionaryHeader, dictLocale: Locale) { 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() val displayNamesArray = locales.map { LocaleUtils.getLocaleDisplayNameInSystemLocale(it, context) }.toTypedArray()
AlertDialog.Builder(context) AlertDialog.Builder(context)
.setTitle(R.string.button_select_language) .setTitle(R.string.button_select_language)

View file

@ -20,257 +20,259 @@ import helium314.keyboard.latin.utils.ScriptUtils.script
import helium314.keyboard.latin.utils.SettingsSubtype.Companion.toSettingsSubtype import helium314.keyboard.latin.utils.SettingsSubtype.Companion.toSettingsSubtype
import java.util.Locale import java.util.Locale
/** @return enabled subtypes. If no subtypes are enabled, but a contextForFallback is provided, object SubtypeSettings {
* subtypes for system locales will be returned, or en-US if none found. */ /** @return enabled subtypes. If no subtypes are enabled, but a contextForFallback is provided,
fun getEnabledSubtypes(prefs: SharedPreferences, fallback: Boolean = false): List<InputMethodSubtype> { * subtypes for system locales will be returned, or en-US if none found. */
require(initialized) fun getEnabledSubtypes(prefs: SharedPreferences, fallback: Boolean = false): List<InputMethodSubtype> {
if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) require(initialized)
return getDefaultEnabledSubtypes() if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES))
if (fallback && enabledSubtypes.isEmpty()) return getDefaultEnabledSubtypes()
return getDefaultEnabledSubtypes() if (fallback && enabledSubtypes.isEmpty())
return enabledSubtypes return getDefaultEnabledSubtypes()
} return enabledSubtypes
fun getAllAvailableSubtypes(): List<InputMethodSubtype> {
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()}")
} }
}
fun addEnabledSubtype(prefs: SharedPreferences, newSubtype: InputMethodSubtype) { fun getAllAvailableSubtypes(): List<InputMethodSubtype> {
require(initialized) require(initialized)
val subtypeString = newSubtype.toSettingsSubtype().toPref() return resourceSubtypesByLocale.values.flatten() + additionalSubtypes
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) { fun getMatchingMainLayoutNameForLocale(locale: Locale): String {
enabledSubtypes.add(newSubtype) val subtypes = resourceSubtypesByLocale.values.flatten()
enabledSubtypes.sortBy { it.locale().toLanguageTag() } // for consistent order 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() RichInputMethodManager.getInstance().refreshSubtypeCaches()
} }
}
/** returns whether subtype was actually removed, does not remove last subtype */ fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype {
fun removeEnabledSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) { require(initialized)
require(initialized) val selectedSubtype = prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)!!.toSettingsSubtype()
removeEnabledSubtype(prefs, subtype.toSettingsSubtype().toPref()) val selectedAdditionalSubtype = selectedSubtype.toAdditionalSubtype()
enabledSubtypes.remove(subtype) if (selectedAdditionalSubtype != null && additionalSubtypes.contains(selectedAdditionalSubtype))
RichInputMethodManager.getInstance().refreshSubtypeCaches() 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 else enabledSubtypes
val subtype = subtypes.firstOrNull { it.toSettingsSubtype() == selectedSubtype } val subtype = subtypes.firstOrNull { it.toSettingsSubtype() == selectedSubtype }
if (subtype != null) { if (subtype != null) {
return subtype return subtype
} else { } else {
Log.w(TAG, "selected subtype $selectedSubtype / ${prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)} not found") 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) { fun setSelectedSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) {
val subtypeString = subtype.toSettingsSubtype().toPref() val subtypeString = subtype.toSettingsSubtype().toPref()
if (subtype.locale().toLanguageTag().isEmpty() || prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE) == subtypeString) if (subtype.locale().toLanguageTag().isEmpty() || prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE) == subtypeString)
return return
prefs.edit { putString(Settings.PREF_SELECTED_SUBTYPE, subtypeString) } 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<InputMethodSubtype>) {
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)
} }
systemSubtypes.clear()
}
fun getSystemLocales(): List<Locale> { // todo: use this or the version in SubtypeUtilsAdditional?
require(initialized) fun isAdditionalSubtype(subtype: InputMethodSubtype): Boolean {
return systemLocales return subtype in additionalSubtypes
} }
fun hasMatchingSubtypeForLocale(locale: Locale): Boolean { fun updateAdditionalSubtypes(subtypes: List<InputMethodSubtype>) {
require(initialized) additionalSubtypes.clear()
return !resourceSubtypesByLocale[locale].isNullOrEmpty() additionalSubtypes.addAll(subtypes)
} RichInputMethodManager.getInstance().refreshSubtypeCaches()
}
fun getSubtypesForLocale(locale: Locale): List<InputMethodSubtype> = 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<Locale> { fun getSystemLocales(): List<Locale> {
require(initialized) require(initialized)
return resourceSubtypesByLocale.keys return systemLocales
} }
fun reloadEnabledSubtypes(context: Context) { fun hasMatchingSubtypeForLocale(locale: Locale): Boolean {
require(initialized) require(initialized)
enabledSubtypes.clear() return !resourceSubtypesByLocale[locale].isNullOrEmpty()
removeInvalidCustomSubtypes(context) }
loadEnabledSubtypes(context)
}
fun init(context: Context) { fun getSubtypesForLocale(locale: Locale): List<InputMethodSubtype> = resourceSubtypesByLocale[locale].orEmpty()
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?) fun getAvailableSubtypeLocales(): Collection<Locale> {
// LocaleManagerCompat.getSystemLocales(context) sometimes doesn't return all system locales require(initialized)
reloadSystemLocales(context) return resourceSubtypesByLocale.keys
}
loadResourceSubtypes(context.resources) fun reloadEnabledSubtypes(context: Context) {
removeInvalidCustomSubtypes(context) require(initialized)
loadAdditionalSubtypes(context.prefs()) enabledSubtypes.clear()
loadEnabledSubtypes(context) removeInvalidCustomSubtypes(context)
initialized = true loadEnabledSubtypes(context)
} }
private fun getDefaultEnabledSubtypes(): List<InputMethodSubtype> { fun init(context: Context) {
if (systemSubtypes.isNotEmpty()) return systemSubtypes if (initialized) return
val subtypes = systemLocales.mapNotNull { locale -> SubtypeLocaleUtils.init(context) // necessary to get the correct getKeyboardLayoutSetName
val subtypesOfLocale = resourceSubtypesByLocale[locale]
// 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<InputMethodSubtype> {
if (systemSubtypes.isNotEmpty()) return systemSubtypes
val subtypes = systemLocales.mapNotNull { locale ->
val subtypesOfLocale = resourceSubtypesByLocale[locale]
// get best match // get best match
?: LocaleUtils.getBestMatch(locale, resourceSubtypesByLocale.keys) {it}?.let { resourceSubtypesByLocale[it] } ?: LocaleUtils.getBestMatch(locale, resourceSubtypesByLocale.keys) {it}?.let { resourceSubtypesByLocale[it] }
subtypesOfLocale?.firstOrNull() 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<String>()
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
} }
val subtypesForLocale = resourceSubtypesByLocale[settingsSubtype.locale] if (subtypes.isEmpty()) {
if (subtypesForLocale == null) { // hardcoded fallback to en-US for weird cases
val message = "no resource subtype for $settingsSubtype" systemSubtypes.add(resourceSubtypesByLocale[Locale.US]!!.first())
Log.w(TAG, message) } else {
if (DebugFlags.DEBUG_ENABLED) systemSubtypes.addAll(subtypes)
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
else // don't remove in debug mode
removeEnabledSubtype(prefs, settingsSubtype.toPref())
continue
} }
return systemSubtypes
}
val subtype = subtypesForLocale.firstOrNull { SubtypeLocaleUtils.getMainLayoutName(it) == (settingsSubtype.mainLayoutName() ?: "qwerty") } private fun loadResourceSubtypes(resources: Resources) {
if (subtype == null) { getResourceSubtypes(resources).forEach {
val message = "subtype $settingsSubtype could not be loaded" resourceSubtypesByLocale.getOrPut(it.locale()) { ArrayList(2) }.add(it)
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) { // remove custom subtypes without a layout file
val oldSubtypeString = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!! private fun removeInvalidCustomSubtypes(context: Context) { // todo: new layout structure!
val newString = (oldSubtypeString.split(Separators.SETS) - subtypeString).joinToString(Separators.SETS) val prefs = context.prefs()
if (newString == oldSubtypeString) val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(";")
return // already removed val customSubtypeFiles by lazy { LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, context).map { it.name } }
prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) } val subtypesToRemove = mutableListOf<String>()
if (subtypeString == prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)) { additionalSubtypes.forEach {
// switch subtype if the currently used one has been disabled val name = it.substringAfter(":").substringBefore(":")
try { if (!LayoutUtilsCustom.isCustomLayout(name)) return@forEach
val nextSubtype = RichInputMethodManager.getInstance().getNextSubtypeInThisIme(true) if (name !in customSubtypeFiles)
if (subtypeString == nextSubtype?.toSettingsSubtype()?.toPref()) subtypesToRemove.add(it)
KeyboardSwitcher.getInstance().switchToSubtype(getDefaultEnabledSubtypes().first()) }
else if (subtypesToRemove.isEmpty()) return
KeyboardSwitcher.getInstance().switchToSubtype(nextSubtype) Log.w(TAG, "removing custom subtypes without files: $subtypesToRemove")
} catch (_: Exception) { } // do nothing if RichInputMethodManager isn't initialized Settings.writePrefAdditionalSubtypes(prefs, additionalSubtypes.filterNot { it in subtypesToRemove }.joinToString(";"))
} }
}
var initialized = false private fun loadAdditionalSubtypes(prefs: SharedPreferences) {
private set val additionalSubtypeString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
private val enabledSubtypes = mutableListOf<InputMethodSubtype>() val subtypes = SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypeString)
private val resourceSubtypesByLocale = LinkedHashMap<Locale, MutableList<InputMethodSubtype>>(100) additionalSubtypes.addAll(subtypes)
private val additionalSubtypes = mutableListOf<InputMethodSubtype>() }
private val systemLocales = mutableListOf<Locale>()
private val systemSubtypes = mutableListOf<InputMethodSubtype>() // requires loadResourceSubtypes to be called before
private const val TAG = "SubtypeSettings" 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<InputMethodSubtype>()
private val resourceSubtypesByLocale = LinkedHashMap<Locale, MutableList<InputMethodSubtype>>(100)
private val additionalSubtypes = mutableListOf<InputMethodSubtype>()
private val systemLocales = mutableListOf<Locale>()
private val systemSubtypes = mutableListOf<InputMethodSubtype>()
private const val TAG = "SubtypeSettings"
}

View file

@ -21,8 +21,8 @@ import helium314.keyboard.latin.common.FileUtils
import helium314.keyboard.latin.define.DebugFlags import helium314.keyboard.latin.define.DebugFlags
import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.utils.ExecutorUtils import helium314.keyboard.latin.utils.ExecutorUtils
import helium314.keyboard.latin.utils.SubtypeSettings
import helium314.keyboard.latin.utils.cleanUnusedMainDicts import helium314.keyboard.latin.utils.cleanUnusedMainDicts
import helium314.keyboard.latin.utils.init
import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.prefs
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
@ -45,7 +45,7 @@ class SettingsActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferen
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (Settings.getInstance().current == null) if (Settings.getInstance().current == null)
Settings.init(this) 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) } ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute { cleanUnusedMainDicts(this) }
if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED) if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED)
askAboutCrashReports() askAboutCrashReports()

View file

@ -34,12 +34,11 @@ import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.ExecutorUtils import helium314.keyboard.latin.utils.ExecutorUtils
import helium314.keyboard.latin.utils.LayoutUtilsCustom import helium314.keyboard.latin.utils.LayoutUtilsCustom
import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.SubtypeSettings
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.getActivity
import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.prefs
import helium314.keyboard.latin.utils.protectedPrefs 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.Setting
import helium314.keyboard.settings.SettingsActivity import helium314.keyboard.settings.SettingsActivity
import helium314.keyboard.settings.dialogs.ConfirmationDialog import helium314.keyboard.settings.dialogs.ConfirmationDialog
@ -176,8 +175,8 @@ fun BackupRestorePreference(setting: Setting) {
checkVersionUpgrade(ctx) checkVersionUpgrade(ctx)
Settings.getInstance().startListener() Settings.getInstance().startListener()
val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) SubtypeSettings.updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes))
reloadEnabledSubtypes(ctx) SubtypeSettings.reloadEnabledSubtypes(ctx)
val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)
ctx.getActivity()?.sendBroadcast(newDictBroadcast) ctx.getActivity()?.sendBroadcast(newDictBroadcast)
LayoutUtilsCustom.onLayoutFileChanged() LayoutUtilsCustom.onLayoutFileChanged()

View file

@ -15,8 +15,8 @@ import helium314.keyboard.latin.R
import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Defaults
import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.SubtypeSettings
import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.getActivity
import helium314.keyboard.latin.utils.getEnabledSubtypes
import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.locale
import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.prefs
import helium314.keyboard.settings.SettingsContainer import helium314.keyboard.settings.SettingsContainer
@ -57,7 +57,7 @@ fun PreferencesScreen(
Settings.PREF_KEYPRESS_SOUND_VOLUME else null, Settings.PREF_KEYPRESS_SOUND_VOLUME else null,
R.string.settings_category_additional_keys, R.string.settings_category_additional_keys,
Settings.PREF_SHOW_NUMBER_ROW, 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, Settings.PREF_LOCALIZED_NUMBER_ROW else null,
if (prefs.getBoolean(Settings.PREF_SHOW_HINTS, Defaults.PREF_SHOW_HINTS) if (prefs.getBoolean(Settings.PREF_SHOW_HINTS, Defaults.PREF_SHOW_HINTS)
&& prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, Defaults.PREF_SHOW_NUMBER_ROW)) && prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, Defaults.PREF_SHOW_NUMBER_ROW))