mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-06 14:50:14 +00:00
put LayoutUtilsCustom into an object
This commit is contained in:
parent
a3e85bc664
commit
aa3bf37852
20 changed files with 305 additions and 326 deletions
|
@ -18,11 +18,10 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.VariationSele
|
||||||
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.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
|
||||||
import helium314.keyboard.latin.utils.LayoutType
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
import helium314.keyboard.latin.utils.LayoutUtils
|
import helium314.keyboard.latin.utils.LayoutUtils
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
@ -76,7 +75,7 @@ object LayoutParser {
|
||||||
private fun createCacheLambda(layoutType: LayoutType, layoutName: String, context: Context):
|
private fun createCacheLambda(layoutType: LayoutType, layoutName: String, context: Context):
|
||||||
(KeyboardParams) -> MutableList<MutableList<KeyData>> {
|
(KeyboardParams) -> MutableList<MutableList<KeyData>> {
|
||||||
val layoutFileContent = getLayoutFileContent(layoutType, layoutName.substringBefore("+"), context).trimStart()
|
val layoutFileContent = getLayoutFileContent(layoutType, layoutName.substringBefore("+"), context).trimStart()
|
||||||
if (layoutFileContent.startsWith("[") || (layoutName.startsWith(CUSTOM_LAYOUT_PREFIX) && layoutFileContent.startsWith("/"))) {
|
if (layoutFileContent.startsWith("[") || (LayoutUtilsCustom.isCustomLayout(layoutName) && layoutFileContent.startsWith("/"))) {
|
||||||
try {
|
try {
|
||||||
val florisKeyData = parseJsonString(layoutFileContent, false)
|
val florisKeyData = parseJsonString(layoutFileContent, false)
|
||||||
return { params ->
|
return { params ->
|
||||||
|
@ -101,8 +100,8 @@ object LayoutParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLayoutFileContent(layoutType: LayoutType, layoutName: String, context: Context): String {
|
private fun getLayoutFileContent(layoutType: LayoutType, layoutName: String, context: Context): String {
|
||||||
if (layoutName.startsWith(CUSTOM_LAYOUT_PREFIX))
|
if (LayoutUtilsCustom.isCustomLayout(layoutName))
|
||||||
getCustomLayoutFiles(layoutType, context)
|
LayoutUtilsCustom.getCustomLayoutFiles(layoutType, context)
|
||||||
.firstOrNull { it.name.startsWith(layoutName) }?.let { return it.readText() }
|
.firstOrNull { it.name.startsWith(layoutName) }?.let { return it.readText() }
|
||||||
return LayoutUtils.getContent(layoutType, layoutName, context)
|
return LayoutUtils.getContent(layoutType, layoutName, context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,21 +9,18 @@ import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
|
||||||
import helium314.keyboard.latin.common.ColorType
|
import helium314.keyboard.latin.common.ColorType
|
||||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||||
|
import helium314.keyboard.latin.common.encodeBase36
|
||||||
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.settings.colorPrefsAndResIds
|
import helium314.keyboard.latin.settings.colorPrefsAndResIds
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
|
||||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
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
|
||||||
import helium314.keyboard.latin.utils.LayoutType.Companion.folder
|
import helium314.keyboard.latin.utils.LayoutType.Companion.folder
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
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.getCustomLayoutFiles
|
|
||||||
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.latin.utils.protectedPrefs
|
import helium314.keyboard.latin.utils.protectedPrefs
|
||||||
import helium314.keyboard.latin.utils.upgradeToolbarPrefs
|
import helium314.keyboard.latin.utils.upgradeToolbarPrefs
|
||||||
|
@ -50,6 +47,10 @@ class App : Application() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// old variant for old folder structure
|
||||||
|
private fun getCustomLayoutFile(layoutName: String, context: Context): File =
|
||||||
|
File(File(DeviceProtectedUtils.getFilesDir(context), "layouts"), layoutName)
|
||||||
|
|
||||||
fun checkVersionUpgrade(context: Context) {
|
fun checkVersionUpgrade(context: Context) {
|
||||||
val prefs = context.prefs()
|
val prefs = context.prefs()
|
||||||
val oldVersion = prefs.getInt(Settings.PREF_VERSION_CODE, 0)
|
val oldVersion = prefs.getInt(Settings.PREF_VERSION_CODE, 0)
|
||||||
|
@ -67,9 +68,9 @@ fun checkVersionUpgrade(context: Context) {
|
||||||
if (oldVersion == 0) // new install or restoring settings from old app name
|
if (oldVersion == 0) // new install or restoring settings from old app name
|
||||||
upgradesWhenComingFromOldAppName(context)
|
upgradesWhenComingFromOldAppName(context)
|
||||||
if (oldVersion <= 1000) { // upgrade old custom layouts name
|
if (oldVersion <= 1000) { // upgrade old custom layouts name
|
||||||
val oldShiftSymbolsFile = getCustomLayoutFile("${CUSTOM_LAYOUT_PREFIX}shift_symbols", context)
|
val oldShiftSymbolsFile = getCustomLayoutFile("custom.shift_symbols", context)
|
||||||
if (oldShiftSymbolsFile.exists()) {
|
if (oldShiftSymbolsFile.exists()) {
|
||||||
oldShiftSymbolsFile.renameTo(getCustomLayoutFile("${CUSTOM_LAYOUT_PREFIX}symbols_shifted", context))
|
oldShiftSymbolsFile.renameTo(getCustomLayoutFile("custom.symbols_shifted", context))
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename subtype setting, and clean old subtypes that might remain in some cases
|
// rename subtype setting, and clean old subtypes that might remain in some cases
|
||||||
|
@ -147,8 +148,8 @@ fun checkVersionUpgrade(context: Context) {
|
||||||
Settings.writePrefAdditionalSubtypes(prefs, newSubtypeStrings.joinToString(";"))
|
Settings.writePrefAdditionalSubtypes(prefs, newSubtypeStrings.joinToString(";"))
|
||||||
}
|
}
|
||||||
// rename other custom layouts
|
// rename other custom layouts
|
||||||
onCustomLayoutFileListChanged()
|
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
||||||
getCustomLayoutFiles(context).forEach {
|
File(DeviceProtectedUtils.getFilesDir(context), "layouts").listFiles()?.forEach {
|
||||||
val newFile = getCustomLayoutFile(it.name.substringBeforeLast(".") + ".", context)
|
val newFile = getCustomLayoutFile(it.name.substringBeforeLast(".") + ".", context)
|
||||||
if (newFile.name == it.name) return@forEach
|
if (newFile.name == it.name) return@forEach
|
||||||
if (newFile.exists()) newFile.delete() // should never happen
|
if (newFile.exists()) newFile.delete() // should never happen
|
||||||
|
@ -243,99 +244,99 @@ fun checkVersionUpgrade(context: Context) {
|
||||||
File(DeviceProtectedUtils.getFilesDir(context), "layouts").listFiles()?.forEach { file ->
|
File(DeviceProtectedUtils.getFilesDir(context), "layouts").listFiles()?.forEach { file ->
|
||||||
val folder = DeviceProtectedUtils.getFilesDir(context)
|
val folder = DeviceProtectedUtils.getFilesDir(context)
|
||||||
when (file.name) {
|
when (file.name) {
|
||||||
"${CUSTOM_LAYOUT_PREFIX}symbols." -> {
|
"custom.symbols." -> {
|
||||||
val dir = File(folder, LayoutType.SYMBOLS.folder)
|
val dir = File(folder, LayoutType.SYMBOLS.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("symbols")}."
|
val name = "custom.${encodeBase36("symbols")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.SYMBOLS.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.SYMBOLS.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}symbols_shifted." -> {
|
"custom.symbols_shifted." -> {
|
||||||
val dir = File(folder, LayoutType.MORE_SYMBOLS.folder)
|
val dir = File(folder, LayoutType.MORE_SYMBOLS.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("symbols_shifted")}."
|
val name = "custom.${encodeBase36("symbols_shifted")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.MORE_SYMBOLS.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.MORE_SYMBOLS.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}symbols_arabic." -> {
|
"custom.symbols_arabic." -> {
|
||||||
val dir = File(folder, LayoutType.SYMBOLS.folder)
|
val dir = File(folder, LayoutType.SYMBOLS.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("symbols_arabic")}."
|
val name = "custom.${encodeBase36("symbols_arabic")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}numpad." -> {
|
"custom.numpad." -> {
|
||||||
val dir = File(folder, LayoutType.NUMPAD.folder)
|
val dir = File(folder, LayoutType.NUMPAD.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("numpad")}."
|
val name = "custom.${encodeBase36("numpad")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMPAD.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMPAD.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}numpad_landscape." -> {
|
"custom.numpad_landscape." -> {
|
||||||
val dir = File(folder, LayoutType.NUMPAD_LANDSCAPE.folder)
|
val dir = File(folder, LayoutType.NUMPAD_LANDSCAPE.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("numpad_landscape")}."
|
val name = "custom.${encodeBase36("numpad_landscape")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMPAD_LANDSCAPE.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMPAD_LANDSCAPE.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}number." -> {
|
"custom.number." -> {
|
||||||
val dir = File(folder, LayoutType.NUMBER.folder)
|
val dir = File(folder, LayoutType.NUMBER.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("number")}."
|
val name = "custom.${encodeBase36("number")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMBER.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMBER.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}phone." -> {
|
"custom.phone." -> {
|
||||||
val dir = File(folder, LayoutType.PHONE.folder)
|
val dir = File(folder, LayoutType.PHONE.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("phone")}."
|
val name = "custom.${encodeBase36("phone")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.PHONE.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.PHONE.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}phone_symbols." -> {
|
"custom.phone_symbols." -> {
|
||||||
val dir = File(folder, LayoutType.PHONE_SYMBOLS.folder)
|
val dir = File(folder, LayoutType.PHONE_SYMBOLS.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("phone_symbols")}."
|
val name = "custom.${encodeBase36("phone_symbols")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.PHONE_SYMBOLS.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.PHONE_SYMBOLS.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}number_row." -> {
|
"custom.number_row." -> {
|
||||||
val dir = File(folder, LayoutType.NUMBER_ROW.folder)
|
val dir = File(folder, LayoutType.NUMBER_ROW.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("number_row")}."
|
val name = "custom.${encodeBase36("number_row")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMBER_ROW.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.NUMBER_ROW.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}emoji_bottom_row." -> {
|
"custom.emoji_bottom_row." -> {
|
||||||
val dir = File(folder, LayoutType.EMOJI_BOTTOM.folder)
|
val dir = File(folder, LayoutType.EMOJI_BOTTOM.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("emoji_bottom_row")}."
|
val name = "custom.${encodeBase36("emoji_bottom_row")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.EMOJI_BOTTOM.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.EMOJI_BOTTOM.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}clip_bottom_row." -> {
|
"custom.clip_bottom_row." -> {
|
||||||
val dir = File(folder, LayoutType.CLIPBOARD_BOTTOM.folder)
|
val dir = File(folder, LayoutType.CLIPBOARD_BOTTOM.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("clip_bottom_row")}."
|
val name = "custom.${encodeBase36("clip_bottom_row")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.CLIPBOARD_BOTTOM.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.CLIPBOARD_BOTTOM.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}functional_keys." -> {
|
"custom.functional_keys." -> {
|
||||||
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("functional_keys")}."
|
val name = "custom.${encodeBase36("functional_keys")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.FUNCTIONAL.name, name).apply()
|
prefs.edit().putString(Settings.PREF_LAYOUT_PREFIX + LayoutType.FUNCTIONAL.name, name).apply()
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}functional_keys_symbols." -> {
|
"custom.functional_keys_symbols." -> {
|
||||||
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("functional_keys_symbols")}."
|
val name = "custom.${encodeBase36("functional_keys_symbols")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
}
|
}
|
||||||
"${CUSTOM_LAYOUT_PREFIX}functional_keys_symbols_shifted." -> {
|
"custom.functional_keys_symbols_shifted." -> {
|
||||||
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
val dir = File(folder, LayoutType.FUNCTIONAL.folder)
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val name = "$CUSTOM_LAYOUT_PREFIX${encodeBase36("functional_keys_symbols_shifted")}."
|
val name = "custom.${encodeBase36("functional_keys_symbols_shifted")}."
|
||||||
file.renameTo(File(dir, name))
|
file.renameTo(File(dir, name))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -354,7 +355,7 @@ fun checkVersionUpgrade(context: Context) {
|
||||||
prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!!.replace(":", "§")).apply()
|
prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!!.replace(":", "§")).apply()
|
||||||
}
|
}
|
||||||
upgradeToolbarPrefs(prefs)
|
upgradeToolbarPrefs(prefs)
|
||||||
onCustomLayoutFileListChanged() // just to be sure
|
LayoutUtilsCustom.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) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import helium314.keyboard.latin.common.Constants
|
||||||
import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET
|
import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET
|
||||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||||
import helium314.keyboard.latin.common.LocaleUtils.isRtlLanguage
|
import helium314.keyboard.latin.common.LocaleUtils.isRtlLanguage
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
|
||||||
import helium314.keyboard.latin.utils.LayoutType
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.SubtypeLocaleUtils
|
import helium314.keyboard.latin.utils.SubtypeLocaleUtils
|
||||||
import helium314.keyboard.latin.utils.locale
|
import helium314.keyboard.latin.utils.locale
|
||||||
|
@ -38,7 +38,7 @@ class RichInputMethodSubtype private constructor(val rawSubtype: InputMethodSubt
|
||||||
/** layout names for this subtype by LayoutType */
|
/** 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() = LayoutUtilsCustom.isCustomLayout(mainLayoutName)
|
||||||
|
|
||||||
val fullDisplayName: String get() {
|
val fullDisplayName: String get() {
|
||||||
if (isNoLanguage) {
|
if (isNoLanguage) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
||||||
import helium314.keyboard.latin.common.StringUtils.mightBeEmoji
|
import helium314.keyboard.latin.common.StringUtils.mightBeEmoji
|
||||||
import helium314.keyboard.latin.common.StringUtils.newSingleCodePointString
|
import helium314.keyboard.latin.common.StringUtils.newSingleCodePointString
|
||||||
import helium314.keyboard.latin.settings.SpacingAndPunctuations
|
import helium314.keyboard.latin.settings.SpacingAndPunctuations
|
||||||
|
import java.math.BigInteger
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
fun loopOverCodePoints(s: CharSequence, run: (Int) -> Boolean) {
|
fun loopOverCodePoints(s: CharSequence, run: (Int) -> Boolean) {
|
||||||
|
@ -124,6 +125,10 @@ fun String.decapitalize(locale: Locale): String {
|
||||||
return replaceFirstChar { it.lowercase(locale) }
|
return replaceFirstChar { it.lowercase(locale) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun encodeBase36(string: String): String = BigInteger(string.toByteArray()).toString(36)
|
||||||
|
|
||||||
|
fun decodeBase36(string: String) = BigInteger(string, 36).toByteArray().decodeToString()
|
||||||
|
|
||||||
fun isEmoji(c: Int): Boolean = mightBeEmoji(c) && isEmoji(newSingleCodePointString(c))
|
fun isEmoji(c: Int): Boolean = mightBeEmoji(c) && isEmoji(newSingleCodePointString(c))
|
||||||
|
|
||||||
fun isEmoji(s: CharSequence): Boolean = mightBeEmoji(s) && s.matches(emoRegex)
|
fun isEmoji(s: CharSequence): Boolean = mightBeEmoji(s) && s.matches(emoRegex)
|
||||||
|
|
|
@ -46,19 +46,11 @@ 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.AdditionalSubtypeUtils
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_FUNCTIONAL_LAYOUT_NORMAL
|
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_FUNCTIONAL_LAYOUT_SYMBOLS
|
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_FUNCTIONAL_LAYOUT_SYMBOLS_SHIFTED
|
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
|
||||||
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.editCustomLayout
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
|
||||||
import helium314.keyboard.latin.utils.infoDialog
|
import helium314.keyboard.latin.utils.infoDialog
|
||||||
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
|
||||||
import helium314.keyboard.latin.utils.reloadEnabledSubtypes
|
import helium314.keyboard.latin.utils.reloadEnabledSubtypes
|
||||||
import helium314.keyboard.latin.utils.updateAdditionalSubtypes
|
import helium314.keyboard.latin.utils.updateAdditionalSubtypes
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -76,7 +68,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
private val libfile by lazy { File(requireContext().filesDir.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME) }
|
private val libfile by lazy { File(requireContext().filesDir.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME) }
|
||||||
private val backupFilePatterns by lazy { listOf(
|
private val backupFilePatterns by lazy { listOf(
|
||||||
"blacklists/.*\\.txt".toRegex(),
|
"blacklists/.*\\.txt".toRegex(),
|
||||||
"layouts/$CUSTOM_LAYOUT_PREFIX+\\..{0,4}".toRegex(), // can't expect a period at the end, as this would break restoring older backups
|
// "layouts/$CUSTOM_LAYOUT_PREFIX+\\..{0,4}".toRegex(), // can't expect a period at the end, as this would break restoring older backups
|
||||||
"dicts/.*/.*user\\.dict".toRegex(),
|
"dicts/.*/.*user\\.dict".toRegex(),
|
||||||
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
||||||
"custom_background_image.*".toRegex(),
|
"custom_background_image.*".toRegex(),
|
||||||
|
@ -134,7 +126,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
findPreference<Preference>("custom_functional_key_layouts")?.setOnPreferenceClickListener {
|
findPreference<Preference>("custom_functional_key_layouts")?.setOnPreferenceClickListener {
|
||||||
showCustomizeFunctionalKeyLayoutsDialog()
|
// showCustomizeFunctionalKeyLayoutsDialog()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +165,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 }
|
||||||
.firstOrNull { it.startsWith("$CUSTOM_LAYOUT_PREFIX$layoutName.") }
|
.firstOrNull { it.startsWith("$CUSTOM_LAYOUT_PREFIX$layoutName.") }
|
||||||
|
@ -211,7 +203,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
val displayName = layoutName.substringAfter(CUSTOM_LAYOUT_PREFIX).getStringResourceOrName("layout_", requireContext())
|
val displayName = layoutName.substringAfter(CUSTOM_LAYOUT_PREFIX).getStringResourceOrName("layout_", requireContext())
|
||||||
editCustomLayout(customLayoutName ?: "$layoutName.", requireContext(), originalLayout, displayName)
|
editCustomLayout(customLayoutName ?: "$layoutName.", requireContext(), originalLayout, displayName)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
@SuppressLint("ApplySharedPref")
|
@SuppressLint("ApplySharedPref")
|
||||||
private fun onClickLoadLibrary(): Boolean {
|
private fun onClickLoadLibrary(): Boolean {
|
||||||
// get architecture for telling user which file to use
|
// get architecture for telling user which file to use
|
||||||
|
@ -425,7 +417,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
// reload current prefs screen
|
// reload current prefs screen
|
||||||
preferenceScreen.removeAll()
|
preferenceScreen.removeAll()
|
||||||
setupPreferences()
|
setupPreferences()
|
||||||
onCustomLayoutFileListChanged()
|
// onCustomLayoutFileListChanged()
|
||||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
|
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ class LanguageSettingsDialog(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSubtype(name: String) {
|
private fun addSubtype(name: String) {
|
||||||
onCustomLayoutFileListChanged()
|
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
||||||
val newSubtype = AdditionalSubtypeUtils.createEmojiCapableAdditionalSubtype(mainLocale, name, infos.first().subtype.isAsciiCapable)
|
val newSubtype = AdditionalSubtypeUtils.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.getKeyboardLayoutSetDisplayName(newSubtype)
|
||||||
|
@ -138,7 +138,7 @@ class LanguageSettingsDialog(
|
||||||
val displayNames = mutableListOf<String>()
|
val displayNames = mutableListOf<String>()
|
||||||
infos.forEach {
|
infos.forEach {
|
||||||
val mainLayoutName = it.subtype.mainLayoutName() ?: "qwerty"
|
val mainLayoutName = it.subtype.mainLayoutName() ?: "qwerty"
|
||||||
if (!mainLayoutName.startsWith(CUSTOM_LAYOUT_PREFIX) // don't allow copying custom layout (at least for now)
|
if (!LayoutUtilsCustom.isCustomLayout(mainLayoutName) // 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)
|
||||||
displayNames.add(it.subtype.displayName(context).toString())
|
displayNames.add(it.subtype.displayName(context).toString())
|
||||||
|
@ -155,7 +155,7 @@ class LanguageSettingsDialog(
|
||||||
.setItems(displayNames.toTypedArray()) { di, i ->
|
.setItems(displayNames.toTypedArray()) { di, i ->
|
||||||
di.dismiss()
|
di.dismiss()
|
||||||
val fileName = context.assets.list("layouts")?.firstOrNull { it.startsWith(layouts[i]) } ?: return@setItems
|
val fileName = context.assets.list("layouts")?.firstOrNull { it.startsWith(layouts[i]) } ?: return@setItems
|
||||||
loadCustomLayout(context.assets.open("layouts${File.separator}$fileName").reader().readText(),
|
LayoutUtilsCustom.loadCustomLayout(context.assets.open("layouts${File.separator}$fileName").reader().readText(),
|
||||||
displayNames[i], mainLocale.toLanguageTag(), context) { addSubtype(it) }
|
displayNames[i], mainLocale.toLanguageTag(), context) { addSubtype(it) }
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
@ -163,7 +163,7 @@ class LanguageSettingsDialog(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewLayoutFile(uri: Uri?) {
|
override fun onNewLayoutFile(uri: Uri?) {
|
||||||
loadCustomLayout(uri, mainLocale.toLanguageTag(), context) { addSubtype(it) }
|
LayoutUtilsCustom.loadCustomLayout(uri, mainLocale.toLanguageTag(), context) { addSubtype(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSubtypeToView(subtype: SubtypeInfo) {
|
private fun addSubtypeToView(subtype: SubtypeInfo) {
|
||||||
|
@ -172,9 +172,9 @@ class LanguageSettingsDialog(
|
||||||
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)
|
||||||
if (layoutSetName.startsWith(CUSTOM_LAYOUT_PREFIX)) {
|
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)
|
||||||
row.findViewById<View>(R.id.language_text).setOnClickListener { editCustomLayout(layoutSetName, context) }
|
row.findViewById<View>(R.id.language_text).setOnClickListener { LayoutUtilsCustom.editCustomLayout(layoutSetName, context) }
|
||||||
} else {
|
} else {
|
||||||
row.findViewById<View>(R.id.language_details).isGone = true
|
row.findViewById<View>(R.id.language_details).isGone = true
|
||||||
}
|
}
|
||||||
|
@ -198,18 +198,18 @@ class LanguageSettingsDialog(
|
||||||
row.findViewById<ImageView>(R.id.delete_button).apply {
|
row.findViewById<ImageView>(R.id.delete_button).apply {
|
||||||
isVisible = true
|
isVisible = true
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
val isCustom = layoutSetName.startsWith(CUSTOM_LAYOUT_PREFIX)
|
val isCustom = LayoutUtilsCustom.isCustomLayout(layoutSetName)
|
||||||
fun delete() {
|
fun delete() {
|
||||||
binding.subtypes.removeView(row)
|
binding.subtypes.removeView(row)
|
||||||
infos.remove(subtype)
|
infos.remove(subtype)
|
||||||
if (isCustom)
|
if (isCustom)
|
||||||
removeCustomLayoutFile(layoutSetName, context)
|
LayoutUtilsCustom.removeCustomLayoutFile(layoutSetName, context)
|
||||||
removeAdditionalSubtype(prefs, subtype.subtype)
|
removeAdditionalSubtype(prefs, subtype.subtype)
|
||||||
removeEnabledSubtype(prefs, subtype.subtype)
|
removeEnabledSubtype(prefs, subtype.subtype)
|
||||||
reloadSetting()
|
reloadSetting()
|
||||||
}
|
}
|
||||||
if (isCustom) {
|
if (isCustom) {
|
||||||
confirmDialog(context, context.getString(R.string.delete_layout, getCustomLayoutDisplayName(layoutSetName)), context.getString(R.string.delete)) { delete() }
|
confirmDialog(context, context.getString(R.string.delete_layout, LayoutUtilsCustom.getCustomLayoutDisplayName(layoutSetName)), context.getString(R.string.delete)) { delete() }
|
||||||
} else {
|
} else {
|
||||||
delete()
|
delete()
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ public final class AdditionalSubtypeUtils {
|
||||||
final boolean asciiCapable = ScriptUtils.script(locale).equals(ScriptUtils.SCRIPT_LATIN);
|
final boolean asciiCapable = ScriptUtils.script(locale).equals(ScriptUtils.SCRIPT_LATIN);
|
||||||
// Here we assume that all the additional subtypes are EmojiCapable
|
// Here we assume that all the additional subtypes are EmojiCapable
|
||||||
final InputMethodSubtype subtype = createEmojiCapableAdditionalSubtype(locale, keyboardLayoutSetName, asciiCapable);
|
final InputMethodSubtype subtype = createEmojiCapableAdditionalSubtype(locale, keyboardLayoutSetName, asciiCapable);
|
||||||
if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT && !LayoutUtilsCustomKt.isCustomLayout(keyboardLayoutSetName)) {
|
if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT && !LayoutUtilsCustom.INSTANCE.isCustomLayout(keyboardLayoutSetName)) {
|
||||||
// Skip unknown keyboard layout subtype. This may happen when predefined keyboard
|
// Skip unknown keyboard layout subtype. This may happen when predefined keyboard
|
||||||
// layout has been removed.
|
// layout has been removed.
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -14,7 +14,7 @@ object LayoutUtils {
|
||||||
if (locale == null)
|
if (locale == null)
|
||||||
return getAllAvailableSubtypes().mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" }
|
return getAllAvailableSubtypes().mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" }
|
||||||
if (locale.script() == ScriptUtils.SCRIPT_LATIN)
|
if (locale.script() == ScriptUtils.SCRIPT_LATIN)
|
||||||
return getAllAvailableSubtypes().filter { it.isAsciiCapable && it.mainLayoutName()?.startsWith(CUSTOM_LAYOUT_PREFIX) == false }
|
return getAllAvailableSubtypes().filter { it.isAsciiCapable && LayoutUtilsCustom.isCustomLayout(it.mainLayoutName() ?: "qwerty") }
|
||||||
.mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" }
|
.mapTo(HashSet()) { it.mainLayoutName()?.substringBefore("+") ?: "qwerty" }
|
||||||
return getSubtypesForLocale(locale).mapNotNullTo(HashSet()) { it.mainLayoutName() }
|
return getSubtypesForLocale(locale).mapNotNullTo(HashSet()) { it.mainLayoutName() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,230 +18,223 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.POPUP_KEYS_NORMAL
|
||||||
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.FileUtils
|
import helium314.keyboard.latin.common.FileUtils
|
||||||
|
import helium314.keyboard.latin.common.decodeBase36
|
||||||
|
import helium314.keyboard.latin.common.encodeBase36
|
||||||
import helium314.keyboard.latin.utils.LayoutType.Companion.folder
|
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.util.EnumMap
|
import java.util.EnumMap
|
||||||
|
|
||||||
// todo: object like LayoutUtils
|
object LayoutUtilsCustom {
|
||||||
|
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)
|
return infoDialog(context, context.getString(R.string.layout_error, "layout file not found"))
|
||||||
return infoDialog(context, context.getString(R.string.layout_error, "layout file not found"))
|
val layoutContent: String
|
||||||
val layoutContent: String
|
try {
|
||||||
try {
|
val tmpFile = File(context.filesDir.absolutePath + File.separator + "tmpfile")
|
||||||
val tmpFile = File(context.filesDir.absolutePath + File.separator + "tmpfile")
|
FileUtils.copyContentUriToNewFile(uri, context, tmpFile)
|
||||||
FileUtils.copyContentUriToNewFile(uri, context, tmpFile)
|
layoutContent = tmpFile.readText()
|
||||||
layoutContent = tmpFile.readText()
|
tmpFile.delete()
|
||||||
tmpFile.delete()
|
} catch (e: IOException) {
|
||||||
} catch (e: IOException) {
|
return infoDialog(context, context.getString(R.string.layout_error, "cannot read layout file"))
|
||||||
return infoDialog(context, context.getString(R.string.layout_error, "cannot read layout file"))
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = ""
|
|
||||||
context.contentResolver.query(uri, null, null, null, null).use {
|
|
||||||
if (it != null && it.moveToFirst()) {
|
|
||||||
val idx = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
|
||||||
if (idx >= 0)
|
|
||||||
name = it.getString(idx).substringBeforeLast(".")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
loadCustomLayout(layoutContent, name, languageTag, context, onAdded)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadCustomLayout(layoutContent: String, layoutName: String, languageTag: String, context: Context, onAdded: (String) -> Unit) {
|
var name = ""
|
||||||
var name = layoutName
|
context.contentResolver.query(uri, null, null, null, null).use {
|
||||||
if (!checkLayout(layoutContent, context))
|
if (it != null && it.moveToFirst()) {
|
||||||
return infoDialog(context, context.getString(R.string.layout_error, "invalid layout file, ${Log.getLog(10).lastOrNull { it.tag == TAG }?.message}"))
|
val idx = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
|
if (idx >= 0)
|
||||||
|
name = it.getString(idx).substringBeforeLast(".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadCustomLayout(layoutContent, name, languageTag, context, onAdded)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadCustomLayout(layoutContent: String, layoutName: String, languageTag: String, context: Context, onAdded: (String) -> Unit) {
|
||||||
|
var name = layoutName
|
||||||
|
if (!checkLayout(layoutContent, context))
|
||||||
|
return infoDialog(context, context.getString(R.string.layout_error, "invalid layout file, ${Log.getLog(10).lastOrNull { it.tag == TAG }?.message}"))
|
||||||
// val isJson = checkLayout(layoutContent, context)
|
// val isJson = checkLayout(layoutContent, context)
|
||||||
// ?: return infoDialog(context, context.getString(R.string.layout_error, "invalid layout file, ${Log.getLog(10).lastOrNull { it.tag == TAG }?.message}"))
|
// ?: return infoDialog(context, context.getString(R.string.layout_error, "invalid layout file, ${Log.getLog(10).lastOrNull { it.tag == TAG }?.message}"))
|
||||||
|
|
||||||
AlertDialog.Builder(context)
|
AlertDialog.Builder(context)
|
||||||
.setTitle(R.string.title_layout_name_select)
|
.setTitle(R.string.title_layout_name_select)
|
||||||
.setView(EditText(context).apply {
|
.setView(EditText(context).apply {
|
||||||
setText(name)
|
setText(name)
|
||||||
doAfterTextChanged { name = it.toString() }
|
doAfterTextChanged { name = it.toString() }
|
||||||
val padding = ResourceUtils.toPx(8, context.resources)
|
val padding = ResourceUtils.toPx(8, context.resources)
|
||||||
setPadding(3 * padding, padding, 3 * padding, padding)
|
setPadding(3 * padding, padding, 3 * padding, padding)
|
||||||
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_NORMAL
|
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_NORMAL
|
||||||
})
|
})
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
// name must be encoded to avoid issues with validity of subtype extra string or file name
|
// name must be encoded to avoid issues with validity of subtype extra string or file name
|
||||||
name = "$CUSTOM_LAYOUT_PREFIX${languageTag}.${encodeBase36(name)}."
|
name = "$CUSTOM_LAYOUT_PREFIX${languageTag}.${encodeBase36(name)}."
|
||||||
val file = getCustomLayoutFile(name, context)
|
val file = getCustomLayoutFile(name, context)
|
||||||
if (file.exists())
|
if (file.exists())
|
||||||
file.delete()
|
|
||||||
file.parentFile?.mkdir()
|
|
||||||
file.writeText(layoutContent)
|
|
||||||
onAdded(name)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkLayout(layoutContent: String, context: Context): Boolean {
|
|
||||||
val params = KeyboardParams()
|
|
||||||
params.mId = KeyboardLayoutSet.getFakeKeyboardId(KeyboardId.ELEMENT_ALPHABET)
|
|
||||||
params.mPopupKeyTypes.add(POPUP_KEYS_LAYOUT)
|
|
||||||
addLocaleKeyTextsToParams(context, params, POPUP_KEYS_NORMAL)
|
|
||||||
try {
|
|
||||||
val keys = LayoutParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
|
||||||
return checkKeys(keys)
|
|
||||||
} catch (e: SerializationException) {
|
|
||||||
Log.w(TAG, "json parsing error", e)
|
|
||||||
if (layoutContent.trimStart().startsWith("[") && layoutContent.trimEnd().endsWith("]") && layoutContent.contains("},"))
|
|
||||||
return false // we're sure enough it's a json
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.w(TAG, "json layout parsed, but considered invalid", e)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val keys = LayoutParser.parseSimpleString(layoutContent).map { row -> row.map { it.toKeyParams(params) } }
|
|
||||||
return checkKeys(keys)
|
|
||||||
} catch (e: Exception) { Log.w(TAG, "error parsing custom simple layout", e) }
|
|
||||||
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
|
|
||||||
try {
|
|
||||||
LayoutParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
|
||||||
} catch (e: Exception) { Log.w(TAG, "json parsing error", e) }
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkKeys(keys: List<List<Key.KeyParams>>): Boolean {
|
|
||||||
if (keys.isEmpty() || keys.any { it.isEmpty() }) {
|
|
||||||
Log.w(TAG, "empty rows")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (keys.size > 8) {
|
|
||||||
Log.w(TAG, "too many rows")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (keys.any { row -> row.size > 20 }) {
|
|
||||||
Log.w(TAG, "too many keys in one row")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (keys.any { row -> row.any {
|
|
||||||
if ((it.mLabel?.length ?: 0) > 20) {
|
|
||||||
Log.w(TAG, "too long text on key: ${it.mLabel}")
|
|
||||||
true
|
|
||||||
} else false
|
|
||||||
} }) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (keys.any { row -> row.any {
|
|
||||||
if ((it.mPopupKeys?.size ?: 0) > 20) {
|
|
||||||
Log.w(TAG, "too many popup keys on key ${it.mLabel}")
|
|
||||||
true
|
|
||||||
} else false
|
|
||||||
} }) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (keys.any { row -> row.any { true == it.mPopupKeys?.any { popupKey ->
|
|
||||||
if ((popupKey.mLabel?.length ?: 0) > 10) {
|
|
||||||
Log.w(TAG, "too long text on popup key: ${popupKey.mLabel}")
|
|
||||||
true
|
|
||||||
} else false
|
|
||||||
} } }) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/** don't rename or delete the file without calling [onCustomLayoutFileListChanged] */
|
|
||||||
fun getCustomLayoutFile(layoutName: String, context: Context) = // todo: remove
|
|
||||||
File(getCustomLayoutsDir(context), layoutName)
|
|
||||||
|
|
||||||
// cache to avoid frequently listing files
|
|
||||||
/** don't rename or delete files without calling [onCustomLayoutFileListChanged] */
|
|
||||||
fun getCustomLayoutFiles(context: Context): List<File> { // todo: remove, AND USE THE NEW THING FOR SUBTYPE SETTINGS
|
|
||||||
customLayouts?.let { return it }
|
|
||||||
val layouts = getCustomLayoutsDir(context).listFiles()?.toList() ?: emptyList()
|
|
||||||
customLayouts = 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() {
|
|
||||||
customLayouts = null
|
|
||||||
customLayoutMap.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCustomLayoutsDir(context: Context) = File(DeviceProtectedUtils.getFilesDir(context), "layouts")
|
|
||||||
|
|
||||||
fun getCustomLayoutDisplayName(layoutName: String) =
|
|
||||||
try {
|
|
||||||
decodeBase36(layoutName.substringAfter(CUSTOM_LAYOUT_PREFIX).substringBeforeLast("."))
|
|
||||||
} catch (_: NumberFormatException) {
|
|
||||||
layoutName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCustomLayoutName(displayName: String) = CUSTOM_LAYOUT_PREFIX + encodeBase36(displayName) + "."
|
|
||||||
|
|
||||||
fun isCustomLayout(layoutName: String) = layoutName.startsWith(CUSTOM_LAYOUT_PREFIX)
|
|
||||||
|
|
||||||
fun getCustomLayoutFile(layoutName: String, layoutType: LayoutType, context: Context): File {
|
|
||||||
val file = File(DeviceProtectedUtils.getFilesDir(context), layoutType.folder + layoutName)
|
|
||||||
file.parentFile?.mkdirs()
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeCustomLayoutFile(layoutName: String, context: Context) {
|
|
||||||
getCustomLayoutFile(layoutName, context).delete()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun editCustomLayout(layoutName: String, context: Context, startContent: String? = null, displayName: CharSequence? = null) {
|
|
||||||
val file = getCustomLayoutFile(layoutName, context)
|
|
||||||
val editText = EditText(context).apply {
|
|
||||||
setText(startContent ?: file.readText())
|
|
||||||
}
|
|
||||||
val builder = AlertDialog.Builder(context)
|
|
||||||
.setTitle(getCustomLayoutDisplayName(layoutName))
|
|
||||||
.setView(editText)
|
|
||||||
.setPositiveButton(R.string.save) { _, _ ->
|
|
||||||
val content = editText.text.toString()
|
|
||||||
if (!checkLayout(content, context)) {
|
|
||||||
editCustomLayout(layoutName, context, content)
|
|
||||||
infoDialog(context, context.getString(R.string.layout_error, Log.getLog(10).lastOrNull { it.tag == TAG }?.message))
|
|
||||||
} else {
|
|
||||||
file.parentFile?.mkdir()
|
|
||||||
file.writeText(content)
|
|
||||||
onCustomLayoutFileListChanged()
|
|
||||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
if (displayName != null) {
|
|
||||||
if (file.exists()) {
|
|
||||||
builder.setNeutralButton(R.string.delete) { _, _ ->
|
|
||||||
confirmDialog(context, context.getString(R.string.delete_layout, displayName), context.getString(R.string.delete)) {
|
|
||||||
file.delete()
|
file.delete()
|
||||||
|
file.parentFile?.mkdir()
|
||||||
|
file.writeText(layoutContent)
|
||||||
|
onAdded(name)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkLayout(layoutContent: String, context: Context): Boolean {
|
||||||
|
val params = KeyboardParams()
|
||||||
|
params.mId = KeyboardLayoutSet.getFakeKeyboardId(KeyboardId.ELEMENT_ALPHABET)
|
||||||
|
params.mPopupKeyTypes.add(POPUP_KEYS_LAYOUT)
|
||||||
|
addLocaleKeyTextsToParams(context, params, POPUP_KEYS_NORMAL)
|
||||||
|
try {
|
||||||
|
val keys = LayoutParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||||
|
return checkKeys(keys)
|
||||||
|
} catch (e: SerializationException) {
|
||||||
|
Log.w(TAG, "json parsing error", e)
|
||||||
|
if (layoutContent.trimStart().startsWith("[") && layoutContent.trimEnd().endsWith("]") && layoutContent.contains("},"))
|
||||||
|
return false // we're sure enough it's a json
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "json layout parsed, but considered invalid", e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val keys = LayoutParser.parseSimpleString(layoutContent).map { row -> row.map { it.toKeyParams(params) } }
|
||||||
|
return checkKeys(keys)
|
||||||
|
} catch (e: Exception) { Log.w(TAG, "error parsing custom simple layout", e) }
|
||||||
|
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
|
||||||
|
try {
|
||||||
|
LayoutParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||||
|
} catch (e: Exception) { Log.w(TAG, "json parsing error", e) }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkKeys(keys: List<List<Key.KeyParams>>): Boolean {
|
||||||
|
if (keys.isEmpty() || keys.any { it.isEmpty() }) {
|
||||||
|
Log.w(TAG, "empty rows")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (keys.size > 8) {
|
||||||
|
Log.w(TAG, "too many rows")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (keys.any { row -> row.size > 20 }) {
|
||||||
|
Log.w(TAG, "too many keys in one row")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (keys.any { row -> row.any {
|
||||||
|
if ((it.mLabel?.length ?: 0) > 20) {
|
||||||
|
Log.w(TAG, "too long text on key: ${it.mLabel}")
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
} }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (keys.any { row -> row.any {
|
||||||
|
if ((it.mPopupKeys?.size ?: 0) > 20) {
|
||||||
|
Log.w(TAG, "too many popup keys on key ${it.mLabel}")
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
} }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (keys.any { row -> row.any { true == it.mPopupKeys?.any { popupKey ->
|
||||||
|
if ((popupKey.mLabel?.length ?: 0) > 10) {
|
||||||
|
Log.w(TAG, "too long text on popup key: ${popupKey.mLabel}")
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
} } }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/** don't rename or delete the file without calling [onCustomLayoutFileListChanged] */
|
||||||
|
fun getCustomLayoutFile(layoutName: String, context: Context) = // todo: remove
|
||||||
|
File(getCustomLayoutsDir(context), layoutName)
|
||||||
|
|
||||||
|
// cache to avoid frequently listing files
|
||||||
|
/** don't rename or delete files without calling [onCustomLayoutFileListChanged] */
|
||||||
|
fun getCustomLayoutFiles(context: Context): List<File> { // todo: remove, AND USE THE NEW THING FOR SUBTYPE SETTINGS
|
||||||
|
customLayouts?.let { return it }
|
||||||
|
val layouts = getCustomLayoutsDir(context).listFiles()?.toList() ?: emptyList()
|
||||||
|
customLayouts = 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() {
|
||||||
|
customLayouts = null
|
||||||
|
customLayoutMap.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCustomLayoutsDir(context: Context) = File(DeviceProtectedUtils.getFilesDir(context), "layouts")
|
||||||
|
|
||||||
|
fun getCustomLayoutDisplayName(layoutName: String) =
|
||||||
|
try {
|
||||||
|
decodeBase36(layoutName.substringAfter(CUSTOM_LAYOUT_PREFIX).substringBeforeLast("."))
|
||||||
|
} catch (_: NumberFormatException) {
|
||||||
|
layoutName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCustomLayoutName(displayName: String) = CUSTOM_LAYOUT_PREFIX + encodeBase36(displayName) + "."
|
||||||
|
|
||||||
|
fun isCustomLayout(layoutName: String) = layoutName.startsWith(CUSTOM_LAYOUT_PREFIX)
|
||||||
|
|
||||||
|
fun getCustomLayoutFile(layoutName: String, layoutType: LayoutType, context: Context): File {
|
||||||
|
val file = File(DeviceProtectedUtils.getFilesDir(context), layoutType.folder + layoutName)
|
||||||
|
file.parentFile?.mkdirs()
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeCustomLayoutFile(layoutName: String, context: Context) {
|
||||||
|
getCustomLayoutFile(layoutName, context).delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun editCustomLayout(layoutName: String, context: Context, startContent: String? = null, displayName: CharSequence? = null) {
|
||||||
|
val file = getCustomLayoutFile(layoutName, context)
|
||||||
|
val editText = EditText(context).apply {
|
||||||
|
setText(startContent ?: file.readText())
|
||||||
|
}
|
||||||
|
val builder = AlertDialog.Builder(context)
|
||||||
|
.setTitle(getCustomLayoutDisplayName(layoutName))
|
||||||
|
.setView(editText)
|
||||||
|
.setPositiveButton(R.string.save) { _, _ ->
|
||||||
|
val content = editText.text.toString()
|
||||||
|
if (!checkLayout(content, context)) {
|
||||||
|
editCustomLayout(layoutName, context, content)
|
||||||
|
infoDialog(context, context.getString(R.string.layout_error, Log.getLog(10).lastOrNull { it.tag == TAG }?.message))
|
||||||
|
} else {
|
||||||
|
file.parentFile?.mkdir()
|
||||||
|
file.writeText(content)
|
||||||
onCustomLayoutFileListChanged()
|
onCustomLayoutFileListChanged()
|
||||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
if (displayName != null) {
|
||||||
|
if (file.exists()) {
|
||||||
|
builder.setNeutralButton(R.string.delete) { _, _ ->
|
||||||
|
confirmDialog(context, context.getString(R.string.delete_layout, displayName), context.getString(R.string.delete)) {
|
||||||
|
file.delete()
|
||||||
|
onCustomLayoutFileListChanged()
|
||||||
|
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.setTitle(displayName)
|
||||||
}
|
}
|
||||||
builder.setTitle(displayName)
|
builder.show()
|
||||||
}
|
}
|
||||||
builder.show()
|
|
||||||
|
// this goes into prefs and file names, so do not change!
|
||||||
|
const val CUSTOM_LAYOUT_PREFIX = "custom."
|
||||||
|
private const val TAG = "LayoutUtilsCustom"
|
||||||
|
private var customLayouts: List<File>? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun encodeBase36(string: String): String = BigInteger(string.toByteArray()).toString(36)
|
|
||||||
|
|
||||||
fun decodeBase36(string: String) = BigInteger(string, 36).toByteArray().decodeToString()
|
|
||||||
|
|
||||||
// this goes into prefs and file names, so do not change!
|
|
||||||
const val CUSTOM_LAYOUT_PREFIX = "custom."
|
|
||||||
private const val TAG = "CustomLayoutUtils"
|
|
||||||
private var customLayouts: List<File>? = null
|
|
||||||
|
|
||||||
const val CUSTOM_FUNCTIONAL_LAYOUT_SYMBOLS_SHIFTED = "${CUSTOM_LAYOUT_PREFIX}functional_keys_symbols_shifted."
|
|
||||||
const val CUSTOM_FUNCTIONAL_LAYOUT_SYMBOLS = "${CUSTOM_LAYOUT_PREFIX}functional_keys_symbols."
|
|
||||||
const val CUSTOM_FUNCTIONAL_LAYOUT_NORMAL = "${CUSTOM_LAYOUT_PREFIX}functional_keys."
|
|
||||||
|
|
|
@ -266,8 +266,8 @@ public final class SubtypeLocaleUtils {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getKeyboardLayoutSetDisplayName(@NonNull final String layoutName) {
|
public static String getKeyboardLayoutSetDisplayName(@NonNull final String layoutName) {
|
||||||
if (LayoutUtilsCustomKt.isCustomLayout(layoutName))
|
if (LayoutUtilsCustom.INSTANCE.isCustomLayout(layoutName))
|
||||||
return LayoutUtilsCustomKt.getCustomLayoutDisplayName(layoutName);
|
return LayoutUtilsCustom.INSTANCE.getCustomLayoutDisplayName(layoutName);
|
||||||
return sKeyboardLayoutToDisplayNameMap.get(layoutName);
|
return sKeyboardLayoutToDisplayNameMap.get(layoutName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,14 +246,14 @@ private fun loadResourceSubtypes(resources: Resources) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove custom subtypes without a layout file
|
// remove custom subtypes without a layout file
|
||||||
private fun removeInvalidCustomSubtypes(context: Context) {
|
private fun removeInvalidCustomSubtypes(context: Context) { // todo: new layout structure!
|
||||||
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(LayoutType.MAIN, context).map { it.name } }
|
val customSubtypeFiles by lazy { LayoutUtilsCustom.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(":")
|
||||||
if (!name.startsWith(CUSTOM_LAYOUT_PREFIX)) return@forEach
|
if (!LayoutUtilsCustom.isCustomLayout(name)) return@forEach
|
||||||
if (name !in customSubtypeFiles)
|
if (name !in customSubtypeFiles)
|
||||||
subtypesToRemove.add(it)
|
subtypesToRemove.add(it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ fun InputMethodSubtype.mainLayoutName(): String? {
|
||||||
// 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.getKeyboardLayoutSetName(this)
|
||||||
if (layoutName.startsWith(CUSTOM_LAYOUT_PREFIX))
|
if (LayoutUtilsCustom.isCustomLayout(layoutName))
|
||||||
return "${LocaleUtils.getLocaleDisplayNameInSystemLocale(locale(), context)} (${getCustomLayoutDisplayName(layoutName)})"
|
return "${LocaleUtils.getLocaleDisplayNameInSystemLocale(locale(), context)} (${LayoutUtilsCustom.getCustomLayoutDisplayName(layoutName)})"
|
||||||
return SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(this)
|
return SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(this)
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,9 @@ import helium314.keyboard.keyboard.ColorSetting
|
||||||
import helium314.keyboard.keyboard.KeyboardTheme
|
import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.common.ColorType
|
import helium314.keyboard.latin.common.ColorType
|
||||||
|
import helium314.keyboard.latin.common.decodeBase36
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.decodeBase36
|
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
|
|
|
@ -20,14 +20,9 @@ import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.utils.LayoutType
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.checkLayout
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFile
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutDisplayName
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutName
|
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
import helium314.keyboard.latin.utils.isCustomLayout
|
|
||||||
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
|
||||||
import helium314.keyboard.settings.keyboardNeedsReload
|
import helium314.keyboard.settings.keyboardNeedsReload
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -47,17 +42,17 @@ fun LayoutEditDialog(
|
||||||
val ctx = LocalContext.current
|
val ctx = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var job: Job? = null
|
var job: Job? = null
|
||||||
val startIsCustom = isCustomLayout(initialLayoutName)
|
val startIsCustom = LayoutUtilsCustom.isCustomLayout(initialLayoutName)
|
||||||
var displayNameValue by rememberSaveable(stateSaver = TextFieldValue.Saver) {
|
var displayNameValue by rememberSaveable(stateSaver = TextFieldValue.Saver) {
|
||||||
mutableStateOf(TextFieldValue(
|
mutableStateOf(TextFieldValue(
|
||||||
if (startIsCustom) getCustomLayoutDisplayName(initialLayoutName)
|
if (startIsCustom) LayoutUtilsCustom.getCustomLayoutDisplayName(initialLayoutName)
|
||||||
else initialLayoutName.getStringResourceOrName("layout_", ctx)
|
else initialLayoutName.getStringResourceOrName("layout_", ctx)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
val nameValid = displayNameValue.text.isNotBlank()
|
val nameValid = displayNameValue.text.isNotBlank()
|
||||||
&& (
|
&& (
|
||||||
(startIsCustom && getCustomLayoutName(displayNameValue.text) == initialLayoutName)
|
(startIsCustom && LayoutUtilsCustom.getCustomLayoutName(displayNameValue.text) == initialLayoutName)
|
||||||
|| isNameValid(getCustomLayoutName(displayNameValue.text))
|
|| isNameValid(LayoutUtilsCustom.getCustomLayoutName(displayNameValue.text))
|
||||||
)
|
)
|
||||||
|
|
||||||
TextInputDialog(
|
TextInputDialog(
|
||||||
|
@ -66,15 +61,15 @@ fun LayoutEditDialog(
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
},
|
},
|
||||||
onConfirmed = {
|
onConfirmed = {
|
||||||
val newLayoutName = getCustomLayoutName(displayNameValue.text)
|
val newLayoutName = LayoutUtilsCustom.getCustomLayoutName(displayNameValue.text)
|
||||||
if (startIsCustom && initialLayoutName != newLayoutName)
|
if (startIsCustom && initialLayoutName != newLayoutName)
|
||||||
getCustomLayoutFile(initialLayoutName, layoutType, ctx).delete()
|
LayoutUtilsCustom.getCustomLayoutFile(initialLayoutName, layoutType, ctx).delete()
|
||||||
getCustomLayoutFile(newLayoutName, layoutType, ctx).writeText(it)
|
LayoutUtilsCustom.getCustomLayoutFile(newLayoutName, layoutType, ctx).writeText(it)
|
||||||
onCustomLayoutFileListChanged()
|
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
||||||
keyboardNeedsReload = true
|
keyboardNeedsReload = true
|
||||||
},
|
},
|
||||||
confirmButtonText = stringResource(R.string.save),
|
confirmButtonText = stringResource(R.string.save),
|
||||||
initialText = startContent ?: getCustomLayoutFile(initialLayoutName, layoutType, ctx).readText(),
|
initialText = startContent ?: LayoutUtilsCustom.getCustomLayoutFile(initialLayoutName, layoutType, ctx).readText(),
|
||||||
singleLine = false,
|
singleLine = false,
|
||||||
title = {
|
title = {
|
||||||
TextField(
|
TextField(
|
||||||
|
@ -87,13 +82,13 @@ fun LayoutEditDialog(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
checkTextValid = {
|
checkTextValid = {
|
||||||
val valid = checkLayout(it, ctx)
|
val valid = LayoutUtilsCustom.checkLayout(it, ctx)
|
||||||
job?.cancel()
|
job?.cancel()
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
job = scope.launch {
|
job = scope.launch {
|
||||||
delay(3000)
|
delay(3000)
|
||||||
val message = Log.getLog(10)
|
val message = Log.getLog(10)
|
||||||
.lastOrNull { it.tag == "CustomLayoutUtils" }?.message
|
.lastOrNull { it.tag == "LayoutUtilsCustom" }?.message
|
||||||
?.split("\n")?.take(2)?.joinToString("\n")
|
?.split("\n")?.take(2)?.joinToString("\n")
|
||||||
Toast.makeText(ctx, ctx.getString(R.string.layout_error, message), Toast.LENGTH_LONG).show()
|
Toast.makeText(ctx, ctx.getString(R.string.layout_error, message), Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,10 @@ import helium314.keyboard.latin.settings.Defaults.default
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.LayoutType
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
import helium314.keyboard.latin.utils.LayoutUtils
|
import helium314.keyboard.latin.utils.LayoutUtils
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.checkLayout
|
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutDisplayName
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutFiles
|
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutName
|
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.settings.Setting
|
import helium314.keyboard.settings.Setting
|
||||||
import helium314.keyboard.settings.SettingsActivity
|
import helium314.keyboard.settings.SettingsActivity
|
||||||
|
@ -72,7 +68,7 @@ fun LayoutPickerDialog(
|
||||||
val currentLayout = Settings.readDefaultLayoutName(layoutType, prefs)
|
val currentLayout = Settings.readDefaultLayoutName(layoutType, prefs)
|
||||||
val internalLayouts = LayoutUtils.getAvailableLayouts(layoutType, ctx)
|
val internalLayouts = LayoutUtils.getAvailableLayouts(layoutType, ctx)
|
||||||
// todo: getCustomLayoutFiles does not work nicely for main layout, but currently this dialog is not used for them
|
// todo: getCustomLayoutFiles does not work nicely for main layout, but currently this dialog is not used for them
|
||||||
val customLayouts = getCustomLayoutFiles(layoutType, ctx).map { it.name }.sorted()
|
val customLayouts = LayoutUtilsCustom.getCustomLayoutFiles(layoutType, ctx).map { it.name }.sorted()
|
||||||
val layouts = internalLayouts + customLayouts + ""
|
val layouts = internalLayouts + customLayouts + ""
|
||||||
|
|
||||||
val state = rememberLazyListState()
|
val state = rememberLazyListState()
|
||||||
|
@ -94,7 +90,7 @@ fun LayoutPickerDialog(
|
||||||
}
|
}
|
||||||
cr.openInputStream(uri)?.use {
|
cr.openInputStream(uri)?.use {
|
||||||
val content = it.reader().readText()
|
val content = it.reader().readText()
|
||||||
errorDialog = !checkLayout(content, ctx)
|
errorDialog = !LayoutUtilsCustom.checkLayout(content, ctx)
|
||||||
if (!errorDialog)
|
if (!errorDialog)
|
||||||
newLayoutDialog = (name ?: layoutType.default) to content
|
newLayoutDialog = (name ?: layoutType.default) to content
|
||||||
}
|
}
|
||||||
|
@ -129,8 +125,8 @@ fun LayoutPickerDialog(
|
||||||
prefs.edit().remove(Settings.PREF_LAYOUT_PREFIX + layoutType.name).apply()
|
prefs.edit().remove(Settings.PREF_LAYOUT_PREFIX + layoutType.name).apply()
|
||||||
keyboardNeedsReload = true
|
keyboardNeedsReload = true
|
||||||
}
|
}
|
||||||
getCustomLayoutFiles(layoutType, ctx).firstOrNull { it.name == deletedLayout }?.delete()
|
LayoutUtilsCustom.getCustomLayoutFiles(layoutType, ctx).firstOrNull { it.name == deletedLayout }?.delete()
|
||||||
onCustomLayoutFileListChanged()
|
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
||||||
},
|
},
|
||||||
layoutType = layoutType,
|
layoutType = layoutType,
|
||||||
layoutName = item,
|
layoutName = item,
|
||||||
|
@ -171,7 +167,7 @@ private fun AddLayoutRow(onNewLayout: (String) -> Unit, userLayouts: Collection<
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
IconButton(
|
IconButton(
|
||||||
enabled = textValue.text.isNotEmpty() && getCustomLayoutName(textValue.text) !in userLayouts,
|
enabled = textValue.text.isNotEmpty() && LayoutUtilsCustom.getCustomLayoutName(textValue.text) !in userLayouts,
|
||||||
onClick = { onNewLayout(textValue.text) }
|
onClick = { onNewLayout(textValue.text) }
|
||||||
) { Icon(painterResource(R.drawable.ic_edit), null) }
|
) { Icon(painterResource(R.drawable.ic_edit), null) }
|
||||||
}
|
}
|
||||||
|
@ -210,7 +206,7 @@ private fun LayoutItemRow(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = if (isCustom) getCustomLayoutDisplayName(layoutName)
|
text = if (isCustom) LayoutUtilsCustom.getCustomLayoutDisplayName(layoutName)
|
||||||
else layoutName.getStringResourceOrName("layout_", ctx),
|
else layoutName.getStringResourceOrName("layout_", ctx),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
@ -223,7 +219,7 @@ private fun LayoutItemRow(
|
||||||
if (showDeleteDialog)
|
if (showDeleteDialog)
|
||||||
ConfirmationDialog(
|
ConfirmationDialog(
|
||||||
onDismissRequest = { showDeleteDialog = false },
|
onDismissRequest = { showDeleteDialog = false },
|
||||||
text = { Text(stringResource(R.string.delete_layout, getCustomLayoutDisplayName(layoutName))) },
|
text = { Text(stringResource(R.string.delete_layout, LayoutUtilsCustom.getCustomLayoutDisplayName(layoutName))) },
|
||||||
confirmButtonText = stringResource(R.string.delete),
|
confirmButtonText = stringResource(R.string.delete),
|
||||||
onConfirmed = {
|
onConfirmed = {
|
||||||
showDeleteDialog = false
|
showDeleteDialog = false
|
||||||
|
|
|
@ -31,12 +31,11 @@ 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.AdditionalSubtypeUtils
|
||||||
import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX
|
|
||||||
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.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
|
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.latin.utils.protectedPrefs
|
import helium314.keyboard.latin.utils.protectedPrefs
|
||||||
import helium314.keyboard.latin.utils.reloadEnabledSubtypes
|
import helium314.keyboard.latin.utils.reloadEnabledSubtypes
|
||||||
|
@ -63,7 +62,7 @@ fun BackupRestorePreference(setting: Setting) {
|
||||||
var error: String? by rememberSaveable { mutableStateOf(null) }
|
var error: String? by rememberSaveable { mutableStateOf(null) }
|
||||||
val backupFilePatterns by lazy { listOf(
|
val backupFilePatterns by lazy { listOf(
|
||||||
"blacklists/.*\\.txt".toRegex(),
|
"blacklists/.*\\.txt".toRegex(),
|
||||||
"layouts/$CUSTOM_LAYOUT_PREFIX+\\..{0,4}".toRegex(), // can't expect a period at the end, as this would break restoring older backups
|
"layouts/${LayoutUtilsCustom.CUSTOM_LAYOUT_PREFIX}+\\..{0,4}".toRegex(), // can't expect a period at the end, as this would break restoring older backups
|
||||||
"dicts/.*/.*user\\.dict".toRegex(),
|
"dicts/.*/.*user\\.dict".toRegex(),
|
||||||
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
||||||
"custom_background_image.*".toRegex(),
|
"custom_background_image.*".toRegex(),
|
||||||
|
@ -181,7 +180,7 @@ fun BackupRestorePreference(setting: Setting) {
|
||||||
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)
|
||||||
onCustomLayoutFileListChanged()
|
LayoutUtilsCustom.onCustomLayoutFileListChanged()
|
||||||
(ctx.getActivity() as? SettingsActivity)?.prefChanged?.value = 210 // for settings reload
|
(ctx.getActivity() as? SettingsActivity)?.prefChanged?.value = 210 // for settings reload
|
||||||
keyboardNeedsReload = true
|
keyboardNeedsReload = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
package helium314.keyboard.settings.preferences
|
package helium314.keyboard.settings.preferences
|
||||||
|
/*
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
@ -14,7 +14,7 @@ import helium314.keyboard.settings.Setting
|
||||||
import helium314.keyboard.settings.dialogs.LayoutEditDialog
|
import helium314.keyboard.settings.dialogs.LayoutEditDialog
|
||||||
import helium314.keyboard.settings.dialogs.ListPickerDialog
|
import helium314.keyboard.settings.dialogs.ListPickerDialog
|
||||||
import java.io.File
|
import java.io.File
|
||||||
/*
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LayoutEditPreference(
|
fun LayoutEditPreference(
|
||||||
setting: Setting,
|
setting: Setting,
|
||||||
|
|
|
@ -51,13 +51,13 @@ import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.common.ColorType
|
import helium314.keyboard.latin.common.ColorType
|
||||||
import helium314.keyboard.latin.common.default
|
import helium314.keyboard.latin.common.default
|
||||||
|
import helium314.keyboard.latin.common.encodeBase36
|
||||||
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.colorPrefsAndResIds
|
import helium314.keyboard.latin.settings.colorPrefsAndResIds
|
||||||
import helium314.keyboard.latin.settings.getColorPrefsToHideInitially
|
import helium314.keyboard.latin.settings.getColorPrefsToHideInitially
|
||||||
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.encodeBase36
|
|
||||||
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.settings.SearchScreen
|
import helium314.keyboard.settings.SearchScreen
|
||||||
|
|
|
@ -13,11 +13,10 @@ import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.LayoutType
|
import helium314.keyboard.latin.utils.LayoutType
|
||||||
import helium314.keyboard.latin.utils.LayoutType.Companion.displayNameId
|
import helium314.keyboard.latin.utils.LayoutType.Companion.displayNameId
|
||||||
|
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.getCustomLayoutDisplayName
|
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
import helium314.keyboard.latin.utils.isCustomLayout
|
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.settings.SearchSettingsScreen
|
import helium314.keyboard.settings.SearchSettingsScreen
|
||||||
import helium314.keyboard.settings.Setting
|
import helium314.keyboard.settings.Setting
|
||||||
|
@ -51,7 +50,7 @@ fun createLayoutSettings(context: Context) = listOf(
|
||||||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
val currentLayout = Settings.readDefaultLayoutName(layoutType, prefs)
|
val currentLayout = Settings.readDefaultLayoutName(layoutType, prefs)
|
||||||
val displayName = if (isCustomLayout(currentLayout)) getCustomLayoutDisplayName(currentLayout)
|
val displayName = if (LayoutUtilsCustom.isCustomLayout(currentLayout)) LayoutUtilsCustom.getCustomLayoutDisplayName(currentLayout)
|
||||||
else currentLayout.getStringResourceOrName("layout_", ctx)
|
else currentLayout.getStringResourceOrName("layout_", ctx)
|
||||||
Preference(
|
Preference(
|
||||||
name = setting.title,
|
name = setting.title,
|
||||||
|
|
|
@ -20,8 +20,8 @@ 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.AdditionalSubtypeUtils.createEmojiCapableAdditionalSubtype
|
||||||
|
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.checkKeys
|
|
||||||
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
|
||||||
|
@ -484,7 +484,7 @@ f""", // no newline at the end
|
||||||
// todo (later): what's wrong with popup order?
|
// todo (later): what's wrong with popup order?
|
||||||
assertEquals(expected[index].popups?.sortedBy { it.first }, keyParams.mPopupKeys?.mapNotNull { it.mLabel to it.mCode }?.sortedBy { it.first })
|
assertEquals(expected[index].popups?.sortedBy { it.first }, keyParams.mPopupKeys?.mapNotNull { it.mLabel to it.mCode }?.sortedBy { it.first })
|
||||||
assertEquals(expected[index].text, keyParams.outputText)
|
assertEquals(expected[index].text, keyParams.outputText)
|
||||||
assertTrue(checkKeys(listOf(listOf(keyParams))))
|
assertTrue(LayoutUtilsCustom.checkKeys(listOf(listOf(keyParams))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue