mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
chore: telnet supports backspace key setting
This commit is contained in:
@@ -19,14 +19,13 @@ import java.awt.event.ComponentEvent
|
|||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
|
|
||||||
@Suppress("CascadeIf")
|
class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() {
|
||||||
open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() {
|
|
||||||
protected val generalOption = GeneralOption()
|
protected val generalOption = GeneralOption()
|
||||||
|
|
||||||
// telnet 不支持代理密码
|
// telnet 不支持代理密码
|
||||||
protected val proxyOption = BasicProxyOption(authenticationTypes = listOf())
|
private val proxyOption = BasicProxyOption(authenticationTypes = listOf())
|
||||||
protected val terminalOption = TerminalOption()
|
private val terminalOption = TerminalOption()
|
||||||
protected val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
private val owner: Window get() = SwingUtilities.getWindowAncestor(this)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addOption(generalOption)
|
addOption(generalOption)
|
||||||
@@ -35,7 +34,7 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun getHost(): Host {
|
fun getHost(): Host {
|
||||||
val name = generalOption.nameTextField.text
|
val name = generalOption.nameTextField.text
|
||||||
val protocol = TelnetProtocolProvider.PROTOCOL
|
val protocol = TelnetProtocolProvider.PROTOCOL
|
||||||
val host = generalOption.hostTextField.text
|
val host = generalOption.hostTextField.text
|
||||||
@@ -70,6 +69,7 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
env = terminalOption.environmentTextArea.text,
|
env = terminalOption.environmentTextArea.text,
|
||||||
startupCommand = terminalOption.startupCommandTextField.text,
|
startupCommand = terminalOption.startupCommandTextField.text,
|
||||||
serialComm = serialComm,
|
serialComm = serialComm,
|
||||||
|
extras = mutableMapOf("backspace" to (terminalOption.backspaceComboBox.selectedItem as Backspace).name)
|
||||||
)
|
)
|
||||||
|
|
||||||
return Host(
|
return Host(
|
||||||
@@ -106,6 +106,8 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
terminalOption.charsetComboBox.selectedItem = host.options.encoding
|
terminalOption.charsetComboBox.selectedItem = host.options.encoding
|
||||||
terminalOption.environmentTextArea.text = host.options.env
|
terminalOption.environmentTextArea.text = host.options.env
|
||||||
terminalOption.startupCommandTextField.text = host.options.startupCommand
|
terminalOption.startupCommandTextField.text = host.options.startupCommand
|
||||||
|
terminalOption.backspaceComboBox.selectedItem =
|
||||||
|
Backspace.valueOf(host.options.extras["backspace"] ?: Backspace.Delete.name)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,20 +121,13 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.equalsIgnoreCase(host.protocol, TelnetProtocolProvider.PROTOCOL)) {
|
if (host.authentication.type == AuthenticationType.Password) {
|
||||||
if (validateField(generalOption.usernameTextField)) {
|
if (validateField(generalOption.usernameTextField)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (host.authentication.type == AuthenticationType.Password) {
|
|
||||||
if (validateField(generalOption.passwordTextField)) {
|
if (validateField(generalOption.passwordTextField)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else if (host.authentication.type == AuthenticationType.PublicKey) {
|
|
||||||
if (validateField(generalOption.publicKeyComboBox)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// proxy
|
// proxy
|
||||||
@@ -341,8 +336,9 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected inner class TerminalOption : JPanel(BorderLayout()), Option {
|
private inner class TerminalOption : JPanel(BorderLayout()), Option {
|
||||||
val charsetComboBox = JComboBox<String>()
|
val charsetComboBox = JComboBox<String>()
|
||||||
|
val backspaceComboBox = JComboBox<Backspace>()
|
||||||
val startupCommandTextField = OutlineTextField()
|
val startupCommandTextField = OutlineTextField()
|
||||||
val environmentTextArea = FixedLengthTextArea(2048)
|
val environmentTextArea = FixedLengthTextArea(2048)
|
||||||
|
|
||||||
@@ -355,6 +351,10 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
private fun initView() {
|
private fun initView() {
|
||||||
add(getCenterComponent(), BorderLayout.CENTER)
|
add(getCenterComponent(), BorderLayout.CENTER)
|
||||||
|
|
||||||
|
backspaceComboBox.addItem(Backspace.Delete)
|
||||||
|
backspaceComboBox.addItem(Backspace.Backspace)
|
||||||
|
backspaceComboBox.addItem(Backspace.VT220)
|
||||||
|
|
||||||
|
|
||||||
environmentTextArea.setFocusTraversalKeys(
|
environmentTextArea.setFocusTraversalKeys(
|
||||||
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
|
||||||
@@ -399,7 +399,7 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
private fun getCenterComponent(): JComponent {
|
private fun getCenterComponent(): JComponent {
|
||||||
val layout = FormLayout(
|
val layout = FormLayout(
|
||||||
"left:pref, $FORM_MARGIN, default:grow",
|
"left:pref, $FORM_MARGIN, default:grow",
|
||||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rows = 1
|
var rows = 1
|
||||||
@@ -407,6 +407,8 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
val panel = FormBuilder.create().layout(layout)
|
val panel = FormBuilder.create().layout(layout)
|
||||||
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
.add("${I18n.getString("termora.new-host.terminal.encoding")}:").xy(1, rows)
|
||||||
.add(charsetComboBox).xy(3, rows).apply { rows += step }
|
.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.startup-commands")}:").xy(1, rows)
|
.add("${I18n.getString("termora.new-host.terminal.startup-commands")}:").xy(1, rows)
|
||||||
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
.add(startupCommandTextField).xy(3, rows).apply { rows += step }
|
||||||
.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
.add("${I18n.getString("termora.new-host.terminal.env")}:").xy(1, rows)
|
||||||
@@ -419,4 +421,28 @@ open class TelnetHostOptionsPane(private val accountOwner: AccountOwner) : Optio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Backspace {
|
||||||
|
/**
|
||||||
|
* 0x08
|
||||||
|
*/
|
||||||
|
Backspace,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0x7F 默认
|
||||||
|
*/
|
||||||
|
Delete,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ESC[3~
|
||||||
|
*/
|
||||||
|
VT220, ;
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return when (this) {
|
||||||
|
Backspace -> "ASCII Backspace (0x08)"
|
||||||
|
Delete -> "ASCII Delete (0x7F)"
|
||||||
|
VT220 -> "VT220 Delete (ESC[3~)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
package app.termora.plugin.internal.telnet
|
package app.termora.plugin.internal.telnet
|
||||||
|
|
||||||
import app.termora.*
|
import app.termora.*
|
||||||
|
import app.termora.terminal.ControlCharacters
|
||||||
|
import app.termora.terminal.KeyEncoderImpl
|
||||||
import app.termora.terminal.PtyConnector
|
import app.termora.terminal.PtyConnector
|
||||||
|
import app.termora.terminal.TerminalKeyEvent
|
||||||
import org.apache.commons.net.telnet.*
|
import org.apache.commons.net.telnet.*
|
||||||
|
import java.awt.event.KeyEvent
|
||||||
import java.net.InetSocketAddress
|
import java.net.InetSocketAddress
|
||||||
import java.net.Proxy
|
import java.net.Proxy
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@@ -42,6 +46,16 @@ class TelnetTerminalTab(
|
|||||||
telnet.connect(host.host, host.port)
|
telnet.connect(host.host, host.port)
|
||||||
telnet.keepAlive = true
|
telnet.keepAlive = true
|
||||||
|
|
||||||
|
val encoder = terminal.getKeyEncoder()
|
||||||
|
if (encoder is KeyEncoderImpl) {
|
||||||
|
val backspace = host.options.extras["backspace"]
|
||||||
|
if (backspace == TelnetHostOptionsPane.Backspace.Backspace.name) {
|
||||||
|
encoder.putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_BACK_SPACE), String(byteArrayOf(0x08)))
|
||||||
|
} else if (backspace == TelnetHostOptionsPane.Backspace.VT220.name) {
|
||||||
|
encoder.putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_BACK_SPACE), "${ControlCharacters.ESC}[3~")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ptyConnectorFactory.decorate(TelnetStreamPtyConnector(telnet, telnet.charset))
|
return ptyConnectorFactory.decorate(TelnetStreamPtyConnector(telnet, telnet.charset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
|
|
||||||
configureLeftRight()
|
configureLeftRight()
|
||||||
|
|
||||||
// Ctrl + C
|
// Ctrl + C: 0x7F ASCII Delete
|
||||||
putCode(TerminalKeyEvent(keyCode = 8), String(byteArrayOf(127)))
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_BACK_SPACE), String(byteArrayOf(0x7F)))
|
||||||
|
|
||||||
// Enter
|
// Enter
|
||||||
if (terminalModel.getData(DataKey.AutoNewline, false)) {
|
if (terminalModel.getData(DataKey.AutoNewline, false)) {
|
||||||
@@ -113,7 +113,7 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
return terminal
|
return terminal
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun putCode(event: TerminalKeyEvent, encode: String) {
|
internal fun putCode(event: TerminalKeyEvent, encode: String) {
|
||||||
mapping[event] = encode
|
mapping[event] = encode
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
|| key == KeyEvent.VK_PAGE_UP || key == KeyEvent.VK_PAGE_DOWN
|
|| key == KeyEvent.VK_PAGE_UP || key == KeyEvent.VK_PAGE_DOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
fun arrowKeysApplicationSequences() {
|
private fun arrowKeysApplicationSequences() {
|
||||||
// Up
|
// Up
|
||||||
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_UP), encode = "${ControlCharacters.ESC}OA")
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_UP), encode = "${ControlCharacters.ESC}OA")
|
||||||
// Down
|
// Down
|
||||||
@@ -213,7 +213,7 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_RIGHT), encode = "${ControlCharacters.ESC}OC")
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_RIGHT), encode = "${ControlCharacters.ESC}OC")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun arrowKeysAnsiCursorSequences() {
|
private fun arrowKeysAnsiCursorSequences() {
|
||||||
// Up
|
// Up
|
||||||
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_UP), encode = "${ControlCharacters.ESC}[A")
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_UP), encode = "${ControlCharacters.ESC}[A")
|
||||||
// Down
|
// Down
|
||||||
@@ -227,7 +227,7 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
/**
|
/**
|
||||||
* Alt + Left/Right
|
* Alt + Left/Right
|
||||||
*/
|
*/
|
||||||
fun configureLeftRight() {
|
private fun configureLeftRight() {
|
||||||
if (SystemInfo.isMacOS) {
|
if (SystemInfo.isMacOS) {
|
||||||
putCode(
|
putCode(
|
||||||
TerminalKeyEvent(keyCode = KeyEvent.VK_LEFT, TerminalEvent.ALT_MASK),
|
TerminalKeyEvent(keyCode = KeyEvent.VK_LEFT, TerminalEvent.ALT_MASK),
|
||||||
@@ -262,7 +262,7 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun keypadApplicationSequences() {
|
private fun keypadApplicationSequences() {
|
||||||
// Up
|
// Up
|
||||||
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_KP_UP), encode = "${ControlCharacters.ESC}OA")
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_KP_UP), encode = "${ControlCharacters.ESC}OA")
|
||||||
// Down
|
// Down
|
||||||
@@ -277,7 +277,7 @@ open class KeyEncoderImpl(private val terminal: Terminal) : KeyEncoder, DataList
|
|||||||
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_END), encode = "${ControlCharacters.ESC}OF")
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_END), encode = "${ControlCharacters.ESC}OF")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun keypadAnsiSequences() {
|
private fun keypadAnsiSequences() {
|
||||||
// Up
|
// Up
|
||||||
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_KP_UP), encode = "${ControlCharacters.ESC}[A")
|
putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_KP_UP), encode = "${ControlCharacters.ESC}[A")
|
||||||
// Down
|
// Down
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ termora.new-host.proxy=Proxy
|
|||||||
|
|
||||||
termora.new-host.terminal=${termora.settings.terminal}
|
termora.new-host.terminal=${termora.settings.terminal}
|
||||||
termora.new-host.terminal.encoding=Encoding
|
termora.new-host.terminal.encoding=Encoding
|
||||||
|
termora.new-host.terminal.backspace=Backspace
|
||||||
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.env=Environment
|
termora.new-host.terminal.env=Environment
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ termora.new-host.proxy=代理
|
|||||||
|
|
||||||
termora.new-host.terminal=${termora.settings.terminal}
|
termora.new-host.terminal=${termora.settings.terminal}
|
||||||
termora.new-host.terminal.encoding=编码
|
termora.new-host.terminal.encoding=编码
|
||||||
|
termora.new-host.terminal.backspace=退格键
|
||||||
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.env=环境
|
termora.new-host.terminal.env=环境
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ termora.new-host.proxy=代理
|
|||||||
|
|
||||||
termora.new-host.terminal=${termora.settings.terminal}
|
termora.new-host.terminal=${termora.settings.terminal}
|
||||||
termora.new-host.terminal.encoding=編碼
|
termora.new-host.terminal.encoding=編碼
|
||||||
|
termora.new-host.terminal.backspace=退格鍵
|
||||||
termora.new-host.terminal.startup-commands=啟動命令
|
termora.new-host.terminal.startup-commands=啟動命令
|
||||||
termora.new-host.terminal.heartbeat-interval=心跳間隔
|
termora.new-host.terminal.heartbeat-interval=心跳間隔
|
||||||
termora.new-host.terminal.env=環境
|
termora.new-host.terminal.env=環境
|
||||||
|
|||||||
Reference in New Issue
Block a user