mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-22 15:19:10 +00:00
adjust arrangement for layouts
so we can have more than one layout per type (was possible only for main)
This commit is contained in:
parent
846388de97
commit
5ba40f7875
98 changed files with 260 additions and 207 deletions
|
@ -13,8 +13,8 @@ android {
|
||||||
applicationId = "helium314.keyboard"
|
applicationId = "helium314.keyboard"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 2303
|
versionCode = 2304
|
||||||
versionName = "2.3+dev2"
|
versionName = "2.3+dev3"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters.clear()
|
abiFilters.clear()
|
||||||
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64"))
|
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64"))
|
||||||
|
|
|
@ -16,9 +16,9 @@ import helium314.keyboard.keyboard.internal.KeyboardBuilder;
|
||||||
import helium314.keyboard.keyboard.internal.KeyboardIconsSet;
|
import helium314.keyboard.keyboard.internal.KeyboardIconsSet;
|
||||||
import helium314.keyboard.keyboard.internal.KeyboardParams;
|
import helium314.keyboard.keyboard.internal.KeyboardParams;
|
||||||
import helium314.keyboard.keyboard.internal.UniqueKeysCache;
|
import helium314.keyboard.keyboard.internal.UniqueKeysCache;
|
||||||
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LayoutParser;
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfos;
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfos;
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfosKt;
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfosKt;
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser;
|
|
||||||
import helium314.keyboard.latin.RichInputMethodManager;
|
import helium314.keyboard.latin.RichInputMethodManager;
|
||||||
import helium314.keyboard.latin.RichInputMethodSubtype;
|
import helium314.keyboard.latin.RichInputMethodSubtype;
|
||||||
import helium314.keyboard.latin.settings.Settings;
|
import helium314.keyboard.latin.settings.Settings;
|
||||||
|
@ -104,7 +104,7 @@ public final class KeyboardLayoutSet {
|
||||||
private static void clearKeyboardCache() {
|
private static void clearKeyboardCache() {
|
||||||
sKeyboardCache.clear();
|
sKeyboardCache.clear();
|
||||||
sUniqueKeysCache.clear();
|
sUniqueKeysCache.clear();
|
||||||
RawKeyboardParser.INSTANCE.clearCache();
|
LayoutParser.INSTANCE.clearCache();
|
||||||
KeyboardIconsSet.Companion.setNeedsReload(true);
|
KeyboardIconsSet.Companion.setNeedsReload(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,9 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.TextKeyData
|
||||||
import helium314.keyboard.latin.common.isEmoji
|
import helium314.keyboard.latin.common.isEmoji
|
||||||
import helium314.keyboard.latin.define.DebugFlags
|
import helium314.keyboard.latin.define.DebugFlags
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
import helium314.keyboard.latin.utils.POPUP_KEYS_LAYOUT
|
import helium314.keyboard.latin.utils.POPUP_KEYS_LAYOUT
|
||||||
import helium314.keyboard.latin.utils.POPUP_KEYS_NUMBER
|
import helium314.keyboard.latin.utils.POPUP_KEYS_NUMBER
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils
|
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils.script
|
|
||||||
import helium314.keyboard.latin.utils.replaceFirst
|
import helium314.keyboard.latin.utils.replaceFirst
|
||||||
import helium314.keyboard.latin.utils.splitAt
|
import helium314.keyboard.latin.utils.splitAt
|
||||||
import helium314.keyboard.latin.utils.sumOf
|
import helium314.keyboard.latin.utils.sumOf
|
||||||
|
@ -47,7 +46,20 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co
|
||||||
fun parseLayout(): ArrayList<ArrayList<KeyParams>> {
|
fun parseLayout(): ArrayList<ArrayList<KeyParams>> {
|
||||||
params.readAttributes(context, null)
|
params.readAttributes(context, null)
|
||||||
|
|
||||||
val baseKeys = RawKeyboardParser.parseLayout(params, context)
|
// todo: maybe determine layoutType earlier, and to less stuff based on elementId
|
||||||
|
val layoutType = when (params.mId.mElementId) {
|
||||||
|
KeyboardId.ELEMENT_SYMBOLS -> LayoutType.SYMBOLS
|
||||||
|
KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> LayoutType.MORE_SYMBOLS
|
||||||
|
KeyboardId.ELEMENT_PHONE -> LayoutType.PHONE
|
||||||
|
KeyboardId.ELEMENT_PHONE_SYMBOLS -> LayoutType.PHONE_SYMBOLS
|
||||||
|
KeyboardId.ELEMENT_NUMBER -> LayoutType.NUMBER
|
||||||
|
KeyboardId.ELEMENT_NUMPAD -> if (Settings.getInstance().current.mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE)
|
||||||
|
LayoutType.NUMPAD_LANDSCAPE else LayoutType.NUMPAD
|
||||||
|
KeyboardId.ELEMENT_EMOJI_BOTTOM_ROW -> LayoutType.EMOJI_BOTTOM
|
||||||
|
KeyboardId.ELEMENT_CLIPBOARD_BOTTOM_ROW -> LayoutType.CLIPBOARD_BOTTOM
|
||||||
|
else -> LayoutType.MAIN
|
||||||
|
}
|
||||||
|
val baseKeys = LayoutParser.parseLayout(layoutType, params, context)
|
||||||
val keysInRows = createRows(baseKeys)
|
val keysInRows = createRows(baseKeys)
|
||||||
val heightRescale: Float
|
val heightRescale: Float
|
||||||
if (params.mId.isEmojiClipBottomRow) {
|
if (params.mId.isEmojiClipBottomRow) {
|
||||||
|
@ -94,7 +106,7 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co
|
||||||
if (!params.mAllowRedundantPopupKeys)
|
if (!params.mAllowRedundantPopupKeys)
|
||||||
params.baseKeys = baseKeys.flatMap { it.map { it.toKeyParams(params) } }
|
params.baseKeys = baseKeys.flatMap { it.map { it.toKeyParams(params) } }
|
||||||
|
|
||||||
val allFunctionalKeys = RawKeyboardParser.parseLayout(params, context, true)
|
val allFunctionalKeys = LayoutParser.parseLayout(LayoutType.FUNCTIONAL, params, context)
|
||||||
adjustBottomFunctionalRowAndBaseKeys(allFunctionalKeys, baseKeys)
|
adjustBottomFunctionalRowAndBaseKeys(allFunctionalKeys, baseKeys)
|
||||||
|
|
||||||
if (allFunctionalKeys.none { it.singleOrNull()?.isKeyPlaceholder() == true })
|
if (allFunctionalKeys.none { it.singleOrNull()?.isKeyPlaceholder() == true })
|
||||||
|
@ -272,8 +284,7 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSymbolPopupKeys(baseKeys: MutableList<MutableList<KeyData>>) {
|
private fun addSymbolPopupKeys(baseKeys: MutableList<MutableList<KeyData>>) {
|
||||||
val layoutName = if (params.mId.locale.script() == ScriptUtils.SCRIPT_ARABIC) LAYOUT_SYMBOLS_ARABIC else LAYOUT_SYMBOLS
|
val layout = LayoutParser.parseLayout(LayoutType.SYMBOLS, params, context)
|
||||||
val layout = RawKeyboardParser.parseLayout(layoutName, params, context)
|
|
||||||
layout.forEachIndexed { i, row ->
|
layout.forEachIndexed { i, row ->
|
||||||
val baseRow = baseKeys.getOrNull(i) ?: return@forEachIndexed
|
val baseRow = baseKeys.getOrNull(i) ?: return@forEachIndexed
|
||||||
row.forEachIndexed { j, key ->
|
row.forEachIndexed { j, key ->
|
||||||
|
@ -283,7 +294,7 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNumberRow(): MutableList<KeyData> {
|
private fun getNumberRow(): MutableList<KeyData> {
|
||||||
val row = RawKeyboardParser.parseLayout(LAYOUT_NUMBER_ROW, params, context).first()
|
val row = LayoutParser.parseLayout(LayoutType.NUMBER_ROW, params, context).first()
|
||||||
val localizedNumbers = params.mLocaleKeyboardInfos.localizedNumberKeys
|
val localizedNumbers = params.mLocaleKeyboardInfos.localizedNumberKeys
|
||||||
if (localizedNumbers?.size != 10) return row
|
if (localizedNumbers?.size != 10) return row
|
||||||
if (Settings.getInstance().current.mLocalizedNumberRow) {
|
if (Settings.getInstance().current.mLocalizedNumberRow) {
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
package helium314.keyboard.keyboard.internal.keyboard_parser
|
package helium314.keyboard.keyboard.internal.keyboard_parser
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
|
||||||
import helium314.keyboard.keyboard.KeyboardId
|
|
||||||
import helium314.keyboard.keyboard.internal.KeyboardParams
|
import helium314.keyboard.keyboard.internal.KeyboardParams
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.AbstractKeyData
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.AbstractKeyData
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.AutoTextKeyData
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.AutoTextKeyData
|
||||||
|
@ -19,45 +17,32 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.TextKeyData
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.VariationSelector
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.VariationSelector
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.toTextKey
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.toTextKey
|
||||||
import helium314.keyboard.latin.common.splitOnWhitespace
|
import helium314.keyboard.latin.common.splitOnWhitespace
|
||||||
|
import helium314.keyboard.latin.settings.Defaults.default
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
||||||
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
|
import helium314.keyboard.latin.utils.LayoutType.Companion.folder
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils
|
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils.script
|
|
||||||
import helium314.keyboard.latin.utils.getCustomFunctionalLayoutName
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFile
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
||||||
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
import kotlinx.serialization.modules.polymorphic
|
import kotlinx.serialization.modules.polymorphic
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
object RawKeyboardParser {
|
object LayoutParser {
|
||||||
private const val TAG = "RawKeyboardParser"
|
private const val TAG = "LayoutParser"
|
||||||
private val rawLayoutCache = hashMapOf<String, (KeyboardParams) -> MutableList<MutableList<KeyData>>>()
|
private val layoutCache = hashMapOf<String, (KeyboardParams) -> MutableList<MutableList<KeyData>>>()
|
||||||
|
|
||||||
val symbolAndNumberLayouts = listOf(LAYOUT_SYMBOLS, LAYOUT_SYMBOLS_SHIFTED, LAYOUT_SYMBOLS_ARABIC,
|
fun clearCache() = layoutCache.clear()
|
||||||
LAYOUT_NUMBER, LAYOUT_NUMPAD, LAYOUT_NUMPAD_LANDSCAPE, LAYOUT_PHONE, LAYOUT_PHONE_SYMBOLS,
|
|
||||||
LAYOUT_NUMBER_ROW, LAYOUT_EMOJI_BOTTOM_ROW, LAYOUT_CLIPBOARD_BOTTOM_ROW)
|
|
||||||
|
|
||||||
fun clearCache() = rawLayoutCache.clear()
|
fun parseLayout(layoutType: LayoutType, params: KeyboardParams, context: Context): MutableList<MutableList<KeyData>> {
|
||||||
|
if (layoutType == LayoutType.FUNCTIONAL && !params.mId.isAlphaOrSymbolKeyboard)
|
||||||
fun parseLayout(params: KeyboardParams, context: Context, isFunctional: Boolean = false): MutableList<MutableList<KeyData>> {
|
return mutableListOf(mutableListOf()) // no functional keys
|
||||||
val layoutName = if (isFunctional) {
|
val layoutName = if (layoutType == LayoutType.MAIN) params.mId.mSubtype.mainLayoutName
|
||||||
if (!params.mId.isAlphaOrSymbolKeyboard) return mutableListOf(mutableListOf())
|
else params.mId.mSubtype.layouts[layoutType] ?: Settings.getLayoutName(layoutType, context.prefs())
|
||||||
else getFunctionalLayoutName(params, context)
|
return layoutCache.getOrPut(layoutType.name + layoutName) {
|
||||||
} else {
|
createCacheLambda(layoutType, layoutName, context)
|
||||||
getLayoutName(params, context)
|
|
||||||
}
|
|
||||||
return rawLayoutCache.getOrPut(layoutName) {
|
|
||||||
createCacheLambda(layoutName, context)
|
|
||||||
}(params)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun parseLayout(layoutName: String, params: KeyboardParams, context: Context): MutableList<MutableList<KeyData>> {
|
|
||||||
return rawLayoutCache.getOrPut(layoutName) {
|
|
||||||
createCacheLambda(layoutName, context)
|
|
||||||
}(params)
|
}(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,25 +74,12 @@ object RawKeyboardParser {
|
||||||
else split.first().toTextKey(split.drop(1))
|
else split.first().toTextKey(split.drop(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCacheLambda(layoutName: String, context: Context): (KeyboardParams) -> MutableList<MutableList<KeyData>> {
|
private fun createCacheLambda(layoutType: LayoutType, layoutName: String, context: Context):
|
||||||
val layoutFileName = getLayoutFileName(layoutName, context)
|
(KeyboardParams) -> MutableList<MutableList<KeyData>> {
|
||||||
val layoutText = if (layoutFileName.startsWith(CUSTOM_LAYOUT_PREFIX)) {
|
val layoutFileContent = getLayoutFileContent(layoutType, layoutName.substringBefore("+"), context).trimStart()
|
||||||
|
if (layoutFileContent.startsWith("[") || (layoutName.startsWith(CUSTOM_LAYOUT_PREFIX) && layoutFileContent.startsWith("/"))) {
|
||||||
try {
|
try {
|
||||||
getCustomLayoutFile(layoutFileName, context).readText().trimStart()
|
val florisKeyData = parseJsonString(layoutFileContent, false)
|
||||||
} catch (e: Exception) { // fall back to defaults if for some reason file is broken
|
|
||||||
val name = when {
|
|
||||||
layoutName.contains("functional") -> "functional_keys.json"
|
|
||||||
layoutName.contains("number_row") -> "number_row.txt"
|
|
||||||
layoutName.contains("symbols") -> "symbols.txt"
|
|
||||||
else -> "qwerty.txt"
|
|
||||||
}
|
|
||||||
Log.e(TAG, "cannot open layout $layoutName, falling back to $name", e)
|
|
||||||
context.assets.open("layouts${File.separator}$name").reader().use { it.readText() }
|
|
||||||
}
|
|
||||||
} else context.assets.open("layouts${File.separator}$layoutFileName").reader().use { it.readText() }
|
|
||||||
if (layoutFileName.endsWith(".json") || (layoutFileName.startsWith(CUSTOM_LAYOUT_PREFIX) && layoutText.startsWith("["))) {
|
|
||||||
try {
|
|
||||||
val florisKeyData = parseJsonString(layoutText, false)
|
|
||||||
return { params ->
|
return { params ->
|
||||||
florisKeyData.mapTo(mutableListOf()) { row ->
|
florisKeyData.mapTo(mutableListOf()) { row ->
|
||||||
row.mapNotNullTo(mutableListOf()) { it.compute(params) }
|
row.mapNotNullTo(mutableListOf()) { it.compute(params) }
|
||||||
|
@ -118,60 +90,26 @@ object RawKeyboardParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not a json, or invalid json
|
// not a json, or invalid json
|
||||||
val simpleKeyData = parseSimpleString(layoutText)
|
val simpleKeyData = parseSimpleString(layoutFileContent)
|
||||||
return { params ->
|
return { params ->
|
||||||
simpleKeyData.mapIndexedTo(mutableListOf()) { i, row ->
|
simpleKeyData.mapIndexedTo(mutableListOf()) { i, row ->
|
||||||
val newRow = row.toMutableList()
|
val newRow = row.toMutableList()
|
||||||
if (params.mId.isAlphabetKeyboard
|
if (params.mId.isAlphabetKeyboard && layoutName.endsWith("+"))
|
||||||
&& params.mId.mSubtype.mainLayoutName.endsWith("+")
|
|
||||||
&& "$layoutName+" == params.mId.mSubtype.mainLayoutName
|
|
||||||
) {
|
|
||||||
params.mLocaleKeyboardInfos.getExtraKeys(i+1)?.let { newRow.addAll(it) }
|
params.mLocaleKeyboardInfos.getExtraKeys(i+1)?.let { newRow.addAll(it) }
|
||||||
}
|
|
||||||
newRow
|
newRow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLayoutName(params: KeyboardParams, context: Context) = when (params.mId.mElementId) {
|
private fun getLayoutFileContent(layoutType: LayoutType, layoutName: String, context: Context): String {
|
||||||
KeyboardId.ELEMENT_SYMBOLS -> if (params.mId.locale.script() == ScriptUtils.SCRIPT_ARABIC) LAYOUT_SYMBOLS_ARABIC else LAYOUT_SYMBOLS
|
if (layoutName.startsWith(CUSTOM_LAYOUT_PREFIX))
|
||||||
KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> LAYOUT_SYMBOLS_SHIFTED
|
getCustomLayoutFiles(layoutType, context)
|
||||||
KeyboardId.ELEMENT_NUMPAD -> if (context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
|
.firstOrNull { it.name.startsWith(layoutName) }?.let { return it.readText() }
|
||||||
LAYOUT_NUMPAD_LANDSCAPE
|
val layouts = context.assets.list(layoutType.folder)!!
|
||||||
else
|
layouts.firstOrNull { it.startsWith("$layoutName.") }
|
||||||
LAYOUT_NUMPAD
|
?.let { return context.assets.open(layoutType.folder + it).reader().readText() }
|
||||||
KeyboardId.ELEMENT_NUMBER -> LAYOUT_NUMBER
|
val fallback = layouts.first { it.startsWith(layoutType.default) } // must exist!
|
||||||
KeyboardId.ELEMENT_PHONE -> LAYOUT_PHONE
|
return context.assets.open(layoutType.folder + fallback).reader().readText()
|
||||||
KeyboardId.ELEMENT_PHONE_SYMBOLS -> LAYOUT_PHONE_SYMBOLS
|
|
||||||
KeyboardId.ELEMENT_EMOJI_BOTTOM_ROW -> LAYOUT_EMOJI_BOTTOM_ROW
|
|
||||||
KeyboardId.ELEMENT_CLIPBOARD_BOTTOM_ROW -> LAYOUT_CLIPBOARD_BOTTOM_ROW
|
|
||||||
else -> params.mId.mSubtype.mainLayoutName.substringBeforeLast("+")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getFunctionalLayoutName(params: KeyboardParams, context: Context): String {
|
|
||||||
if (Settings.getInstance().current.mHasCustomFunctionalLayout) {
|
|
||||||
getCustomFunctionalLayoutName(params.mId.mElementId, params.mId.mSubtype.rawSubtype, context)
|
|
||||||
?.let { return it }
|
|
||||||
}
|
|
||||||
return if (Settings.getInstance().isTablet) "functional_keys_tablet" else "functional_keys"
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns the file name matching the layout name, making sure the file exists (falling back to qwerty.txt) */
|
|
||||||
private fun getLayoutFileName(layoutName: String, context: Context): String {
|
|
||||||
val customFiles = getCustomLayoutFiles(context).map { it.name }
|
|
||||||
if (layoutName.startsWith(CUSTOM_LAYOUT_PREFIX)) {
|
|
||||||
return customFiles.firstOrNull { it.startsWith(layoutName)}
|
|
||||||
?: if (layoutName.contains("functional")) "functional_keys.json" else "qwerty.txt" // fallback to defaults
|
|
||||||
}
|
|
||||||
val assetsFiles by lazy { context.assets.list("layouts")!! }
|
|
||||||
return if (layoutName in symbolAndNumberLayouts) {
|
|
||||||
customFiles.firstOrNull { it.startsWith("$CUSTOM_LAYOUT_PREFIX$layoutName.")}
|
|
||||||
?: assetsFiles.first { it.startsWith(layoutName) }
|
|
||||||
} else {
|
|
||||||
// can't be custom layout, so it must be in assets
|
|
||||||
val searchName = layoutName.substringBeforeLast("+") // consider there are layouts ending in "+" for adding extra keys
|
|
||||||
assetsFiles.firstOrNull { it.startsWith(searchName) } ?: "qwerty.txt" // in case it was removed
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow commenting lines by starting them with "//"
|
// allow commenting lines by starting them with "//"
|
|
@ -195,6 +195,9 @@ fun addLocaleKeyTextsToParams(context: Context, params: KeyboardParams, popupKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hasLocalizedNumberRow(locale: Locale, context: Context) =
|
||||||
|
getStreamForLocale(locale, context)?.bufferedReader()?.readLines()?.any { it == "[number_row]" } == true
|
||||||
|
|
||||||
private fun createLocaleKeyTexts(context: Context, params: KeyboardParams, popupKeysSetting: Int): LocaleKeyboardInfos {
|
private fun createLocaleKeyTexts(context: Context, params: KeyboardParams, popupKeysSetting: Int): LocaleKeyboardInfos {
|
||||||
val lkt = LocaleKeyboardInfos(getStreamForLocale(params.mId.locale, context), params.mId.locale)
|
val lkt = LocaleKeyboardInfos(getStreamForLocale(params.mId.locale, context), params.mId.locale)
|
||||||
params.mSecondaryLocales.forEach { locale ->
|
params.mSecondaryLocales.forEach { locale ->
|
||||||
|
|
|
@ -3,7 +3,6 @@ package helium314.keyboard.latin
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import helium314.keyboard.keyboard.ColorSetting
|
import helium314.keyboard.keyboard.ColorSetting
|
||||||
import helium314.keyboard.keyboard.KeyboardTheme
|
import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
|
@ -15,9 +14,13 @@ 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.settings.colorPrefsAndResIds
|
import helium314.keyboard.latin.settings.colorPrefsAndResIds
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
||||||
|
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||||
import helium314.keyboard.latin.utils.DictionaryInfoUtils
|
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.ToolbarKey
|
import helium314.keyboard.latin.utils.ToolbarKey
|
||||||
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
|
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
|
||||||
|
import helium314.keyboard.latin.utils.encodeBase36
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFile
|
import helium314.keyboard.latin.utils.getCustomLayoutFile
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
||||||
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
||||||
|
@ -236,6 +239,120 @@ fun checkVersionUpgrade(context: Context) {
|
||||||
} }
|
} }
|
||||||
writeCustomKeyCodes(prefs, combined)
|
writeCustomKeyCodes(prefs, combined)
|
||||||
}
|
}
|
||||||
|
if (oldVersion <= 2303) {
|
||||||
|
File(DeviceProtectedUtils.getFilesDir(context), "layouts").listFiles()?.forEach { file ->
|
||||||
|
val folder = DeviceProtectedUtils.getFilesDir(context)
|
||||||
|
when (file.name) {
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}symbols." -> {
|
||||||
|
val dir = File(folder, LayoutType.SYMBOLS.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("symbols")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.SYMBOLS.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}symbols_shifted." -> {
|
||||||
|
val dir = File(folder, LayoutType.MORE_SYMBOLS.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("symbols_shifted")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.MORE_SYMBOLS.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}symbols_arabic." -> {
|
||||||
|
val dir = File(folder, LayoutType.SYMBOLS.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("symbols_arabic")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}numpad." -> {
|
||||||
|
val dir = File(folder, LayoutType.NUMPAD.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("numpad")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMPAD.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}numpad_landscape." -> {
|
||||||
|
val dir = File(folder, LayoutType.NUMPAD_LANDSCAPE.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("numpad_landscape")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMPAD_LANDSCAPE.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}number." -> {
|
||||||
|
val dir = File(folder, LayoutType.NUMBER.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("number")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMBER.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}phone." -> {
|
||||||
|
val dir = File(folder, LayoutType.PHONE.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("phone")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.PHONE.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}phone_symbols." -> {
|
||||||
|
val dir = File(folder, LayoutType.PHONE_SYMBOLS.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("phone_symbols")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.PHONE_SYMBOLS.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}number_row." -> {
|
||||||
|
val dir = File(folder, LayoutType.NUMBER_ROW.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("number_row")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMBER_ROW.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}emoji_bottom_row." -> {
|
||||||
|
val dir = File(folder, LayoutType.EMOJI_BOTTOM.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("emoji_bottom_row")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.EMOJI_BOTTOM.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}clip_bottom_row." -> {
|
||||||
|
val dir = File(folder, LayoutType.CLIPBOARD_BOTTOM.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("clip_bottom_row")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.CLIPBOARD_BOTTOM.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}functional_keys." -> {
|
||||||
|
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("functional_keys")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.FUNCTIONAL.name, name).apply()
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}functional_keys_symbols." -> {
|
||||||
|
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("functional_keys_symbols")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
}
|
||||||
|
"${CUSTOM_LAYOUT_PREFIX}functional_keys_symbols_shifted." -> {
|
||||||
|
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("functional_keys_symbols_shifted")}."
|
||||||
|
file.renameTo(File(dir, name))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// main layouts
|
||||||
|
val dir = File(folder, LayoutType.MAIN.folder)
|
||||||
|
dir.mkdirs()
|
||||||
|
file.renameTo(File(dir, file.name))
|
||||||
|
// todo: maybe rename to custom.latn.name. instead of custom.en-GB.name. for latin script?
|
||||||
|
// just make sure the subtypes are still working when the file name is different (need to upgrade PREF_ADDITIONAL_SUBTYPES)
|
||||||
|
// also consider name collision when a user has layout with the same name for 2 languages
|
||||||
|
// decode name, append number, encode name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prefs.contains(Settings.PREF_ADDITIONAL_SUBTYPES))
|
||||||
|
prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!!.replace(":", "§")).apply()
|
||||||
|
}
|
||||||
upgradeToolbarPrefs(prefs)
|
upgradeToolbarPrefs(prefs)
|
||||||
onCustomLayoutFileListChanged() // just to be sure
|
onCustomLayoutFileListChanged() // just to be sure
|
||||||
prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) }
|
prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) }
|
||||||
|
|
|
@ -35,6 +35,7 @@ class RichInputMethodSubtype private constructor(val rawSubtype: InputMethodSubt
|
||||||
|
|
||||||
val mainLayoutName: String get() = layouts[LayoutType.MAIN] ?: "qwerty"
|
val mainLayoutName: String get() = layouts[LayoutType.MAIN] ?: "qwerty"
|
||||||
|
|
||||||
|
/** layout names for this subtype by LayoutType */
|
||||||
val layouts = LayoutType.getLayoutMap(getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "")
|
val layouts = LayoutType.getLayoutMap(getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "")
|
||||||
|
|
||||||
val isCustom: Boolean get() = mainLayoutName.startsWith(CUSTOM_LAYOUT_PREFIX)
|
val isCustom: Boolean get() = mainLayoutName.startsWith(CUSTOM_LAYOUT_PREFIX)
|
||||||
|
|
|
@ -22,7 +22,6 @@ import androidx.core.content.edit
|
||||||
import androidx.core.widget.doAfterTextChanged
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import helium314.keyboard.dictionarypack.DictionaryPackConstants
|
import helium314.keyboard.dictionarypack.DictionaryPackConstants
|
||||||
import helium314.keyboard.keyboard.KeyboardActionListener
|
import helium314.keyboard.keyboard.KeyboardActionListener
|
||||||
|
@ -37,7 +36,6 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_PHONE_SYMBOLS
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_SYMBOLS
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_SYMBOLS
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_SYMBOLS_ARABIC
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_SYMBOLS_ARABIC
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_SYMBOLS_SHIFTED
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LAYOUT_SYMBOLS_SHIFTED
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser
|
|
||||||
import helium314.keyboard.latin.AudioAndHapticFeedbackManager
|
import helium314.keyboard.latin.AudioAndHapticFeedbackManager
|
||||||
import helium314.keyboard.latin.BuildConfig
|
import helium314.keyboard.latin.BuildConfig
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
|
@ -165,7 +163,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showCustomizeSymbolNumberLayoutsDialog() {
|
private fun showCustomizeSymbolNumberLayoutsDialog() {
|
||||||
val layoutNames = RawKeyboardParser.symbolAndNumberLayouts.map { it.getStringResourceOrName("layout_", requireContext()) }.toTypedArray()
|
/* val layoutNames = RawKeyboardParser.symbolAndNumberLayouts.map { it.getStringResourceOrName("layout_", requireContext()) }.toTypedArray()
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setTitle(R.string.customize_symbols_number_layouts)
|
.setTitle(R.string.customize_symbols_number_layouts)
|
||||||
.setItems(layoutNames) { di, i ->
|
.setItems(layoutNames) { di, i ->
|
||||||
|
@ -174,7 +172,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.show()
|
.show()
|
||||||
}
|
*/ }
|
||||||
|
|
||||||
private fun customizeSymbolNumberLayout(layoutName: String) {
|
private fun customizeSymbolNumberLayout(layoutName: String) {
|
||||||
val customLayoutName = getCustomLayoutFiles(requireContext()).map { it.name }
|
val customLayoutName = getCustomLayoutFiles(requireContext()).map { it.name }
|
||||||
|
|
|
@ -9,6 +9,7 @@ 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.AdditionalSubtypeUtils
|
||||||
import helium314.keyboard.latin.utils.JniUtils
|
import helium314.keyboard.latin.utils.JniUtils
|
||||||
|
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.defaultClipboardToolbarPref
|
import helium314.keyboard.latin.utils.defaultClipboardToolbarPref
|
||||||
|
@ -27,6 +28,22 @@ object Defaults {
|
||||||
PREF_POPUP_ON = dm.widthPixels >= px600 || dm.heightPixels >= px600
|
PREF_POPUP_ON = dm.widthPixels >= px600 || dm.heightPixels >= px600
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// must correspond to a file name
|
||||||
|
val LayoutType.default get() = when (this) {
|
||||||
|
LayoutType.MAIN -> "qwerty"
|
||||||
|
LayoutType.SYMBOLS -> "symbols"
|
||||||
|
LayoutType.MORE_SYMBOLS -> "symbols_shifted"
|
||||||
|
LayoutType.FUNCTIONAL -> if (Settings.getInstance().isTablet) "functional_keys_tablet" else "functional_keys"
|
||||||
|
LayoutType.NUMBER -> "number"
|
||||||
|
LayoutType.NUMBER_ROW -> "number_row"
|
||||||
|
LayoutType.NUMPAD -> "numpad"
|
||||||
|
LayoutType.NUMPAD_LANDSCAPE -> "numpad_landscape"
|
||||||
|
LayoutType.PHONE -> "phone"
|
||||||
|
LayoutType.PHONE_SYMBOLS -> "phone_symbols"
|
||||||
|
LayoutType.EMOJI_BOTTOM -> "emoji_bottom_row"
|
||||||
|
LayoutType.CLIPBOARD_BOTTOM -> "clipboard_bottom_row"
|
||||||
|
}
|
||||||
|
|
||||||
const val PREF_THEME_STYLE = KeyboardTheme.STYLE_MATERIAL
|
const val PREF_THEME_STYLE = KeyboardTheme.STYLE_MATERIAL
|
||||||
const val PREF_ICON_STYLE = KeyboardTheme.STYLE_MATERIAL
|
const val PREF_ICON_STYLE = KeyboardTheme.STYLE_MATERIAL
|
||||||
const val PREF_THEME_COLORS = KeyboardTheme.THEME_LIGHT
|
const val PREF_THEME_COLORS = KeyboardTheme.THEME_LIGHT
|
||||||
|
@ -56,8 +73,10 @@ 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
|
||||||
const val PREF_ADDITIONAL_SUBTYPES = "de:qwerty:AsciiCapable${AdditionalSubtypeUtils.PREF_SUBTYPE_SEPARATOR}" +
|
private const val ls = AdditionalSubtypeUtils.LOCALE_AND_EXTRA_SEPARATOR
|
||||||
"fr:qwertz:AsciiCapable${AdditionalSubtypeUtils.PREF_SUBTYPE_SEPARATOR}hu:qwerty:AsciiCapable"
|
private const val subs = AdditionalSubtypeUtils.PREF_SUBTYPE_SEPARATOR
|
||||||
|
const val PREF_ADDITIONAL_SUBTYPES = "de${ls}qwerty${ls}AsciiCapable${subs}" +
|
||||||
|
"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
|
||||||
const val PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE = false
|
const val PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE = false
|
||||||
const val PREF_SPLIT_SPACER_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
const val PREF_SPLIT_SPACER_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||||
|
|
|
@ -137,7 +137,7 @@ class LanguageSettingsDialog(
|
||||||
val layouts = mutableListOf<String>()
|
val layouts = mutableListOf<String>()
|
||||||
val displayNames = mutableListOf<String>()
|
val displayNames = mutableListOf<String>()
|
||||||
infos.forEach {
|
infos.forEach {
|
||||||
val mainLayoutName = it.subtype.mainLayoutName()
|
val mainLayoutName = it.subtype.mainLayoutName() ?: "qwerty"
|
||||||
if (!mainLayoutName.startsWith(CUSTOM_LAYOUT_PREFIX) // don't allow copying custom layout (at least for now)
|
if (!mainLayoutName.startsWith(CUSTOM_LAYOUT_PREFIX) // don't allow copying custom layout (at least for now)
|
||||||
&& !mainLayoutName.endsWith("+")) { // don't allow copying layouts only defined via extra keys
|
&& !mainLayoutName.endsWith("+")) { // don't allow copying layouts only defined via extra keys
|
||||||
layouts.add(mainLayoutName)
|
layouts.add(mainLayoutName)
|
||||||
|
@ -168,7 +168,7 @@ class LanguageSettingsDialog(
|
||||||
|
|
||||||
private fun addSubtypeToView(subtype: SubtypeInfo) {
|
private fun addSubtypeToView(subtype: SubtypeInfo) {
|
||||||
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()
|
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.getKeyboardLayoutSetDisplayName(subtype.subtype)
|
||||||
?: subtype.subtype.displayName(context)
|
?: subtype.subtype.displayName(context)
|
||||||
|
|
|
@ -32,6 +32,7 @@ import helium314.keyboard.latin.common.LocaleUtils;
|
||||||
import helium314.keyboard.latin.utils.AdditionalSubtypeUtils;
|
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.Log;
|
import helium314.keyboard.latin.utils.Log;
|
||||||
import helium314.keyboard.latin.utils.ResourceUtils;
|
import helium314.keyboard.latin.utils.ResourceUtils;
|
||||||
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
||||||
|
@ -68,6 +69,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
|
|
||||||
public static final String PREF_CUSTOM_ICON_NAMES = "custom_icon_names";
|
public static final String PREF_CUSTOM_ICON_NAMES = "custom_icon_names";
|
||||||
public static final String PREF_TOOLBAR_CUSTOM_KEY_CODES = "toolbar_custom_key_codes";
|
public static final String PREF_TOOLBAR_CUSTOM_KEY_CODES = "toolbar_custom_key_codes";
|
||||||
|
public static final String PREF_LAYOUT_PREFIX = "layout_";
|
||||||
|
|
||||||
public static final String PREF_AUTO_CAP = "auto_cap";
|
public static final String PREF_AUTO_CAP = "auto_cap";
|
||||||
public static final String PREF_VIBRATE_ON = "vibrate_on";
|
public static final String PREF_VIBRATE_ON = "vibrate_on";
|
||||||
|
@ -549,6 +551,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
return new File(DeviceProtectedUtils.getFilesDir(context), "custom_font");
|
return new File(DeviceProtectedUtils.getFilesDir(context), "custom_font");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getLayoutName(final LayoutType type, final SharedPreferences prefs) {
|
||||||
|
return prefs.getString(PREF_LAYOUT_PREFIX + type.name(), Defaults.INSTANCE.getDefault(type));
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Typeface getCustomTypeface() {
|
public Typeface getCustomTypeface() {
|
||||||
if (!sCustomTypefaceLoaded) {
|
if (!sCustomTypefaceLoaded) {
|
||||||
|
|
|
@ -144,7 +144,6 @@ public class SettingsValues {
|
||||||
public final SettingsValuesForSuggestion mSettingsValuesForSuggestion;
|
public final SettingsValuesForSuggestion mSettingsValuesForSuggestion;
|
||||||
public final boolean mIncognitoModeEnabled;
|
public final boolean mIncognitoModeEnabled;
|
||||||
public final boolean mLongPressSymbolsForNumpad;
|
public final boolean mLongPressSymbolsForNumpad;
|
||||||
public final boolean mHasCustomFunctionalLayout;
|
|
||||||
public final int mEmojiMaxSdk;
|
public final int mEmojiMaxSdk;
|
||||||
|
|
||||||
// User-defined colors
|
// User-defined colors
|
||||||
|
@ -276,7 +275,6 @@ public class SettingsValues {
|
||||||
mLongPressSymbolsForNumpad = prefs.getBoolean(Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, Defaults.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD);
|
mLongPressSymbolsForNumpad = prefs.getBoolean(Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, Defaults.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD);
|
||||||
mAutoShowToolbar = prefs.getBoolean(Settings.PREF_AUTO_SHOW_TOOLBAR, Defaults.PREF_AUTO_SHOW_TOOLBAR);
|
mAutoShowToolbar = prefs.getBoolean(Settings.PREF_AUTO_SHOW_TOOLBAR, Defaults.PREF_AUTO_SHOW_TOOLBAR);
|
||||||
mAutoHideToolbar = suggestionsEnabled && prefs.getBoolean(Settings.PREF_AUTO_HIDE_TOOLBAR, Defaults.PREF_AUTO_HIDE_TOOLBAR);
|
mAutoHideToolbar = suggestionsEnabled && prefs.getBoolean(Settings.PREF_AUTO_HIDE_TOOLBAR, Defaults.PREF_AUTO_HIDE_TOOLBAR);
|
||||||
mHasCustomFunctionalLayout = CustomLayoutUtilsKt.hasCustomFunctionalLayout(selectedSubtype, context);
|
|
||||||
mAlphaAfterEmojiInEmojiView = prefs.getBoolean(Settings.PREF_ABC_AFTER_EMOJI, Defaults.PREF_ABC_AFTER_EMOJI);
|
mAlphaAfterEmojiInEmojiView = prefs.getBoolean(Settings.PREF_ABC_AFTER_EMOJI, Defaults.PREF_ABC_AFTER_EMOJI);
|
||||||
mAlphaAfterClipHistoryEntry = prefs.getBoolean(Settings.PREF_ABC_AFTER_CLIP, Defaults.PREF_ABC_AFTER_CLIP);
|
mAlphaAfterClipHistoryEntry = prefs.getBoolean(Settings.PREF_ABC_AFTER_CLIP, Defaults.PREF_ABC_AFTER_CLIP);
|
||||||
mAlphaAfterSymbolAndSpace = prefs.getBoolean(Settings.PREF_ABC_AFTER_SYMBOL_SPACE, Defaults.PREF_ABC_AFTER_SYMBOL_SPACE);
|
mAlphaAfterSymbolAndSpace = prefs.getBoolean(Settings.PREF_ABC_AFTER_SYMBOL_SPACE, Defaults.PREF_ABC_AFTER_SYMBOL_SPACE);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public final class AdditionalSubtypeUtils {
|
||||||
return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE);
|
return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":";
|
public static final String LOCALE_AND_EXTRA_SEPARATOR = "§";
|
||||||
private static final int INDEX_OF_LANGUAGE_TAG = 0;
|
private static final int INDEX_OF_LANGUAGE_TAG = 0;
|
||||||
private static final int INDEX_OF_KEYBOARD_LAYOUT = 1;
|
private static final int INDEX_OF_KEYBOARD_LAYOUT = 1;
|
||||||
private static final int INDEX_OF_EXTRA_VALUE = 2;
|
private static final int INDEX_OF_EXTRA_VALUE = 2;
|
||||||
|
@ -85,10 +85,12 @@ public final class AdditionalSubtypeUtils {
|
||||||
final String extraValue = StringUtils.removeFromCommaSplittableTextIfExists(
|
final String extraValue = StringUtils.removeFromCommaSplittableTextIfExists(
|
||||||
layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists(
|
layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists(
|
||||||
IS_ADDITIONAL_SUBTYPE, subtype.getExtraValue()));
|
IS_ADDITIONAL_SUBTYPE, subtype.getExtraValue()));
|
||||||
final String basePrefSubtype = SubtypeUtilsKt.locale(subtype).toLanguageTag() + LOCALE_AND_LAYOUT_SEPARATOR
|
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;
|
+ keyboardLayoutSetName;
|
||||||
return extraValue.isEmpty() ? basePrefSubtype
|
return extraValue.isEmpty() ? basePrefSubtype
|
||||||
: basePrefSubtype + LOCALE_AND_LAYOUT_SEPARATOR + extraValue;
|
: basePrefSubtype + LOCALE_AND_EXTRA_SEPARATOR + extraValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) {
|
public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) {
|
||||||
|
@ -107,7 +109,7 @@ public final class AdditionalSubtypeUtils {
|
||||||
|
|
||||||
// use string created with getPrefSubtype
|
// use string created with getPrefSubtype
|
||||||
public static InputMethodSubtype createSubtypeFromString(final String prefSubtype) {
|
public static InputMethodSubtype createSubtypeFromString(final String prefSubtype) {
|
||||||
final String[] elems = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR);
|
final String[] elems = prefSubtype.split(LOCALE_AND_EXTRA_SEPARATOR);
|
||||||
if (elems.length != LENGTH_WITHOUT_EXTRA_VALUE
|
if (elems.length != LENGTH_WITHOUT_EXTRA_VALUE
|
||||||
&& elems.length != LENGTH_WITH_EXTRA_VALUE) {
|
&& elems.length != LENGTH_WITH_EXTRA_VALUE) {
|
||||||
Log.w(TAG, "Unknown additional subtype specified: " + prefSubtype);
|
Log.w(TAG, "Unknown additional subtype specified: " + prefSubtype);
|
||||||
|
|
|
@ -14,17 +14,17 @@ import helium314.keyboard.keyboard.KeyboardId
|
||||||
import helium314.keyboard.keyboard.KeyboardLayoutSet
|
import helium314.keyboard.keyboard.KeyboardLayoutSet
|
||||||
import helium314.keyboard.keyboard.KeyboardSwitcher
|
import helium314.keyboard.keyboard.KeyboardSwitcher
|
||||||
import helium314.keyboard.keyboard.internal.KeyboardParams
|
import helium314.keyboard.keyboard.internal.KeyboardParams
|
||||||
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LayoutParser
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.POPUP_KEYS_NORMAL
|
import helium314.keyboard.keyboard.internal.keyboard_parser.POPUP_KEYS_NORMAL
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser
|
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
|
import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.common.Constants
|
|
||||||
import helium314.keyboard.latin.common.FileUtils
|
import helium314.keyboard.latin.common.FileUtils
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.utils.LayoutType.Companion.folder
|
||||||
import kotlinx.serialization.SerializationException
|
import kotlinx.serialization.SerializationException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
import java.util.EnumMap
|
||||||
|
|
||||||
fun loadCustomLayout(uri: Uri?, languageTag: String, context: Context, onAdded: (String) -> Unit) {
|
fun loadCustomLayout(uri: Uri?, languageTag: String, context: Context, onAdded: (String) -> Unit) {
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
|
@ -85,7 +85,7 @@ fun checkLayout(layoutContent: String, context: Context): Boolean {
|
||||||
params.mPopupKeyTypes.add(POPUP_KEYS_LAYOUT)
|
params.mPopupKeyTypes.add(POPUP_KEYS_LAYOUT)
|
||||||
addLocaleKeyTextsToParams(context, params, POPUP_KEYS_NORMAL)
|
addLocaleKeyTextsToParams(context, params, POPUP_KEYS_NORMAL)
|
||||||
try {
|
try {
|
||||||
val keys = RawKeyboardParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
val keys = LayoutParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||||
return checkKeys(keys)
|
return checkKeys(keys)
|
||||||
} catch (e: SerializationException) {
|
} catch (e: SerializationException) {
|
||||||
Log.w(TAG, "json parsing error", e)
|
Log.w(TAG, "json parsing error", e)
|
||||||
|
@ -96,13 +96,13 @@ fun checkLayout(layoutContent: String, context: Context): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val keys = RawKeyboardParser.parseSimpleString(layoutContent).map { row -> row.map { it.toKeyParams(params) } }
|
val keys = LayoutParser.parseSimpleString(layoutContent).map { row -> row.map { it.toKeyParams(params) } }
|
||||||
return checkKeys(keys)
|
return checkKeys(keys)
|
||||||
} catch (e: Exception) { Log.w(TAG, "error parsing custom simple layout", e) }
|
} catch (e: Exception) { Log.w(TAG, "error parsing custom simple layout", e) }
|
||||||
if (layoutContent.trimStart().startsWith("[") && layoutContent.trimEnd().endsWith("]")) {
|
if (layoutContent.trimStart().startsWith("[") && layoutContent.trimEnd().endsWith("]")) {
|
||||||
// layout can't be loaded, assume it's json -> load json layout again because the error message shown to the user is from the most recent error
|
// layout can't be loaded, assume it's json -> load json layout again because the error message shown to the user is from the most recent error
|
||||||
try {
|
try {
|
||||||
RawKeyboardParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
LayoutParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||||
} catch (e: Exception) { Log.w(TAG, "json parsing error", e) }
|
} catch (e: Exception) { Log.w(TAG, "json parsing error", e) }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -149,20 +149,28 @@ fun checkKeys(keys: List<List<Key.KeyParams>>): Boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** don't rename or delete the file without calling [onCustomLayoutFileListChanged] */
|
/** don't rename or delete the file without calling [onCustomLayoutFileListChanged] */
|
||||||
fun getCustomLayoutFile(layoutName: String, context: Context) =
|
fun getCustomLayoutFile(layoutName: String, context: Context) = // todo: remove
|
||||||
File(getCustomLayoutsDir(context), layoutName)
|
File(getCustomLayoutsDir(context), layoutName)
|
||||||
|
|
||||||
// cache to avoid frequently listing files
|
// cache to avoid frequently listing files
|
||||||
/** don't rename or delete files without calling [onCustomLayoutFileListChanged] */
|
/** don't rename or delete files without calling [onCustomLayoutFileListChanged] */
|
||||||
fun getCustomLayoutFiles(context: Context): List<File> {
|
fun getCustomLayoutFiles(context: Context): List<File> { // todo: remove, AND USE THE NEW THING FOR SUBTYPE SETTINGS
|
||||||
customLayouts?.let { return it }
|
customLayouts?.let { return it }
|
||||||
val layouts = getCustomLayoutsDir(context).listFiles()?.toList() ?: emptyList()
|
val layouts = getCustomLayoutsDir(context).listFiles()?.toList() ?: emptyList()
|
||||||
customLayouts = layouts
|
customLayouts = layouts
|
||||||
return layouts
|
return layouts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCustomLayoutFiles(layoutType: LayoutType, context: Context): List<File> =
|
||||||
|
customLayoutMap.getOrPut(layoutType) {
|
||||||
|
File(DeviceProtectedUtils.getFilesDir(context), layoutType.folder).listFiles()?.toList() ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val customLayoutMap = EnumMap<LayoutType, List<File>>(LayoutType::class.java)
|
||||||
|
|
||||||
fun onCustomLayoutFileListChanged() {
|
fun onCustomLayoutFileListChanged() {
|
||||||
customLayouts = null
|
customLayouts = null
|
||||||
|
customLayoutMap.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCustomLayoutsDir(context: Context) = File(DeviceProtectedUtils.getFilesDir(context), "layouts")
|
private fun getCustomLayoutsDir(context: Context) = File(DeviceProtectedUtils.getFilesDir(context), "layouts")
|
||||||
|
@ -215,45 +223,6 @@ fun editCustomLayout(layoutName: String, context: Context, startContent: String?
|
||||||
builder.show()
|
builder.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasCustomFunctionalLayout(subtype: InputMethodSubtype, context: Context): Boolean {
|
|
||||||
val anyCustomFunctionalLayout = getCustomFunctionalLayoutName(KeyboardId.ELEMENT_ALPHABET, subtype, context)
|
|
||||||
?: getCustomFunctionalLayoutName(KeyboardId.ELEMENT_SYMBOLS, subtype, context)
|
|
||||||
?: getCustomFunctionalLayoutName(KeyboardId.ELEMENT_SYMBOLS_SHIFTED, subtype, context)
|
|
||||||
return anyCustomFunctionalLayout != null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCustomFunctionalLayoutName(elementId: Int, subtype: InputMethodSubtype, context: Context): String? {
|
|
||||||
val customFunctionalLayoutNames = getCustomLayoutFiles(context).filter { it.name.contains("functional") }.map { it.name.substringBeforeLast(".") + "." }
|
|
||||||
if (customFunctionalLayoutNames.isEmpty()) return null
|
|
||||||
val languageTag = subtype.locale().toLanguageTag()
|
|
||||||
val mainLayoutName = subtype.mainLayoutName()
|
|
||||||
|
|
||||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
|
|
||||||
findMatchingLayout(customFunctionalLayoutNames.filter { it.startsWith(CUSTOM_FUNCTIONAL_LAYOUT_SYMBOLS_SHIFTED) }, mainLayoutName, languageTag)
|
|
||||||
?.let { return it }
|
|
||||||
}
|
|
||||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS) {
|
|
||||||
findMatchingLayout(customFunctionalLayoutNames.filter { it.startsWith(CUSTOM_FUNCTIONAL_LAYOUT_SYMBOLS) }, mainLayoutName, languageTag)
|
|
||||||
?.let { return it }
|
|
||||||
}
|
|
||||||
return findMatchingLayout(customFunctionalLayoutNames.filter { it.startsWith(CUSTOM_FUNCTIONAL_LAYOUT_NORMAL) }, mainLayoutName, languageTag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo (when adding custom layouts per locale or main layout): adjust mainLayoutName for custom layouts?
|
|
||||||
// remove language tag and file ending (currently name is e.g. custom.en-US.abcdfdsg3.json, and we could use abcdfdsg3 only)
|
|
||||||
// this way, custom layouts with same name could use same custom functional layouts
|
|
||||||
// currently there is no way to set the language tag or main layout name, so changes don't break backwards compatibility
|
|
||||||
private fun findMatchingLayout(layoutNames: List<String>, mainLayoutName: String, languageTag: String): String? {
|
|
||||||
// first find layout with matching locale and main layout
|
|
||||||
return layoutNames.firstOrNull { it.endsWith(".$languageTag.$mainLayoutName.") }
|
|
||||||
// then find matching main layout
|
|
||||||
?: layoutNames.firstOrNull { it.endsWith(".$mainLayoutName.") }
|
|
||||||
// then find matching language
|
|
||||||
?: layoutNames.firstOrNull { it.endsWith(".$languageTag.") }
|
|
||||||
// then find "normal" functional layout (make use of the '.' separator
|
|
||||||
?: layoutNames.firstOrNull { it.count { it == '.' } == 2 }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun encodeBase36(string: String): String = BigInteger(string.toByteArray()).toString(36)
|
fun encodeBase36(string: String): String = BigInteger(string.toByteArray()).toString(36)
|
||||||
|
|
||||||
fun decodeBase36(string: String) = BigInteger(string, 36).toByteArray().decodeToString()
|
fun decodeBase36(string: String) = BigInteger(string, 36).toByteArray().decodeToString()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package helium314.keyboard.latin.utils
|
package helium314.keyboard.latin.utils
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
import java.util.EnumMap
|
import java.util.EnumMap
|
||||||
|
|
||||||
enum class LayoutType {
|
enum class LayoutType {
|
||||||
|
@ -17,5 +18,7 @@ enum class LayoutType {
|
||||||
}
|
}
|
||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val LayoutType.folder get() = "layouts${File.separator}${name.lowercase()}${File.separator}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ public final class SubtypeLocaleUtils {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static String getKeyboardLayoutSetName(final InputMethodSubtype subtype) {
|
public static String getKeyboardLayoutSetName(final InputMethodSubtype subtype) {
|
||||||
String keyboardLayoutSet = SubtypeUtilsKt.explicitMainLayoutName(subtype);
|
String keyboardLayoutSet = SubtypeUtilsKt.mainLayoutName(subtype);
|
||||||
if (keyboardLayoutSet == null && subtype.isAsciiCapable()) {
|
if (keyboardLayoutSet == null && subtype.isAsciiCapable()) {
|
||||||
keyboardLayoutSet = QWERTY;
|
keyboardLayoutSet = QWERTY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import androidx.core.content.edit
|
||||||
import helium314.keyboard.keyboard.KeyboardSwitcher
|
import helium314.keyboard.keyboard.KeyboardSwitcher
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.RichInputMethodManager
|
import helium314.keyboard.latin.RichInputMethodManager
|
||||||
import helium314.keyboard.latin.common.Constants
|
|
||||||
import helium314.keyboard.latin.common.LocaleUtils
|
import helium314.keyboard.latin.common.LocaleUtils
|
||||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||||
import helium314.keyboard.latin.define.DebugFlags
|
import helium314.keyboard.latin.define.DebugFlags
|
||||||
|
@ -41,7 +40,7 @@ fun getAllAvailableSubtypes(): List<InputMethodSubtype> {
|
||||||
|
|
||||||
fun getMatchingLayoutSetNameForLocale(locale: Locale): String {
|
fun getMatchingLayoutSetNameForLocale(locale: Locale): String {
|
||||||
val subtypes = resourceSubtypesByLocale.values.flatten()
|
val subtypes = resourceSubtypesByLocale.values.flatten()
|
||||||
val name = LocaleUtils.getBestMatch(locale, subtypes) { it.locale() }?.explicitMainLayoutName()
|
val name = LocaleUtils.getBestMatch(locale, subtypes) { it.locale() }?.mainLayoutName()
|
||||||
if (name != null) return name
|
if (name != null) return name
|
||||||
return when (locale.script()) {
|
return when (locale.script()) {
|
||||||
ScriptUtils.SCRIPT_LATIN -> "qwerty"
|
ScriptUtils.SCRIPT_LATIN -> "qwerty"
|
||||||
|
@ -246,7 +245,7 @@ private fun loadResourceSubtypes(resources: Resources) {
|
||||||
private fun removeInvalidCustomSubtypes(context: Context) {
|
private fun removeInvalidCustomSubtypes(context: Context) {
|
||||||
val prefs = context.prefs()
|
val prefs = context.prefs()
|
||||||
val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(";")
|
val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(";")
|
||||||
val customSubtypeFiles by lazy { getCustomLayoutFiles(context).map { it.name } }
|
val customSubtypeFiles by lazy { getCustomLayoutFiles(LayoutType.MAIN, context).map { it.name } }
|
||||||
val subtypesToRemove = mutableListOf<String>()
|
val subtypesToRemove = mutableListOf<String>()
|
||||||
additionalSubtypes.forEach {
|
additionalSubtypes.forEach {
|
||||||
val name = it.substringAfter(":").substringBefore(":")
|
val name = it.substringAfter(":").substringBefore(":")
|
||||||
|
|
|
@ -16,12 +16,7 @@ fun InputMethodSubtype.locale(): Locale {
|
||||||
@Suppress("deprecation") return locale.constructLocale()
|
@Suppress("deprecation") return locale.constructLocale()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun InputMethodSubtype.mainLayoutName(): String {
|
fun InputMethodSubtype.mainLayoutName(): String? {
|
||||||
val map = LayoutType.getLayoutMap(getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "")
|
|
||||||
return map[LayoutType.MAIN] ?: "qwerty"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun InputMethodSubtype.explicitMainLayoutName(): String? {
|
|
||||||
val map = LayoutType.getLayoutMap(getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "")
|
val map = LayoutType.getLayoutMap(getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "")
|
||||||
return map[LayoutType.MAIN]
|
return map[LayoutType.MAIN]
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,13 +74,11 @@ object SettingsWithoutKey {
|
||||||
const val GITHUB = "github"
|
const val GITHUB = "github"
|
||||||
const val SAVE_LOG = "save_log"
|
const val SAVE_LOG = "save_log"
|
||||||
const val CUSTOM_KEY_CODES = "customize_key_codes"
|
const val CUSTOM_KEY_CODES = "customize_key_codes"
|
||||||
const val CUSTOM_SYMBOLS_NUMBER_LAYOUTS = "custom_symbols_number_layouts"
|
// const val CUSTOM_SYMBOLS_NUMBER_LAYOUTS = "custom_symbols_number_layouts"
|
||||||
const val CUSTOM_FUNCTIONAL_LAYOUTS = "custom_functional_key_layouts"
|
// const val CUSTOM_FUNCTIONAL_LAYOUTS = "custom_functional_key_layouts"
|
||||||
const val BACKUP_RESTORE = "backup_restore"
|
const val BACKUP_RESTORE = "backup_restore"
|
||||||
const val DEBUG_SETTINGS = "screen_debug"
|
const val DEBUG_SETTINGS = "screen_debug"
|
||||||
const val LOAD_GESTURE_LIB = "load_gesture_library"
|
const val LOAD_GESTURE_LIB = "load_gesture_library"
|
||||||
const val ADJUST_COLORS = "adjust_colors"
|
|
||||||
const val ADJUST_COLORS_NIGHT = "adjust_colors_night"
|
|
||||||
const val BACKGROUND_IMAGE = "background_image"
|
const val BACKGROUND_IMAGE = "background_image"
|
||||||
const val BACKGROUND_IMAGE_LANDSCAPE = "background_image_landscape"
|
const val BACKGROUND_IMAGE_LANDSCAPE = "background_image_landscape"
|
||||||
const val CUSTOM_FONT = "custom_font"
|
const val CUSTOM_FONT = "custom_font"
|
||||||
|
|
|
@ -20,7 +20,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import helium314.keyboard.keyboard.KeyboardActionListener
|
import helium314.keyboard.keyboard.KeyboardActionListener
|
||||||
import helium314.keyboard.keyboard.KeyboardLayoutSet
|
import helium314.keyboard.keyboard.KeyboardLayoutSet
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser
|
|
||||||
import helium314.keyboard.latin.BuildConfig
|
import helium314.keyboard.latin.BuildConfig
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.SystemBroadcastReceiver
|
import helium314.keyboard.latin.SystemBroadcastReceiver
|
||||||
|
@ -74,8 +73,6 @@ fun AdvancedSettingsScreen(
|
||||||
Settings.PREF_ABC_AFTER_CLIP,
|
Settings.PREF_ABC_AFTER_CLIP,
|
||||||
Settings.PREF_CUSTOM_CURRENCY_KEY,
|
Settings.PREF_CUSTOM_CURRENCY_KEY,
|
||||||
Settings.PREF_MORE_POPUP_KEYS,
|
Settings.PREF_MORE_POPUP_KEYS,
|
||||||
SettingsWithoutKey.CUSTOM_SYMBOLS_NUMBER_LAYOUTS,
|
|
||||||
SettingsWithoutKey.CUSTOM_FUNCTIONAL_LAYOUTS,
|
|
||||||
SettingsWithoutKey.BACKUP_RESTORE,
|
SettingsWithoutKey.BACKUP_RESTORE,
|
||||||
if (BuildConfig.DEBUG || prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, Defaults.PREF_SHOW_DEBUG_SETTINGS))
|
if (BuildConfig.DEBUG || prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, Defaults.PREF_SHOW_DEBUG_SETTINGS))
|
||||||
SettingsWithoutKey.DEBUG_SETTINGS else null,
|
SettingsWithoutKey.DEBUG_SETTINGS else null,
|
||||||
|
@ -195,7 +192,7 @@ fun createAdvancedSettings(context: Context) = listOf(
|
||||||
)
|
)
|
||||||
ListPreference(it, items, Defaults.PREF_MORE_POPUP_KEYS) { KeyboardLayoutSet.onSystemLocaleChanged() }
|
ListPreference(it, items, Defaults.PREF_MORE_POPUP_KEYS) { KeyboardLayoutSet.onSystemLocaleChanged() }
|
||||||
},
|
},
|
||||||
Setting(context, SettingsWithoutKey.CUSTOM_SYMBOLS_NUMBER_LAYOUTS, R.string.customize_symbols_number_layouts) { setting ->
|
/* Setting(context, SettingsWithoutKey.CUSTOM_SYMBOLS_NUMBER_LAYOUTS, R.string.customize_symbols_number_layouts) { setting ->
|
||||||
LayoutEditPreference(
|
LayoutEditPreference(
|
||||||
setting = setting,
|
setting = setting,
|
||||||
items = RawKeyboardParser.symbolAndNumberLayouts,
|
items = RawKeyboardParser.symbolAndNumberLayouts,
|
||||||
|
@ -211,7 +208,7 @@ fun createAdvancedSettings(context: Context) = listOf(
|
||||||
getItemName = { it.substringAfter(CUSTOM_LAYOUT_PREFIX).getStringResourceOrName("layout_", LocalContext.current) },
|
getItemName = { it.substringAfter(CUSTOM_LAYOUT_PREFIX).getStringResourceOrName("layout_", LocalContext.current) },
|
||||||
getDefaultLayout = { if (Settings.getInstance().isTablet) "functional_keys_tablet.json" else "functional_keys.json" }
|
getDefaultLayout = { if (Settings.getInstance().isTablet) "functional_keys_tablet.json" else "functional_keys.json" }
|
||||||
)
|
)
|
||||||
},
|
},*/ // todo: these settings are disabled for now -> remove them and use a layoutScreen instead
|
||||||
Setting(context, SettingsWithoutKey.BACKUP_RESTORE, R.string.backup_restore_title) {
|
Setting(context, SettingsWithoutKey.BACKUP_RESTORE, R.string.backup_restore_title) {
|
||||||
BackupRestorePreference(it)
|
BackupRestorePreference(it)
|
||||||
},
|
},
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
android:imeSubtypeLocale="ar"
|
android:imeSubtypeLocale="ar"
|
||||||
android:languageTag="ar"
|
android:languageTag="ar"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:arabic,NoShiftKey,SupportTouchPositionCorrection,EmojiCapable"
|
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:arabic|SYMBOLS:symbols_arabic,NoShiftKey,SupportTouchPositionCorrection,EmojiCapable"
|
||||||
android:isAsciiCapable="false"
|
android:isAsciiCapable="false"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
android:imeSubtypeLocale="ar"
|
android:imeSubtypeLocale="ar"
|
||||||
android:languageTag="ar"
|
android:languageTag="ar"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:arabic_pc,NoShiftKey,EmojiCapable"
|
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:arabic_pc|SYMBOLS:symbols_arabic,NoShiftKey,EmojiCapable"
|
||||||
android:isAsciiCapable="false"
|
android:isAsciiCapable="false"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||||
|
@ -184,7 +184,7 @@
|
||||||
android:imeSubtypeLocale="ar"
|
android:imeSubtypeLocale="ar"
|
||||||
android:languageTag="ar"
|
android:languageTag="ar"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:arabic_hijai,NoShiftKey,SupportTouchPositionCorrection,EmojiCapable"
|
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:arabic_hijai|SYMBOLS:symbols_arabic,NoShiftKey,SupportTouchPositionCorrection,EmojiCapable"
|
||||||
android:isAsciiCapable="false"
|
android:isAsciiCapable="false"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||||
|
@ -409,7 +409,7 @@
|
||||||
android:imeSubtypeLocale="fa"
|
android:imeSubtypeLocale="fa"
|
||||||
android:languageTag="fa"
|
android:languageTag="fa"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:farsi,NoShiftKey,EmojiCapable"
|
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:farsi|SYMBOLS:symbols_arabic,NoShiftKey,EmojiCapable"
|
||||||
android:isAsciiCapable="false"
|
android:isAsciiCapable="false"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||||
|
@ -1060,7 +1060,7 @@
|
||||||
android:imeSubtypeLocale="ur_PK"
|
android:imeSubtypeLocale="ur_PK"
|
||||||
android:languageTag="ur-PK"
|
android:languageTag="ur-PK"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:urdu,EmojiCapable"
|
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:urdu|SYMBOLS:symbols_arabic,EmojiCapable"
|
||||||
android:isAsciiCapable="false"
|
android:isAsciiCapable="false"
|
||||||
/>
|
/>
|
||||||
<!-- This Uzbek keyboard is a preliminary layout.
|
<!-- This Uzbek keyboard is a preliminary layout.
|
||||||
|
|
|
@ -8,14 +8,13 @@ import helium314.keyboard.keyboard.Key.KeyParams
|
||||||
import helium314.keyboard.keyboard.Keyboard
|
import helium314.keyboard.keyboard.Keyboard
|
||||||
import helium314.keyboard.keyboard.KeyboardId
|
import helium314.keyboard.keyboard.KeyboardId
|
||||||
import helium314.keyboard.keyboard.KeyboardLayoutSet
|
import helium314.keyboard.keyboard.KeyboardLayoutSet
|
||||||
import helium314.keyboard.keyboard.internal.KeySpecParser
|
|
||||||
import helium314.keyboard.keyboard.internal.KeySpecParser.KeySpecParserError
|
import helium314.keyboard.keyboard.internal.KeySpecParser.KeySpecParserError
|
||||||
import helium314.keyboard.keyboard.internal.KeyboardBuilder
|
import helium314.keyboard.keyboard.internal.KeyboardBuilder
|
||||||
import helium314.keyboard.keyboard.internal.KeyboardParams
|
import helium314.keyboard.keyboard.internal.KeyboardParams
|
||||||
import helium314.keyboard.keyboard.internal.TouchPositionCorrection
|
import helium314.keyboard.keyboard.internal.TouchPositionCorrection
|
||||||
import helium314.keyboard.keyboard.internal.UniqueKeysCache
|
import helium314.keyboard.keyboard.internal.UniqueKeysCache
|
||||||
|
import helium314.keyboard.keyboard.internal.keyboard_parser.LayoutParser
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.POPUP_KEYS_NORMAL
|
import helium314.keyboard.keyboard.internal.keyboard_parser.POPUP_KEYS_NORMAL
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser
|
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
|
import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
|
||||||
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
|
||||||
|
@ -119,7 +118,7 @@ f""", // no newline at the end
|
||||||
val wantedKeyLabels = listOf(listOf("a", "b", "c"), listOf("d", "e", "f"))
|
val wantedKeyLabels = listOf(listOf("a", "b", "c"), listOf("d", "e", "f"))
|
||||||
layoutStrings.forEachIndexed { i, layout ->
|
layoutStrings.forEachIndexed { i, layout ->
|
||||||
println(i)
|
println(i)
|
||||||
val keyLabels = RawKeyboardParser.parseSimpleString(layout).map { it.map { it.toKeyParams(params).mLabel } }
|
val keyLabels = LayoutParser.parseSimpleString(layout).map { it.map { it.toKeyParams(params).mLabel } }
|
||||||
assertEquals(wantedKeyLabels, keyLabels)
|
assertEquals(wantedKeyLabels, keyLabels)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,12 +320,12 @@ f""", // no newline at the end
|
||||||
|
|
||||||
@Test fun invalidKeys() {
|
@Test fun invalidKeys() {
|
||||||
assertFailsWith<KeySpecParserError> {
|
assertFailsWith<KeySpecParserError> {
|
||||||
RawKeyboardParser.parseJsonString("""[[{ "label": "!icon/clipboard_action_key" }]]""").map { it.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
LayoutParser.parseJsonString("""[[{ "label": "!icon/clipboard_action_key" }]]""").map { it.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun popupWithCodeAndLabel() {
|
@Test fun popupWithCodeAndLabel() {
|
||||||
val key = RawKeyboardParser.parseJsonString("""[[{ "label": "w", "popup": {
|
val key = LayoutParser.parseJsonString("""[[{ "label": "w", "popup": {
|
||||||
"main": { "code": 55, "label": "!" }
|
"main": { "code": 55, "label": "!" }
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
assertEquals("!", key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
assertEquals("!", key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
||||||
|
@ -334,7 +333,7 @@ f""", // no newline at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun popupWithCodeAndIcon() {
|
@Test fun popupWithCodeAndIcon() {
|
||||||
val key = RawKeyboardParser.parseJsonString("""[[{ "label": "w", "popup": {
|
val key = LayoutParser.parseJsonString("""[[{ "label": "w", "popup": {
|
||||||
"main": { "code": 55, "label": "!icon/clipboard_action_key" }
|
"main": { "code": 55, "label": "!icon/clipboard_action_key" }
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
assertEquals(null, key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
assertEquals(null, key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
||||||
|
@ -343,7 +342,7 @@ f""", // no newline at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun popupToolbarKey() {
|
@Test fun popupToolbarKey() {
|
||||||
val key = RawKeyboardParser.parseJsonString("""[[{ "label": "x", "popup": {
|
val key = LayoutParser.parseJsonString("""[[{ "label": "x", "popup": {
|
||||||
"main": { "label": "undo" }
|
"main": { "label": "undo" }
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
assertEquals(null, key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
assertEquals(null, key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
||||||
|
@ -352,7 +351,7 @@ f""", // no newline at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun popupKeyWithIconAndImplicitText() {
|
@Test fun popupKeyWithIconAndImplicitText() {
|
||||||
val key = RawKeyboardParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
val key = LayoutParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
||||||
{ "label": "!icon/go_key|aa" }
|
{ "label": "!icon/go_key|aa" }
|
||||||
]
|
]
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
|
@ -361,7 +360,7 @@ f""", // no newline at the end
|
||||||
assertEquals(KeyCode.MULTIPLE_CODE_POINTS, key.toKeyParams(params).mPopupKeys?.first()?.mCode)
|
assertEquals(KeyCode.MULTIPLE_CODE_POINTS, key.toKeyParams(params).mPopupKeys?.first()?.mCode)
|
||||||
assertEquals("aa", key.toKeyParams(params).mPopupKeys?.first()?.mOutputText)
|
assertEquals("aa", key.toKeyParams(params).mPopupKeys?.first()?.mOutputText)
|
||||||
|
|
||||||
val key2 = RawKeyboardParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
val key2 = LayoutParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
||||||
{ "label": "!icon/go_key|" }
|
{ "label": "!icon/go_key|" }
|
||||||
]
|
]
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
|
@ -373,7 +372,7 @@ f""", // no newline at the end
|
||||||
|
|
||||||
// output text is null here, maybe should be changed?
|
// output text is null here, maybe should be changed?
|
||||||
@Test fun popupKeyWithIconAndCodeAndImplicitText() {
|
@Test fun popupKeyWithIconAndCodeAndImplicitText() {
|
||||||
val key = RawKeyboardParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
val key = LayoutParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
||||||
{ "label": "!icon/go_key|", "code": 55 }
|
{ "label": "!icon/go_key|", "code": 55 }
|
||||||
]
|
]
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
|
@ -382,7 +381,7 @@ f""", // no newline at the end
|
||||||
assertEquals(55, key.toKeyParams(params).mPopupKeys?.first()?.mCode)
|
assertEquals(55, key.toKeyParams(params).mPopupKeys?.first()?.mCode)
|
||||||
assertEquals(null, key.toKeyParams(params).mPopupKeys?.first()?.mOutputText)
|
assertEquals(null, key.toKeyParams(params).mPopupKeys?.first()?.mOutputText)
|
||||||
|
|
||||||
val key2 = RawKeyboardParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
val key2 = LayoutParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
||||||
{ "label": "!icon/go_key|a", "code": 55 }
|
{ "label": "!icon/go_key|a", "code": 55 }
|
||||||
]
|
]
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
|
@ -391,7 +390,7 @@ f""", // no newline at the end
|
||||||
assertEquals(55, key2.toKeyParams(params).mPopupKeys?.first()?.mCode)
|
assertEquals(55, key2.toKeyParams(params).mPopupKeys?.first()?.mCode)
|
||||||
assertEquals(null, key2.toKeyParams(params).mPopupKeys?.first()?.mOutputText)
|
assertEquals(null, key2.toKeyParams(params).mPopupKeys?.first()?.mOutputText)
|
||||||
|
|
||||||
val key3 = RawKeyboardParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
val key3 = LayoutParser.parseJsonString("""[[{ "label": "a", "popup": { "relevant": [
|
||||||
{ "label": "!icon/go_key|aa", "code": 55 }
|
{ "label": "!icon/go_key|aa", "code": 55 }
|
||||||
]
|
]
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
|
@ -403,14 +402,14 @@ f""", // no newline at the end
|
||||||
|
|
||||||
@Test fun invalidPopupKeys() {
|
@Test fun invalidPopupKeys() {
|
||||||
assertFailsWith<KeySpecParserError> {
|
assertFailsWith<KeySpecParserError> {
|
||||||
RawKeyboardParser.parseJsonString("""[[{ "label": "a", "popup": {
|
LayoutParser.parseJsonString("""[[{ "label": "a", "popup": {
|
||||||
"main": { "label": "!icon/clipboard_action_key" }
|
"main": { "label": "!icon/clipboard_action_key" }
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
} }]]""").map { it.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun popupSymbolAlpha() {
|
@Test fun popupSymbolAlpha() {
|
||||||
val key = RawKeyboardParser.parseJsonString("""[[{ "label": "c", "popup": {
|
val key = LayoutParser.parseJsonString("""[[{ "label": "c", "popup": {
|
||||||
"main": { "code": -10001, "label": "x" }
|
"main": { "code": -10001, "label": "x" }
|
||||||
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
} }]]""").map { it.mapNotNull { it.compute(params) } }.flatten().single()
|
||||||
assertEquals("x", key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
assertEquals("x", key.toKeyParams(params).mPopupKeys?.first()?.mLabel)
|
||||||
|
@ -462,8 +461,8 @@ f""", // no newline at the end
|
||||||
latinIME.assets.list("layouts")?.forEach {
|
latinIME.assets.list("layouts")?.forEach {
|
||||||
val content = latinIME.assets.open("layouts/$it").reader().readText()
|
val content = latinIME.assets.open("layouts/$it").reader().readText()
|
||||||
if (it.endsWith(".json"))
|
if (it.endsWith(".json"))
|
||||||
RawKeyboardParser.parseJsonString(content)
|
LayoutParser.parseJsonString(content)
|
||||||
else RawKeyboardParser.parseSimpleString(content)
|
else LayoutParser.parseSimpleString(content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +473,7 @@ f""", // no newline at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assertAreExpected(json: String, expected: List<Expected>) {
|
private fun assertAreExpected(json: String, expected: List<Expected>) {
|
||||||
val keys = RawKeyboardParser.parseJsonString(json).map { it.mapNotNull { it.compute(params) } }.flatten()
|
val keys = LayoutParser.parseJsonString(json).map { it.mapNotNull { it.compute(params) } }.flatten()
|
||||||
keys.forEachIndexed { index, keyData ->
|
keys.forEachIndexed { index, keyData ->
|
||||||
println("data: key ${keyData.label}: code ${keyData.code}, popups: ${keyData.popup.getPopupKeyLabels(params)}")
|
println("data: key ${keyData.label}: code ${keyData.code}, popups: ${keyData.popup.getPopupKeyLabels(params)}")
|
||||||
val keyParams = keyData.toKeyParams(params)
|
val keyParams = keyData.toKeyParams(params)
|
||||||
|
|
Loading…
Add table
Reference in a new issue