mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-17 07:22:45 +00:00
don't use json/txt file endings for custom layouts
just determine json or simple when parsing fixes #1034
This commit is contained in:
parent
a1a7489856
commit
44eb296d38
4 changed files with 75 additions and 50 deletions
|
@ -52,8 +52,10 @@ fun loadCustomLayout(uri: Uri?, languageTag: String, context: Context, onAdded:
|
|||
|
||||
fun loadCustomLayout(layoutContent: String, layoutName: String, languageTag: String, context: Context, onAdded: (String) -> Unit) {
|
||||
var name = layoutName
|
||||
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}"))
|
||||
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)
|
||||
// ?: return infoDialog(context, context.getString(R.string.layout_error, "invalid layout file, ${Log.getLog(10).lastOrNull { it.tag == TAG }?.message}"))
|
||||
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(R.string.title_layout_name_select)
|
||||
|
@ -66,7 +68,7 @@ fun loadCustomLayout(layoutContent: String, layoutName: String, languageTag: Str
|
|||
})
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
// name must be encoded to avoid issues with validity of subtype extra string or file name
|
||||
name = "$CUSTOM_LAYOUT_PREFIX${languageTag}.${encodeBase36(name)}.${if (isJson) "json" else "txt"}"
|
||||
name = "$CUSTOM_LAYOUT_PREFIX${languageTag}.${encodeBase36(name)}."
|
||||
val file = getCustomLayoutFile(name, context)
|
||||
if (file.exists())
|
||||
file.delete()
|
||||
|
@ -77,28 +79,23 @@ fun loadCustomLayout(layoutContent: String, layoutName: String, languageTag: Str
|
|||
.show()
|
||||
}
|
||||
|
||||
/** @return true if json, false if simple, null if invalid */
|
||||
private fun checkLayout(layoutContent: String, context: Context): Boolean? {
|
||||
private 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 = RawKeyboardParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||
if (!checkKeys(keys))
|
||||
return null
|
||||
return true
|
||||
return checkKeys(keys)
|
||||
} catch (e: SerializationException) {
|
||||
Log.w(TAG, "json parsing error", e)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "json layout parsed, but considered invalid", e)
|
||||
return null
|
||||
return false
|
||||
}
|
||||
try {
|
||||
val keys = RawKeyboardParser.parseSimpleString(layoutContent).map { row -> row.map { it.toKeyParams(params) } }
|
||||
if (!checkKeys(keys))
|
||||
return null
|
||||
return false
|
||||
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
|
||||
|
@ -106,7 +103,7 @@ private fun checkLayout(layoutContent: String, context: Context): Boolean? {
|
|||
RawKeyboardParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }
|
||||
} catch (e: Exception) { Log.w(TAG, "json parsing error", e) }
|
||||
}
|
||||
return null
|
||||
return false
|
||||
}
|
||||
|
||||
fun checkKeys(keys: List<List<Key.KeyParams>>): Boolean {
|
||||
|
@ -190,27 +187,12 @@ fun editCustomLayout(layoutName: String, context: Context, startContent: String?
|
|||
.setView(editText)
|
||||
.setPositiveButton(R.string.save) { _, _ ->
|
||||
val content = editText.text.toString()
|
||||
val isJson = checkLayout(content, context)
|
||||
if (isJson == null) {
|
||||
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 {
|
||||
val wasJson = file.name.substringAfterLast(".") == "json"
|
||||
file.parentFile?.mkdir()
|
||||
file.writeText(content)
|
||||
if (isJson != wasJson) {
|
||||
// unlikely to be needed
|
||||
// actually does not work properly (need to restart the app)
|
||||
// todo: can we just remove the json and txt endings and determine type using trc/catch?
|
||||
// now we cache the layouts, so a bit slower reading should be fine
|
||||
val newEnding = if (isJson) ".json" else ".txt"
|
||||
file.renameTo(File(file.absolutePath.substringBeforeLast(".") + newEnding))
|
||||
val newLayoutName = layoutName.substringBeforeLast(".") + newEnding
|
||||
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
|
||||
val subtypesString = Settings.readPrefAdditionalSubtypes(prefs, context.resources)
|
||||
val newSubtypesString = subtypesString.replace(layoutName, newLayoutName)
|
||||
Settings.writePrefAdditionalSubtypes(prefs, newSubtypesString)
|
||||
}
|
||||
onCustomLayoutFileListChanged()
|
||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue