@@ -53,6 +53,10 @@ class TextEditorActivity : AppCompatActivity() {
5353 private const val EXTRA_WRAP = " wrap"
5454 private const val EXTRA_DIR = " dir"
5555 private const val EXTRA_PLACEHOLDER = " placeholder"
56+ private const val EXTRA_READONLY = " readonly"
57+ private const val EXTRA_NEED_INPUT = " need_input"
58+ private const val EXTRA_VALUE = " value"
59+ private const val EXTRA_VALUE_SH = " value_sh"
5660
5761 // Tối ưu RAM: Giảm Undo Stack từ 200 xuống 50 để tránh OutOfMemory
5862 private const val UNDO_HISTORY_LIMIT = 50
@@ -85,7 +89,11 @@ class TextEditorActivity : AppCompatActivity() {
8589 desc : String? = null,
8690 wrap : Boolean = true,
8791 dir : String? = null,
88- placeholder : String? = null
92+ placeholder : String? = null,
93+ readonly : Boolean = false,
94+ needInput : Boolean = false,
95+ value : String? = null,
96+ valueSh : String? = null
8997 ) {
9098 val intent = Intent (context, TextEditorActivity ::class .java).apply {
9199 putExtra(EXTRA_FILE , file)
@@ -94,6 +102,10 @@ class TextEditorActivity : AppCompatActivity() {
94102 putExtra(EXTRA_WRAP , wrap)
95103 putExtra(EXTRA_DIR , dir ? : " " )
96104 putExtra(EXTRA_PLACEHOLDER , placeholder ? : " " )
105+ putExtra(EXTRA_READONLY , readonly)
106+ putExtra(EXTRA_NEED_INPUT , needInput)
107+ putExtra(EXTRA_VALUE , value ? : " " )
108+ putExtra(EXTRA_VALUE_SH , valueSh ? : " " )
97109 if (context !is AppCompatActivity ) addFlags(Intent .FLAG_ACTIVITY_NEW_TASK )
98110 }
99111 context.startActivity(intent)
@@ -113,6 +125,10 @@ class TextEditorActivity : AppCompatActivity() {
113125 private var syntaxHighlighter: SyntaxHighlighter ? = null
114126 private var placeholderText: String = " "
115127 private var titleText: String = " "
128+ private var readonlyMode: Boolean = false
129+ private var needInput: Boolean = false
130+ private var initialValue: String = " "
131+ private var initialValueSh: String = " "
116132 private var lastLanguageOverride: String? = null
117133 private var lastLineCount = - 1
118134
@@ -166,12 +182,17 @@ class TextEditorActivity : AppCompatActivity() {
166182 wrapEnabled = intent.getBooleanExtra(EXTRA_WRAP , true )
167183 placeholderText = intent.getStringExtra(EXTRA_PLACEHOLDER ).orEmpty()
168184 titleText = intent.getStringExtra(EXTRA_TITLE ).orEmpty()
185+ readonlyMode = intent.getBooleanExtra(EXTRA_READONLY , false )
186+ needInput = intent.getBooleanExtra(EXTRA_NEED_INPUT , false )
187+ initialValue = intent.getStringExtra(EXTRA_VALUE ).orEmpty()
188+ initialValueSh = intent.getStringExtra(EXTRA_VALUE_SH ).orEmpty()
169189
170190 applyWrapState()
171191 applyMonospaceState()
172192 setupUnifiedTextWatcher()
173193 setupSpecialCharsBar()
174194 setupEditorTouchAndFocus()
195+ applyReadonlyState()
175196 loadFileContent()
176197 }
177198
@@ -616,6 +637,31 @@ class TextEditorActivity : AppCompatActivity() {
616637 } catch (_: Exception ) {
617638 }
618639
640+ // Chỉ điền nội dung khởi tạo (value / value-sh) khi file CHƯA tồn tại.
641+ // Nếu file đã tồn tại thì giữ nguyên, không điền/ghi đè gì thêm.
642+ if (newFile) {
643+ val computedValue = if (initialValueSh.isNotEmpty()) {
644+ try {
645+ com.omarea.krscript.executor.ScriptEnvironmen .executeResultRoot(
646+ applicationContext,
647+ initialValueSh,
648+ com.omarea.krscript.model.NodeInfoBase (" " )
649+ )
650+ } catch (_: Exception ) {
651+ " "
652+ }
653+ } else {
654+ initialValue
655+ }
656+
657+ if (computedValue.isNotEmpty()) {
658+ content = computedValue
659+ if (writeFileContent(absoluteFilePath, content)) {
660+ newFile = false
661+ }
662+ }
663+ }
664+
619665 withContext(Dispatchers .Main ) {
620666 savedContent = content
621667 isApplyingHistory = true
@@ -644,6 +690,15 @@ class TextEditorActivity : AppCompatActivity() {
644690 }
645691 }
646692
693+ // Áp dụng trạng thái chỉ đọc (readonly="true"): không cho phép gõ/sửa/dán nội dung
694+ private fun applyReadonlyState () {
695+ if (! readonlyMode) return
696+ binding.editorContent.keyListener = null
697+ binding.editorContent.isFocusable = true
698+ binding.editorContent.isFocusableInTouchMode = true
699+ binding.editorContent.isLongClickable = true
700+ }
701+
647702 private fun applyWrapState () {
648703 val editText = binding.editorContent
649704 val container = binding.editorContentContainer
@@ -705,6 +760,10 @@ class TextEditorActivity : AppCompatActivity() {
705760
706761 private fun attemptClose () {
707762 if (isSaving) return
763+ if (readonlyMode) {
764+ finish()
765+ return
766+ }
708767 commitPendingUndoSnapshot()
709768
710769 if (! hasUnsavedChanges()) {
@@ -738,7 +797,13 @@ class TextEditorActivity : AppCompatActivity() {
738797
739798 menu.findItem(R .id.editor_menu_wrap)?.isChecked = wrapEnabled
740799 menu.findItem(R .id.editor_menu_monospace)?.isChecked = monospaceEnabled
741- menu.findItem(R .id.editor_menu_run)?.isVisible = runnableInterpreter() != null
800+ menu.findItem(R .id.editor_menu_run)?.isVisible = ! readonlyMode && runnableInterpreter() != null
801+
802+ if (readonlyMode) {
803+ menu.findItem(R .id.editor_menu_save)?.isVisible = false
804+ menu.findItem(R .id.editor_menu_undo)?.isVisible = false
805+ menu.findItem(R .id.editor_menu_redo)?.isVisible = false
806+ }
742807
743808 refreshToolbarButtons()
744809 return true
@@ -787,6 +852,7 @@ class TextEditorActivity : AppCompatActivity() {
787852 onResult : ((Boolean ) -> Unit )? = null
788853 ) {
789854 if (isSaving || ! hasUnsavedChanges()) return
855+ if (readonlyMode) return
790856 isSaving = true
791857 commitPendingUndoSnapshot()
792858
@@ -869,6 +935,7 @@ class TextEditorActivity : AppCompatActivity() {
869935 title = titleText.ifEmpty { File (absoluteFilePath).name }
870936 interruptable = true
871937 shell = RunnableNode .shellModeDefault
938+ needInput = this @TextEditorActivity.needInput
872939 }
873940 val script = " chmod 755 \" $absoluteFilePath \" 2>/dev/null\n $interpreter \" $absoluteFilePath \"\n "
874941 DialogLogFragment .create(
0 commit comments