mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-29 11:08:07 +00:00
convert additionalSubtypeUtils to kotlin
This commit is contained in:
parent
aa3bf37852
commit
42f4561422
17 changed files with 290 additions and 310 deletions
|
@ -42,7 +42,6 @@ import helium314.keyboard.latin.WordComposer;
|
||||||
import helium314.keyboard.latin.settings.Settings;
|
import helium314.keyboard.latin.settings.Settings;
|
||||||
import helium314.keyboard.latin.settings.SettingsValues;
|
import helium314.keyboard.latin.settings.SettingsValues;
|
||||||
import helium314.keyboard.latin.suggestions.SuggestionStripView;
|
import helium314.keyboard.latin.suggestions.SuggestionStripView;
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils;
|
|
||||||
import helium314.keyboard.latin.utils.CapsModeUtils;
|
import helium314.keyboard.latin.utils.CapsModeUtils;
|
||||||
import helium314.keyboard.latin.utils.KtxKt;
|
import helium314.keyboard.latin.utils.KtxKt;
|
||||||
import helium314.keyboard.latin.utils.LanguageOnSpacebarUtils;
|
import helium314.keyboard.latin.utils.LanguageOnSpacebarUtils;
|
||||||
|
@ -50,6 +49,7 @@ import helium314.keyboard.latin.utils.Log;
|
||||||
import helium314.keyboard.latin.utils.RecapitalizeStatus;
|
import helium314.keyboard.latin.utils.RecapitalizeStatus;
|
||||||
import helium314.keyboard.latin.utils.ResourceUtils;
|
import helium314.keyboard.latin.utils.ResourceUtils;
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils;
|
import helium314.keyboard.latin.utils.ScriptUtils;
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional;
|
||||||
|
|
||||||
public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
|
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
|
||||||
|
@ -159,7 +159,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
} catch (KeyboardLayoutSetException e) {
|
} catch (KeyboardLayoutSetException e) {
|
||||||
Log.e(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
|
Log.e(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
|
||||||
try {
|
try {
|
||||||
final InputMethodSubtype qwerty = AdditionalSubtypeUtils.createEmojiCapableAdditionalSubtype(mRichImm.getCurrentSubtypeLocale(), "qwerty", true);
|
final InputMethodSubtype qwerty = SubtypeUtilsAdditional.INSTANCE
|
||||||
|
.createEmojiCapableAdditionalSubtype(mRichImm.getCurrentSubtypeLocale(), "qwerty", true);
|
||||||
mKeyboardLayoutSet = builder.setKeyboardGeometry(keyboardWidth, keyboardHeight)
|
mKeyboardLayoutSet = builder.setKeyboardGeometry(keyboardWidth, keyboardHeight)
|
||||||
.setSubtype(RichInputMethodSubtype.Companion.get(qwerty))
|
.setSubtype(RichInputMethodSubtype.Companion.get(qwerty))
|
||||||
.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey)
|
.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey)
|
||||||
|
|
|
@ -302,7 +302,7 @@ public class RichInputMethodManager {
|
||||||
final int count = myImi.getSubtypeCount();
|
final int count = myImi.getSubtypeCount();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
|
final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
|
||||||
final String layoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
|
final String layoutName = SubtypeLocaleUtils.getMainLayoutName(subtype);
|
||||||
if (locale.equals(SubtypeUtilsKt.locale(subtype))
|
if (locale.equals(SubtypeUtilsKt.locale(subtype))
|
||||||
&& keyboardLayoutSetName.equals(layoutName)) {
|
&& keyboardLayoutSetName.equals(layoutName)) {
|
||||||
return subtype;
|
return subtype;
|
||||||
|
|
|
@ -42,7 +42,7 @@ class RichInputMethodSubtype private constructor(val rawSubtype: InputMethodSubt
|
||||||
|
|
||||||
val fullDisplayName: String get() {
|
val fullDisplayName: String get() {
|
||||||
if (isNoLanguage) {
|
if (isNoLanguage) {
|
||||||
return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(rawSubtype)!!
|
return SubtypeLocaleUtils.getMainLayoutDisplayName(rawSubtype)!!
|
||||||
}
|
}
|
||||||
return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale)
|
return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale)
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ class RichInputMethodSubtype private constructor(val rawSubtype: InputMethodSubt
|
||||||
// Get the RichInputMethodSubtype's middle display name in its locale.
|
// Get the RichInputMethodSubtype's middle display name in its locale.
|
||||||
get() {
|
get() {
|
||||||
if (isNoLanguage) {
|
if (isNoLanguage) {
|
||||||
return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(rawSubtype)!!
|
return SubtypeLocaleUtils.getMainLayoutDisplayName(rawSubtype)!!
|
||||||
}
|
}
|
||||||
return SubtypeLocaleUtils.getSubtypeLanguageDisplayName(locale)
|
return SubtypeLocaleUtils.getSubtypeLanguageDisplayName(locale)
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,11 +45,11 @@ import helium314.keyboard.latin.common.FileUtils
|
||||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||||
import helium314.keyboard.latin.common.splitOnWhitespace
|
import helium314.keyboard.latin.common.splitOnWhitespace
|
||||||
import helium314.keyboard.latin.settings.SeekBarDialogPreference.ValueProxy
|
import helium314.keyboard.latin.settings.SeekBarDialogPreference.ValueProxy
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils
|
|
||||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||||
import helium314.keyboard.latin.utils.ExecutorUtils
|
import helium314.keyboard.latin.utils.ExecutorUtils
|
||||||
import helium314.keyboard.latin.utils.JniUtils
|
import helium314.keyboard.latin.utils.JniUtils
|
||||||
import helium314.keyboard.latin.utils.ResourceUtils
|
import helium314.keyboard.latin.utils.ResourceUtils
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||||
import helium314.keyboard.latin.utils.infoDialog
|
import helium314.keyboard.latin.utils.infoDialog
|
||||||
import helium314.keyboard.latin.utils.reloadEnabledSubtypes
|
import helium314.keyboard.latin.utils.reloadEnabledSubtypes
|
||||||
import helium314.keyboard.latin.utils.updateAdditionalSubtypes
|
import helium314.keyboard.latin.utils.updateAdditionalSubtypes
|
||||||
|
@ -409,8 +409,8 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
}
|
}
|
||||||
checkVersionUpgrade(requireContext())
|
checkVersionUpgrade(requireContext())
|
||||||
Settings.getInstance().startListener()
|
Settings.getInstance().startListener()
|
||||||
val additionalSubtypes = sharedPreferences.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)
|
val additionalSubtypes = sharedPreferences.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
|
||||||
updateAdditionalSubtypes(AdditionalSubtypeUtils.createAdditionalSubtypesArray(additionalSubtypes))
|
updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes))
|
||||||
reloadEnabledSubtypes(requireContext())
|
reloadEnabledSubtypes(requireContext())
|
||||||
val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)
|
val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)
|
||||||
activity?.sendBroadcast(newDictBroadcast)
|
activity?.sendBroadcast(newDictBroadcast)
|
||||||
|
|
|
@ -7,11 +7,11 @@ import android.util.TypedValue
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import helium314.keyboard.keyboard.KeyboardTheme
|
import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
import helium314.keyboard.latin.BuildConfig
|
import helium314.keyboard.latin.BuildConfig
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils
|
|
||||||
import helium314.keyboard.latin.utils.JniUtils
|
import helium314.keyboard.latin.utils.JniUtils
|
||||||
import helium314.keyboard.latin.utils.LayoutType
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
import helium314.keyboard.latin.utils.POPUP_KEYS_LABEL_DEFAULT
|
import helium314.keyboard.latin.utils.POPUP_KEYS_LABEL_DEFAULT
|
||||||
import helium314.keyboard.latin.utils.POPUP_KEYS_ORDER_DEFAULT
|
import helium314.keyboard.latin.utils.POPUP_KEYS_ORDER_DEFAULT
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||||
import helium314.keyboard.latin.utils.defaultClipboardToolbarPref
|
import helium314.keyboard.latin.utils.defaultClipboardToolbarPref
|
||||||
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
|
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
|
||||||
import helium314.keyboard.latin.utils.defaultToolbarPref
|
import helium314.keyboard.latin.utils.defaultToolbarPref
|
||||||
|
@ -73,8 +73,8 @@ object Defaults {
|
||||||
const val PREF_LANGUAGE_SWITCH_KEY = "internal"
|
const val PREF_LANGUAGE_SWITCH_KEY = "internal"
|
||||||
const val PREF_SHOW_EMOJI_KEY = false
|
const val PREF_SHOW_EMOJI_KEY = false
|
||||||
const val PREF_VARIABLE_TOOLBAR_DIRECTION = true
|
const val PREF_VARIABLE_TOOLBAR_DIRECTION = true
|
||||||
private const val ls = AdditionalSubtypeUtils.LOCALE_AND_EXTRA_SEPARATOR
|
private const val ls = SubtypeUtilsAdditional.LOCALE_AND_EXTRA_SEPARATOR
|
||||||
private const val subs = AdditionalSubtypeUtils.PREF_SUBTYPE_SEPARATOR
|
private const val subs = SubtypeUtilsAdditional.PREF_SUBTYPE_SEPARATOR
|
||||||
const val PREF_ADDITIONAL_SUBTYPES = "de${ls}qwerty${ls}AsciiCapable${subs}" +
|
const val PREF_ADDITIONAL_SUBTYPES = "de${ls}qwerty${ls}AsciiCapable${subs}" +
|
||||||
"fr${ls}qwertz:${ls}AsciiCapable${subs}hu${ls}qwerty${ls}AsciiCapable"
|
"fr${ls}qwertz:${ls}AsciiCapable${subs}hu${ls}qwerty${ls}AsciiCapable"
|
||||||
const val PREF_ENABLE_SPLIT_KEYBOARD = false
|
const val PREF_ENABLE_SPLIT_KEYBOARD = false
|
||||||
|
|
|
@ -89,7 +89,7 @@ private class LanguageAdapter(list: List<MutableList<SubtypeInfo>> = listOf(), c
|
||||||
if (infos.size > 1 && !onlySystemLocales) {
|
if (infos.size > 1 && !onlySystemLocales) {
|
||||||
var start = true
|
var start = true
|
||||||
infos.forEach {
|
infos.forEach {
|
||||||
val string = SpannableString(SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(it.subtype)
|
val string = SpannableString(SubtypeLocaleUtils.getMainLayoutDisplayName(it.subtype)
|
||||||
?: it.subtype.displayName(context))
|
?: it.subtype.displayName(context))
|
||||||
if (it.isEnabled)
|
if (it.isEnabled)
|
||||||
string.setSpan(StyleSpan(Typeface.BOLD), 0, string.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
string.setSpan(StyleSpan(Typeface.BOLD), 0, string.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
|
|
@ -78,8 +78,8 @@ class LanguageSettingsDialog(
|
||||||
if (infos.first().subtype.isAsciiCapable) {
|
if (infos.first().subtype.isAsciiCapable) {
|
||||||
binding.addSubtype.setOnClickListener {
|
binding.addSubtype.setOnClickListener {
|
||||||
val layouts = context.resources.getStringArray(R.array.predefined_layouts)
|
val layouts = context.resources.getStringArray(R.array.predefined_layouts)
|
||||||
.filterNot { layoutName -> infos.any { SubtypeLocaleUtils.getKeyboardLayoutSetName(it.subtype) == layoutName } }
|
.filterNot { layoutName -> infos.any { SubtypeLocaleUtils.getMainLayoutName(it.subtype) == layoutName } }
|
||||||
val displayNames = layouts.map { SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(it) }
|
val displayNames = layouts.map { SubtypeLocaleUtils.getMainLayoutDisplayName(it) }
|
||||||
Builder(context)
|
Builder(context)
|
||||||
.setTitle(R.string.keyboard_layout_set)
|
.setTitle(R.string.keyboard_layout_set)
|
||||||
.setItems(displayNames.toTypedArray()) { di, i ->
|
.setItems(displayNames.toTypedArray()) { di, i ->
|
||||||
|
@ -101,17 +101,17 @@ class LanguageSettingsDialog(
|
||||||
|
|
||||||
private fun addSubtype(name: String) {
|
private fun addSubtype(name: String) {
|
||||||
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
||||||
val newSubtype = AdditionalSubtypeUtils.createEmojiCapableAdditionalSubtype(mainLocale, name, infos.first().subtype.isAsciiCapable)
|
val newSubtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(mainLocale, name, infos.first().subtype.isAsciiCapable)
|
||||||
val newSubtypeInfo = newSubtype.toSubtypeInfo(mainLocale, context, true, infos.first().hasDictionary) // enabled by default
|
val newSubtypeInfo = newSubtype.toSubtypeInfo(mainLocale, context, true, infos.first().hasDictionary) // enabled by default
|
||||||
val displayName = SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(newSubtype)
|
val displayName = SubtypeLocaleUtils.getMainLayoutDisplayName(newSubtype)
|
||||||
val old = infos.firstOrNull { isAdditionalSubtype(it.subtype) && displayName == SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(it.subtype) }
|
val old = infos.firstOrNull { isAdditionalSubtype(it.subtype) && displayName == SubtypeLocaleUtils.getMainLayoutDisplayName(it.subtype) }
|
||||||
if (old != null) {
|
if (old != null) {
|
||||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
||||||
reloadSetting()
|
reloadSetting()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
addAdditionalSubtype(prefs, newSubtype)
|
SubtypeUtilsAdditional.addAdditionalSubtype(prefs, newSubtype)
|
||||||
addEnabledSubtype(prefs, newSubtype)
|
addEnabledSubtype(prefs, newSubtype)
|
||||||
addSubtypeToView(newSubtypeInfo)
|
addSubtypeToView(newSubtypeInfo)
|
||||||
KeyboardLayoutSet.onKeyboardThemeChanged()
|
KeyboardLayoutSet.onKeyboardThemeChanged()
|
||||||
|
@ -147,7 +147,7 @@ class LanguageSettingsDialog(
|
||||||
if (infos.first().subtype.isAsciiCapable) {
|
if (infos.first().subtype.isAsciiCapable) {
|
||||||
context.resources.getStringArray(R.array.predefined_layouts).forEach {
|
context.resources.getStringArray(R.array.predefined_layouts).forEach {
|
||||||
layouts.add(it)
|
layouts.add(it)
|
||||||
displayNames.add(SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(it) ?: it)
|
displayNames.add(SubtypeLocaleUtils.getMainLayoutDisplayName(it) ?: it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Builder(context)
|
Builder(context)
|
||||||
|
@ -170,7 +170,7 @@ class LanguageSettingsDialog(
|
||||||
val row = LayoutInflater.from(context).inflate(R.layout.language_list_item, listView)
|
val row = LayoutInflater.from(context).inflate(R.layout.language_list_item, listView)
|
||||||
val layoutSetName = subtype.subtype.mainLayoutName() ?: "qwerty"
|
val layoutSetName = subtype.subtype.mainLayoutName() ?: "qwerty"
|
||||||
row.findViewById<TextView>(R.id.language_name).text =
|
row.findViewById<TextView>(R.id.language_name).text =
|
||||||
SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype.subtype)
|
SubtypeLocaleUtils.getMainLayoutDisplayName(subtype.subtype)
|
||||||
?: subtype.subtype.displayName(context)
|
?: subtype.subtype.displayName(context)
|
||||||
if (LayoutUtilsCustom.isCustomLayout(layoutSetName)) {
|
if (LayoutUtilsCustom.isCustomLayout(layoutSetName)) {
|
||||||
row.findViewById<TextView>(R.id.language_details).setText(R.string.edit_layout)
|
row.findViewById<TextView>(R.id.language_details).setText(R.string.edit_layout)
|
||||||
|
@ -204,7 +204,7 @@ class LanguageSettingsDialog(
|
||||||
infos.remove(subtype)
|
infos.remove(subtype)
|
||||||
if (isCustom)
|
if (isCustom)
|
||||||
LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context)
|
LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context)
|
||||||
removeAdditionalSubtype(prefs, subtype.subtype)
|
SubtypeUtilsAdditional.removeAdditionalSubtype(prefs, subtype.subtype)
|
||||||
removeEnabledSubtype(prefs, subtype.subtype)
|
removeEnabledSubtype(prefs, subtype.subtype)
|
||||||
reloadSetting()
|
reloadSetting()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import helium314.keyboard.latin.InputAttributes;
|
||||||
import helium314.keyboard.latin.R;
|
import helium314.keyboard.latin.R;
|
||||||
import helium314.keyboard.latin.common.Colors;
|
import helium314.keyboard.latin.common.Colors;
|
||||||
import helium314.keyboard.latin.common.LocaleUtils;
|
import helium314.keyboard.latin.common.LocaleUtils;
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils;
|
|
||||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils;
|
import helium314.keyboard.latin.utils.DeviceProtectedUtils;
|
||||||
import helium314.keyboard.latin.utils.KtxKt;
|
import helium314.keyboard.latin.utils.KtxKt;
|
||||||
import helium314.keyboard.latin.utils.LayoutType;
|
import helium314.keyboard.latin.utils.LayoutType;
|
||||||
|
@ -38,6 +37,7 @@ import helium314.keyboard.latin.utils.ResourceUtils;
|
||||||
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
||||||
import helium314.keyboard.latin.utils.StatsUtils;
|
import helium314.keyboard.latin.utils.StatsUtils;
|
||||||
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional;
|
||||||
import helium314.keyboard.latin.utils.ToolbarKey;
|
import helium314.keyboard.latin.utils.ToolbarKey;
|
||||||
import helium314.keyboard.latin.utils.ToolbarUtilsKt;
|
import helium314.keyboard.latin.utils.ToolbarUtilsKt;
|
||||||
import helium314.keyboard.settings.SettingsActivity;
|
import helium314.keyboard.settings.SettingsActivity;
|
||||||
|
@ -242,7 +242,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
}
|
}
|
||||||
if (PREF_ADDITIONAL_SUBTYPES.equals(key)) {
|
if (PREF_ADDITIONAL_SUBTYPES.equals(key)) {
|
||||||
final String additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES);
|
final String additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES);
|
||||||
SubtypeSettingsKt.updateAdditionalSubtypes(AdditionalSubtypeUtils.createAdditionalSubtypesArray(additionalSubtypes));
|
SubtypeSettingsKt.updateAdditionalSubtypes(SubtypeUtilsAdditional.INSTANCE.createAdditionalSubtypes(additionalSubtypes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ import helium314.keyboard.latin.common.ComposedData;
|
||||||
import helium314.keyboard.latin.settings.Defaults;
|
import helium314.keyboard.latin.settings.Defaults;
|
||||||
import helium314.keyboard.latin.settings.Settings;
|
import helium314.keyboard.latin.settings.Settings;
|
||||||
import helium314.keyboard.latin.settings.SettingsValuesForSuggestion;
|
import helium314.keyboard.latin.settings.SettingsValuesForSuggestion;
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils;
|
|
||||||
import helium314.keyboard.latin.utils.KtxKt;
|
import helium314.keyboard.latin.utils.KtxKt;
|
||||||
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional;
|
||||||
import helium314.keyboard.latin.utils.SuggestionResults;
|
import helium314.keyboard.latin.utils.SuggestionResults;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -200,7 +200,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
|
||||||
Settings.getInstance().loadSettings(this, locale, new InputAttributes(editorInfo, false, getPackageName()));
|
Settings.getInstance().loadSettings(this, locale, new InputAttributes(editorInfo, false, getPackageName()));
|
||||||
}
|
}
|
||||||
final String keyboardLayoutName = SubtypeSettingsKt.getMatchingLayoutSetNameForLocale(locale);
|
final String keyboardLayoutName = SubtypeSettingsKt.getMatchingLayoutSetNameForLocale(locale);
|
||||||
final InputMethodSubtype subtype = AdditionalSubtypeUtils.createDummyAdditionalSubtype(locale, keyboardLayoutName);
|
final InputMethodSubtype subtype = SubtypeUtilsAdditional.INSTANCE.createDummyAdditionalSubtype(locale, keyboardLayoutName);
|
||||||
final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype);
|
final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype);
|
||||||
return keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
return keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
* modified
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package helium314.keyboard.latin.utils;
|
|
||||||
|
|
||||||
import android.os.Build;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.inputmethod.InputMethodSubtype;
|
|
||||||
|
|
||||||
import helium314.keyboard.latin.R;
|
|
||||||
import helium314.keyboard.latin.common.LocaleUtils;
|
|
||||||
import helium314.keyboard.latin.common.StringUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.ASCII_CAPABLE;
|
|
||||||
import static helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
|
|
||||||
import static helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE;
|
|
||||||
import static helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
|
|
||||||
import static helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME;
|
|
||||||
import static helium314.keyboard.latin.common.Constants.Subtype.KEYBOARD_MODE;
|
|
||||||
|
|
||||||
public final class AdditionalSubtypeUtils {
|
|
||||||
private static final String TAG = AdditionalSubtypeUtils.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final InputMethodSubtype[] EMPTY_SUBTYPE_ARRAY = new InputMethodSubtype[0];
|
|
||||||
|
|
||||||
private AdditionalSubtypeUtils() {
|
|
||||||
// This utility class is not publicly instantiable.
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAdditionalSubtype(final InputMethodSubtype subtype) {
|
|
||||||
return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String LOCALE_AND_EXTRA_SEPARATOR = "§";
|
|
||||||
private static final int INDEX_OF_LANGUAGE_TAG = 0;
|
|
||||||
private static final int INDEX_OF_KEYBOARD_LAYOUT = 1;
|
|
||||||
private static final int INDEX_OF_EXTRA_VALUE = 2;
|
|
||||||
private static final int LENGTH_WITHOUT_EXTRA_VALUE = (INDEX_OF_KEYBOARD_LAYOUT + 1);
|
|
||||||
private static final int LENGTH_WITH_EXTRA_VALUE = (INDEX_OF_EXTRA_VALUE + 1);
|
|
||||||
public static final String PREF_SUBTYPE_SEPARATOR = ";";
|
|
||||||
|
|
||||||
private static InputMethodSubtype createAdditionalSubtypeInternal(
|
|
||||||
final Locale locale, final String keyboardLayoutSetName,
|
|
||||||
final boolean isAsciiCapable, final boolean isEmojiCapable) {
|
|
||||||
final int nameId = SubtypeLocaleUtils.getSubtypeNameId(locale, keyboardLayoutSetName);
|
|
||||||
final String platformVersionDependentExtraValues = getPlatformVersionDependentExtraValue(
|
|
||||||
locale, keyboardLayoutSetName, isAsciiCapable, isEmojiCapable);
|
|
||||||
final int platformVersionIndependentSubtypeId =
|
|
||||||
getPlatformVersionIndependentSubtypeId(locale, keyboardLayoutSetName);
|
|
||||||
final InputMethodSubtype.InputMethodSubtypeBuilder builder = new InputMethodSubtype.InputMethodSubtypeBuilder()
|
|
||||||
.setSubtypeNameResId(nameId)
|
|
||||||
.setSubtypeIconResId(R.drawable.ic_ime_switcher)
|
|
||||||
.setSubtypeLocale(locale.toString())
|
|
||||||
.setSubtypeMode(KEYBOARD_MODE)
|
|
||||||
.setSubtypeExtraValue(platformVersionDependentExtraValues)
|
|
||||||
.setIsAuxiliary(false)
|
|
||||||
.setOverridesImplicitlyEnabledSubtype(false)
|
|
||||||
.setSubtypeId(platformVersionIndependentSubtypeId)
|
|
||||||
.setIsAsciiCapable(isAsciiCapable);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
|
||||||
builder.setLanguageTag(locale.toLanguageTag());
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputMethodSubtype createDummyAdditionalSubtype(
|
|
||||||
final Locale locale, final String keyboardLayoutSetName) {
|
|
||||||
return createAdditionalSubtypeInternal(locale, keyboardLayoutSetName, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputMethodSubtype createEmojiCapableAdditionalSubtype(
|
|
||||||
final Locale locale, final String keyboardLayoutSetName, final boolean asciiCapable) {
|
|
||||||
return createAdditionalSubtypeInternal(locale, keyboardLayoutSetName, asciiCapable, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: adjust so we can store more stuff in extra values
|
|
||||||
private static String getPrefSubtype(final InputMethodSubtype subtype) {
|
|
||||||
final String keyboardLayoutSetName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
|
|
||||||
final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=MAIN:" + keyboardLayoutSetName;
|
|
||||||
final String extraValue = StringUtils.removeFromCommaSplittableTextIfExists(
|
|
||||||
layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists(
|
|
||||||
IS_ADDITIONAL_SUBTYPE, subtype.getExtraValue()));
|
|
||||||
if (extraValue.contains(PREF_SUBTYPE_SEPARATOR) || extraValue.contains(LOCALE_AND_EXTRA_SEPARATOR))
|
|
||||||
throw new IllegalArgumentException("extra value contains not allowed characters " + extraValue);
|
|
||||||
final String basePrefSubtype = SubtypeUtilsKt.locale(subtype).toLanguageTag() + LOCALE_AND_EXTRA_SEPARATOR
|
|
||||||
+ keyboardLayoutSetName;
|
|
||||||
return extraValue.isEmpty() ? basePrefSubtype
|
|
||||||
: basePrefSubtype + LOCALE_AND_EXTRA_SEPARATOR + extraValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) {
|
|
||||||
if (TextUtils.isEmpty(prefSubtypes)) {
|
|
||||||
return EMPTY_SUBTYPE_ARRAY;
|
|
||||||
}
|
|
||||||
final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR);
|
|
||||||
final ArrayList<InputMethodSubtype> subtypesList = new ArrayList<>(prefSubtypeArray.length);
|
|
||||||
for (final String prefSubtype : prefSubtypeArray) {
|
|
||||||
final InputMethodSubtype subtype = createSubtypeFromString(prefSubtype);
|
|
||||||
if (subtype != null)
|
|
||||||
subtypesList.add(subtype);
|
|
||||||
}
|
|
||||||
return subtypesList.toArray(new InputMethodSubtype[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// use string created with getPrefSubtype
|
|
||||||
public static InputMethodSubtype createSubtypeFromString(final String prefSubtype) {
|
|
||||||
final String[] elems = prefSubtype.split(LOCALE_AND_EXTRA_SEPARATOR);
|
|
||||||
if (elems.length != LENGTH_WITHOUT_EXTRA_VALUE
|
|
||||||
&& elems.length != LENGTH_WITH_EXTRA_VALUE) {
|
|
||||||
Log.w(TAG, "Unknown additional subtype specified: " + prefSubtype);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final String languageTag = elems[INDEX_OF_LANGUAGE_TAG];
|
|
||||||
final Locale locale = LocaleUtils.constructLocale(languageTag);
|
|
||||||
final String keyboardLayoutSetName = elems[INDEX_OF_KEYBOARD_LAYOUT];
|
|
||||||
final boolean asciiCapable = ScriptUtils.script(locale).equals(ScriptUtils.SCRIPT_LATIN);
|
|
||||||
// Here we assume that all the additional subtypes are EmojiCapable
|
|
||||||
final InputMethodSubtype subtype = createEmojiCapableAdditionalSubtype(locale, keyboardLayoutSetName, asciiCapable);
|
|
||||||
if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT && !LayoutUtilsCustom.INSTANCE.isCustomLayout(keyboardLayoutSetName)) {
|
|
||||||
// Skip unknown keyboard layout subtype. This may happen when predefined keyboard
|
|
||||||
// layout has been removed.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return subtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createPrefSubtypes(final InputMethodSubtype[] subtypes) {
|
|
||||||
if (subtypes == null || subtypes.length == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
for (final InputMethodSubtype subtype : subtypes) {
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
sb.append(PREF_SUBTYPE_SEPARATOR);
|
|
||||||
}
|
|
||||||
sb.append(getPrefSubtype(subtype));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createPrefSubtypes(final String[] prefSubtypes) {
|
|
||||||
if (prefSubtypes == null || prefSubtypes.length == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
for (final String prefSubtype : prefSubtypes) {
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
sb.append(PREF_SUBTYPE_SEPARATOR);
|
|
||||||
}
|
|
||||||
sb.append(prefSubtype);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the extra value that is optimized for the running OS.
|
|
||||||
* <p>
|
|
||||||
* Historically the extra value has been used as the last resort to annotate various kinds of
|
|
||||||
* attributes. Some of these attributes are valid only on some platform versions. Thus we cannot
|
|
||||||
* assume that the extra values stored in a persistent storage are always valid. We need to
|
|
||||||
* regenerate the extra value on the fly instead.
|
|
||||||
* </p>
|
|
||||||
* @param keyboardLayoutSetName the keyboard layout set name (e.g., "dvorak").
|
|
||||||
* @param isAsciiCapable true when ASCII characters are supported with this layout.
|
|
||||||
* @param isEmojiCapable true when Unicode Emoji characters are supported with this layout.
|
|
||||||
* @return extra value that is optimized for the running OS.
|
|
||||||
* @see #getPlatformVersionIndependentSubtypeId(Locale, String)
|
|
||||||
*/
|
|
||||||
private static String getPlatformVersionDependentExtraValue(final Locale locale,
|
|
||||||
final String keyboardLayoutSetName, final boolean isAsciiCapable,
|
|
||||||
final boolean isEmojiCapable) {
|
|
||||||
final ArrayList<String> extraValueItems = new ArrayList<>();
|
|
||||||
extraValueItems.add(KEYBOARD_LAYOUT_SET + "=MAIN:" + keyboardLayoutSetName);
|
|
||||||
if (isAsciiCapable) {
|
|
||||||
extraValueItems.add(ASCII_CAPABLE);
|
|
||||||
}
|
|
||||||
if (SubtypeLocaleUtils.isExceptionalLocale(locale)) {
|
|
||||||
extraValueItems.add(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" +
|
|
||||||
SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(keyboardLayoutSetName));
|
|
||||||
}
|
|
||||||
if (isEmojiCapable) {
|
|
||||||
extraValueItems.add(EMOJI_CAPABLE);
|
|
||||||
}
|
|
||||||
extraValueItems.add(IS_ADDITIONAL_SUBTYPE);
|
|
||||||
return TextUtils.join(",", extraValueItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the subtype ID that is supposed to be compatible between different version of OSes.
|
|
||||||
* <p>
|
|
||||||
* From the compatibility point of view, it is important to keep subtype id predictable and
|
|
||||||
* stable between different OSes. For this purpose, the calculation code in this method is
|
|
||||||
* carefully chosen and then fixed. Treat the following code as no more or less than a
|
|
||||||
* hash function. Each component to be hashed can be different from the corresponding value
|
|
||||||
* that is used to instantiate {@link InputMethodSubtype} actually.
|
|
||||||
* For example, you don't need to update <code>compatibilityExtraValueItems</code> in this
|
|
||||||
* method even when we need to add some new extra values for the actual instance of
|
|
||||||
* {@link InputMethodSubtype}.
|
|
||||||
* </p>
|
|
||||||
* @param keyboardLayoutSetName the keyboard layout set name (e.g., "dvorak").
|
|
||||||
* @return a platform-version independent subtype ID.
|
|
||||||
* @see #getPlatformVersionDependentExtraValue(Locale, String, boolean, boolean)
|
|
||||||
*/
|
|
||||||
private static int getPlatformVersionIndependentSubtypeId(final Locale locale,
|
|
||||||
final String keyboardLayoutSetName) {
|
|
||||||
// For compatibility reasons, we concatenate the extra values in the following order.
|
|
||||||
// - KeyboardLayoutSet
|
|
||||||
// - AsciiCapable
|
|
||||||
// - UntranslatableReplacementStringInSubtypeName
|
|
||||||
// - EmojiCapable
|
|
||||||
// - isAdditionalSubtype
|
|
||||||
final ArrayList<String> compatibilityExtraValueItems = new ArrayList<>();
|
|
||||||
compatibilityExtraValueItems.add(KEYBOARD_LAYOUT_SET + "=MAIN:" + keyboardLayoutSetName);
|
|
||||||
compatibilityExtraValueItems.add(ASCII_CAPABLE);
|
|
||||||
if (SubtypeLocaleUtils.isExceptionalLocale(locale)) {
|
|
||||||
compatibilityExtraValueItems.add(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" +
|
|
||||||
SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(keyboardLayoutSetName));
|
|
||||||
}
|
|
||||||
compatibilityExtraValueItems.add(EMOJI_CAPABLE);
|
|
||||||
compatibilityExtraValueItems.add(IS_ADDITIONAL_SUBTYPE);
|
|
||||||
final String compatibilityExtraValues = TextUtils.join(",", compatibilityExtraValueItems);
|
|
||||||
return Arrays.hashCode(new Object[] {
|
|
||||||
locale,
|
|
||||||
KEYBOARD_MODE,
|
|
||||||
compatibilityExtraValues,
|
|
||||||
false /* isAuxiliary */,
|
|
||||||
false /* overrideImplicitlyEnabledSubtype */ });
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -52,7 +52,7 @@ public final class LanguageOnSpacebarUtils {
|
||||||
for (final InputMethodSubtype ims : sEnabledSubtypes) {
|
for (final InputMethodSubtype ims : sEnabledSubtypes) {
|
||||||
final String language = SubtypeUtilsKt.locale(ims).getLanguage();
|
final String language = SubtypeUtilsKt.locale(ims).getLanguage();
|
||||||
if (keyboardLanguage.equals(language) && keyboardLayout.equals(
|
if (keyboardLanguage.equals(language) && keyboardLayout.equals(
|
||||||
SubtypeLocaleUtils.getKeyboardLayoutSetName(ims))) {
|
SubtypeLocaleUtils.getMainLayoutName(ims))) {
|
||||||
sameLanguageAndLayoutCount++;
|
sameLanguageAndLayoutCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ public final class SubtypeLocaleUtils {
|
||||||
return NO_LANGUAGE + "_" + keyboardLayoutName;
|
return NO_LANGUAGE + "_" + keyboardLayoutName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getSubtypeNameId(final Locale locale, final String keyboardLayoutName) {
|
public static int getSubtypeNameResId(final Locale locale, final String keyboardLayoutName) {
|
||||||
final String languageTag = locale.toLanguageTag();
|
final String languageTag = locale.toLanguageTag();
|
||||||
if (isExceptionalLocale(locale)) {
|
if (isExceptionalLocale(locale)) {
|
||||||
return sExceptionalLocaleToWithLayoutNameIdsMap.get(languageTag);
|
return sExceptionalLocaleToWithLayoutNameIdsMap.get(languageTag);
|
||||||
|
@ -235,7 +235,7 @@ public final class SubtypeLocaleUtils {
|
||||||
if (subtype == null) {
|
if (subtype == null) {
|
||||||
return "<null subtype>";
|
return "<null subtype>";
|
||||||
}
|
}
|
||||||
return SubtypeUtilsKt.locale(subtype) + "/" + getKeyboardLayoutSetName(subtype);
|
return SubtypeUtilsKt.locale(subtype) + "/" + getMainLayoutName(subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -259,30 +259,30 @@ public final class SubtypeLocaleUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getKeyboardLayoutSetDisplayName(@NonNull final InputMethodSubtype subtype) {
|
public static String getMainLayoutDisplayName(@NonNull final InputMethodSubtype subtype) {
|
||||||
final String layoutName = getKeyboardLayoutSetName(subtype);
|
final String layoutName = getMainLayoutName(subtype);
|
||||||
return getKeyboardLayoutSetDisplayName(layoutName);
|
return getMainLayoutDisplayName(layoutName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getKeyboardLayoutSetDisplayName(@NonNull final String layoutName) {
|
public static String getMainLayoutDisplayName(@NonNull final String layoutName) {
|
||||||
if (LayoutUtilsCustom.INSTANCE.isCustomLayout(layoutName))
|
if (LayoutUtilsCustom.INSTANCE.isCustomLayout(layoutName))
|
||||||
return LayoutUtilsCustom.INSTANCE.getCustomLayoutDisplayName(layoutName);
|
return LayoutUtilsCustom.INSTANCE.getCustomLayoutDisplayName(layoutName);
|
||||||
return sKeyboardLayoutToDisplayNameMap.get(layoutName);
|
return sKeyboardLayoutToDisplayNameMap.get(layoutName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static String getKeyboardLayoutSetName(final InputMethodSubtype subtype) {
|
public static String getMainLayoutName(final InputMethodSubtype subtype) {
|
||||||
String keyboardLayoutSet = SubtypeUtilsKt.mainLayoutName(subtype);
|
String mainLayoutName = SubtypeUtilsKt.mainLayoutName(subtype);
|
||||||
if (keyboardLayoutSet == null && subtype.isAsciiCapable()) {
|
if (mainLayoutName == null && subtype.isAsciiCapable()) {
|
||||||
keyboardLayoutSet = QWERTY;
|
mainLayoutName = QWERTY;
|
||||||
}
|
}
|
||||||
if (keyboardLayoutSet == null) { // we could search for a subtype with the correct script, but this is a bug anyway...
|
if (mainLayoutName == null) { // we could search for a subtype with the correct script, but this is a bug anyway...
|
||||||
Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " +
|
Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " +
|
||||||
"locale=" + subtype.getLocale() + " extraValue=" + subtype.getExtraValue());
|
"locale=" + subtype.getLocale() + " extraValue=" + subtype.getExtraValue());
|
||||||
return QWERTY;
|
return QWERTY;
|
||||||
}
|
}
|
||||||
return keyboardLayoutSet;
|
return mainLayoutName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getCombiningRulesExtraValue(final InputMethodSubtype subtype) {
|
public static String getCombiningRulesExtraValue(final InputMethodSubtype subtype) {
|
||||||
|
|
|
@ -20,9 +20,7 @@ import helium314.keyboard.latin.settings.Defaults
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils.script
|
import helium314.keyboard.latin.utils.ScriptUtils.script
|
||||||
import org.xmlpull.v1.XmlPullParser
|
import org.xmlpull.v1.XmlPullParser
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
|
|
||||||
// todo: move some parts, to subtypeUtils, and only keep actual settings?
|
|
||||||
|
|
||||||
/** @return enabled subtypes. If no subtypes are enabled, but a contextForFallback is provided,
|
/** @return enabled subtypes. If no subtypes are enabled, but a contextForFallback is provided,
|
||||||
* subtypes for system locales will be returned, or en-US if none found. */
|
* subtypes for system locales will be returned, or en-US if none found. */
|
||||||
|
@ -78,28 +76,12 @@ fun removeEnabledSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype)
|
||||||
RichInputMethodManager.getInstance().refreshSubtypeCaches()
|
RichInputMethodManager.getInstance().refreshSubtypeCaches()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addAdditionalSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) {
|
|
||||||
val oldAdditionalSubtypesString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)
|
|
||||||
val additionalSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(oldAdditionalSubtypesString).toMutableSet()
|
|
||||||
additionalSubtypes.add(subtype)
|
|
||||||
val newAdditionalSubtypesString = AdditionalSubtypeUtils.createPrefSubtypes(additionalSubtypes.toTypedArray())
|
|
||||||
Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeAdditionalSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) {
|
|
||||||
val oldAdditionalSubtypesString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)
|
|
||||||
val oldAdditionalSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(oldAdditionalSubtypesString)
|
|
||||||
val newAdditionalSubtypes = oldAdditionalSubtypes.filter { it != subtype }
|
|
||||||
val newAdditionalSubtypesString = AdditionalSubtypeUtils.createPrefSubtypes(newAdditionalSubtypes.toTypedArray())
|
|
||||||
Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype {
|
fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype {
|
||||||
require(initialized)
|
require(initialized)
|
||||||
val localeAndLayout = prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)!!.toLocaleAndLayout()
|
val localeAndLayout = prefs.getString(Settings.PREF_SELECTED_SUBTYPE, Defaults.PREF_SELECTED_SUBTYPE)!!.toLocaleAndLayout()
|
||||||
val subtypes = if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) getDefaultEnabledSubtypes()
|
val subtypes = if (prefs.getBoolean(Settings.PREF_USE_SYSTEM_LOCALES, Defaults.PREF_USE_SYSTEM_LOCALES)) getDefaultEnabledSubtypes()
|
||||||
else enabledSubtypes
|
else enabledSubtypes
|
||||||
val subtype = subtypes.firstOrNull { localeAndLayout.first == it.locale() && localeAndLayout.second == SubtypeLocaleUtils.getKeyboardLayoutSetName(it) }
|
val subtype = subtypes.firstOrNull { localeAndLayout.first == it.locale() && localeAndLayout.second == SubtypeLocaleUtils.getMainLayoutName(it) }
|
||||||
if (subtype != null) {
|
if (subtype != null) {
|
||||||
return subtype
|
return subtype
|
||||||
} else {
|
} else {
|
||||||
|
@ -108,8 +90,8 @@ fun getSelectedSubtype(prefs: SharedPreferences): InputMethodSubtype {
|
||||||
if (subtypes.isNotEmpty())
|
if (subtypes.isNotEmpty())
|
||||||
return subtypes.first()
|
return subtypes.first()
|
||||||
val defaultSubtypes = getDefaultEnabledSubtypes()
|
val defaultSubtypes = getDefaultEnabledSubtypes()
|
||||||
return defaultSubtypes.firstOrNull { localeAndLayout.first == it.locale() && localeAndLayout.second == SubtypeLocaleUtils.getKeyboardLayoutSetName(it) }
|
return defaultSubtypes.firstOrNull { localeAndLayout.first == it.locale() && localeAndLayout.second == SubtypeLocaleUtils.getMainLayoutName(it) }
|
||||||
?: defaultSubtypes.firstOrNull { localeAndLayout.first.language == it.locale().language && localeAndLayout.second == SubtypeLocaleUtils.getKeyboardLayoutSetName(it) }
|
?: defaultSubtypes.firstOrNull { localeAndLayout.first.language == it.locale().language && localeAndLayout.second == SubtypeLocaleUtils.getMainLayoutName(it) }
|
||||||
?: defaultSubtypes.first()
|
?: defaultSubtypes.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +102,12 @@ fun setSelectedSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) {
|
||||||
prefs.edit { putString(Settings.PREF_SELECTED_SUBTYPE, subtypeString) }
|
prefs.edit { putString(Settings.PREF_SELECTED_SUBTYPE, subtypeString) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: use this or the version in SubtypeUtilsAdditional?
|
||||||
fun isAdditionalSubtype(subtype: InputMethodSubtype): Boolean {
|
fun isAdditionalSubtype(subtype: InputMethodSubtype): Boolean {
|
||||||
return subtype in additionalSubtypes
|
return subtype in additionalSubtypes
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateAdditionalSubtypes(subtypes: Array<InputMethodSubtype>) {
|
fun updateAdditionalSubtypes(subtypes: List<InputMethodSubtype>) {
|
||||||
additionalSubtypes.clear()
|
additionalSubtypes.clear()
|
||||||
additionalSubtypes.addAll(subtypes)
|
additionalSubtypes.addAll(subtypes)
|
||||||
RichInputMethodManager.getInstance().refreshSubtypeCaches()
|
RichInputMethodManager.getInstance().refreshSubtypeCaches()
|
||||||
|
@ -202,7 +185,7 @@ private fun InputMethodSubtype.prefString(): String {
|
||||||
@Suppress("deprecation") // it's debug logging, better get all information
|
@Suppress("deprecation") // it's debug logging, better get all information
|
||||||
Log.e(TAG, "unknown language, should not happen ${locale}, $languageTag, $extraValue, ${hashCode()}, $nameResId")
|
Log.e(TAG, "unknown language, should not happen ${locale}, $languageTag, $extraValue, ${hashCode()}, $nameResId")
|
||||||
}
|
}
|
||||||
return locale().toLanguageTag() + LOCALE_LAYOUT_SEPARATOR + SubtypeLocaleUtils.getKeyboardLayoutSetName(this)
|
return locale().toLanguageTag() + LOCALE_LAYOUT_SEPARATOR + SubtypeLocaleUtils.getMainLayoutName(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.toLocaleAndLayout(): Pair<Locale, String> =
|
private fun String.toLocaleAndLayout(): Pair<Locale, String> =
|
||||||
|
@ -263,8 +246,8 @@ private fun removeInvalidCustomSubtypes(context: Context) { // todo: new layout
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAdditionalSubtypes(prefs: SharedPreferences) {
|
private fun loadAdditionalSubtypes(prefs: SharedPreferences) {
|
||||||
val additionalSubtypeString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)
|
val additionalSubtypeString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
|
||||||
val subtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(additionalSubtypeString)
|
val subtypes = SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypeString)
|
||||||
additionalSubtypes.addAll(subtypes)
|
additionalSubtypes.addAll(subtypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,8 +269,8 @@ private fun loadEnabledSubtypes(context: Context) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val subtype = subtypesForLocale.firstOrNull { SubtypeLocaleUtils.getKeyboardLayoutSetName(it) == localeAndLayout.second }
|
val subtype = subtypesForLocale.firstOrNull { SubtypeLocaleUtils.getMainLayoutName(it) == localeAndLayout.second }
|
||||||
?: additionalSubtypes.firstOrNull { it.locale() == localeAndLayout.first && SubtypeLocaleUtils.getKeyboardLayoutSetName(it) == localeAndLayout.second }
|
?: additionalSubtypes.firstOrNull { it.locale() == localeAndLayout.first && SubtypeLocaleUtils.getMainLayoutName(it) == localeAndLayout.second }
|
||||||
if (subtype == null) {
|
if (subtype == null) {
|
||||||
val message = "subtype $localeAndLayout could not be loaded"
|
val message = "subtype $localeAndLayout could not be loaded"
|
||||||
Log.w(TAG, message)
|
Log.w(TAG, message)
|
||||||
|
|
|
@ -24,7 +24,7 @@ fun InputMethodSubtype.mainLayoutName(): String? {
|
||||||
/** Workaround for SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale ignoring custom layout names */
|
/** Workaround for SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale ignoring custom layout names */
|
||||||
// todo (later): this should be done properly and in SubtypeLocaleUtils
|
// todo (later): this should be done properly and in SubtypeLocaleUtils
|
||||||
fun InputMethodSubtype.displayName(context: Context): CharSequence {
|
fun InputMethodSubtype.displayName(context: Context): CharSequence {
|
||||||
val layoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(this)
|
val layoutName = SubtypeLocaleUtils.getMainLayoutName(this)
|
||||||
if (LayoutUtilsCustom.isCustomLayout(layoutName))
|
if (LayoutUtilsCustom.isCustomLayout(layoutName))
|
||||||
return "${LocaleUtils.getLocaleDisplayNameInSystemLocale(locale(), context)} (${LayoutUtilsCustom.getCustomLayoutDisplayName(layoutName)})"
|
return "${LocaleUtils.getLocaleDisplayNameInSystemLocale(locale(), context)} (${LayoutUtilsCustom.getCustomLayoutDisplayName(layoutName)})"
|
||||||
return SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(this)
|
return SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(this)
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
package helium314.keyboard.latin.utils
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.os.Build
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.view.inputmethod.InputMethodSubtype
|
||||||
|
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder
|
||||||
|
import helium314.keyboard.latin.R
|
||||||
|
import helium314.keyboard.latin.common.Constants
|
||||||
|
import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue
|
||||||
|
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||||
|
import helium314.keyboard.latin.common.StringUtils
|
||||||
|
import helium314.keyboard.latin.settings.Defaults
|
||||||
|
import helium314.keyboard.latin.settings.Settings
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom.isCustomLayout
|
||||||
|
import helium314.keyboard.latin.utils.ScriptUtils.script
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
object SubtypeUtilsAdditional {
|
||||||
|
fun isAdditionalSubtype(subtype: InputMethodSubtype): Boolean {
|
||||||
|
return subtype.containsExtraValueKey(ExtraValue.IS_ADDITIONAL_SUBTYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createAdditionalSubtypeInternal(locale: Locale, keyboardLayoutSetName: String,
|
||||||
|
isAsciiCapable: Boolean, isEmojiCapable: Boolean
|
||||||
|
): InputMethodSubtype {
|
||||||
|
val nameId = SubtypeLocaleUtils.getSubtypeNameResId(locale, keyboardLayoutSetName)
|
||||||
|
val platformVersionDependentExtraValues =
|
||||||
|
getPlatformVersionDependentExtraValue(locale, keyboardLayoutSetName, isAsciiCapable, isEmojiCapable)
|
||||||
|
val platformVersionIndependentSubtypeId =
|
||||||
|
getPlatformVersionIndependentSubtypeId(locale, keyboardLayoutSetName)
|
||||||
|
val builder = InputMethodSubtypeBuilder()
|
||||||
|
.setSubtypeNameResId(nameId)
|
||||||
|
.setSubtypeIconResId(R.drawable.ic_ime_switcher)
|
||||||
|
.setSubtypeLocale(locale.toString())
|
||||||
|
.setSubtypeMode(Constants.Subtype.KEYBOARD_MODE)
|
||||||
|
.setSubtypeExtraValue(platformVersionDependentExtraValues)
|
||||||
|
.setIsAuxiliary(false)
|
||||||
|
.setOverridesImplicitlyEnabledSubtype(false)
|
||||||
|
.setSubtypeId(platformVersionIndependentSubtypeId)
|
||||||
|
.setIsAsciiCapable(isAsciiCapable)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
|
builder.setLanguageTag(locale.toLanguageTag())
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createDummyAdditionalSubtype(locale: Locale, keyboardLayoutSetName: String) =
|
||||||
|
createAdditionalSubtypeInternal(locale, keyboardLayoutSetName, false, false)
|
||||||
|
|
||||||
|
fun createEmojiCapableAdditionalSubtype(locale: Locale, keyboardLayoutSetName: String, asciiCapable: Boolean) =
|
||||||
|
createAdditionalSubtypeInternal(locale, keyboardLayoutSetName, asciiCapable, true)
|
||||||
|
|
||||||
|
fun addAdditionalSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) {
|
||||||
|
val oldAdditionalSubtypesString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
|
||||||
|
val additionalSubtypes = createAdditionalSubtypes(oldAdditionalSubtypesString).toMutableSet()
|
||||||
|
additionalSubtypes.add(subtype)
|
||||||
|
val newAdditionalSubtypesString = createPrefSubtypes(additionalSubtypes.toTypedArray())
|
||||||
|
Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeAdditionalSubtype(prefs: SharedPreferences, subtype: InputMethodSubtype) {
|
||||||
|
val oldAdditionalSubtypesString = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
|
||||||
|
val oldAdditionalSubtypes = createAdditionalSubtypes(oldAdditionalSubtypesString)
|
||||||
|
val newAdditionalSubtypes = oldAdditionalSubtypes.filter { it != subtype }
|
||||||
|
val newAdditionalSubtypesString = createPrefSubtypes(newAdditionalSubtypes.toTypedArray())
|
||||||
|
Settings.writePrefAdditionalSubtypes(prefs, newAdditionalSubtypesString)
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: adjust so we can store more stuff in extra values
|
||||||
|
private fun getPrefSubtype(subtype: InputMethodSubtype): String {
|
||||||
|
val mainLayoutName = SubtypeLocaleUtils.getMainLayoutName(subtype)
|
||||||
|
val layoutExtraValue = ExtraValue.KEYBOARD_LAYOUT_SET + "=MAIN:" + mainLayoutName
|
||||||
|
val extraValue = StringUtils.removeFromCommaSplittableTextIfExists(
|
||||||
|
layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists(
|
||||||
|
ExtraValue.IS_ADDITIONAL_SUBTYPE, subtype.extraValue
|
||||||
|
)
|
||||||
|
)
|
||||||
|
require(!extraValue.contains(PREF_SUBTYPE_SEPARATOR) && !extraValue.contains(LOCALE_AND_EXTRA_SEPARATOR))
|
||||||
|
{ "extra value contains not allowed characters $extraValue" }
|
||||||
|
val basePrefSubtype = subtype.locale().toLanguageTag() + LOCALE_AND_EXTRA_SEPARATOR + mainLayoutName
|
||||||
|
return if (extraValue.isEmpty()) basePrefSubtype
|
||||||
|
else basePrefSubtype + LOCALE_AND_EXTRA_SEPARATOR + extraValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createAdditionalSubtypes(prefSubtypes: String): List<InputMethodSubtype> {
|
||||||
|
if (TextUtils.isEmpty(prefSubtypes)) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
return prefSubtypes.split(PREF_SUBTYPE_SEPARATOR)
|
||||||
|
.mapNotNull { createSubtypeFromString(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// use string created with getPrefSubtype
|
||||||
|
fun createSubtypeFromString(prefSubtype: String): InputMethodSubtype? {
|
||||||
|
val elems = prefSubtype.split(LOCALE_AND_EXTRA_SEPARATOR)
|
||||||
|
if (elems.size != LENGTH_WITHOUT_EXTRA_VALUE && elems.size != LENGTH_WITH_EXTRA_VALUE) {
|
||||||
|
Log.w(TAG, "Unknown additional subtype specified: $prefSubtype")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val languageTag = elems[INDEX_OF_LANGUAGE_TAG]
|
||||||
|
val locale = languageTag.constructLocale()
|
||||||
|
val keyboardLayoutSet = elems[INDEX_OF_KEYBOARD_LAYOUT]
|
||||||
|
val asciiCapable = locale.script() == ScriptUtils.SCRIPT_LATIN
|
||||||
|
// Here we assume that all the additional subtypes are EmojiCapable
|
||||||
|
val subtype = createEmojiCapableAdditionalSubtype(locale, keyboardLayoutSet, asciiCapable)
|
||||||
|
if (subtype.nameResId == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT && !isCustomLayout(keyboardLayoutSet)) {
|
||||||
|
// Skip unknown keyboard layout subtype. This may happen when predefined keyboard
|
||||||
|
// layout has been removed.
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return subtype
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createPrefSubtypes(subtypes: Array<InputMethodSubtype>?): String {
|
||||||
|
if (subtypes.isNullOrEmpty()) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for (subtype in subtypes) {
|
||||||
|
if (sb.isNotEmpty()) {
|
||||||
|
sb.append(PREF_SUBTYPE_SEPARATOR)
|
||||||
|
}
|
||||||
|
sb.append(getPrefSubtype(subtype))
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createPrefSubtypes(prefSubtypes: Array<String>?): String {
|
||||||
|
if (prefSubtypes.isNullOrEmpty()) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for (prefSubtype in prefSubtypes) {
|
||||||
|
if (sb.isNotEmpty()) {
|
||||||
|
sb.append(PREF_SUBTYPE_SEPARATOR)
|
||||||
|
}
|
||||||
|
sb.append(prefSubtype)
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the extra value that is optimized for the running OS.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Historically the extra value has been used as the last resort to annotate various kinds of
|
||||||
|
* attributes. Some of these attributes are valid only on some platform versions. Thus we cannot
|
||||||
|
* assume that the extra values stored in a persistent storage are always valid. We need to
|
||||||
|
* regenerate the extra value on the fly instead.
|
||||||
|
*
|
||||||
|
* @param keyboardLayoutSetName the keyboard layout set name (e.g., "dvorak").
|
||||||
|
* @param isAsciiCapable true when ASCII characters are supported with this layout.
|
||||||
|
* @param isEmojiCapable true when Unicode Emoji characters are supported with this layout.
|
||||||
|
* @return extra value that is optimized for the running OS.
|
||||||
|
* @see .getPlatformVersionIndependentSubtypeId
|
||||||
|
*/
|
||||||
|
private fun getPlatformVersionDependentExtraValue(locale: Locale,
|
||||||
|
keyboardLayoutSetName: String, isAsciiCapable: Boolean, isEmojiCapable: Boolean
|
||||||
|
): String {
|
||||||
|
val extraValueItems = mutableListOf<String>()
|
||||||
|
extraValueItems.add(ExtraValue.KEYBOARD_LAYOUT_SET + "=MAIN:" + keyboardLayoutSetName)
|
||||||
|
if (isAsciiCapable) {
|
||||||
|
extraValueItems.add(ExtraValue.ASCII_CAPABLE)
|
||||||
|
}
|
||||||
|
if (SubtypeLocaleUtils.isExceptionalLocale(locale)) {
|
||||||
|
extraValueItems.add(
|
||||||
|
ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" +
|
||||||
|
SubtypeLocaleUtils.getMainLayoutDisplayName(keyboardLayoutSetName)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (isEmojiCapable) {
|
||||||
|
extraValueItems.add(ExtraValue.EMOJI_CAPABLE)
|
||||||
|
}
|
||||||
|
extraValueItems.add(ExtraValue.IS_ADDITIONAL_SUBTYPE)
|
||||||
|
return extraValueItems.joinToString(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the subtype ID that is supposed to be compatible between different version of OSes.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* From the compatibility point of view, it is important to keep subtype id predictable and
|
||||||
|
* stable between different OSes. For this purpose, the calculation code in this method is
|
||||||
|
* carefully chosen and then fixed. Treat the following code as no more or less than a
|
||||||
|
* hash function. Each component to be hashed can be different from the corresponding value
|
||||||
|
* that is used to instantiate [InputMethodSubtype] actually.
|
||||||
|
* For example, you don't need to update `compatibilityExtraValueItems` in this
|
||||||
|
* method even when we need to add some new extra values for the actual instance of
|
||||||
|
* [InputMethodSubtype].
|
||||||
|
*
|
||||||
|
* @param keyboardLayoutSetName the keyboard layout set name (e.g., "dvorak").
|
||||||
|
* @return a platform-version independent subtype ID.
|
||||||
|
* @see .getPlatformVersionDependentExtraValue
|
||||||
|
*/
|
||||||
|
private fun getPlatformVersionIndependentSubtypeId(locale: Locale, keyboardLayoutSetName: String): Int {
|
||||||
|
// For compatibility reasons, we concatenate the extra values in the following order.
|
||||||
|
// - KeyboardLayoutSet
|
||||||
|
// - AsciiCapable
|
||||||
|
// - UntranslatableReplacementStringInSubtypeName
|
||||||
|
// - EmojiCapable
|
||||||
|
// - isAdditionalSubtype
|
||||||
|
val compatibilityExtraValueItems = mutableListOf<String>()
|
||||||
|
compatibilityExtraValueItems.add(ExtraValue.KEYBOARD_LAYOUT_SET + "=MAIN:" + keyboardLayoutSetName)
|
||||||
|
compatibilityExtraValueItems.add(ExtraValue.ASCII_CAPABLE)
|
||||||
|
if (SubtypeLocaleUtils.isExceptionalLocale(locale)) {
|
||||||
|
compatibilityExtraValueItems.add(
|
||||||
|
ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" +
|
||||||
|
SubtypeLocaleUtils.getMainLayoutDisplayName(keyboardLayoutSetName)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
compatibilityExtraValueItems.add(ExtraValue.EMOJI_CAPABLE)
|
||||||
|
compatibilityExtraValueItems.add(ExtraValue.IS_ADDITIONAL_SUBTYPE)
|
||||||
|
val compatibilityExtraValues = compatibilityExtraValueItems.joinToString(",")
|
||||||
|
return arrayOf(
|
||||||
|
locale,
|
||||||
|
Constants.Subtype.KEYBOARD_MODE,
|
||||||
|
compatibilityExtraValues,
|
||||||
|
false, // isAuxiliary
|
||||||
|
false // overrideImplicitlyEnabledSubtype
|
||||||
|
).contentHashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val TAG: String = SubtypeUtilsAdditional::class.java.simpleName
|
||||||
|
const val LOCALE_AND_EXTRA_SEPARATOR: String = "§"
|
||||||
|
const val PREF_SUBTYPE_SEPARATOR: String = ";"
|
||||||
|
private const val INDEX_OF_LANGUAGE_TAG: Int = 0
|
||||||
|
private const val INDEX_OF_KEYBOARD_LAYOUT: Int = 1
|
||||||
|
private const val INDEX_OF_EXTRA_VALUE: Int = 2
|
||||||
|
private const val LENGTH_WITHOUT_EXTRA_VALUE: Int = (INDEX_OF_KEYBOARD_LAYOUT + 1)
|
||||||
|
private const val LENGTH_WITH_EXTRA_VALUE: Int = (INDEX_OF_EXTRA_VALUE + 1)
|
||||||
|
}
|
|
@ -30,11 +30,11 @@ import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||||
import helium314.keyboard.latin.settings.Defaults
|
import helium314.keyboard.latin.settings.Defaults
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.settings.USER_DICTIONARY_SUFFIX
|
import helium314.keyboard.latin.settings.USER_DICTIONARY_SUFFIX
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils
|
|
||||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||||
import helium314.keyboard.latin.utils.ExecutorUtils
|
import helium314.keyboard.latin.utils.ExecutorUtils
|
||||||
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.latin.utils.protectedPrefs
|
import helium314.keyboard.latin.utils.protectedPrefs
|
||||||
|
@ -175,8 +175,8 @@ fun BackupRestorePreference(setting: Setting) {
|
||||||
wait.await()
|
wait.await()
|
||||||
checkVersionUpgrade(ctx)
|
checkVersionUpgrade(ctx)
|
||||||
Settings.getInstance().startListener()
|
Settings.getInstance().startListener()
|
||||||
val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)
|
val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
|
||||||
updateAdditionalSubtypes(AdditionalSubtypeUtils.createAdditionalSubtypesArray(additionalSubtypes))
|
updateAdditionalSubtypes(SubtypeUtilsAdditional.createAdditionalSubtypes(additionalSubtypes))
|
||||||
reloadEnabledSubtypes(ctx)
|
reloadEnabledSubtypes(ctx)
|
||||||
val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)
|
val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION)
|
||||||
ctx.getActivity()?.sendBroadcast(newDictBroadcast)
|
ctx.getActivity()?.sendBroadcast(newDictBroadcast)
|
||||||
|
|
|
@ -19,9 +19,9 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToP
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
||||||
import helium314.keyboard.latin.LatinIME
|
import helium314.keyboard.latin.LatinIME
|
||||||
import helium314.keyboard.latin.RichInputMethodSubtype
|
import helium314.keyboard.latin.RichInputMethodSubtype
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils.createEmojiCapableAdditionalSubtype
|
|
||||||
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.POPUP_KEYS_LAYOUT
|
import helium314.keyboard.latin.utils.POPUP_KEYS_LAYOUT
|
||||||
|
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.robolectric.Robolectric
|
import org.robolectric.Robolectric
|
||||||
import org.robolectric.RobolectricTestRunner
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
@ -418,21 +418,21 @@ f""", // no newline at the end
|
||||||
|
|
||||||
@Test fun canLoadKeyboard() {
|
@Test fun canLoadKeyboard() {
|
||||||
val editorInfo = EditorInfo()
|
val editorInfo = EditorInfo()
|
||||||
val subtype = createEmojiCapableAdditionalSubtype(Locale.ENGLISH, "qwerty", true)
|
val subtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(Locale.ENGLISH, "qwerty", true)
|
||||||
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
||||||
assertEquals(kb.sortedKeys.size, keys.sumOf { it.size })
|
assertEquals(kb.sortedKeys.size, keys.sumOf { it.size })
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `dvorak has 4 rows`() {
|
@Test fun `dvorak has 4 rows`() {
|
||||||
val editorInfo = EditorInfo()
|
val editorInfo = EditorInfo()
|
||||||
val subtype = createEmojiCapableAdditionalSubtype(Locale.ENGLISH, "dvorak", true)
|
val subtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(Locale.ENGLISH, "dvorak", true)
|
||||||
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
||||||
assertEquals(keys.size, 4)
|
assertEquals(keys.size, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `de_DE has extra keys`() {
|
@Test fun `de_DE has extra keys`() {
|
||||||
val editorInfo = EditorInfo()
|
val editorInfo = EditorInfo()
|
||||||
val subtype = createEmojiCapableAdditionalSubtype(Locale.GERMANY, "qwertz+", true)
|
val subtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(Locale.GERMANY, "qwertz+", true)
|
||||||
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
||||||
assertEquals(11, keys[0].size)
|
assertEquals(11, keys[0].size)
|
||||||
assertEquals(11, keys[1].size)
|
assertEquals(11, keys[1].size)
|
||||||
|
@ -445,7 +445,7 @@ f""", // no newline at the end
|
||||||
|
|
||||||
@Test fun `popup key count does not depend on shift for (for simple layout)`() {
|
@Test fun `popup key count does not depend on shift for (for simple layout)`() {
|
||||||
val editorInfo = EditorInfo()
|
val editorInfo = EditorInfo()
|
||||||
val subtype = createEmojiCapableAdditionalSubtype(Locale.ENGLISH, "qwerty", true)
|
val subtype = SubtypeUtilsAdditional.createEmojiCapableAdditionalSubtype(Locale.ENGLISH, "qwerty", true)
|
||||||
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
val (kb, keys) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET)
|
||||||
val (kb2, keys2) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)
|
val (kb2, keys2) = buildKeyboard(editorInfo, subtype, KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)
|
||||||
assertEquals(kb.sortedKeys.size, kb2.sortedKeys.size)
|
assertEquals(kb.sortedKeys.size, kb2.sortedKeys.size)
|
||||||
|
|
Loading…
Add table
Reference in a new issue