6.7.0 - Alpha19 - 降低代码编辑器保存失败率; 优化代码编辑器保存按钮状态逻辑
This commit is contained in:
@@ -145,6 +145,8 @@
|
|||||||
"代码编辑器保存文件失败时自动存为草稿并支持另存为新文件",
|
"代码编辑器保存文件失败时自动存为草稿并支持另存为新文件",
|
||||||
"代码编辑器加载大文件时提升一定程度的流畅度",
|
"代码编辑器加载大文件时提升一定程度的流畅度",
|
||||||
"代码编辑器 \"查找/替换\" 支持状态持久化及实时显示搜索计数信息",
|
"代码编辑器 \"查找/替换\" 支持状态持久化及实时显示搜索计数信息",
|
||||||
|
"代码编辑器提示保存时确保保存成功后再退出编辑器以降低保存失败率",
|
||||||
|
"代码编辑器保存按钮的状态更符合用户主观逻辑",
|
||||||
"打包应用页面默认勾选必要权限 (WAKE_LOCK/INTERNET/WRITE_EXTERNAL_STORAGE) _[`issue #397`](http://issues.autojs6.com/397)_",
|
"打包应用页面默认勾选必要权限 (WAKE_LOCK/INTERNET/WRITE_EXTERNAL_STORAGE) _[`issue #397`](http://issues.autojs6.com/397)_",
|
||||||
"打包应用设置页面增加前台服务开关 _[`issue #406`](http://issues.autojs6.com/406)_",
|
"打包应用设置页面增加前台服务开关 _[`issue #406`](http://issues.autojs6.com/406)_",
|
||||||
"脚本项目配置文件保存时增加键名冲突检测机制防止键名歧义",
|
"脚本项目配置文件保存时增加键名冲突检测机制防止键名歧义",
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ import android.text.TextPaint
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.ActionMode
|
import android.view.ActionMode
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.core.view.get
|
import androidx.core.view.get
|
||||||
import androidx.core.view.size
|
import androidx.core.view.size
|
||||||
|
import com.afollestad.materialdialogs.DialogAction
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
@@ -32,6 +34,7 @@ import org.autojs.autojs.pio.PFiles
|
|||||||
import org.autojs.autojs.storage.file.TmpScriptFiles
|
import org.autojs.autojs.storage.file.TmpScriptFiles
|
||||||
import org.autojs.autojs.theme.widget.ThemeColorToolbar
|
import org.autojs.autojs.theme.widget.ThemeColorToolbar
|
||||||
import org.autojs.autojs.ui.BaseActivity
|
import org.autojs.autojs.ui.BaseActivity
|
||||||
|
import org.autojs.autojs.ui.error.ErrorDialogActivity
|
||||||
import org.autojs.autojs.ui.main.MainActivity
|
import org.autojs.autojs.ui.main.MainActivity
|
||||||
import org.autojs.autojs.ui.main.scripts.EditableFileInfoDialogManager
|
import org.autojs.autojs.ui.main.scripts.EditableFileInfoDialogManager
|
||||||
import org.autojs.autojs.util.DialogUtils
|
import org.autojs.autojs.util.DialogUtils
|
||||||
@@ -48,8 +51,8 @@ import java.io.IOException
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Jan 29, 2017.
|
* Created by Stardust on Jan 29, 2017.
|
||||||
* Modified by SuperMonster003 as of Jan 21, 2023.
|
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 12, 2026.
|
||||||
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 8, 2026.
|
* Modified by SuperMonster003 as of Feb 12, 2026.
|
||||||
*/
|
*/
|
||||||
open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyActivity {
|
open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyActivity {
|
||||||
|
|
||||||
@@ -290,7 +293,7 @@ open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun finish() {
|
override fun finish() {
|
||||||
if (mEditorView.isTextChanged) {
|
if (mEditorView.saveStickyDirty) {
|
||||||
showExitConfirmDialog()
|
showExitConfirmDialog()
|
||||||
} else {
|
} else {
|
||||||
finishAndRemoveFromRecents()
|
finishAndRemoveFromRecents()
|
||||||
@@ -305,6 +308,7 @@ open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyAc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
private fun showExitConfirmDialog() {
|
private fun showExitConfirmDialog() {
|
||||||
DialogUtils.buildAndShowAdaptive {
|
DialogUtils.buildAndShowAdaptive {
|
||||||
MaterialDialog.Builder(this)
|
MaterialDialog.Builder(this)
|
||||||
@@ -312,17 +316,60 @@ open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyAc
|
|||||||
.content(R.string.edit_exit_without_save_warn)
|
.content(R.string.edit_exit_without_save_warn)
|
||||||
.neutralText(R.string.dialog_button_back)
|
.neutralText(R.string.dialog_button_back)
|
||||||
.negativeText(R.string.text_exit_directly)
|
.negativeText(R.string.text_exit_directly)
|
||||||
|
.onNeutral { d, _ -> d.dismiss() }
|
||||||
.negativeColorRes(R.color.dialog_button_caution)
|
.negativeColorRes(R.color.dialog_button_caution)
|
||||||
.onNegative { _, _ ->
|
.onNegative { d, _ ->
|
||||||
|
runCatching { d.dismiss() }
|
||||||
finishAndRemoveFromRecents()
|
finishAndRemoveFromRecents()
|
||||||
}
|
}
|
||||||
.positiveText(R.string.text_save_and_exit)
|
.positiveText(R.string.text_save_and_exit)
|
||||||
.positiveColorRes(R.color.dialog_button_warn)
|
.positiveColorRes(R.color.dialog_button_warn)
|
||||||
.onPositive { _, _ ->
|
.onPositive { d, _ ->
|
||||||
mEditorView.saveFile()
|
// Save is async, exit only after success.
|
||||||
finishAndRemoveFromRecents()
|
// zh-CN: 保存是异步的, 保存成功后再退出.
|
||||||
|
d.apply {
|
||||||
|
setCancelable(false)
|
||||||
|
getActionButton(DialogAction.NEUTRAL).apply {
|
||||||
|
isEnabled = false
|
||||||
|
setTextColor(getColor(R.color.dialog_button_unavailable))
|
||||||
|
}
|
||||||
|
getActionButton(DialogAction.NEGATIVE).apply {
|
||||||
|
isEnabled = false
|
||||||
|
setTextColor(getColor(R.color.dialog_button_unavailable))
|
||||||
|
}
|
||||||
|
getActionButton(DialogAction.POSITIVE).apply {
|
||||||
|
isEnabled = false
|
||||||
|
setTextColor(getColor(R.color.dialog_button_unavailable))
|
||||||
|
}
|
||||||
|
contentView?.postDelayed({
|
||||||
|
contentView?.text = getString(R.string.text_saving)
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
mEditorView
|
||||||
|
.save()
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({
|
||||||
|
runCatching { d.dismiss() }
|
||||||
|
finishAndRemoveFromRecents()
|
||||||
|
}, { e: Throwable ->
|
||||||
|
// Save failed, keep editor open.
|
||||||
|
// zh-CN: 保存失败, 保持编辑器不退出.
|
||||||
|
e.printStackTrace()
|
||||||
|
runCatching { d.dismiss() }
|
||||||
|
ErrorDialogActivity.showErrorDialog(this@EditActivity, R.string.error_failed_to_save, e.message)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
.autoDismiss(false)
|
||||||
.build()
|
.build()
|
||||||
|
.apply {
|
||||||
|
contentView?.apply {
|
||||||
|
setLineSpacing(0f, 1.2f)
|
||||||
|
setLines(2)
|
||||||
|
minLines = 2
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ import java.util.regex.Pattern
|
|||||||
* Created by Stardust on Sep 28, 2017.
|
* Created by Stardust on Sep 28, 2017.
|
||||||
* Transformed by SuperMonster003 on May 1, 2023.
|
* Transformed by SuperMonster003 on May 1, 2023.
|
||||||
* Modified by SuperMonster003 as of Feb 3, 2026.
|
* Modified by SuperMonster003 as of Feb 3, 2026.
|
||||||
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 8, 2026.
|
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 12, 2026.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFragment.OnMenuItemClickListener {
|
class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFragment.OnMenuItemClickListener {
|
||||||
@@ -135,6 +135,46 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
|
|
||||||
private var _name: String? = null
|
private var _name: String? = null
|
||||||
|
|
||||||
|
// Sticky save dirty flag.
|
||||||
|
// Behavior:
|
||||||
|
// - Set to true on ANY text change (including undo/redo).
|
||||||
|
// - Reset to false only after successful save or when a new baseline text is loaded.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 保存按钮的 sticky 脏标记.
|
||||||
|
// 行为:
|
||||||
|
// - 任意文本变化 (包括 undo/redo) 都会置为 true.
|
||||||
|
// - 仅在保存成功或加载新基线文本时重置为 false.
|
||||||
|
@Volatile
|
||||||
|
var saveStickyDirty: Boolean = false
|
||||||
|
|
||||||
|
// Whether we have had any direct edits since last save/baseline.
|
||||||
|
// Direct edits mean changes NOT caused by undo/redo buttons.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 自上次保存/建立基线以来是否发生过任何直接编辑.
|
||||||
|
// 直接编辑指不是由撤销/重做按钮触发的文本变化.
|
||||||
|
@Volatile
|
||||||
|
private var mHadDirectEditSinceSave: Boolean = false
|
||||||
|
|
||||||
|
// Guard flag to mark text changes caused by undo/redo button actions.
|
||||||
|
// This is used to distinguish direct edits from history navigation.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 用于标记由撤销/重做按钮动作导致的文本变化的哨兵标记.
|
||||||
|
// 用于区分直接编辑与历史导航.
|
||||||
|
@Volatile
|
||||||
|
private var mUndoRedoButtonInProgress: Boolean = false
|
||||||
|
|
||||||
|
// Whether user has touched/moved caret during large file loading.
|
||||||
|
// If true, we should NOT force caret to 0 on load completion.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 用户是否在大文件加载期间触摸过/移动过光标.
|
||||||
|
// 若为 true, 则加载完成时不要强制把光标设为 0.
|
||||||
|
@Volatile
|
||||||
|
private var mUserMovedCursorDuringLoading: Boolean = false
|
||||||
|
|
||||||
var name: String
|
var name: String
|
||||||
get() = _name ?: "[ ${this.context.getString(text_unknown)} ]"
|
get() = _name ?: "[ ${this.context.getString(text_unknown)} ]"
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -232,7 +272,7 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
|
|
||||||
// Delay showing loading bar to avoid flicker.
|
// Delay showing loading bar to avoid flicker.
|
||||||
// zh-CN: 延迟显示加载提示条, 避免闪烁.
|
// zh-CN: 延迟显示加载提示条, 避免闪烁.
|
||||||
private val mLoadingBarShowDelayMs = 1500L
|
private val mLoadingBarShowDelayMs = 300L
|
||||||
|
|
||||||
// Once shown, keep it visible for at least this duration.
|
// Once shown, keep it visible for at least this duration.
|
||||||
// zh-CN: 一旦显示, 则保证最短展示时间.
|
// zh-CN: 一旦显示, 则保证最短展示时间.
|
||||||
@@ -333,6 +373,8 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
// Initialize menu state early to avoid "first render" flicker.
|
// Initialize menu state early to avoid "first render" flicker.
|
||||||
// zh-CN: 尽早初始化菜单状态, 避免首次渲染闪烁.
|
// zh-CN: 尽早初始化菜单状态, 避免首次渲染闪烁.
|
||||||
mEditorLoading = true
|
mEditorLoading = true
|
||||||
|
saveStickyDirty = false
|
||||||
|
mHadDirectEditSinceSave = false
|
||||||
syncPrimaryMenuState()
|
syncPrimaryMenuState()
|
||||||
|
|
||||||
val name = intent.getStringExtra(EXTRA_NAME)
|
val name = intent.getStringExtra(EXTRA_NAME)
|
||||||
@@ -851,12 +893,14 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
|
|
||||||
mLargeFileMode = true
|
mLargeFileMode = true
|
||||||
mEditorLoading = true
|
mEditorLoading = true
|
||||||
|
mUserMovedCursorDuringLoading = false
|
||||||
syncPrimaryMenuState()
|
syncPrimaryMenuState()
|
||||||
|
|
||||||
editText.setLoadingText(true)
|
editText.setLoadingText(true)
|
||||||
editor.setRedoUndoEnabled(false)
|
editor.setRedoUndoEnabled(false)
|
||||||
editText.setLoadingGutterDigits(7)
|
editText.setLoadingGutterDigits(3)
|
||||||
editText.setText("")
|
editText.setText("")
|
||||||
|
editText.setSelection(0)
|
||||||
|
|
||||||
val choreographer = Choreographer.getInstance()
|
val choreographer = Choreographer.getInstance()
|
||||||
|
|
||||||
@@ -901,8 +945,19 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
endEditorLoadingUi()
|
endEditorLoadingUi()
|
||||||
|
|
||||||
// Ensure caret/focus after loading is done.
|
// Ensure caret/focus after loading is done.
|
||||||
// zh-CN: 加载结束后确保光标/焦点.
|
// - Default: caret at 0 for "read from top".
|
||||||
post { ensureEditorHasCursorAfterLoadIfNeeded() }
|
// - If user touched during loading: keep current caret (do not force to 0).
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 加载结束后确保光标/焦点.
|
||||||
|
// - 默认: 光标置于 0, 方便从头阅读.
|
||||||
|
// - 若用户在加载期间触摸过: 保持当前光标, 不强制跳回 0.
|
||||||
|
post {
|
||||||
|
if (!mUserMovedCursorDuringLoading) {
|
||||||
|
runCatching { editText.setSelection(0) }
|
||||||
|
}
|
||||||
|
ensureEditorHasCursorAfterLoadIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
mLargeFileFrameCallback = null
|
mLargeFileFrameCallback = null
|
||||||
return
|
return
|
||||||
@@ -996,6 +1051,12 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
editor.markUndoRedoBaselineAsUnchanged()
|
editor.markUndoRedoBaselineAsUnchanged()
|
||||||
editor.setRedoUndoEnabled(!mLargeFileMode)
|
editor.setRedoUndoEnabled(!mLargeFileMode)
|
||||||
|
|
||||||
|
// Reset sticky dirty because we just established a new baseline.
|
||||||
|
// zh-CN: 因刚刚建立了新的基线, 重置 sticky 脏标记.
|
||||||
|
saveStickyDirty = false
|
||||||
|
mHadDirectEditSinceSave = false
|
||||||
|
syncPrimaryMenuState()
|
||||||
|
|
||||||
// Refresh highlight for restored text if size allows.
|
// Refresh highlight for restored text if size allows.
|
||||||
// zh-CN: 若大小允许, 则对恢复文本刷新一次高亮.
|
// zh-CN: 若大小允许, 则对恢复文本刷新一次高亮.
|
||||||
post { editor.refreshHighlightTokensIfAllowed() }
|
post { editor.refreshHighlightTokensIfAllowed() }
|
||||||
@@ -1016,11 +1077,19 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
try {
|
try {
|
||||||
editText.setText(text)
|
editText.setText(text)
|
||||||
editor.markUndoRedoBaselineAsUnchanged()
|
editor.markUndoRedoBaselineAsUnchanged()
|
||||||
|
|
||||||
|
// Reset sticky dirty because we just established a new baseline.
|
||||||
|
// zh-CN: 因刚刚建立了新的基线, 重置 sticky 脏标记.
|
||||||
|
saveStickyDirty = false
|
||||||
|
mHadDirectEditSinceSave = false
|
||||||
} finally {
|
} finally {
|
||||||
editor.setRedoUndoEnabled(true)
|
editor.setRedoUndoEnabled(true)
|
||||||
editText.setLoadingText(false)
|
editText.setLoadingText(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEditorLoading = false
|
||||||
|
syncPrimaryMenuState()
|
||||||
|
|
||||||
// Ensure caret/focus after fast load.
|
// Ensure caret/focus after fast load.
|
||||||
// zh-CN: 快速加载完成后确保光标/焦点.
|
// zh-CN: 快速加载完成后确保光标/焦点.
|
||||||
post { ensureEditorHasCursorAfterLoadIfNeeded() }
|
post { ensureEditorHasCursorAfterLoadIfNeeded() }
|
||||||
@@ -1048,7 +1117,7 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
setMenuItemStatus(R.id.run, true)
|
setMenuItemStatus(R.id.run, true)
|
||||||
setMenuItemStatus(R.id.undo, false)
|
setMenuItemStatus(R.id.undo, false)
|
||||||
setMenuItemStatus(R.id.redo, false)
|
setMenuItemStatus(R.id.redo, false)
|
||||||
setMenuItemStatus(R.id.save, editor.isTextChanged)
|
setMenuItemStatus(R.id.save, saveStickyDirty)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// Normal mode.
|
// Normal mode.
|
||||||
@@ -1056,7 +1125,7 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
setMenuItemStatus(R.id.run, true)
|
setMenuItemStatus(R.id.run, true)
|
||||||
setMenuItemStatus(R.id.undo, editor.canUndo())
|
setMenuItemStatus(R.id.undo, editor.canUndo())
|
||||||
setMenuItemStatus(R.id.redo, editor.canRedo())
|
setMenuItemStatus(R.id.redo, editor.canRedo())
|
||||||
setMenuItemStatus(R.id.save, editor.isTextChanged)
|
setMenuItemStatus(R.id.save, saveStickyDirty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1224,12 +1293,40 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
private fun setUpEditor() {
|
private fun setUpEditor() {
|
||||||
editor.let { editor ->
|
editor.let { editor ->
|
||||||
editor.codeEditText.let { editText ->
|
editor.codeEditText.let { editText ->
|
||||||
|
// Observe user touch in text area to preserve caret position after large-file load.
|
||||||
|
// zh-CN: 监听用户在文本区域的触摸, 以便大文件加载完成后保留光标位置.
|
||||||
|
editText.onUserTouchInTextArea = {
|
||||||
|
if (mEditorLoading && mLargeFileMode) {
|
||||||
|
mUserMovedCursorDuringLoading = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
editText.addTextChangedListener(SimpleTextWatcher { _ ->
|
editText.addTextChangedListener(SimpleTextWatcher { _ ->
|
||||||
// Skip menu state updates during progressive loading.
|
// Skip menu state updates during progressive loading.
|
||||||
// zh-CN: 渐进式加载期间跳过菜单状态更新.
|
// zh-CN: 渐进式加载期间跳过菜单状态更新.
|
||||||
if (editText.isLoadingText() || mEditorLoading) {
|
if (editText.isLoadingText() || mEditorLoading) {
|
||||||
return@SimpleTextWatcher
|
return@SimpleTextWatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this change is not caused by undo/redo buttons, treat it as a direct edit.
|
||||||
|
// Direct edits keep Save sticky until next successful save.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 若本次变化并非由撤销/重做按钮触发, 则视为直接编辑.
|
||||||
|
// 直接编辑会使保存按钮保持 sticky, 直到下一次保存成功.
|
||||||
|
if (!mUndoRedoButtonInProgress) {
|
||||||
|
mHadDirectEditSinceSave = true
|
||||||
|
saveStickyDirty = true
|
||||||
|
} else {
|
||||||
|
// Undo/redo navigation:
|
||||||
|
// Save should reflect (baseline changed) OR (there has been any direct edit since save).
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// undo/redo 历史导航:
|
||||||
|
// 保存按钮应反映 (相对基线有变化) 或 (自保存以来发生过直接编辑).
|
||||||
|
saveStickyDirty = editor.isTextChanged || mHadDirectEditSinceSave
|
||||||
|
}
|
||||||
|
|
||||||
syncPrimaryMenuState()
|
syncPrimaryMenuState()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1268,6 +1365,8 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
// zh-CN: 初始化为 "新建文件" 预期状态: 仅运行可用.
|
// zh-CN: 初始化为 "新建文件" 预期状态: 仅运行可用.
|
||||||
mEditorLoading = false
|
mEditorLoading = false
|
||||||
mLargeFileMode = false
|
mLargeFileMode = false
|
||||||
|
saveStickyDirty = false
|
||||||
|
mHadDirectEditSinceSave = false
|
||||||
setMenuItemStatus(R.id.run, true)
|
setMenuItemStatus(R.id.run, true)
|
||||||
setMenuItemStatus(R.id.undo, false)
|
setMenuItemStatus(R.id.undo, false)
|
||||||
setMenuItemStatus(R.id.redo, false)
|
setMenuItemStatus(R.id.redo, false)
|
||||||
@@ -1287,7 +1386,9 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
val imeBarBackgroundColor = it.imeBarBackgroundColor
|
val imeBarBackgroundColor = it.imeBarBackgroundColor
|
||||||
|
|
||||||
editor.setTheme(it)
|
editor.setTheme(it)
|
||||||
|
|
||||||
mInputMethodEnhanceBar.setBackgroundColor(imeBarBackgroundColor)
|
mInputMethodEnhanceBar.setBackgroundColor(imeBarBackgroundColor)
|
||||||
|
mLoadingBarContainer.setBackgroundColor(imeBarBackgroundColor)
|
||||||
|
|
||||||
run {
|
run {
|
||||||
val adjustedImageContrastColor = ColorUtils.adjustColorForContrast(imeBarBackgroundColor, appThemeColor, 3.6)
|
val adjustedImageContrastColor = ColorUtils.adjustColorForContrast(imeBarBackgroundColor, appThemeColor, 3.6)
|
||||||
@@ -1390,9 +1491,43 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
return run(true, file, uri?.path)
|
return run(true, file, uri?.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun undo() = editor.undo()
|
private fun undo() {
|
||||||
|
// Mark undo/redo button action so TextWatcher can distinguish it.
|
||||||
|
// zh-CN: 标记撤销/重做按钮动作, 以便 TextWatcher 区分来源.
|
||||||
|
mUndoRedoButtonInProgress = true
|
||||||
|
try {
|
||||||
|
editor.undo()
|
||||||
|
} finally {
|
||||||
|
mUndoRedoButtonInProgress = false
|
||||||
|
}
|
||||||
|
|
||||||
private fun redo() = editor.redo()
|
// Recompute Save state after history navigation.
|
||||||
|
// zh-CN: 历史导航后重新计算保存按钮状态.
|
||||||
|
saveStickyDirty = editor.isTextChanged || mHadDirectEditSinceSave
|
||||||
|
syncPrimaryMenuState()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun redo() {
|
||||||
|
// Mark undo/redo button action so TextWatcher can distinguish it.
|
||||||
|
// zh-CN: 标记撤销/重做按钮动作, 以便 TextWatcher 区分来源.
|
||||||
|
mUndoRedoButtonInProgress = true
|
||||||
|
try {
|
||||||
|
editor.redo()
|
||||||
|
} finally {
|
||||||
|
mUndoRedoButtonInProgress = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recompute Save state after history navigation.
|
||||||
|
// This makes "edit -> save -> undo -> redo" turn Save off again,
|
||||||
|
// because we are back to baseline and there was no direct edit since save.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 历史导航后重新计算保存按钮状态.
|
||||||
|
// 这会使 "编辑 -> 保存 -> 撤销 -> 重做" 再次熄灭保存按钮,
|
||||||
|
// 因为已回到基线, 且保存后没有发生直接编辑.
|
||||||
|
saveStickyDirty = editor.isTextChanged || mHadDirectEditSinceSave
|
||||||
|
syncPrimaryMenuState()
|
||||||
|
}
|
||||||
|
|
||||||
fun save(): Observable<String> =
|
fun save(): Observable<String> =
|
||||||
Observable
|
Observable
|
||||||
@@ -1414,6 +1549,12 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnNext {
|
.doOnNext {
|
||||||
editor.markTextAsSaved()
|
editor.markTextAsSaved()
|
||||||
|
|
||||||
|
// Reset sticky dirty only on successful save.
|
||||||
|
// zh-CN: 仅在保存成功后重置 sticky 脏标记.
|
||||||
|
saveStickyDirty = false
|
||||||
|
mHadDirectEditSinceSave = false
|
||||||
|
|
||||||
setMenuItemStatus(R.id.save, false)
|
setMenuItemStatus(R.id.save, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1695,9 +1836,13 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
uri = uri,
|
uri = uri,
|
||||||
onRestoreToEditor = { restoredText ->
|
onRestoreToEditor = { restoredText ->
|
||||||
editor.text = restoredText
|
editor.text = restoredText
|
||||||
|
|
||||||
|
// Restoring changes content => mark sticky dirty.
|
||||||
|
// zh-CN: 恢复版本会改变内容, 因此置 sticky 脏标记.
|
||||||
|
saveStickyDirty = true
|
||||||
},
|
},
|
||||||
onRestoredUi = {
|
onRestoredUi = {
|
||||||
setMenuItemStatus(R.id.save, true)
|
syncPrimaryMenuState()
|
||||||
showSnack(this@EditorView, R.string.text_done)
|
showSnack(this@EditorView, R.string.text_done)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -83,6 +83,15 @@ class CodeEditText : AppCompatEditText {
|
|||||||
private var mDebuggingLine = -1
|
private var mDebuggingLine = -1
|
||||||
private var mCursorChangeCallbacks: CopyOnWriteArrayList<CursorChangeCallback>? = null
|
private var mCursorChangeCallbacks: CopyOnWriteArrayList<CursorChangeCallback>? = null
|
||||||
|
|
||||||
|
// Callback when user touches the editor text area (not gutter).
|
||||||
|
// This is used by large-file loader to avoid forcing caret to 0 after user interaction.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 当用户触摸编辑器文本区域 (非行号区域) 时的回调.
|
||||||
|
// 用于大文件加载逻辑: 若用户已交互, 则避免加载完成后强制将光标跳到 0.
|
||||||
|
@Volatile
|
||||||
|
var onUserTouchInTextArea: (() -> Unit)? = null
|
||||||
|
|
||||||
// Read-only state.
|
// Read-only state.
|
||||||
// zh-CN: 只读状态.
|
// zh-CN: 只读状态.
|
||||||
private var mReadOnly = false
|
private var mReadOnly = false
|
||||||
@@ -649,6 +658,12 @@ class CodeEditText : AppCompatEditText {
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
|
// Notify outer layer early when user touches inside text area (not gutter).
|
||||||
|
// zh-CN: 当用户触摸文本区域 (非行号区域) 时尽早通知外层.
|
||||||
|
if (event.action == MotionEvent.ACTION_DOWN && event.x >= paddingLeft) {
|
||||||
|
onUserTouchInTextArea?.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
// 如果行号区域被按下
|
// 如果行号区域被按下
|
||||||
if (event.action == MotionEvent.ACTION_DOWN && event.x < paddingLeft) {
|
if (event.action == MotionEvent.ACTION_DOWN && event.x < paddingLeft) {
|
||||||
// 则计算当前行, 如果行号有效, 记录起来
|
// 则计算当前行, 如果行号有效, 记录起来
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package org.autojs.autojs.ui.edit.editor;
|
|||||||
* THIS CLASS IS PROVIDED TO THE PUBLIC DOMAIN FOR FREE WITHOUT ANY
|
* THIS CLASS IS PROVIDED TO THE PUBLIC DOMAIN FOR FREE WITHOUT ANY
|
||||||
* RESTRICTIONS OR ANY WARRANTY.
|
* RESTRICTIONS OR ANY WARRANTY.
|
||||||
*/
|
*/
|
||||||
import java.util.LinkedList;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
@@ -15,10 +14,12 @@ import android.text.TextWatcher;
|
|||||||
import android.text.style.UnderlineSpan;
|
import android.text.style.UnderlineSpan;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic undo/redo implementation for TextViews.
|
* A generic undo/redo implementation for TextViews.
|
||||||
*
|
* <p>
|
||||||
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 8, 2026.
|
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 12, 2026.
|
||||||
*/
|
*/
|
||||||
public class TextViewUndoRedo {
|
public class TextViewUndoRedo {
|
||||||
|
|
||||||
@@ -48,6 +49,10 @@ public class TextViewUndoRedo {
|
|||||||
|
|
||||||
private int mInitialHistoryStackSize;
|
private int mInitialHistoryStackSize;
|
||||||
|
|
||||||
|
// Baseline position for "unchanged" state.
|
||||||
|
// zh-CN: "未修改" 状态的基线位置.
|
||||||
|
private int mInitialHistoryPosition;
|
||||||
|
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
private int mTextChangeId = 0;
|
private int mTextChangeId = 0;
|
||||||
private final boolean mTextChanging = false;
|
private final boolean mTextChanging = false;
|
||||||
@@ -76,14 +81,14 @@ public class TextViewUndoRedo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset undo/redo history without modifying the current text.
|
* Reset undo/redo history without modifying the current text.
|
||||||
*
|
* <p>
|
||||||
* This is useful after bulk loading text progressively, where the text is already in the TextView
|
* This is useful after bulk loading text progressively, where the text is already in the TextView
|
||||||
* and we only want to treat it as the "baseline" (unchanged) state.
|
* and we only want to treat it as the "baseline" (unchanged) state.
|
||||||
*
|
* <p>
|
||||||
* zh-CN:
|
* zh-CN:
|
||||||
*
|
* <p>
|
||||||
* 在不修改当前文本的前提下重置 undo/redo 历史.
|
* 在不修改当前文本的前提下重置 undo/redo 历史.
|
||||||
*
|
* <p>
|
||||||
* 适用于渐进式批量加载文本后: 文本已经在 TextView 中, 此时只需要把它视为 "基线" (未修改) 状态.
|
* 适用于渐进式批量加载文本后: 文本已经在 TextView 中, 此时只需要把它视为 "基线" (未修改) 状态.
|
||||||
*/
|
*/
|
||||||
public final void resetHistoryAsUnchanged() {
|
public final void resetHistoryAsUnchanged() {
|
||||||
@@ -110,12 +115,21 @@ public class TextViewUndoRedo {
|
|||||||
mIsUndoOrRedo = false;
|
mIsUndoOrRedo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTextChanged(){
|
public boolean isTextChanged() {
|
||||||
return mInitialHistoryStackSize != mEditHistory.size();
|
// IMPORTANT:
|
||||||
|
// Use history position rather than history size.
|
||||||
|
// Undo/redo changes mmPosition while keeping history size the same.
|
||||||
|
//
|
||||||
|
// zh-CN:
|
||||||
|
// 重要:
|
||||||
|
// 使用 history position 而不是 history size.
|
||||||
|
// undo/redo 会改变 mmPosition, 但 history size 往往不变.
|
||||||
|
return mInitialHistoryPosition != mEditHistory.mmPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markTextAsUnchanged() {
|
public void markTextAsUnchanged() {
|
||||||
mInitialHistoryStackSize = mEditHistory.size();
|
mInitialHistoryStackSize = mEditHistory.size();
|
||||||
|
mInitialHistoryPosition = mEditHistory.mmPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================== //
|
// =================================================================== //
|
||||||
@@ -141,6 +155,7 @@ public class TextViewUndoRedo {
|
|||||||
public void clearHistory() {
|
public void clearHistory() {
|
||||||
mEditHistory.clear();
|
mEditHistory.clear();
|
||||||
mInitialHistoryStackSize = 0;
|
mInitialHistoryStackSize = 0;
|
||||||
|
mInitialHistoryPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -339,7 +354,7 @@ public class TextViewUndoRedo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size(){
|
public int size() {
|
||||||
return mmHistory.size();
|
return mmHistory.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +461,7 @@ public class TextViewUndoRedo {
|
|||||||
mTextChangeId++;
|
mTextChangeId++;
|
||||||
mEditHistory.add(new EditItem(start, mBeforeChange, mAfterChange));
|
mEditHistory.add(new EditItem(start, mBeforeChange, mAfterChange));
|
||||||
int textChangeId = mTextChangeId;
|
int textChangeId = mTextChangeId;
|
||||||
//TODO 增加连续输入文字当成一次撤销的功能
|
// TODO 增加连续输入文字当成一次撤销的功能
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
@@ -456,6 +471,15 @@ public class TextViewUndoRedo {
|
|||||||
if (mEditHistory.size() < mInitialHistoryStackSize) {
|
if (mEditHistory.size() < mInitialHistoryStackSize) {
|
||||||
mInitialHistoryStackSize = 0;
|
mInitialHistoryStackSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep baseline position within valid range after trims.
|
||||||
|
// zh-CN: 在 trim 等场景后, 保持基线 position 落在合法范围内.
|
||||||
|
if (mInitialHistoryPosition > mEditHistory.mmHistory.size()) {
|
||||||
|
mInitialHistoryPosition = mEditHistory.mmHistory.size();
|
||||||
|
}
|
||||||
|
if (mInitialHistoryPosition < 0) {
|
||||||
|
mInitialHistoryPosition = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1331,4 +1331,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">النوافذ المنبثقة في الخلفية</string>
|
<string name="text_xiaomi_background_popup_permission">النوافذ المنبثقة في الخلفية</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">لم يتم حفظ الاعدادات. هل تريد المتابعة?</string>
|
<string name="warn_continue_operation_without_saving_settings">لم يتم حفظ الاعدادات. هل تريد المتابعة?</string>
|
||||||
<string name="warn_exit_without_saving_settings">لم يتم حفظ الاعدادات. هل تريد الخروج?</string>
|
<string name="warn_exit_without_saving_settings">لم يتم حفظ الاعدادات. هل تريد الخروج?</string>
|
||||||
|
<string name="error_failed_to_save">فشل الحفظ</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">جارٍ الحفظ...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1326,4 +1326,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">Display pop-up windows while running in the background</string>
|
<string name="text_xiaomi_background_popup_permission">Display pop-up windows while running in the background</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">The settings has not been saved, are you sure to continue the operation?</string>
|
<string name="warn_continue_operation_without_saving_settings">The settings has not been saved, are you sure to continue the operation?</string>
|
||||||
<string name="warn_exit_without_saving_settings">The settings has not been saved, are you sure to exit?</string>
|
<string name="warn_exit_without_saving_settings">The settings has not been saved, are you sure to exit?</string>
|
||||||
|
<string name="error_failed_to_save">Failed to save</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">Saving...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1329,4 +1329,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">Ventanas emergentes en segundo plano</string>
|
<string name="text_xiaomi_background_popup_permission">Ventanas emergentes en segundo plano</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">La configuracion no se ha guardado. ¿Seguro que quieres continuar?</string>
|
<string name="warn_continue_operation_without_saving_settings">La configuracion no se ha guardado. ¿Seguro que quieres continuar?</string>
|
||||||
<string name="warn_exit_without_saving_settings">La configuracion no se ha guardado. ¿Seguro que quieres salir?</string>
|
<string name="warn_exit_without_saving_settings">La configuracion no se ha guardado. ¿Seguro que quieres salir?</string>
|
||||||
|
<string name="error_failed_to_save">Error al guardar</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">Guardando...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1329,4 +1329,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">Fenêtres contextuelles en arrière-plan</string>
|
<string name="text_xiaomi_background_popup_permission">Fenêtres contextuelles en arrière-plan</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">Les parametres ne sont pas enregistres. Continuer?</string>
|
<string name="warn_continue_operation_without_saving_settings">Les parametres ne sont pas enregistres. Continuer?</string>
|
||||||
<string name="warn_exit_without_saving_settings">Les parametres ne sont pas enregistres. Quitter?</string>
|
<string name="warn_exit_without_saving_settings">Les parametres ne sont pas enregistres. Quitter?</string>
|
||||||
|
<string name="error_failed_to_save">Echec de l\'enregistrement</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">Enregistrement...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1330,4 +1330,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">バックグラウンドでのポップアップ表示</string>
|
<string name="text_xiaomi_background_popup_permission">バックグラウンドでのポップアップ表示</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">設定が保存されていません. 続行しますか?</string>
|
<string name="warn_continue_operation_without_saving_settings">設定が保存されていません. 続行しますか?</string>
|
||||||
<string name="warn_exit_without_saving_settings">設定が保存されていません. 終了しますか?</string>
|
<string name="warn_exit_without_saving_settings">設定が保存されていません. 終了しますか?</string>
|
||||||
|
<string name="error_failed_to_save">保存に失敗しました</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">保存中...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1331,4 +1331,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">백그라운드 팝업</string>
|
<string name="text_xiaomi_background_popup_permission">백그라운드 팝업</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">설정이 저장되지 않았습니다. 계속할까요?</string>
|
<string name="warn_continue_operation_without_saving_settings">설정이 저장되지 않았습니다. 계속할까요?</string>
|
||||||
<string name="warn_exit_without_saving_settings">설정이 저장되지 않았습니다. 종료할까요?</string>
|
<string name="warn_exit_without_saving_settings">설정이 저장되지 않았습니다. 종료할까요?</string>
|
||||||
|
<string name="error_failed_to_save">저장에 실패했습니다</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">저장 중...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1329,4 +1329,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">Всплывающие окна в фоне</string>
|
<string name="text_xiaomi_background_popup_permission">Всплывающие окна в фоне</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">Настройки не сохранены. Продолжить?</string>
|
<string name="warn_continue_operation_without_saving_settings">Настройки не сохранены. Продолжить?</string>
|
||||||
<string name="warn_exit_without_saving_settings">Настройки не сохранены. Выйти?</string>
|
<string name="warn_exit_without_saving_settings">Настройки не сохранены. Выйти?</string>
|
||||||
|
<string name="error_failed_to_save">Не удалось сохранить</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">Сохранение...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1325,4 +1325,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">後台彈出界面</string>
|
<string name="text_xiaomi_background_popup_permission">後台彈出界面</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">設置尚未保存, 確定要繼續操作嗎</string>
|
<string name="warn_continue_operation_without_saving_settings">設置尚未保存, 確定要繼續操作嗎</string>
|
||||||
<string name="warn_exit_without_saving_settings">設置尚未保存, 確定要退出嗎</string>
|
<string name="warn_exit_without_saving_settings">設置尚未保存, 確定要退出嗎</string>
|
||||||
|
<string name="error_failed_to_save">保存失敗</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">正在保存...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1325,4 +1325,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">後臺彈出介面</string>
|
<string name="text_xiaomi_background_popup_permission">後臺彈出介面</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">設定尚未儲存, 確定要繼續操作嗎</string>
|
<string name="warn_continue_operation_without_saving_settings">設定尚未儲存, 確定要繼續操作嗎</string>
|
||||||
<string name="warn_exit_without_saving_settings">設定尚未儲存, 確定要退出嗎</string>
|
<string name="warn_exit_without_saving_settings">設定尚未儲存, 確定要退出嗎</string>
|
||||||
|
<string name="error_failed_to_save">儲存失敗</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">正在儲存...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1326,4 +1326,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">后台弹出界面</string>
|
<string name="text_xiaomi_background_popup_permission">后台弹出界面</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">设置尚未保存, 确定要继续操作吗</string>
|
<string name="warn_continue_operation_without_saving_settings">设置尚未保存, 确定要继续操作吗</string>
|
||||||
<string name="warn_exit_without_saving_settings">设置尚未保存, 确定要退出吗</string>
|
<string name="warn_exit_without_saving_settings">设置尚未保存, 确定要退出吗</string>
|
||||||
|
<string name="error_failed_to_save">保存失败</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">正在保存...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1600,4 +1600,6 @@
|
|||||||
<string name="text_xiaomi_background_popup_permission">Display pop-up windows while running in the background</string>
|
<string name="text_xiaomi_background_popup_permission">Display pop-up windows while running in the background</string>
|
||||||
<string name="warn_continue_operation_without_saving_settings">The settings has not been saved, are you sure to continue the operation?</string>
|
<string name="warn_continue_operation_without_saving_settings">The settings has not been saved, are you sure to continue the operation?</string>
|
||||||
<string name="warn_exit_without_saving_settings">The settings has not been saved, are you sure to exit?</string>
|
<string name="warn_exit_without_saving_settings">The settings has not been saved, are you sure to exit?</string>
|
||||||
|
<string name="error_failed_to_save">Failed to save</string>
|
||||||
|
<string name="text_saving" tools:ignore="TypographyEllipsis">Saving...</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#Thu Feb 12 17:13:51 CST 2026
|
#Thu Feb 12 19:57:00 CST 2026
|
||||||
BUILD_TIME=1770887631678
|
BUILD_TIME=1770897420318
|
||||||
COMPILE_SDK_VERSION=36
|
COMPILE_SDK_VERSION=36
|
||||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||||
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
||||||
@@ -27,6 +27,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
|||||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||||
TARGET_SDK_VERSION=36
|
TARGET_SDK_VERSION=36
|
||||||
TARGET_SDK_VERSION_INRT=29
|
TARGET_SDK_VERSION_INRT=29
|
||||||
VERSION_BUILD=3734
|
VERSION_BUILD=3735
|
||||||
VERSION_NAME=6.7.0 Alpha19
|
VERSION_NAME=6.7.0 Alpha19
|
||||||
VSCODE_EXT_REQUIRED_VERSION=1.0.13
|
VSCODE_EXT_REQUIRED_VERSION=1.0.13
|
||||||
|
|||||||
Reference in New Issue
Block a user