diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 621b7c801..f75fcc0b8 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,8 +13,8 @@ android { applicationId = "helium314.keyboard" minSdk = 21 targetSdk = 34 - versionCode = 2308 - versionName = "2.3+dev7" + versionCode = 2309 + versionName = "2.3+dev8" ndk { abiFilters.clear() abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) diff --git a/app/src/main/java/helium314/keyboard/latin/App.kt b/app/src/main/java/helium314/keyboard/latin/App.kt index cea1919d2..39eae07ed 100644 --- a/app/src/main/java/helium314/keyboard/latin/App.kt +++ b/app/src/main/java/helium314/keyboard/latin/App.kt @@ -21,10 +21,12 @@ import helium314.keyboard.latin.utils.DictionaryInfoUtils import helium314.keyboard.latin.utils.LayoutType import helium314.keyboard.latin.utils.LayoutType.Companion.folder import helium314.keyboard.latin.utils.LayoutUtilsCustom +import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.ScriptUtils.SCRIPT_LATIN import helium314.keyboard.latin.utils.ScriptUtils.script import helium314.keyboard.latin.utils.SettingsSubtype import helium314.keyboard.latin.utils.SettingsSubtype.Companion.toSettingsSubtype +import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.ToolbarKey import helium314.keyboard.latin.utils.defaultPinnedToolbarPref @@ -380,6 +382,7 @@ fun checkVersionUpgrade(context: Context) { if (it.name in value) prefs.edit().putString(key, value.replace(it.name, newFile.name)).apply() } + LayoutUtilsCustom.onLayoutFileChanged() } } if (oldVersion <= 2305) { @@ -394,7 +397,7 @@ fun checkVersionUpgrade(context: Context) { val value = prefs.getString(it, "")!!.replace(":", Separators.SET) prefs.edit().putString(it, value).apply() } - prefs.all.keys.filter { it.startsWith(Settings.PREF_SECONDARY_LOCALES_PREFIX) }.forEach { + prefs.all.keys.filter { it.startsWith("secondary_locales_") }.forEach { val newValue = prefs.getString(it, "")!!.replace(";", Separators.KV) prefs.edit().putString(it, newValue).apply() } @@ -454,6 +457,61 @@ fun checkVersionUpgrade(context: Context) { prefs.edit().putString(it, prefs.getString(it, "")!!.replace("popup_keys_", "")).apply() } } + if (oldVersion <= 2308) { + SubtypeSettings.init(context) // not sure, but there may be cases where it's not initialized + SubtypeSettings.reloadEnabledSubtypes(context) + prefs.all.keys.toList().forEach { key -> + if (key.startsWith(Settings.PREF_POPUP_KEYS_ORDER+"_")) { + val locale = key.substringAfter(Settings.PREF_POPUP_KEYS_ORDER+"_").constructLocale() + SubtypeSettings.getEnabledSubtypes(prefs).forEach { + if (it.locale() == locale && !SubtypeSettings.isAdditionalSubtype(it)) { + SubtypeUtilsAdditional.changeAdditionalSubtype(it.toSettingsSubtype(), it.toSettingsSubtype(), context) + } + } + val additional = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!! + additional.split(Separators.SETS).forEach inner@{ + val subtype = it.toSettingsSubtype() + if (subtype.locale != locale) return@inner + val newSubtype = subtype.with(ExtraValue.POPUP_ORDER, prefs.getString(key, "")) + SubtypeUtilsAdditional.changeAdditionalSubtype(subtype, newSubtype, context) + } + prefs.edit().remove(key).apply() + } + if (key.startsWith(Settings.PREF_POPUP_KEYS_LABELS_ORDER+"_")) { + val locale = key.substringAfter(Settings.PREF_POPUP_KEYS_LABELS_ORDER+"_").constructLocale() + SubtypeSettings.getEnabledSubtypes(prefs).forEach { + if (it.locale() == locale && !SubtypeSettings.isAdditionalSubtype(it)) { + SubtypeUtilsAdditional.changeAdditionalSubtype(it.toSettingsSubtype(), it.toSettingsSubtype(), context) + } + } + val additional = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!! + additional.split(Separators.SETS).forEach inner@{ + val subtype = it.toSettingsSubtype() + if (subtype.locale != locale) return@inner + val newSubtype = subtype.with(ExtraValue.HINT_ORDER, prefs.getString(key, "")) + SubtypeUtilsAdditional.changeAdditionalSubtype(subtype, newSubtype, context) + } + prefs.edit().remove(key).apply() + } + if (key.startsWith("secondary_locales_")) { + val locale = key.substringAfter("secondary_locales_").constructLocale() + SubtypeSettings.getEnabledSubtypes(prefs).forEach { + if (it.locale() == locale && !SubtypeSettings.isAdditionalSubtype(it)) { + SubtypeUtilsAdditional.changeAdditionalSubtype(it.toSettingsSubtype(), it.toSettingsSubtype(), context) + } + } + val additional = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!! + val secondaryLocales = prefs.getString(key, "")!!.split(Separators.KV).filter { it.isNotBlank() }.joinToString(Separators.KV) + additional.split(Separators.SETS).forEach inner@{ + val subtype = it.toSettingsSubtype() + if (subtype.locale != locale) return@inner + val newSubtype = subtype.with(ExtraValue.SECONDARY_LOCALES, secondaryLocales) + SubtypeUtilsAdditional.changeAdditionalSubtype(subtype, newSubtype, context) + } + prefs.edit().remove(key).apply() + } + } + } upgradeToolbarPrefs(prefs) LayoutUtilsCustom.onLayoutFileChanged() // just to be sure prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) } diff --git a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java index e110fe9e1..4d8ca5f6f 100644 --- a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java +++ b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java @@ -57,13 +57,6 @@ public interface DictionaryFacilitator { */ boolean isForLocale(final Locale locale); - /** - * Returns whether this facilitator is exactly for this account. - * - * @param account the account to test against. - */ - boolean isForAccount(@Nullable final String account); - interface DictionaryInitializationListener { void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); } @@ -91,9 +84,12 @@ public interface DictionaryFacilitator { // useful for multilingual typing Locale getCurrentLocale(); - boolean usesContacts(); - - boolean usesPersonalization(); + boolean usesSameSettings( + @NonNull final List locales, + final boolean contacts, + final boolean personalization, + @Nullable final String account + ); String getAccount(); diff --git a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java index 4878f2db6..bd16232f3 100644 --- a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java +++ b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java @@ -16,6 +16,7 @@ import helium314.keyboard.latin.settings.SettingsValues; import helium314.keyboard.latin.utils.KtxKt; import helium314.keyboard.latin.utils.Log; import android.util.LruCache; +import android.view.inputmethod.InputMethodSubtype; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -31,6 +32,8 @@ import helium314.keyboard.latin.personalization.UserHistoryDictionary; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.SettingsValuesForSuggestion; import helium314.keyboard.latin.utils.ExecutorUtils; +import helium314.keyboard.latin.utils.SubtypeSettings; +import helium314.keyboard.latin.utils.SubtypeUtilsKt; import helium314.keyboard.latin.utils.SuggestionResults; import java.io.File; @@ -104,15 +107,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { return false; } - /** - * Returns whether this facilitator is exactly for this account. - * - * @param account the account to test against. - */ - public boolean isForAccount(@Nullable final String account) { - return TextUtils.equals(mDictionaryGroups.get(0).mAccount, account); - } - /** * A group of dictionaries that work together for a single language. */ @@ -277,12 +271,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { return getCurrentlyPreferredDictionaryGroup().mLocale; } - @Override public boolean usesContacts() { return mDictionaryGroups.get(0).getSubDict(Dictionary.TYPE_CONTACTS) != null; } - @Override public boolean usesPersonalization() { return mDictionaryGroups.get(0).getSubDict(Dictionary.TYPE_USER_HISTORY) != null; } @@ -292,6 +284,19 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { return null; } + @Override + public boolean usesSameSettings(@NonNull final List locales, final boolean contacts, + final boolean personalization, @Nullable final String account) { + final boolean first = usesContacts() == contacts && usesPersonalization() == personalization + && TextUtils.equals(mDictionaryGroups.get(0).mAccount, account) + && locales.size() == mDictionaryGroups.size(); + if (!first) return false; + for (int i = 0; i < locales.size(); i++) { + if (locales.get(i) != mDictionaryGroups.get(i).mLocale) return false; + } + return true; + } + @Nullable private static ExpandableBinaryDictionary getSubDict(final String dictType, final Context context, final Locale locale, final File dictFile, @@ -339,7 +344,20 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { Log.i(TAG, "resetDictionaries, force reloading main dictionary: " + forceReloadMainDictionary); final List allLocales = new ArrayList<>() {{ add(newLocale); - addAll(Settings.getSecondaryLocales(KtxKt.prefs(context), newLocale)); + + // adding secondary locales is a bit tricky since they depend on the subtype + // but usually this is called with the selected subtype locale + final InputMethodSubtype selected = SubtypeSettings.INSTANCE.getSelectedSubtype(KtxKt.prefs(context)); + if (SubtypeUtilsKt.locale(selected).equals(newLocale)) { + addAll(SubtypeUtilsKt.getSecondaryLocales(selected.getExtraValue())); + } else { + // probably we're called from the spell checker when using a different app as keyboard + final List enabled = SubtypeSettings.INSTANCE.getEnabledSubtypes(KtxKt.prefs(context), false); + for (InputMethodSubtype subtype : enabled) { + if (SubtypeUtilsKt.locale(subtype).equals(newLocale)) + addAll(SubtypeUtilsKt.getSecondaryLocales(subtype.getExtraValue())); + } + } }}; // Do not use contacts dictionary if we do not have permissions to read contacts. diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index 36ecb334f..159a7b1a8 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -669,11 +669,15 @@ public class LatinIME extends InputMethodService implements } else { subtypeLocale = subtypeSwitcherLocale; } - if (mDictionaryFacilitator.isForLocale(subtypeLocale) - && mDictionaryFacilitator.isForAccount(mSettings.getCurrent().mAccount) - && mDictionaryFacilitator.usesContacts() == mSettings.getCurrent().mUseContactsDictionary - && mDictionaryFacilitator.usesPersonalization() == mSettings.getCurrent().mUsePersonalizedDicts - ) { + final ArrayList locales = new ArrayList<>(); + locales.add(subtypeLocale); + locales.addAll(mSettings.getCurrent().mSecondaryLocales); + if (mDictionaryFacilitator.usesSameSettings( + locales, + mSettings.getCurrent().mUseContactsDictionary, + mSettings.getCurrent().mUsePersonalizedDicts, + mSettings.getCurrent().mAccount + )) { return; } resetDictionaryFacilitator(subtypeLocale); diff --git a/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java b/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java index 914d34408..368386aa4 100644 --- a/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java +++ b/app/src/main/java/helium314/keyboard/latin/RichInputMethodManager.java @@ -319,7 +319,6 @@ public class RichInputMethodManager { // search for first secondary language & script match final int count = subtypes.size(); - final SharedPreferences prefs = KtxKt.prefs(mContext); final String language = locale.getLanguage(); final String script = ScriptUtils.script(locale); for (int i = 0; i < count; ++i) { @@ -328,7 +327,7 @@ public class RichInputMethodManager { if (!ScriptUtils.script(subtypeLocale).equals(script)) continue; // need compatible script bestMatch = subtype; - final List secondaryLocales = Settings.getSecondaryLocales(prefs, subtypeLocale); + final List secondaryLocales = SubtypeUtilsKt.getSecondaryLocales(subtype.getExtraValue()); for (final Locale secondaryLocale : secondaryLocales) { if (secondaryLocale.getLanguage().equals(language)) { return bestMatch; 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 e88357ec0..c89dd70b0 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt @@ -408,8 +408,6 @@ class AdvancedSettingsFragment : SubScreenFragment() { } checkVersionUpgrade(requireContext()) Settings.getInstance().startListener() - val additionalSubtypes = sharedPreferences.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! - SubtypeSettings.updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) SubtypeSettings.reloadEnabledSubtypes(requireContext()) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) activity?.sendBroadcast(newDictBroadcast) 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 b9bf30280..758f6fce8 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/LanguageFilterList.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/LanguageFilterList.kt @@ -27,6 +27,7 @@ import helium314.keyboard.latin.utils.displayName import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.prefs import helium314.keyboard.latin.utils.showMissingDictionaryDialog +import java.util.Locale class LanguageFilterList(searchField: EditText, recyclerView: RecyclerView) { @@ -98,14 +99,14 @@ private class LanguageAdapter(list: List> = listOf(), c sb.append(string) } } - val secondaryLocales = Settings.getSecondaryLocales(prefs, infos.first().subtype.locale()) + val secondaryLocales = emptyList() if (secondaryLocales.isNotEmpty()) { if (sb.isNotEmpty()) sb.append("\n") - sb.append(Settings.getSecondaryLocales(prefs, infos.first().subtype.locale()) - .joinToString(", ") { - LocaleUtils.getLocaleDisplayNameInSystemLocale(it, context) - }) + //sb.append(Settings.getSecondaryLocales(prefs, infos.first().subtype.locale()) + // .joinToString(", ") { + // LocaleUtils.getLocaleDisplayNameInSystemLocale(it, context) + // }) } text = sb if (text.isBlank()) isGone = true @@ -126,7 +127,7 @@ private class LanguageAdapter(list: List> = listOf(), c SubtypeSettings.addEnabledSubtype(prefs, infos.first().subtype) infos.first().isEnabled = true } else { - SubtypeSettings.removeEnabledSubtype(prefs, infos.first().subtype) + SubtypeSettings.removeEnabledSubtype(context, infos.first().subtype) infos.first().isEnabled = false } } 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 8fed8ea1f..6bba6288c 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsDialog.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/LanguageSettingsDialog.kt @@ -188,7 +188,7 @@ class LanguageSettingsDialog( SubtypeSettings.addEnabledSubtype(prefs, subtype.subtype) } else - SubtypeSettings.removeEnabledSubtype(prefs, subtype.subtype) + SubtypeSettings.removeEnabledSubtype(context, subtype.subtype) subtype.isEnabled = b reloadSetting() } @@ -205,7 +205,7 @@ class LanguageSettingsDialog( //if (isCustom) // LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context) SubtypeUtilsAdditional.removeAdditionalSubtype(prefs, subtype.subtype) - SubtypeSettings.removeEnabledSubtype(prefs, subtype.subtype) + SubtypeSettings.removeEnabledSubtype(context, subtype.subtype) reloadSetting() } if (isCustom) { @@ -226,7 +226,7 @@ class LanguageSettingsDialog( mainLocale, infos.first().subtype.isAsciiCapable ) - val selectedSecondaryLocales = Settings.getSecondaryLocales(prefs, mainLocale) + val selectedSecondaryLocales = emptyList()// Settings.getSecondaryLocales(prefs, mainLocale) selectedSecondaryLocales.forEach { addSecondaryLocaleView(it) } @@ -234,14 +234,14 @@ class LanguageSettingsDialog( binding.addSecondaryLanguage.apply { isVisible = true setOnClickListener { - val locales = (availableSecondaryLocales - Settings.getSecondaryLocales(prefs, mainLocale)).sortedBy { it.displayName } + val locales = (availableSecondaryLocales).sortedBy { it.displayName } val localeNames = locales.map { LocaleUtils.getLocaleDisplayNameInSystemLocale(it, context) }.toTypedArray() Builder(context) .setTitle(R.string.button_select_language) .setItems(localeNames) { di, i -> val locale = locales[i] - val currentSecondaryLocales = Settings.getSecondaryLocales(prefs, mainLocale) - Settings.setSecondaryLocales(prefs, mainLocale, currentSecondaryLocales + locale) + //val currentSecondaryLocales = Settings.getSecondaryLocales(prefs, mainLocale) + //Settings.setSecondaryLocales(prefs, mainLocale, currentSecondaryLocales + locale) addSecondaryLocaleView(locale) di.dismiss() reloadSetting() @@ -264,8 +264,8 @@ class LanguageSettingsDialog( rowBinding.deleteButton.apply { isVisible = true setOnClickListener { - val currentSecondaryLocales = Settings.getSecondaryLocales(prefs, mainLocale) - Settings.setSecondaryLocales(prefs, mainLocale, currentSecondaryLocales - locale) + //val currentSecondaryLocales = Settings.getSecondaryLocales(prefs, mainLocale) + //Settings.setSecondaryLocales(prefs, mainLocale, currentSecondaryLocales - locale) binding.secondaryLocales.removeView(rowBinding.root) reloadSetting() reloadDictionaries() 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 1af2446e2..c2e84b19f 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -27,8 +27,6 @@ import helium314.keyboard.latin.AudioAndHapticFeedbackManager; import helium314.keyboard.latin.InputAttributes; import helium314.keyboard.latin.R; import helium314.keyboard.latin.common.Colors; -import helium314.keyboard.latin.common.Constants; -import helium314.keyboard.latin.common.LocaleUtils; import helium314.keyboard.latin.utils.DeviceProtectedUtils; import helium314.keyboard.latin.utils.KtxKt; import helium314.keyboard.latin.utils.LayoutType; @@ -43,10 +41,8 @@ import helium314.keyboard.latin.utils.ToolbarUtilsKt; import helium314.keyboard.settings.SettingsActivity; import java.io.File; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -import java.util.List; import java.util.Locale; import java.util.concurrent.locks.ReentrantLock; @@ -147,7 +143,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_ENABLE_CLIPBOARD_HISTORY = "enable_clipboard_history"; public static final String PREF_CLIPBOARD_HISTORY_RETENTION_TIME = "clipboard_history_retention_time"; - public static final String PREF_SECONDARY_LOCALES_PREFIX = "secondary_locales_"; public static final String PREF_ADD_TO_PERSONAL_DICTIONARY = "add_to_personal_dictionary"; public static final String PREF_NAVBAR_COLOR = "navbar_color"; public static final String PREF_NARROW_KEY_GAPS = "narrow_key_gaps"; @@ -241,8 +236,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang mSettingsValuesLock.unlock(); } if (PREF_ADDITIONAL_SUBTYPES.equals(key)) { - final String additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES); - SubtypeSettings.INSTANCE.updateAdditionalSubtypes(SubtypeUtilsAdditional.INSTANCE.createAdditionalSubtypes(additionalSubtypes)); + SubtypeSettings.INSTANCE.reloadEnabledSubtypes(mContext); } } @@ -466,29 +460,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang Arrays.fill(sCachedBackgroundImages, null); } - public static List getSecondaryLocales(final SharedPreferences prefs, final Locale mainLocale) { - final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocale.toLanguageTag(), Defaults.PREF_SECONDARY_LOCALES); - - final ArrayList locales = new ArrayList<>(); - for (String languageTag : localesString.split(Constants.Separators.KV)) { - if (languageTag.isEmpty()) continue; - locales.add(LocaleUtils.constructLocale(languageTag)); - } - return locales; - } - - public static void setSecondaryLocales(final SharedPreferences prefs, final Locale mainLocale, final List locales) { - if (locales.isEmpty()) { - prefs.edit().putString(PREF_SECONDARY_LOCALES_PREFIX + mainLocale.toLanguageTag(), "").apply(); - return; - } - final StringBuilder sb = new StringBuilder(); - for (Locale locale : locales) { - sb.append(Constants.Separators.KV).append(locale.toLanguageTag()); - } - prefs.edit().putString(PREF_SECONDARY_LOCALES_PREFIX + mainLocale.toLanguageTag(), sb.toString()).apply(); - } - public static Colors getColorsForCurrentTheme(final Context context, final SharedPreferences prefs) { boolean isNight = ResourceUtils.isNight(context.getResources()); if (SettingsActivity.Companion.getForceOppositeTheme()) isNight = !isNight; 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 9cfd86331..95fefd7c7 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -28,9 +28,9 @@ import helium314.keyboard.latin.permissions.PermissionsUtil; import helium314.keyboard.latin.utils.InputTypeUtils; 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.SubtypeSettings; +import helium314.keyboard.latin.utils.SubtypeUtilsKt; import java.util.Arrays; import java.util.List; @@ -156,6 +156,7 @@ public class SettingsValues { @NonNull final InputAttributes inputAttributes) { mLocale = ConfigurationCompatKt.locale(res.getConfiguration()); mDisplayOrientation = res.getConfiguration().orientation; + final InputMethodSubtype selectedSubtype = SubtypeSettings.INSTANCE.getSelectedSubtype(prefs); // Store the input attributes mInputAttributes = inputAttributes; @@ -174,7 +175,7 @@ public class SettingsValues { mLanguageSwitchKeyToOtherSubtypes = languagePref.equals("internal") || languagePref.equals("both"); mShowsLanguageSwitchKey = prefs.getBoolean(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, Defaults.PREF_SHOW_LANGUAGE_SWITCH_KEY); mShowsNumberRow = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, Defaults.PREF_SHOW_NUMBER_ROW); - mLocalizedNumberRow = prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW); + mLocalizedNumberRow = SubtypeUtilsKt.getHasLocalizedNumberRow(selectedSubtype, prefs); mShowNumberRowHints = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW_HINTS, Defaults.PREF_SHOW_NUMBER_ROW_HINTS); mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, Defaults.PREF_SHOW_HINTS); mShowsPopupHints = prefs.getBoolean(Settings.PREF_SHOW_POPUP_HINTS, Defaults.PREF_SHOW_POPUP_HINTS); @@ -247,19 +248,14 @@ public class SettingsValues { mOneHandedModeScale = 1 - (1 - baseScale) * extraScale; } else mOneHandedModeScale = 1f; - final InputMethodSubtype selectedSubtype = SubtypeSettings.INSTANCE.getSelectedSubtype(prefs); - mSecondaryLocales = Settings.getSecondaryLocales(prefs, mLocale); + mSecondaryLocales = SubtypeUtilsKt.getSecondaryLocales(selectedSubtype.getExtraValue()); mShowMorePopupKeys = selectedSubtype.isAsciiCapable() - ? prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS) + ? SubtypeUtilsKt.getMoreKeys(selectedSubtype, prefs) : LocaleKeyboardInfosKt.POPUP_KEYS_NORMAL; mColors = Settings.getColorsForCurrentTheme(context, prefs); - // read locale-specific popup key settings, fall back to global settings - final String popupKeyTypesDefault = prefs.getString(Settings.PREF_POPUP_KEYS_ORDER, Defaults.PREF_POPUP_KEYS_ORDER); - mPopupKeyTypes = PopupKeysUtilsKt.getEnabledPopupKeys(prefs, Settings.PREF_POPUP_KEYS_ORDER + "_" + mLocale.toLanguageTag(), popupKeyTypesDefault); - final String popupKeyLabelDefault = prefs.getString(Settings.PREF_POPUP_KEYS_LABELS_ORDER, Defaults.PREF_POPUP_KEYS_LABELS_ORDER); - mPopupKeyLabelSources = PopupKeysUtilsKt.getEnabledPopupKeys(prefs, Settings.PREF_POPUP_KEYS_LABELS_ORDER + "_" + mLocale.toLanguageTag(), popupKeyLabelDefault); - + mPopupKeyTypes = SubtypeUtilsKt.getPopupKeyTypes(selectedSubtype, prefs); + mPopupKeyLabelSources = SubtypeUtilsKt.getPopupKeyLabelSources(selectedSubtype, prefs); mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, Defaults.PREF_ADD_TO_PERSONAL_DICTIONARY); mUseContactsDictionary = SettingsValues.readUseContactsEnabled(prefs, context); mCustomNavBarColor = prefs.getBoolean(Settings.PREF_NAVBAR_COLOR, Defaults.PREF_NAVBAR_COLOR); 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 98d073c35..4da5cebc4 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/UserDictionaryListFragment.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/UserDictionaryListFragment.java @@ -30,6 +30,7 @@ import helium314.keyboard.latin.utils.SubtypeSettings; import helium314.keyboard.latin.utils.SubtypeUtilsKt; import java.util.Comparator; +import java.util.List; import java.util.Locale; import java.util.TreeSet; @@ -117,7 +118,11 @@ public class UserDictionaryListFragment extends SubScreenFragment { } // Secondary language is added only if main language is selected and if system language is not enabled if (!localeSystemOnly) { - sortedLocales.addAll(Settings.getSecondaryLocales(prefs, mainLocale)); + final List enabled = SubtypeSettings.INSTANCE.getEnabledSubtypes(prefs, false); + for (InputMethodSubtype subtype : enabled) { + if (SubtypeUtilsKt.locale(subtype).equals(mainLocale)) + sortedLocales.addAll(SubtypeUtilsKt.getSecondaryLocales(subtype.getExtraValue())); + } } } 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 c80b49ed3..f05774c3d 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt @@ -105,7 +105,9 @@ fun cleanUnusedMainDicts(context: Context) { SubtypeSettings.getEnabledSubtypes(prefs).forEach { subtype -> val locale = subtype.locale() usedLocaleLanguageTags.add(locale.toLanguageTag()) - Settings.getSecondaryLocales(prefs, locale).forEach { usedLocaleLanguageTags.add(it.toLanguageTag()) } + } + SubtypeSettings.getAdditionalSubtypes().forEach { subtype -> + getSecondaryLocales(subtype.extraValue).forEach { usedLocaleLanguageTags.add(it.toLanguageTag()) } } for (dir in dirs) { if (!dir.isDirectory) continue diff --git a/app/src/main/java/helium314/keyboard/latin/utils/PopupKeysUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/PopupKeysUtils.kt index b03c989ba..cc0c6724c 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/PopupKeysUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/PopupKeysUtils.kt @@ -98,9 +98,9 @@ private fun transformLabel(label: String, params: KeyboardParams): String = } else label /** returns a list of enabled popup keys for pref [key] */ -fun getEnabledPopupKeys(prefs: SharedPreferences, key: String, defaultSetting: String): List { - return prefs.getString(key, defaultSetting)?.split(";")?.mapNotNull { - val split = it.split(",") +fun getEnabledPopupKeys(string: String): List { + return string.split(Separators.ENTRY).mapNotNull { + val split = it.split(Separators.KV) if (split.last() == "true") split.first() else null - } ?: emptyList() + } } 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 20fa3ca2e..06eb7c674 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeSettings.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeSettings.kt @@ -29,7 +29,7 @@ object SubtypeSettings { return getDefaultEnabledSubtypes() if (fallback && enabledSubtypes.isEmpty()) return getDefaultEnabledSubtypes() - return enabledSubtypes + return enabledSubtypes.toList() } fun getAllAvailableSubtypes(): List { @@ -67,20 +67,22 @@ object SubtypeSettings { } } - /** returns whether subtype was actually removed, does not remove last subtype */ - fun removeEnabledSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) { + /** @return whether subtype was actually removed */ + fun removeEnabledSubtype(context: Context, subtype: InputMethodSubtype): Boolean { require(initialized) - removeEnabledSubtype(prefs, subtype.toSettingsSubtype().toPref()) - enabledSubtypes.remove(subtype) - RichInputMethodManager.getInstance().refreshSubtypeCaches() + if (!removeEnabledSubtype(context.prefs(), subtype.toSettingsSubtype().toPref())) return false + if (!enabledSubtypes.remove(subtype)) reloadEnabledSubtypes(context) + else RichInputMethodManager.getInstance().refreshSubtypeCaches() + return true } 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 + if (selectedSubtype.isAdditionalSubtype(prefs)) { + val selectedAdditionalSubtype = selectedSubtype.toAdditionalSubtype() + if (selectedAdditionalSubtype != null) return selectedAdditionalSubtype + } // 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 @@ -111,10 +113,9 @@ object SubtypeSettings { return subtype in additionalSubtypes } - fun updateAdditionalSubtypes(subtypes: List) { - additionalSubtypes.clear() - additionalSubtypes.addAll(subtypes) - RichInputMethodManager.getInstance().refreshSubtypeCaches() + fun getAdditionalSubtypes(): List { + require(initialized) + return additionalSubtypes.toList() } fun reloadSystemLocales(context: Context) { @@ -129,7 +130,7 @@ object SubtypeSettings { fun getSystemLocales(): List { require(initialized) - return systemLocales + return systemLocales.toList() } fun hasMatchingSubtypeForLocale(locale: Locale): Boolean { @@ -139,16 +140,18 @@ object SubtypeSettings { fun getResourceSubtypesForLocale(locale: Locale): List = resourceSubtypesByLocale[locale].orEmpty() - fun getAvailableSubtypeLocales(): Collection { + fun getAvailableSubtypeLocales(): List { require(initialized) - return resourceSubtypesByLocale.keys + return resourceSubtypesByLocale.keys.toList() } fun reloadEnabledSubtypes(context: Context) { require(initialized) enabledSubtypes.clear() removeInvalidCustomSubtypes(context) + loadAdditionalSubtypes(context.prefs()) loadEnabledSubtypes(context) + RichInputMethodManager.getInstance().refreshSubtypeCaches() } fun init(context: Context) { @@ -190,23 +193,24 @@ object SubtypeSettings { } // remove custom subtypes without a layout file - private fun removeInvalidCustomSubtypes(context: Context) { // todo: new layout structure! + private fun removeInvalidCustomSubtypes(context: Context) { 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 additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(Separators.SETS) + val customLayoutFiles by lazy { LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, context).map { it.name } } val subtypesToRemove = mutableListOf() additionalSubtypes.forEach { - val name = it.substringAfter(":").substringBefore(":") + val name = it.toSettingsSubtype().mainLayoutName() ?: "qwerty" if (!LayoutUtilsCustom.isCustomLayout(name)) return@forEach - if (name !in customSubtypeFiles) + if (name !in customLayoutFiles) 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(";")) + Log.w(TAG, "removing custom subtypes without main layout files: $subtypesToRemove") + Settings.writePrefAdditionalSubtypes(prefs, additionalSubtypes.filterNot { it in subtypesToRemove }.joinToString(Separators.SETS)) } private fun loadAdditionalSubtypes(prefs: SharedPreferences) { + additionalSubtypes.clear() val additionalSubtypeString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! val subtypes = SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypeString) additionalSubtypes.addAll(subtypes) @@ -218,10 +222,12 @@ object SubtypeSettings { 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 + if (settingsSubtype.isAdditionalSubtype(prefs)) { + val additionalSubtype = settingsSubtype.toAdditionalSubtype() + if (additionalSubtype != null) { + enabledSubtypes.add(additionalSubtype) + continue + } } val subtypesForLocale = resourceSubtypesByLocale[settingsSubtype.locale] if (subtypesForLocale == null) { @@ -249,11 +255,12 @@ object SubtypeSettings { } } - private fun removeEnabledSubtype(prefs: SharedPreferences, subtypeString: String) { + /** @return whether pref was changed */ + private fun removeEnabledSubtype(prefs: SharedPreferences, subtypeString: String): Boolean { 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 + return false// 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 @@ -265,6 +272,7 @@ object SubtypeSettings { KeyboardSwitcher.getInstance().switchToSubtype(nextSubtype) } catch (_: Exception) { } // do nothing if RichInputMethodManager isn't initialized } + return true } var initialized = false diff --git a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtils.kt index f5c2824dc..594b446a1 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtils.kt @@ -1,6 +1,7 @@ package helium314.keyboard.latin.utils import android.content.Context +import android.content.SharedPreferences import android.content.res.Resources import android.os.Build import android.view.inputmethod.InputMethodSubtype @@ -11,8 +12,11 @@ import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.KEYBOARD_LAY import helium314.keyboard.latin.common.LocaleUtils import helium314.keyboard.latin.common.LocaleUtils.constructLocale import helium314.keyboard.latin.define.DebugFlags +import helium314.keyboard.latin.settings.Defaults +import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.LayoutType.Companion.toExtraValue import helium314.keyboard.latin.utils.ScriptUtils.script +import helium314.keyboard.latin.utils.SettingsSubtype.Companion.getExtraValueOf import org.xmlpull.v1.XmlPullParser import java.util.Locale @@ -72,6 +76,30 @@ fun InputMethodSubtype.displayName(context: Context): String { return SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(this) } +fun getHasLocalizedNumberRow(subtype: InputMethodSubtype, prefs: SharedPreferences): Boolean = + subtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean() + ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW) + +fun getPopupKeyTypes(subtype: InputMethodSubtype, prefs: SharedPreferences): List { + val string = subtype.getExtraValueOf(ExtraValue.POPUP_ORDER) + ?: prefs.getString(Settings.PREF_POPUP_KEYS_ORDER, Defaults.PREF_POPUP_KEYS_ORDER)!! + return getEnabledPopupKeys(string) +} + +fun getPopupKeyLabelSources(subtype: InputMethodSubtype, prefs: SharedPreferences): List { + val string = subtype.getExtraValueOf(ExtraValue.HINT_ORDER) + ?: prefs.getString(Settings.PREF_POPUP_KEYS_LABELS_ORDER, Defaults.PREF_POPUP_KEYS_LABELS_ORDER)!! + return getEnabledPopupKeys(string) +} + +fun getMoreKeys(subtype: InputMethodSubtype, prefs: SharedPreferences): String = + subtype.getExtraValueOf(ExtraValue.MORE_POPUPS) + ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)!! + +fun getSecondaryLocales(extraValues: String): List = + extraValues.getExtraValueOf(ExtraValue.SECONDARY_LOCALES) + ?.split(Separators.KV)?.map { it.constructLocale() }.orEmpty() + // some kind of intermediate between the string stored in preferences and an InputMethodSubtype data class SettingsSubtype(val locale: Locale, val extraValues: String) { @@ -110,10 +138,9 @@ data class SettingsSubtype(val locale: Locale, val extraValues: String) { return copy(extraValues = newValues) } - fun getExtraValueOf(extraValueKey: String): String? = extraValues.split(",") - .firstOrNull { it.startsWith("$extraValueKey=") }?.substringAfter("$extraValueKey=") + fun getExtraValueOf(extraValueKey: String): String? = extraValues.getExtraValueOf(extraValueKey) - fun withLayout(type: LayoutType, name: String): SettingsSubtype { + fun withLayout(type: LayoutType, name: String): SettingsSubtype { val map = LayoutType.getLayoutMap(getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "") map[type] = name return with(KEYBOARD_LAYOUT_SET, map.toExtraValue()) @@ -126,10 +153,17 @@ data class SettingsSubtype(val locale: Locale, val extraValues: String) { else with(KEYBOARD_LAYOUT_SET, map.toExtraValue()) } + fun isAdditionalSubtype(prefs: SharedPreferences) = + prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! + .split(Separators.SETS).contains(toPref()) + companion object { fun String.toSettingsSubtype() = SettingsSubtype(substringBefore(Separators.SET).constructLocale(), substringAfter(Separators.SET)) + fun String.getExtraValueOf(extraValueKey: String) = split(",") + .firstOrNull { it.startsWith("$extraValueKey=") }?.substringAfter("$extraValueKey=") + /** Creates a SettingsSubtype from the given InputMethodSubtype. * Will strip some extra values that are set when creating the InputMethodSubtype from SettingsSubtype */ fun InputMethodSubtype.toSettingsSubtype(): SettingsSubtype { diff --git a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtilsAdditional.kt b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtilsAdditional.kt index 0c712ae94..b6fa4f851 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtilsAdditional.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/SubtypeUtilsAdditional.kt @@ -1,5 +1,6 @@ package helium314.keyboard.latin.utils +import android.content.Context import android.content.SharedPreferences import android.os.Build import android.view.inputmethod.InputMethodSubtype @@ -22,10 +23,11 @@ object SubtypeUtilsAdditional { // todo: extra value does not contain UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME for custom layout // it did contain that key in 2.3, but where was it set? anyway, need to be careful with separators if we want to use it // see also todo in SettingsSubtype + // todo: the name always contains the layout, but we may just use the original one fun createAdditionalSubtype(locale: Locale, extraValue: String, isAsciiCapable: Boolean, isEmojiCapable: Boolean): InputMethodSubtype { val mainLayoutName = LayoutType.getMainLayoutFromExtraValue(extraValue) ?: "qwerty" - val nameId = SubtypeLocaleUtils.getSubtypeNameResId(locale, mainLayoutName) + val nameId = getNameResId(locale, mainLayoutName) val fullExtraValue = extraValue + "," + getAdditionalExtraValues(locale, mainLayoutName, isAsciiCapable, isEmojiCapable) val subtypeId = getSubtypeId(locale, fullExtraValue, isAsciiCapable) val builder = InputMethodSubtypeBuilder() @@ -69,23 +71,22 @@ object SubtypeUtilsAdditional { } // updates additional subtypes, enabled subtypes, and selected subtype - fun changeAdditionalSubtype(from: SettingsSubtype, to: SettingsSubtype, prefs: SharedPreferences) { + fun changeAdditionalSubtype(from: SettingsSubtype, to: SettingsSubtype, context: Context) { + val prefs = context.prefs() val new = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! - .split(Separators.SETS).mapTo(sortedSetOf()) { - if (it == from.toPref()) to.toPref() else it - } + .split(Separators.SETS).mapNotNullTo(sortedSetOf()) { + if (it == from.toPref()) null else it + } + to.toPref() prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, new.joinToString(Separators.SETS)).apply() val fromSubtype = from.toAdditionalSubtype() // will be null if we edit a resource subtype val toSubtype = to.toAdditionalSubtype() // should never be null - if (SubtypeSettings.getSelectedSubtype(prefs) == fromSubtype && toSubtype != null) { + val selectedSubtype = prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)!!.toSettingsSubtype() + if (selectedSubtype == from && toSubtype != null) { SubtypeSettings.setSelectedSubtype(prefs, toSubtype) } - if (SubtypeSettings.getEnabledSubtypes(prefs, false).contains(fromSubtype)) { - if (fromSubtype != null) - SubtypeSettings.removeEnabledSubtype(prefs, fromSubtype) - if (toSubtype != null) - SubtypeSettings.addEnabledSubtype(prefs, toSubtype) + if (fromSubtype != null && SubtypeSettings.removeEnabledSubtype(context, fromSubtype) && toSubtype != null) { + SubtypeSettings.addEnabledSubtype(prefs, toSubtype) } } @@ -101,6 +102,15 @@ object SubtypeUtilsAdditional { return subtypes.joinToString(Separators.SETS) { it.toSettingsSubtype().toPref() } } + private fun getNameResId(locale: Locale, mainLayoutName: String): Int { + val nameId = SubtypeLocaleUtils.getSubtypeNameResId(locale, mainLayoutName) + if (nameId != SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT) return nameId + SubtypeSettings.getResourceSubtypesForLocale(locale).forEach { + if (it.mainLayoutName() == mainLayoutName) return it.nameResId + } + return SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT + } + /** * Returns the subtype ID that is supposed to be compatible between different version of OSes. * diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt index 9c2833dce..2afd002db 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt @@ -59,15 +59,17 @@ import helium314.keyboard.latin.utils.SubtypeLocaleUtils import helium314.keyboard.latin.utils.SubtypeSettings import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.getDictionaryLocales +import helium314.keyboard.latin.utils.getSecondaryLocales import helium314.keyboard.latin.utils.getStringResourceOrName -import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.prefs import helium314.keyboard.settings.screens.GetIcon import java.util.Locale // todo: // save when "editing" a resource subtypes is not working +// but really needs to, because e.g. a user may just want to add a secondary locale on swedish qwerty+ // settings upgrade to move the override settings to extra values, and actually use them (via getSelectedSubtype, not RichIMM) +// maybe hide some settings initially? list is long, any maybe e.g. more popups doesn't need to be subtype-dependent @Composable fun SubtypeDialog( onDismissRequest: () -> Unit, @@ -90,7 +92,7 @@ fun SubtypeDialog( neutralButtonText = if (SubtypeSettings.isAdditionalSubtype(subtype)) null else stringResource(R.string.delete), onNeutral = { SubtypeUtilsAdditional.removeAdditionalSubtype(prefs, subtype) - SubtypeSettings.removeEnabledSubtype(prefs, subtype) + SubtypeSettings.removeEnabledSubtype(ctx, subtype) }, // maybe confirm dialog? title = { Text(SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)) }, @@ -103,8 +105,8 @@ fun SubtypeDialog( val appLayouts = LayoutUtils.getAvailableLayouts(LayoutType.MAIN, ctx, currentSubtype.locale) val customLayouts = LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, ctx, currentSubtype.locale).map { it.name } DropDownField( - items = appLayouts + customLayouts, - selectedItem = currentSubtype.mainLayoutName() ?: "qwerty", // todo: what about qwerty+ and similar? + items = appLayouts + customLayouts, // todo: allow the "+" layouts for languages that have one + selectedItem = currentSubtype.mainLayoutName() ?: "qwerty", onSelected = { currentSubtype = currentSubtype.withLayout(LayoutType.MAIN, it) } @@ -114,13 +116,14 @@ fun SubtypeDialog( // yes, even just to make clear what is custom } } - WithSmallTitle(stringResource(R.string.secondary_locale)) { - TextButton(onClick = { showSecondaryLocaleDialog = true }) { - val text = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES) - ?.split(Separators.KV)?.joinToString(", ") { - LocaleUtils.getLocaleDisplayNameInSystemLocale(it.constructLocale(), ctx) - } ?: stringResource(R.string.action_none) - Text(text, Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge) + if (availableLocalesForScript.size > 1) { + WithSmallTitle(stringResource(R.string.secondary_locale)) { + TextButton(onClick = { showSecondaryLocaleDialog = true }) { + val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") { + LocaleUtils.getLocaleDisplayNameInSystemLocale(it, ctx) + }.ifEmpty { stringResource(R.string.action_none) } + Text(text, Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge) + } } } WithSmallTitle("dictionaries") { 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 9777b65ba..1ae97df25 100644 --- a/app/src/main/java/helium314/keyboard/settings/preferences/BackupRestorePreference.kt +++ b/app/src/main/java/helium314/keyboard/settings/preferences/BackupRestorePreference.kt @@ -177,8 +177,6 @@ fun BackupRestorePreference(setting: Setting) { wait.await() checkVersionUpgrade(ctx) Settings.getInstance().startListener() - val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!! - SubtypeSettings.updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes)) SubtypeSettings.reloadEnabledSubtypes(ctx) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) ctx.getActivity()?.sendBroadcast(newDictBroadcast) diff --git a/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt index 16a6630ac..d44e9e47f 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt @@ -84,7 +84,7 @@ fun LanguageScreen( Text(item.displayName(ctx), style = MaterialTheme.typography.bodyLarge) val description = item.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)?.split(Separators.KV) ?.joinToString(", ") { LocaleUtils.getLocaleDisplayNameInSystemLocale(it.constructLocale(), ctx) } - if (description != null) + if (description != null) // todo: description should clarify when it's a default subtype that can't be changed / will be cloned Text( text = description, style = MaterialTheme.typography.bodyMedium, @@ -95,7 +95,7 @@ fun LanguageScreen( checked = item in SubtypeSettings.getEnabledSubtypes(prefs), onCheckedChange = { if (it) SubtypeSettings.addEnabledSubtype(prefs, item) - else SubtypeSettings.removeEnabledSubtype(prefs, item) + else SubtypeSettings.removeEnabledSubtype(ctx, item) } ) } @@ -106,8 +106,9 @@ fun LanguageScreen( SubtypeDialog( onDismissRequest = { selectedSubtype = null }, onConfirmed = { - // todo: this does not work when "modifying" a resource subtype - SubtypeUtilsAdditional.changeAdditionalSubtype(oldSubtype.toSettingsSubtype(), it, prefs) + // todo: this does not work when "modifying" a resource subtype like German (Germany) or Danish (probably because of the + layout) + // maybe this also applied to upgrading + SubtypeUtilsAdditional.changeAdditionalSubtype(oldSubtype.toSettingsSubtype(), it, ctx) sortedSubtypes = getSortedSubtypes(ctx) }, subtype = oldSubtype