From fcaddcee8020847458103553dbabb59dd95a7533 Mon Sep 17 00:00:00 2001 From: hstyi Date: Thu, 13 Feb 2025 16:46:52 +0800 Subject: [PATCH] feat: open SFTP directly to the current SSH server (#216) --- .../kotlin/app/termora/SFTPTerminalTab.kt | 12 ++++- .../app/termora/transport/SFTPAction.kt | 50 ++++++++++++++++++- .../termora/transport/SftpFileSystemPanel.kt | 2 +- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/app/termora/SFTPTerminalTab.kt b/src/main/kotlin/app/termora/SFTPTerminalTab.kt index d04f807..f56629c 100644 --- a/src/main/kotlin/app/termora/SFTPTerminalTab.kt +++ b/src/main/kotlin/app/termora/SFTPTerminalTab.kt @@ -1,5 +1,7 @@ package app.termora +import app.termora.actions.DataProvider +import app.termora.terminal.DataKey import app.termora.transport.TransportDataProviders import app.termora.transport.TransportPanel import java.beans.PropertyChangeListener @@ -8,7 +10,7 @@ import javax.swing.JComponent import javax.swing.JOptionPane import javax.swing.SwingUtilities -class SFTPTerminalTab : Disposable, TerminalTab { +class SFTPTerminalTab : Disposable, TerminalTab, DataProvider { private val transportPanel by lazy { TransportPanel().apply { @@ -54,4 +56,12 @@ class SFTPTerminalTab : Disposable, TerminalTab { ) == JOptionPane.OK_OPTION } + @Suppress("UNCHECKED_CAST") + override fun getData(dataKey: DataKey): T? { + if (dataKey == TransportDataProviders.TransportPanel) { + return transportPanel as T + } + return null + } + } \ No newline at end of file diff --git a/src/main/kotlin/app/termora/transport/SFTPAction.kt b/src/main/kotlin/app/termora/transport/SFTPAction.kt index f59efc1..464b58c 100644 --- a/src/main/kotlin/app/termora/transport/SFTPAction.kt +++ b/src/main/kotlin/app/termora/transport/SFTPAction.kt @@ -1,7 +1,9 @@ package app.termora.transport +import app.termora.Host import app.termora.Icons import app.termora.SFTPTerminalTab +import app.termora.SSHTerminalTab import app.termora.actions.AnAction import app.termora.actions.AnActionEvent import app.termora.actions.DataProviders @@ -9,15 +11,61 @@ import app.termora.actions.DataProviders class SFTPAction : AnAction("SFTP", Icons.folder) { override fun actionPerformed(evt: AnActionEvent) { val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return + val selectedTerminalTab = terminalTabbedManager.getSelectedTerminalTab() + val host = if (selectedTerminalTab is SSHTerminalTab) selectedTerminalTab.host else null + val tabs = terminalTabbedManager.getTerminalTabs() for (tab in tabs) { if (tab is SFTPTerminalTab) { terminalTabbedManager.setSelectedTerminalTab(tab) + if (host != null) { + connectHost(host, tab) + } return } } // 创建一个新的 - terminalTabbedManager.addTerminalTab(SFTPTerminalTab()) + val tab = SFTPTerminalTab() + terminalTabbedManager.addTerminalTab(tab) + + if (host != null) { + connectHost(host, tab) + } + } + + /** + * 如果当前选中的是 SSH 服务器 Tab,那么直接打开 SFTP 通道 + */ + private fun connectHost(host: Host, tab: SFTPTerminalTab) { + val tabbed = tab.getData(TransportDataProviders.TransportPanel) + ?.getData(TransportDataProviders.RightFileSystemTabbed) ?: return + + // 如果已经有对应的连接 + for (i in 0 until tabbed.tabCount) { + val c = tabbed.getComponentAt(i) + if (c is SftpFileSystemPanel) { + if (c.host == host) { + tabbed.selectedIndex = i + return + } + } + } + + // 寻找空的 Tab,如果有则占用 + for (i in 0 until tabbed.tabCount) { + val c = tabbed.getComponentAt(i) + if (c is SftpFileSystemPanel) { + if (c.host == null) { + c.host = host + c.connect() + tabbed.selectedIndex = i + return + } + } + } + + // 开启一个新的 + tabbed.addTab(host.name, SftpFileSystemPanel(host).apply { connect() }) } } \ No newline at end of file diff --git a/src/main/kotlin/app/termora/transport/SftpFileSystemPanel.kt b/src/main/kotlin/app/termora/transport/SftpFileSystemPanel.kt index 76935ad..c49dbf0 100644 --- a/src/main/kotlin/app/termora/transport/SftpFileSystemPanel.kt +++ b/src/main/kotlin/app/termora/transport/SftpFileSystemPanel.kt @@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicBoolean import javax.swing.* class SftpFileSystemPanel( - private var host: Host? = null + var host: Host? = null ) : JPanel(BorderLayout()), Disposable { companion object {