diff --git a/plugins/editor/build.gradle.kts b/plugins/editor/build.gradle.kts index 2126a4c..6cc79b5 100644 --- a/plugins/editor/build.gradle.kts +++ b/plugins/editor/build.gradle.kts @@ -4,7 +4,7 @@ plugins { -project.version = "0.0.5" +project.version = "0.0.6" dependencies { diff --git a/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorDialog.kt b/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorDialog.kt index 9dc4ffd..0e0a57e 100644 --- a/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorDialog.kt +++ b/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorDialog.kt @@ -10,6 +10,7 @@ import java.awt.event.WindowAdapter import java.awt.event.WindowEvent import java.io.File import java.nio.file.Path +import java.util.concurrent.atomic.AtomicBoolean import javax.swing.JComponent import javax.swing.JOptionPane import javax.swing.UIManager @@ -22,6 +23,7 @@ class EditorDialog(file: Path, owner: Window, private val myDisposable: Disposab private val filename = file.name private val filepath = File(file.absolutePathString()) private val editorPanel = EditorPanel(this, filepath) + private val disposed = AtomicBoolean() init { size = Dimension(UIManager.getInt("Dialog.width"), UIManager.getInt("Dialog.height")) @@ -42,21 +44,28 @@ class EditorDialog(file: Path, owner: Window, private val myDisposable: Disposab private fun initEvents() { + addWindowListener(object : WindowAdapter() { override fun windowClosing(e: WindowEvent?) { - doCancelAction() + if (disposed.compareAndSet(false, true)) { + doCancelAction() + } } }) Disposer.register(myDisposable, object : Disposable { override fun dispose() { - doCancelAction() + if (disposed.compareAndSet(false, true)) { + doCancelAction() + } } }) Disposer.register(disposable, object : Disposable { override fun dispose() { - Disposer.dispose(myDisposable) + if (disposed.compareAndSet(false, true)) { + Disposer.dispose(myDisposable) + } } }) } diff --git a/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorPanel.kt b/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorPanel.kt index 1bbdd37..647dcc2 100644 --- a/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorPanel.kt +++ b/plugins/editor/src/main/kotlin/app/termora/plugins/editor/EditorPanel.kt @@ -33,6 +33,7 @@ import javax.swing.* import javax.swing.SwingConstants.VERTICAL import javax.swing.event.DocumentEvent import kotlin.math.max +import kotlin.math.min class EditorPanel(private val window: JDialog, private val file: File) : JPanel(BorderLayout()) { @@ -212,28 +213,7 @@ class EditorPanel(private val window: JDialog, private val file: File) : JPanel( textArea.actionMap.put("Format", object : AbstractAction() { override fun actionPerformed(e: ActionEvent) { - if (textArea.syntaxEditingStyle == SyntaxConstants.SYNTAX_STYLE_JSON) { - runCatching { - val json = prettyJson.parseToJsonElement(textArea.text) - textArea.text = prettyJson.encodeToString(json) - }.onFailure { - if (log.isErrorEnabled) { - log.error(it.message, it) - } - } - } else if (textArea.syntaxEditingStyle == SyntaxConstants.SYNTAX_STYLE_XML) { - runCatching { - val document = SAXReader().read(StringReader(textArea.text)) - val sw = StringWriter() - val writer = XMLWriter(sw, OutputFormat.createPrettyPrint()) - writer.write(document) - textArea.text = sw.toString() - }.onFailure { - if (log.isErrorEnabled) { - log.error(it.message, it) - } - } - } + format() } }) @@ -265,12 +245,59 @@ class EditorPanel(private val window: JDialog, private val file: File) : JPanel( - prettyBtn.addActionListener(searchTextField.actionMap.get("Format")) + prettyBtn.addActionListener(textArea.actionMap.get("Format")) prevBtn.addActionListener { search(false) } nextBtn.addActionListener { search(true) } } + private fun format() { + val vertical = scrollPane.verticalScrollBar.value + val horizontal = scrollPane.horizontalScrollBar.value + val caretPosition = textArea.caretPosition + + val c = if (textArea.syntaxEditingStyle == SyntaxConstants.SYNTAX_STYLE_JSON) { + runCatching { + val json = prettyJson.parseToJsonElement(textArea.text) + textArea.text = prettyJson.encodeToString(json) + }.onFailure { + if (log.isErrorEnabled) { + log.error(it.message, it) + } + } + } else if (textArea.syntaxEditingStyle == SyntaxConstants.SYNTAX_STYLE_XML) { + runCatching { + val document = SAXReader().read(StringReader(textArea.text)) + val sw = StringWriter() + val writer = XMLWriter(sw, OutputFormat.createPrettyPrint()) + writer.write(document) + textArea.text = sw.toString() + }.onFailure { + if (log.isErrorEnabled) { + log.error(it.message, it) + } + } + } else { + null + } ?: return + + c.onSuccess { + SwingUtilities.invokeLater { + scrollPane.verticalScrollBar.value = min( + vertical, + scrollPane.verticalScrollBar.maximum + ) + scrollPane.horizontalScrollBar.value = min( + horizontal, + scrollPane.horizontalScrollBar.maximum + ) + if (caretPosition >= 0 && caretPosition < textArea.document.length) { + textArea.caretPosition = caretPosition + } + } + } + } + private fun search(searchForward: Boolean = true) { textArea.clearMarkAllHighlights()