mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
chore: improve terminal options
This commit is contained in:
@@ -4,7 +4,7 @@ plugins {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
project.version = "0.0.1"
|
project.version = "0.0.2"
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package app.termora.plugins.serial
|
package app.termora.plugins.serial
|
||||||
|
|
||||||
import app.termora.*
|
import app.termora.*
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import app.termora.plugin.internal.BasicGeneralOption
|
import app.termora.plugin.internal.BasicGeneralOption
|
||||||
|
import app.termora.plugin.internal.BasicTerminalOption
|
||||||
import com.fazecast.jSerialComm.SerialPort
|
import com.fazecast.jSerialComm.SerialPort
|
||||||
import com.formdev.flatlaf.FlatClientProperties
|
import com.formdev.flatlaf.FlatClientProperties
|
||||||
import com.jgoodies.forms.builder.FormBuilder
|
import com.jgoodies.forms.builder.FormBuilder
|
||||||
@@ -15,12 +17,15 @@ import java.awt.BorderLayout
|
|||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
import java.awt.event.ComponentAdapter
|
import java.awt.event.ComponentAdapter
|
||||||
import java.awt.event.ComponentEvent
|
import java.awt.event.ComponentEvent
|
||||||
import java.nio.charset.Charset
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
|
|
||||||
class SerialHostOptionsPane : OptionsPane() {
|
class SerialHostOptionsPane : OptionsPane() {
|
||||||
private val generalOption = BasicGeneralOption()
|
private val generalOption = BasicGeneralOption()
|
||||||
private val terminalOption = TerminalOption()
|
private val terminalOption = BasicTerminalOption().apply {
|
||||||
|
showCharsetComboBox = true
|
||||||
|
showStartupCommandTextField = true
|
||||||
|
init()
|
||||||
|
}
|
||||||
private val serialCommOption = SerialCommOption()
|
private val serialCommOption = SerialCommOption()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -48,6 +53,10 @@ class SerialHostOptionsPane : OptionsPane() {
|
|||||||
encoding = terminalOption.charsetComboBox.selectedItem as String,
|
encoding = terminalOption.charsetComboBox.selectedItem as String,
|
||||||
startupCommand = terminalOption.startupCommandTextField.text,
|
startupCommand = terminalOption.startupCommandTextField.text,
|
||||||
serialComm = serialComm,
|
serialComm = serialComm,
|
||||||
|
extras = mutableMapOf(
|
||||||
|
"altModifier" to (terminalOption.altModifierComboBox.selectedItem?.toString()
|
||||||
|
?: AltKeyModifier.EightBit.name),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return Host(
|
return Host(
|
||||||
@@ -128,67 +137,6 @@ class SerialHostOptionsPane : OptionsPane() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected inner class TerminalOption : JPanel(BorderLayout()), Option {
|
|
||||||
val charsetComboBox = JComboBox<String>()
|
|
||||||
val startupCommandTextField = OutlineTextField()
|
|
||||||
|
|
||||||
|
|
||||||
init {
|
|
||||||
initView()
|
|
||||||
initEvents()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
add(getCenterComponent(), BorderLayout.CENTER)
|
|
||||||
|
|
||||||
|
|
||||||
for (e in Charset.availableCharsets()) {
|
|
||||||
charsetComboBox.addItem(e.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
charsetComboBox.selectedItem = "UTF-8"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initEvents() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getIcon(isSelected: Boolean): Icon {
|
|
||||||
return Icons.terminal
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTitle(): String {
|
|
||||||
return I18n.getString("termora.new-host.terminal")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJComponent(): JComponent {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCenterComponent(): JComponent {
|
|
||||||
val layout = FormLayout(
|
|
||||||
"left:pref, $FORM_MARGIN, default:grow",
|
|
||||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
|
||||||
)
|
|
||||||
|
|
||||||
var rows = 1
|
|
||||||
val step = 2
|
|
||||||
val panel = FormBuilder.create().layout(layout)
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
|
||||||
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
|
||||||
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.apply { rows += step }
|
|
||||||
.build()
|
|
||||||
|
|
||||||
|
|
||||||
return panel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected inner class SerialCommOption : JPanel(BorderLayout()), Option {
|
protected inner class SerialCommOption : JPanel(BorderLayout()), Option {
|
||||||
val serialPortComboBox = OutlineComboBox<String>()
|
val serialPortComboBox = OutlineComboBox<String>()
|
||||||
val baudRateComboBox = OutlineComboBox<Int>()
|
val baudRateComboBox = OutlineComboBox<Int>()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package app.termora
|
package app.termora
|
||||||
|
|
||||||
import app.termora.actions.DataProviders
|
import app.termora.actions.DataProviders
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import app.termora.terminal.*
|
import app.termora.terminal.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.swing.Swing
|
import kotlinx.coroutines.swing.Swing
|
||||||
@@ -46,6 +47,9 @@ abstract class PtyHostTerminalTab(
|
|||||||
// 开启 reader
|
// 开启 reader
|
||||||
startPtyConnectorReader()
|
startPtyConnectorReader()
|
||||||
|
|
||||||
|
// 修饰
|
||||||
|
terminalKeyModifiers()
|
||||||
|
|
||||||
// 启动命令
|
// 启动命令
|
||||||
if (host.options.startupCommand.isNotBlank()) {
|
if (host.options.startupCommand.isNotBlank()) {
|
||||||
coroutineScope.launch(Dispatchers.IO) {
|
coroutineScope.launch(Dispatchers.IO) {
|
||||||
@@ -155,6 +159,15 @@ abstract class PtyHostTerminalTab(
|
|||||||
ptyConnector.write(bytes)
|
ptyConnector.write(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun terminalKeyModifiers() {
|
||||||
|
val altModifier = host.options.extras["altModifier"]
|
||||||
|
if (altModifier == AltKeyModifier.CharactersPrecededByESC.name) {
|
||||||
|
terminalModel.setData(DataKey.AltModifier, AltKeyModifier.CharactersPrecededByESC)
|
||||||
|
} else {
|
||||||
|
terminalModel.setData(DataKey.AltModifier, AltKeyModifier.EightBit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun canReconnect(): Boolean {
|
override fun canReconnect(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package app.termora.plugin.internal
|
||||||
|
|
||||||
|
enum class AltKeyModifier {
|
||||||
|
EightBit,
|
||||||
|
CharactersPrecededByESC,
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
package app.termora.plugin.internal
|
||||||
|
|
||||||
|
import app.termora.*
|
||||||
|
import app.termora.OptionsPane.Companion.FORM_MARGIN
|
||||||
|
import app.termora.OptionsPane.Option
|
||||||
|
import app.termora.plugin.internal.telnet.TelnetHostOptionsPane.Backspace
|
||||||
|
import com.formdev.flatlaf.extras.components.FlatTabbedPane
|
||||||
|
import com.formdev.flatlaf.ui.FlatTextBorder
|
||||||
|
import com.jgoodies.forms.builder.FormBuilder
|
||||||
|
import com.jgoodies.forms.layout.FormLayout
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.Component
|
||||||
|
import java.awt.KeyboardFocusManager
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
import javax.swing.*
|
||||||
|
|
||||||
|
class BasicTerminalOption() : JPanel(BorderLayout()), Option {
|
||||||
|
|
||||||
|
var showCharsetComboBox: Boolean = false
|
||||||
|
var showStartupCommandTextField: Boolean = false
|
||||||
|
var showHeartbeatIntervalTextField: Boolean = false
|
||||||
|
var showEnvironmentTextArea: Boolean = false
|
||||||
|
var showLoginScripts: Boolean = false
|
||||||
|
var showBackspaceComboBox: Boolean = false
|
||||||
|
var showCharacterAtATimeTextField: Boolean = false
|
||||||
|
var showAltModifierComboBox: Boolean = true
|
||||||
|
|
||||||
|
val charsetComboBox = JComboBox<String>()
|
||||||
|
val startupCommandTextField = OutlineTextField()
|
||||||
|
val heartbeatIntervalTextField = IntSpinner(30, minimum = 3, maximum = Int.MAX_VALUE)
|
||||||
|
val environmentTextArea = FixedLengthTextArea(2048)
|
||||||
|
val loginScripts = mutableListOf<LoginScript>()
|
||||||
|
val backspaceComboBox = JComboBox<Backspace>()
|
||||||
|
val altModifierComboBox = JComboBox<AltKeyModifier>()
|
||||||
|
val characterAtATimeTextField = YesOrNoComboBox()
|
||||||
|
|
||||||
|
|
||||||
|
private val loginScriptPanel = LoginScriptPanel(loginScripts)
|
||||||
|
private val tabbed = FlatTabbedPane()
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
initView()
|
||||||
|
initEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
|
||||||
|
if (showLoginScripts) {
|
||||||
|
tabbed.styleMap = mapOf(
|
||||||
|
"focusColor" to DynamicColor("TabbedPane.background"),
|
||||||
|
"hoverColor" to DynamicColor("TabbedPane.background"),
|
||||||
|
)
|
||||||
|
tabbed.tabHeight = UIManager.getInt("TabbedPane.tabHeight") - 4
|
||||||
|
putClientProperty("ContentPanelBorder", BorderFactory.createEmptyBorder())
|
||||||
|
tabbed.addTab(I18n.getString("termora.new-host.general"), getCenterComponent())
|
||||||
|
tabbed.addTab(I18n.getString("termora.new-host.terminal.login-scripts"), loginScriptPanel)
|
||||||
|
add(tabbed, BorderLayout.CENTER)
|
||||||
|
} else {
|
||||||
|
add(getCenterComponent(), BorderLayout.CENTER)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showAltModifierComboBox) {
|
||||||
|
altModifierComboBox.addItem(AltKeyModifier.EightBit)
|
||||||
|
altModifierComboBox.addItem(AltKeyModifier.CharactersPrecededByESC)
|
||||||
|
|
||||||
|
altModifierComboBox.renderer = object : DefaultListCellRenderer() {
|
||||||
|
override fun getListCellRendererComponent(
|
||||||
|
list: JList<*>?,
|
||||||
|
value: Any?,
|
||||||
|
index: Int,
|
||||||
|
isSelected: Boolean,
|
||||||
|
cellHasFocus: Boolean
|
||||||
|
): Component? {
|
||||||
|
var text = value?.toString() ?: value
|
||||||
|
if (value == AltKeyModifier.CharactersPrecededByESC) {
|
||||||
|
text = I18n.getString("termora.new-host.terminal.alt-modifier.by-esc")
|
||||||
|
} else if (value == AltKeyModifier.EightBit) {
|
||||||
|
text = I18n.getString("termora.new-host.terminal.alt-modifier.eight-bit")
|
||||||
|
}
|
||||||
|
return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showBackspaceComboBox) {
|
||||||
|
backspaceComboBox.addItem(Backspace.Delete)
|
||||||
|
backspaceComboBox.addItem(Backspace.Backspace)
|
||||||
|
backspaceComboBox.addItem(Backspace.VT220)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showCharacterAtATimeTextField) {
|
||||||
|
characterAtATimeTextField.selectedItem = false
|
||||||
|
}
|
||||||
|
|
||||||
|
environmentTextArea.setFocusTraversalKeys(
|
||||||
|
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
||||||
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
|
.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)
|
||||||
|
)
|
||||||
|
environmentTextArea.setFocusTraversalKeys(
|
||||||
|
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
|
||||||
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
|
.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)
|
||||||
|
)
|
||||||
|
|
||||||
|
environmentTextArea.rows = 8
|
||||||
|
environmentTextArea.lineWrap = true
|
||||||
|
environmentTextArea.border = BorderFactory.createEmptyBorder(4, 4, 4, 4)
|
||||||
|
|
||||||
|
for (e in Charset.availableCharsets()) {
|
||||||
|
charsetComboBox.addItem(e.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
charsetComboBox.selectedItem = "UTF-8"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initEvents() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun getIcon(isSelected: Boolean): Icon {
|
||||||
|
return Icons.terminal
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTitle(): String {
|
||||||
|
return I18n.getString("termora.new-host.terminal")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getJComponent(): JComponent {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCenterComponent(): JComponent {
|
||||||
|
val layout = FormLayout(
|
||||||
|
"left:pref, $FORM_MARGIN, default:grow",
|
||||||
|
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
||||||
|
)
|
||||||
|
|
||||||
|
var rows = 1
|
||||||
|
val step = 2
|
||||||
|
val builder = FormBuilder.create().layout(layout)
|
||||||
|
if (showLoginScripts) {
|
||||||
|
builder.border(BorderFactory.createEmptyBorder(6, 8, 6, 8))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showCharsetComboBox) {
|
||||||
|
builder.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
||||||
|
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showAltModifierComboBox) {
|
||||||
|
builder.add("${I18n.getString("termora.new-host.terminal.alt-modifier")}:").xy(1, rows)
|
||||||
|
.add(altModifierComboBox).xy(3, rows).apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showBackspaceComboBox) {
|
||||||
|
builder.add("${I18n.getString("termora.new-host.terminal.backspace")}:").xy(1, rows)
|
||||||
|
.add(backspaceComboBox).xy(3, rows).apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showCharacterAtATimeTextField) {
|
||||||
|
builder
|
||||||
|
.add("${I18n.getString("termora.new-host.terminal.character-mode")}:").xy(1, rows)
|
||||||
|
.add(characterAtATimeTextField).xy(3, rows).apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showHeartbeatIntervalTextField) {
|
||||||
|
builder.add("${I18n.getString("termora.new-host.terminal.heartbeat-interval")}:").xy(1, rows)
|
||||||
|
.add(heartbeatIntervalTextField).xy(3, rows).apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showStartupCommandTextField) {
|
||||||
|
builder.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
||||||
|
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showEnvironmentTextArea) {
|
||||||
|
builder.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
||||||
|
.add(JScrollPane(environmentTextArea).apply { border = FlatTextBorder() }).xy(3, rows)
|
||||||
|
.apply { rows += step }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,20 +1,25 @@
|
|||||||
package app.termora.plugin.internal.local
|
package app.termora.plugin.internal.local
|
||||||
|
|
||||||
import app.termora.*
|
import app.termora.Host
|
||||||
|
import app.termora.Options
|
||||||
|
import app.termora.OptionsPane
|
||||||
|
import app.termora.SerialComm
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import app.termora.plugin.internal.BasicGeneralOption
|
import app.termora.plugin.internal.BasicGeneralOption
|
||||||
|
import app.termora.plugin.internal.BasicTerminalOption
|
||||||
import com.formdev.flatlaf.FlatClientProperties
|
import com.formdev.flatlaf.FlatClientProperties
|
||||||
import com.formdev.flatlaf.ui.FlatTextBorder
|
|
||||||
import com.jgoodies.forms.builder.FormBuilder
|
|
||||||
import com.jgoodies.forms.layout.FormLayout
|
|
||||||
import java.awt.BorderLayout
|
|
||||||
import java.awt.KeyboardFocusManager
|
|
||||||
import java.awt.Window
|
import java.awt.Window
|
||||||
import java.nio.charset.Charset
|
import javax.swing.JTextField
|
||||||
import javax.swing.*
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
internal open class LocalHostOptionsPane : OptionsPane() {
|
internal open class LocalHostOptionsPane : OptionsPane() {
|
||||||
protected val generalOption = BasicGeneralOption()
|
protected val generalOption = BasicGeneralOption()
|
||||||
protected val terminalOption = TerminalOption()
|
private val terminalOption = BasicTerminalOption().apply {
|
||||||
|
showCharsetComboBox = true
|
||||||
|
showEnvironmentTextArea = true
|
||||||
|
showStartupCommandTextField = true
|
||||||
|
init()
|
||||||
|
}
|
||||||
protected val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
protected val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -35,6 +40,10 @@ internal open class LocalHostOptionsPane : OptionsPane() {
|
|||||||
env = terminalOption.environmentTextArea.text,
|
env = terminalOption.environmentTextArea.text,
|
||||||
startupCommand = terminalOption.startupCommandTextField.text,
|
startupCommand = terminalOption.startupCommandTextField.text,
|
||||||
serialComm = serialComm,
|
serialComm = serialComm,
|
||||||
|
extras = mutableMapOf(
|
||||||
|
"altModifier" to (terminalOption.altModifierComboBox.selectedItem?.toString()
|
||||||
|
?: AltKeyModifier.EightBit.name),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return Host(
|
return Host(
|
||||||
@@ -77,83 +86,4 @@ internal open class LocalHostOptionsPane : OptionsPane() {
|
|||||||
textField.requestFocusInWindow()
|
textField.requestFocusInWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected inner class TerminalOption : JPanel(BorderLayout()), Option {
|
|
||||||
val charsetComboBox = JComboBox<String>()
|
|
||||||
val startupCommandTextField = OutlineTextField()
|
|
||||||
val environmentTextArea = FixedLengthTextArea(2048)
|
|
||||||
|
|
||||||
|
|
||||||
init {
|
|
||||||
initView()
|
|
||||||
initEvents()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
add(getCenterComponent(), BorderLayout.CENTER)
|
|
||||||
|
|
||||||
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
|
|
||||||
environmentTextArea.rows = 8
|
|
||||||
environmentTextArea.lineWrap = true
|
|
||||||
environmentTextArea.border = BorderFactory.createEmptyBorder(4, 4, 4, 4)
|
|
||||||
|
|
||||||
for (e in Charset.availableCharsets()) {
|
|
||||||
charsetComboBox.addItem(e.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
charsetComboBox.selectedItem = "UTF-8"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initEvents() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getIcon(isSelected: Boolean): Icon {
|
|
||||||
return Icons.terminal
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTitle(): String {
|
|
||||||
return I18n.getString("termora.new-host.terminal")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJComponent(): JComponent {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCenterComponent(): JComponent {
|
|
||||||
val layout = FormLayout(
|
|
||||||
"left:pref, $FORM_MARGIN, default:grow",
|
|
||||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
|
||||||
)
|
|
||||||
|
|
||||||
var rows = 1
|
|
||||||
val step = 2
|
|
||||||
val panel = FormBuilder.create().layout(layout)
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
|
||||||
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
|
||||||
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
|
||||||
.add(JScrollPane(environmentTextArea).apply { border = FlatTextBorder() }).xy(3, rows)
|
|
||||||
.apply { rows += step }
|
|
||||||
.build()
|
|
||||||
|
|
||||||
|
|
||||||
return panel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,13 +4,14 @@ import app.termora.*
|
|||||||
import app.termora.account.AccountOwner
|
import app.termora.account.AccountOwner
|
||||||
import app.termora.keymgr.KeyManager
|
import app.termora.keymgr.KeyManager
|
||||||
import app.termora.keymgr.KeyManagerDialog
|
import app.termora.keymgr.KeyManagerDialog
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import app.termora.plugin.internal.BasicProxyOption
|
import app.termora.plugin.internal.BasicProxyOption
|
||||||
|
import app.termora.plugin.internal.BasicTerminalOption
|
||||||
import app.termora.tree.Filter
|
import app.termora.tree.Filter
|
||||||
import app.termora.tree.HostTreeNode
|
import app.termora.tree.HostTreeNode
|
||||||
import app.termora.tree.NewHostTreeDialog
|
import app.termora.tree.NewHostTreeDialog
|
||||||
import com.formdev.flatlaf.FlatClientProperties
|
import com.formdev.flatlaf.FlatClientProperties
|
||||||
import com.formdev.flatlaf.extras.components.FlatComboBox
|
import com.formdev.flatlaf.extras.components.FlatComboBox
|
||||||
import com.formdev.flatlaf.extras.components.FlatTabbedPane
|
|
||||||
import com.formdev.flatlaf.ui.FlatTextBorder
|
import com.formdev.flatlaf.ui.FlatTextBorder
|
||||||
import com.formdev.flatlaf.util.SystemInfo
|
import com.formdev.flatlaf.util.SystemInfo
|
||||||
import com.jgoodies.forms.builder.FormBuilder
|
import com.jgoodies.forms.builder.FormBuilder
|
||||||
@@ -21,20 +22,26 @@ import org.eclipse.jgit.internal.transport.sshd.agent.connector.UnixDomainSocket
|
|||||||
import org.eclipse.jgit.internal.transport.sshd.agent.connector.WinPipeConnector
|
import org.eclipse.jgit.internal.transport.sshd.agent.connector.WinPipeConnector
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
import java.awt.event.*
|
import java.awt.event.*
|
||||||
import java.nio.charset.Charset
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import javax.swing.table.DefaultTableCellRenderer
|
import javax.swing.table.DefaultTableCellRenderer
|
||||||
import javax.swing.table.DefaultTableModel
|
import javax.swing.table.DefaultTableModel
|
||||||
|
|
||||||
@Suppress("CascadeIf")
|
@Suppress("CascadeIf")
|
||||||
open class SSHHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() {
|
internal class SSHHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() {
|
||||||
protected val tunnelingOption = TunnelingOption()
|
private val tunnelingOption = TunnelingOption()
|
||||||
protected val generalOption = GeneralOption()
|
private val generalOption = GeneralOption()
|
||||||
protected val proxyOption = BasicProxyOption()
|
private val proxyOption = BasicProxyOption()
|
||||||
protected val terminalOption = TerminalOption()
|
private val terminalOption = BasicTerminalOption().apply {
|
||||||
protected val jumpHostsOption = JumpHostsOption()
|
showCharsetComboBox = true
|
||||||
protected val sftpOption = SFTPOption()
|
showLoginScripts = true
|
||||||
protected val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
showEnvironmentTextArea = true
|
||||||
|
showStartupCommandTextField = true
|
||||||
|
showHeartbeatIntervalTextField = true
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
private val jumpHostsOption = JumpHostsOption()
|
||||||
|
private val sftpOption = SFTPOption()
|
||||||
|
private val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addOption(generalOption)
|
addOption(generalOption)
|
||||||
@@ -47,7 +54,7 @@ open class SSHHostOptionsPane(private val accountOwner: AccountOwner) : OptionsP
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun getHost(): Host {
|
fun getHost(): Host {
|
||||||
val name = generalOption.nameTextField.text
|
val name = generalOption.nameTextField.text
|
||||||
val protocol = SSHProtocolProvider.PROTOCOL
|
val protocol = SSHProtocolProvider.PROTOCOL
|
||||||
val host = generalOption.hostTextField.text
|
val host = generalOption.hostTextField.text
|
||||||
@@ -98,6 +105,10 @@ open class SSHHostOptionsPane(private val accountOwner: AccountOwner) : OptionsP
|
|||||||
enableX11Forwarding = tunnelingOption.x11ForwardingCheckBox.isSelected,
|
enableX11Forwarding = tunnelingOption.x11ForwardingCheckBox.isSelected,
|
||||||
x11Forwarding = tunnelingOption.x11ServerTextField.text,
|
x11Forwarding = tunnelingOption.x11ServerTextField.text,
|
||||||
loginScripts = terminalOption.loginScripts,
|
loginScripts = terminalOption.loginScripts,
|
||||||
|
extras = mutableMapOf(
|
||||||
|
"altModifier" to (terminalOption.altModifierComboBox.selectedItem?.toString()
|
||||||
|
?: AltKeyModifier.EightBit.name),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return Host(
|
return Host(
|
||||||
@@ -486,102 +497,6 @@ open class SSHHostOptionsPane(private val accountOwner: AccountOwner) : OptionsP
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected inner class TerminalOption : JPanel(BorderLayout()), Option {
|
|
||||||
val charsetComboBox = JComboBox<String>()
|
|
||||||
val startupCommandTextField = OutlineTextField()
|
|
||||||
val heartbeatIntervalTextField = IntSpinner(30, minimum = 3, maximum = Int.MAX_VALUE)
|
|
||||||
val environmentTextArea = FixedLengthTextArea(2048)
|
|
||||||
val loginScripts = mutableListOf<LoginScript>()
|
|
||||||
|
|
||||||
private val loginScriptPanel = LoginScriptPanel(loginScripts)
|
|
||||||
private val tabbed = FlatTabbedPane()
|
|
||||||
|
|
||||||
init {
|
|
||||||
initView()
|
|
||||||
initEvents()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
|
|
||||||
|
|
||||||
tabbed.styleMap = mapOf(
|
|
||||||
"focusColor" to DynamicColor("TabbedPane.background"),
|
|
||||||
"hoverColor" to DynamicColor("TabbedPane.background"),
|
|
||||||
)
|
|
||||||
tabbed.tabHeight = UIManager.getInt("TabbedPane.tabHeight") - 4
|
|
||||||
putClientProperty("ContentPanelBorder", BorderFactory.createEmptyBorder())
|
|
||||||
tabbed.addTab(I18n.getString("termora.new-host.general"), getCenterComponent())
|
|
||||||
tabbed.addTab(I18n.getString("termora.new-host.terminal.login-scripts"), loginScriptPanel)
|
|
||||||
add(tabbed, BorderLayout.CENTER)
|
|
||||||
|
|
||||||
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
|
|
||||||
environmentTextArea.rows = 8
|
|
||||||
environmentTextArea.lineWrap = true
|
|
||||||
environmentTextArea.border = BorderFactory.createEmptyBorder(4, 4, 4, 4)
|
|
||||||
|
|
||||||
for (e in Charset.availableCharsets()) {
|
|
||||||
charsetComboBox.addItem(e.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
charsetComboBox.selectedItem = "UTF-8"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initEvents() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getIcon(isSelected: Boolean): Icon {
|
|
||||||
return Icons.terminal
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTitle(): String {
|
|
||||||
return I18n.getString("termora.new-host.terminal")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJComponent(): JComponent {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCenterComponent(): JComponent {
|
|
||||||
val layout = FormLayout(
|
|
||||||
"left:pref, $FORM_MARGIN, default:grow",
|
|
||||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
|
||||||
)
|
|
||||||
|
|
||||||
var rows = 1
|
|
||||||
val step = 2
|
|
||||||
val panel = FormBuilder.create().layout(layout)
|
|
||||||
.border(BorderFactory.createEmptyBorder(6, 8, 6, 8))
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
|
||||||
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.heartbeat-interval")}:").xy(1, rows)
|
|
||||||
.add(heartbeatIntervalTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
|
||||||
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
|
||||||
.add(JScrollPane(environmentTextArea).apply { border = FlatTextBorder() }).xy(3, rows)
|
|
||||||
.apply { rows += step }
|
|
||||||
.build()
|
|
||||||
|
|
||||||
|
|
||||||
return panel
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected inner class SFTPOption : JPanel(BorderLayout()), Option {
|
protected inner class SFTPOption : JPanel(BorderLayout()), Option {
|
||||||
val defaultDirectoryField = OutlineTextField(255)
|
val defaultDirectoryField = OutlineTextField(255)
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package app.termora.plugin.internal.telnet
|
|||||||
|
|
||||||
import app.termora.*
|
import app.termora.*
|
||||||
import app.termora.account.AccountOwner
|
import app.termora.account.AccountOwner
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import app.termora.plugin.internal.BasicProxyOption
|
import app.termora.plugin.internal.BasicProxyOption
|
||||||
|
import app.termora.plugin.internal.BasicTerminalOption
|
||||||
import com.formdev.flatlaf.FlatClientProperties
|
import com.formdev.flatlaf.FlatClientProperties
|
||||||
import com.formdev.flatlaf.extras.components.FlatTabbedPane
|
|
||||||
import com.formdev.flatlaf.ui.FlatTextBorder
|
import com.formdev.flatlaf.ui.FlatTextBorder
|
||||||
import com.jgoodies.forms.builder.FormBuilder
|
import com.jgoodies.forms.builder.FormBuilder
|
||||||
import com.jgoodies.forms.layout.FormLayout
|
import com.jgoodies.forms.layout.FormLayout
|
||||||
@@ -12,7 +13,6 @@ import java.awt.BorderLayout
|
|||||||
import java.awt.KeyboardFocusManager
|
import java.awt.KeyboardFocusManager
|
||||||
import java.awt.event.ComponentAdapter
|
import java.awt.event.ComponentAdapter
|
||||||
import java.awt.event.ComponentEvent
|
import java.awt.event.ComponentEvent
|
||||||
import java.nio.charset.Charset
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
|
|
||||||
class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() {
|
class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() {
|
||||||
@@ -20,7 +20,16 @@ class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPan
|
|||||||
|
|
||||||
// telnet 不支持代理密码
|
// telnet 不支持代理密码
|
||||||
private val proxyOption = BasicProxyOption(authenticationTypes = listOf())
|
private val proxyOption = BasicProxyOption(authenticationTypes = listOf())
|
||||||
private val terminalOption = TerminalOption()
|
private val terminalOption = BasicTerminalOption().apply {
|
||||||
|
showCharsetComboBox = true
|
||||||
|
showBackspaceComboBox = true
|
||||||
|
showStartupCommandTextField = true
|
||||||
|
showCharacterAtATimeTextField = true
|
||||||
|
showEnvironmentTextArea = true
|
||||||
|
showLoginScripts = true
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addOption(generalOption)
|
addOption(generalOption)
|
||||||
@@ -58,7 +67,9 @@ class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPan
|
|||||||
serialComm = serialComm,
|
serialComm = serialComm,
|
||||||
extras = mutableMapOf(
|
extras = mutableMapOf(
|
||||||
"backspace" to (terminalOption.backspaceComboBox.selectedItem as Backspace).name,
|
"backspace" to (terminalOption.backspaceComboBox.selectedItem as Backspace).name,
|
||||||
"character-at-a-time" to (terminalOption.characterAtATimeTextField.selectedItem?.toString() ?: "false")
|
"character-at-a-time" to (terminalOption.characterAtATimeTextField.selectedItem?.toString() ?: "false"),
|
||||||
|
"altModifier" to (terminalOption.altModifierComboBox.selectedItem?.toString()
|
||||||
|
?: AltKeyModifier.EightBit.name),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -226,108 +237,6 @@ class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPan
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private inner class TerminalOption : JPanel(BorderLayout()), Option {
|
|
||||||
val charsetComboBox = JComboBox<String>()
|
|
||||||
val backspaceComboBox = JComboBox<Backspace>()
|
|
||||||
val startupCommandTextField = OutlineTextField()
|
|
||||||
val characterAtATimeTextField = YesOrNoComboBox()
|
|
||||||
val environmentTextArea = FixedLengthTextArea(2048)
|
|
||||||
val loginScripts = mutableListOf<LoginScript>()
|
|
||||||
|
|
||||||
private val loginScriptPanel = LoginScriptPanel(loginScripts)
|
|
||||||
|
|
||||||
init {
|
|
||||||
initView()
|
|
||||||
initEvents()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
|
|
||||||
backspaceComboBox.addItem(Backspace.Delete)
|
|
||||||
backspaceComboBox.addItem(Backspace.Backspace)
|
|
||||||
backspaceComboBox.addItem(Backspace.VT220)
|
|
||||||
|
|
||||||
characterAtATimeTextField.selectedItem = false
|
|
||||||
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
|
|
||||||
environmentTextArea.rows = 8
|
|
||||||
environmentTextArea.lineWrap = true
|
|
||||||
environmentTextArea.border = BorderFactory.createEmptyBorder(4, 4, 4, 4)
|
|
||||||
|
|
||||||
for (e in Charset.availableCharsets()) {
|
|
||||||
charsetComboBox.addItem(e.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
charsetComboBox.selectedItem = "UTF-8"
|
|
||||||
|
|
||||||
val tabbed = FlatTabbedPane()
|
|
||||||
tabbed.styleMap = mapOf(
|
|
||||||
"focusColor" to DynamicColor("TabbedPane.background"),
|
|
||||||
"hoverColor" to DynamicColor("TabbedPane.background"),
|
|
||||||
)
|
|
||||||
tabbed.tabHeight = UIManager.getInt("TabbedPane.tabHeight") - 4
|
|
||||||
putClientProperty("ContentPanelBorder", BorderFactory.createEmptyBorder())
|
|
||||||
tabbed.addTab(I18n.getString("termora.new-host.general"), getCenterComponent())
|
|
||||||
tabbed.addTab(I18n.getString("termora.new-host.terminal.login-scripts"), loginScriptPanel)
|
|
||||||
add(tabbed, BorderLayout.CENTER)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initEvents() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getIcon(isSelected: Boolean): Icon {
|
|
||||||
return Icons.terminal
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTitle(): String {
|
|
||||||
return I18n.getString("termora.new-host.terminal")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJComponent(): JComponent {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCenterComponent(): JComponent {
|
|
||||||
val layout = FormLayout(
|
|
||||||
"left:pref, $FORM_MARGIN, default:grow",
|
|
||||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
|
||||||
)
|
|
||||||
|
|
||||||
var rows = 1
|
|
||||||
val step = 2
|
|
||||||
val panel = FormBuilder.create().layout(layout)
|
|
||||||
.border(BorderFactory.createEmptyBorder(6, 8, 6, 8))
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
|
||||||
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.backspace")}:").xy(1, rows)
|
|
||||||
.add(backspaceComboBox).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.character-mode")}:").xy(1, rows)
|
|
||||||
.add(characterAtATimeTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
|
||||||
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
|
||||||
.add(JScrollPane(environmentTextArea).apply { border = FlatTextBorder() }).xy(3, rows)
|
|
||||||
.apply { rows += step }
|
|
||||||
.build()
|
|
||||||
|
|
||||||
|
|
||||||
return panel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Backspace {
|
enum class Backspace {
|
||||||
/**
|
/**
|
||||||
* 0x08
|
* 0x08
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package app.termora.plugin.internal.wsl
|
package app.termora.plugin.internal.wsl
|
||||||
|
|
||||||
import app.termora.*
|
import app.termora.*
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
|
import app.termora.plugin.internal.BasicTerminalOption
|
||||||
import com.formdev.flatlaf.FlatClientProperties
|
import com.formdev.flatlaf.FlatClientProperties
|
||||||
import com.formdev.flatlaf.ui.FlatTextBorder
|
import com.formdev.flatlaf.ui.FlatTextBorder
|
||||||
import com.jgoodies.forms.builder.FormBuilder
|
import com.jgoodies.forms.builder.FormBuilder
|
||||||
@@ -12,12 +14,17 @@ import java.awt.KeyboardFocusManager
|
|||||||
import java.awt.Window
|
import java.awt.Window
|
||||||
import java.awt.event.ComponentAdapter
|
import java.awt.event.ComponentAdapter
|
||||||
import java.awt.event.ComponentEvent
|
import java.awt.event.ComponentEvent
|
||||||
import java.nio.charset.Charset
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
|
|
||||||
internal open class WSLHostOptionsPane : OptionsPane() {
|
internal open class WSLHostOptionsPane : OptionsPane() {
|
||||||
protected val generalOption = GeneralOption()
|
protected val generalOption = GeneralOption()
|
||||||
protected val terminalOption = TerminalOption()
|
protected val terminalOption = BasicTerminalOption().apply {
|
||||||
|
showCharsetComboBox = true
|
||||||
|
showStartupCommandTextField = true
|
||||||
|
showEnvironmentTextArea = true
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
protected val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
protected val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -36,7 +43,11 @@ internal open class WSLHostOptionsPane : OptionsPane() {
|
|||||||
encoding = terminalOption.charsetComboBox.selectedItem as String,
|
encoding = terminalOption.charsetComboBox.selectedItem as String,
|
||||||
env = terminalOption.environmentTextArea.text,
|
env = terminalOption.environmentTextArea.text,
|
||||||
startupCommand = terminalOption.startupCommandTextField.text,
|
startupCommand = terminalOption.startupCommandTextField.text,
|
||||||
extras = mutableMapOf("wsl-guid" to wsl.guid, "wsl-flavor" to wsl.flavor)
|
extras = mutableMapOf(
|
||||||
|
"wsl-guid" to wsl.guid, "wsl-flavor" to wsl.flavor,
|
||||||
|
"altModifier" to (terminalOption.altModifierComboBox.selectedItem?.toString()
|
||||||
|
?: AltKeyModifier.EightBit.name),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return Host(
|
return Host(
|
||||||
@@ -216,85 +227,5 @@ internal open class WSLHostOptionsPane : OptionsPane() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected inner class TerminalOption : JPanel(BorderLayout()), Option {
|
|
||||||
val charsetComboBox = JComboBox<String>()
|
|
||||||
val startupCommandTextField = OutlineTextField()
|
|
||||||
val environmentTextArea = FixedLengthTextArea(2048)
|
|
||||||
|
|
||||||
|
|
||||||
init {
|
|
||||||
initView()
|
|
||||||
initEvents()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
add(getCenterComponent(), BorderLayout.CENTER)
|
|
||||||
|
|
||||||
startupCommandTextField.placeholderText = "--cd ~"
|
|
||||||
|
|
||||||
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
|
||||||
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
|
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
|
||||||
.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)
|
|
||||||
)
|
|
||||||
|
|
||||||
environmentTextArea.rows = 8
|
|
||||||
environmentTextArea.lineWrap = true
|
|
||||||
environmentTextArea.border = BorderFactory.createEmptyBorder(4, 4, 4, 4)
|
|
||||||
|
|
||||||
for (e in Charset.availableCharsets()) {
|
|
||||||
charsetComboBox.addItem(e.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
charsetComboBox.selectedItem = "UTF-8"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initEvents() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getIcon(isSelected: Boolean): Icon {
|
|
||||||
return Icons.terminal
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTitle(): String {
|
|
||||||
return I18n.getString("termora.new-host.terminal")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJComponent(): JComponent {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCenterComponent(): JComponent {
|
|
||||||
val layout = FormLayout(
|
|
||||||
"left:pref, $FORM_MARGIN, default:grow",
|
|
||||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
|
||||||
)
|
|
||||||
|
|
||||||
var rows = 1
|
|
||||||
val step = 2
|
|
||||||
val panel = FormBuilder.create().layout(layout)
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
|
||||||
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
|
||||||
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
|
||||||
.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
|
||||||
.add(JScrollPane(environmentTextArea).apply { border = FlatTextBorder() }).xy(3, rows)
|
|
||||||
.apply { rows += step }
|
|
||||||
.build()
|
|
||||||
|
|
||||||
|
|
||||||
return panel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package app.termora.terminal
|
package app.termora.terminal
|
||||||
|
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
@@ -192,6 +193,11 @@ class DataKey<T : Any>(val clazz: KClass<T>) {
|
|||||||
* TerminalWriter
|
* TerminalWriter
|
||||||
*/
|
*/
|
||||||
val TerminalWriter = DataKey(app.termora.terminal.panel.TerminalWriter::class)
|
val TerminalWriter = DataKey(app.termora.terminal.panel.TerminalWriter::class)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [app.termora.plugin.internal.AltKeyModifier]
|
||||||
|
*/
|
||||||
|
val AltModifier = DataKey(AltKeyModifier::class)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package app.termora.terminal.panel
|
|||||||
|
|
||||||
import app.termora.keymap.KeyShortcut
|
import app.termora.keymap.KeyShortcut
|
||||||
import app.termora.keymap.KeymapManager
|
import app.termora.keymap.KeymapManager
|
||||||
|
import app.termora.plugin.internal.AltKeyModifier
|
||||||
import app.termora.terminal.ControlCharacters
|
import app.termora.terminal.ControlCharacters
|
||||||
|
import app.termora.terminal.DataKey
|
||||||
import app.termora.terminal.Terminal
|
import app.termora.terminal.Terminal
|
||||||
import com.formdev.flatlaf.util.SystemInfo
|
import com.formdev.flatlaf.util.SystemInfo
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
@@ -89,8 +91,10 @@ class TerminalPanelKeyAdapter(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/TermoraDev/termora/issues/865
|
||||||
|
val modifier = terminal.getTerminalModel().getData(DataKey.AltModifier, AltKeyModifier.EightBit)
|
||||||
// https://github.com/TermoraDev/termora/issues/331
|
// https://github.com/TermoraDev/termora/issues/331
|
||||||
if (isAltPressedOnly(e) && Character.isDefined(e.keyChar)) {
|
if (isAltPressedOnly(e) && Character.isDefined(e.keyChar) && modifier == AltKeyModifier.CharactersPrecededByESC) {
|
||||||
val c = String(charArrayOf(ASCII_ESC, simpleMapKeyCodeToChar(e)))
|
val c = String(charArrayOf(ASCII_ESC, simpleMapKeyCodeToChar(e)))
|
||||||
writer.write(TerminalWriter.WriteRequest.fromBytes(c.toByteArray(writer.getCharset())))
|
writer.write(TerminalWriter.WriteRequest.fromBytes(c.toByteArray(writer.getCharset())))
|
||||||
// scroll to bottom
|
// scroll to bottom
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ termora.new-host.terminal.backspace=Backspace
|
|||||||
termora.new-host.terminal.character-mode=Character-at-a-time
|
termora.new-host.terminal.character-mode=Character-at-a-time
|
||||||
termora.new-host.terminal.heartbeat-interval=Heartbeat Interval
|
termora.new-host.terminal.heartbeat-interval=Heartbeat Interval
|
||||||
termora.new-host.terminal.startup-commands=Startup Command
|
termora.new-host.terminal.startup-commands=Startup Command
|
||||||
|
termora.new-host.terminal.alt-modifier=Alt modifier
|
||||||
|
termora.new-host.terminal.alt-modifier.eight-bit=8-bit characters
|
||||||
|
termora.new-host.terminal.alt-modifier.by-esc=Characters preceded by ESC
|
||||||
termora.new-host.terminal.env=Environment
|
termora.new-host.terminal.env=Environment
|
||||||
termora.new-host.terminal.login-scripts=Login Scripts
|
termora.new-host.terminal.login-scripts=Login Scripts
|
||||||
termora.new-host.terminal.expect=Expect
|
termora.new-host.terminal.expect=Expect
|
||||||
|
|||||||
@@ -178,6 +178,9 @@ termora.new-host.terminal.backspace=退格键
|
|||||||
termora.new-host.terminal.character-mode=单字符模式
|
termora.new-host.terminal.character-mode=单字符模式
|
||||||
termora.new-host.terminal.heartbeat-interval=心跳间隔
|
termora.new-host.terminal.heartbeat-interval=心跳间隔
|
||||||
termora.new-host.terminal.startup-commands=启动命令
|
termora.new-host.terminal.startup-commands=启动命令
|
||||||
|
termora.new-host.terminal.alt-modifier=Alt 键修饰
|
||||||
|
termora.new-host.terminal.alt-modifier.eight-bit=8 位字符
|
||||||
|
termora.new-host.terminal.alt-modifier.by-esc=ESC 键作为前缀
|
||||||
termora.new-host.terminal.env=环境
|
termora.new-host.terminal.env=环境
|
||||||
termora.new-host.terminal.login-scripts=登录脚本
|
termora.new-host.terminal.login-scripts=登录脚本
|
||||||
termora.new-host.terminal.expect=预期
|
termora.new-host.terminal.expect=预期
|
||||||
|
|||||||
@@ -175,6 +175,9 @@ termora.new-host.terminal.encoding=編碼
|
|||||||
termora.new-host.terminal.backspace=退格鍵
|
termora.new-host.terminal.backspace=退格鍵
|
||||||
termora.new-host.terminal.character-mode=單字元模式
|
termora.new-host.terminal.character-mode=單字元模式
|
||||||
termora.new-host.terminal.startup-commands=啟動命令
|
termora.new-host.terminal.startup-commands=啟動命令
|
||||||
|
termora.new-host.terminal.alt-modifier=Alt 鍵修飾
|
||||||
|
termora.new-host.terminal.alt-modifier.eight-bit=8 位元字符
|
||||||
|
termora.new-host.terminal.alt-modifier.by-esc=ESC 鍵作為前綴
|
||||||
termora.new-host.terminal.heartbeat-interval=心跳間隔
|
termora.new-host.terminal.heartbeat-interval=心跳間隔
|
||||||
termora.new-host.terminal.env=環境
|
termora.new-host.terminal.env=環境
|
||||||
termora.new-host.terminal.login-scripts=登入腳本
|
termora.new-host.terminal.login-scripts=登入腳本
|
||||||
|
|||||||
Reference in New Issue
Block a user