mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-31 11:52:13 +00:00
make the settings overrides in subtype work
This commit is contained in:
parent
eec197c32c
commit
8d094e268a
20 changed files with 257 additions and 155 deletions
|
@ -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"))
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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<Locale> locales,
|
||||
final boolean contacts,
|
||||
final boolean personalization,
|
||||
@Nullable final String account
|
||||
);
|
||||
|
||||
String getAccount();
|
||||
|
||||
|
|
|
@ -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<Locale> 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<Locale> 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<InputMethodSubtype> 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.
|
||||
|
|
|
@ -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<Locale> 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);
|
||||
|
|
|
@ -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<Locale> secondaryLocales = Settings.getSecondaryLocales(prefs, subtypeLocale);
|
||||
final List<Locale> secondaryLocales = SubtypeUtilsKt.getSecondaryLocales(subtype.getExtraValue());
|
||||
for (final Locale secondaryLocale : secondaryLocales) {
|
||||
if (secondaryLocale.getLanguage().equals(language)) {
|
||||
return bestMatch;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<MutableList<SubtypeInfo>> = listOf(), c
|
|||
sb.append(string)
|
||||
}
|
||||
}
|
||||
val secondaryLocales = Settings.getSecondaryLocales(prefs, infos.first().subtype.locale())
|
||||
val secondaryLocales = emptyList<Locale>()
|
||||
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<MutableList<SubtypeInfo>> = 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Locale>()// 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()
|
||||
|
|
|
@ -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<Locale> getSecondaryLocales(final SharedPreferences prefs, final Locale mainLocale) {
|
||||
final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocale.toLanguageTag(), Defaults.PREF_SECONDARY_LOCALES);
|
||||
|
||||
final ArrayList<Locale> 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<Locale> 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<InputMethodSubtype> enabled = SubtypeSettings.INSTANCE.getEnabledSubtypes(prefs, false);
|
||||
for (InputMethodSubtype subtype : enabled) {
|
||||
if (SubtypeUtilsKt.locale(subtype).equals(mainLocale))
|
||||
sortedLocales.addAll(SubtypeUtilsKt.getSecondaryLocales(subtype.getExtraValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<String> {
|
||||
return prefs.getString(key, defaultSetting)?.split(";")?.mapNotNull {
|
||||
val split = it.split(",")
|
||||
fun getEnabledPopupKeys(string: String): List<String> {
|
||||
return string.split(Separators.ENTRY).mapNotNull {
|
||||
val split = it.split(Separators.KV)
|
||||
if (split.last() == "true") split.first() else null
|
||||
} ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ object SubtypeSettings {
|
|||
return getDefaultEnabledSubtypes()
|
||||
if (fallback && enabledSubtypes.isEmpty())
|
||||
return getDefaultEnabledSubtypes()
|
||||
return enabledSubtypes
|
||||
return enabledSubtypes.toList()
|
||||
}
|
||||
|
||||
fun getAllAvailableSubtypes(): List<InputMethodSubtype> {
|
||||
|
@ -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<InputMethodSubtype>) {
|
||||
additionalSubtypes.clear()
|
||||
additionalSubtypes.addAll(subtypes)
|
||||
RichInputMethodManager.getInstance().refreshSubtypeCaches()
|
||||
fun getAdditionalSubtypes(): List<InputMethodSubtype> {
|
||||
require(initialized)
|
||||
return additionalSubtypes.toList()
|
||||
}
|
||||
|
||||
fun reloadSystemLocales(context: Context) {
|
||||
|
@ -129,7 +130,7 @@ object SubtypeSettings {
|
|||
|
||||
fun getSystemLocales(): List<Locale> {
|
||||
require(initialized)
|
||||
return systemLocales
|
||||
return systemLocales.toList()
|
||||
}
|
||||
|
||||
fun hasMatchingSubtypeForLocale(locale: Locale): Boolean {
|
||||
|
@ -139,16 +140,18 @@ object SubtypeSettings {
|
|||
|
||||
fun getResourceSubtypesForLocale(locale: Locale): List<InputMethodSubtype> = resourceSubtypesByLocale[locale].orEmpty()
|
||||
|
||||
fun getAvailableSubtypeLocales(): Collection<Locale> {
|
||||
fun getAvailableSubtypeLocales(): List<Locale> {
|
||||
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<String>()
|
||||
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
|
||||
|
|
|
@ -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<String> {
|
||||
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<String> {
|
||||
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<Locale> =
|
||||
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 {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue