feat: open with SFTP (#217)

This commit is contained in:
hstyi
2025-02-13 17:04:14 +08:00
committed by GitHub
parent fcaddcee80
commit 0e40b5ecce
5 changed files with 47 additions and 16 deletions

View File

@@ -1,11 +1,14 @@
package app.termora package app.termora
import app.termora.actions.AnActionEvent
import app.termora.actions.NewHostAction import app.termora.actions.NewHostAction
import app.termora.actions.OpenHostAction import app.termora.actions.OpenHostAction
import app.termora.transport.SFTPAction
import com.formdev.flatlaf.extras.components.FlatPopupMenu import com.formdev.flatlaf.extras.components.FlatPopupMenu
import com.formdev.flatlaf.icons.FlatTreeClosedIcon import com.formdev.flatlaf.icons.FlatTreeClosedIcon
import com.formdev.flatlaf.icons.FlatTreeOpenIcon import com.formdev.flatlaf.icons.FlatTreeOpenIcon
import org.apache.commons.lang3.StringUtils
import org.jdesktop.swingx.action.ActionManager import org.jdesktop.swingx.action.ActionManager
import org.jdesktop.swingx.tree.DefaultXTreeCellRenderer import org.jdesktop.swingx.tree.DefaultXTreeCellRenderer
import java.awt.Component import java.awt.Component
@@ -350,6 +353,7 @@ class HostTree : JTree(), Disposable {
val newHost = newMenu.add(I18n.getString("termora.welcome.contextmenu.new.host")) val newHost = newMenu.add(I18n.getString("termora.welcome.contextmenu.new.host"))
val open = popupMenu.add(I18n.getString("termora.welcome.contextmenu.open")) val open = popupMenu.add(I18n.getString("termora.welcome.contextmenu.open"))
val openWithSFTP = popupMenu.add(I18n.getString("termora.welcome.contextmenu.open-with-sftp"))
val openInNewWindow = popupMenu.add(I18n.getString("termora.welcome.contextmenu.open-in-new-window")) val openInNewWindow = popupMenu.add(I18n.getString("termora.welcome.contextmenu.open-in-new-window"))
popupMenu.addSeparator() popupMenu.addSeparator()
val copy = popupMenu.add(I18n.getString("termora.welcome.contextmenu.copy")) val copy = popupMenu.add(I18n.getString("termora.welcome.contextmenu.copy"))
@@ -375,8 +379,12 @@ class HostTree : JTree(), Disposable {
val property = popupMenu.add(I18n.getString("termora.welcome.contextmenu.property")) val property = popupMenu.add(I18n.getString("termora.welcome.contextmenu.property"))
open.addActionListener { openHosts(it, false) } open.addActionListener { openHosts(it, false) }
openWithSFTP.addActionListener { openWithSFTP(it) }
openInNewWindow.addActionListener { openHosts(it, true) } openInNewWindow.addActionListener { openHosts(it, true) }
// 如果选中了 SSH 服务器,那么才启用
openWithSFTP.isEnabled = getSelectionNodes().any { it.protocol == Protocol.SSH }
rename.addActionListener { rename.addActionListener {
startEditingAtPath(TreePath(model.getPathToRoot(lastHost))) startEditingAtPath(TreePath(model.getPathToRoot(lastHost)))
} }
@@ -503,6 +511,17 @@ class HostTree : JTree(), Disposable {
nodes.forEach { openHostAction.actionPerformed(OpenHostActionEvent(source, it, evt)) } nodes.forEach { openHostAction.actionPerformed(OpenHostActionEvent(source, it, evt)) }
} }
private fun openWithSFTP(evt: EventObject) {
val nodes = getSelectionNodes().filter { it.protocol == Protocol.SSH }
if (nodes.isEmpty()) return
val sftpAction = ActionManager.getInstance().getAction(Actions.SFTP) as SFTPAction? ?: return
val tab = sftpAction.openOrCreateSFTPTerminalTab(AnActionEvent(this, StringUtils.EMPTY, evt)) ?: return
for (node in nodes) {
sftpAction.connectHost(node, tab)
}
}
fun expandNode(node: Host, including: Boolean = false) { fun expandNode(node: Host, including: Boolean = false) {
expandPath(TreePath(model.getPathToRoot(node))) expandPath(TreePath(model.getPathToRoot(node)))
if (including) { if (including) {

View File

@@ -13,31 +13,40 @@ class SFTPAction : AnAction("SFTP", Icons.folder) {
val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return
val selectedTerminalTab = terminalTabbedManager.getSelectedTerminalTab() val selectedTerminalTab = terminalTabbedManager.getSelectedTerminalTab()
val host = if (selectedTerminalTab is SSHTerminalTab) selectedTerminalTab.host else null val host = if (selectedTerminalTab is SSHTerminalTab) selectedTerminalTab.host else null
val tab = openOrCreateSFTPTerminalTab(evt) ?: return
val tabs = terminalTabbedManager.getTerminalTabs()
for (tab in tabs) {
if (tab is SFTPTerminalTab) {
terminalTabbedManager.setSelectedTerminalTab(tab)
if (host != null) {
connectHost(host, tab)
}
return
}
}
// 创建一个新的
val tab = SFTPTerminalTab()
terminalTabbedManager.addTerminalTab(tab)
if (host != null) { if (host != null) {
connectHost(host, tab) connectHost(host, tab)
} }
} }
/**
* 打开一个已经存在或者创建一个 SFTP Tab
*
* @return null 表示当前条件下无法创建
*/
fun openOrCreateSFTPTerminalTab(evt: AnActionEvent): SFTPTerminalTab? {
val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return null
val tabs = terminalTabbedManager.getTerminalTabs()
for (tab in tabs) {
if (tab is SFTPTerminalTab) {
terminalTabbedManager.setSelectedTerminalTab(tab)
return tab
}
}
// 创建一个新的
val tab = SFTPTerminalTab()
terminalTabbedManager.addTerminalTab(tab)
return tab
}
/** /**
* 如果当前选中的是 SSH 服务器 Tab那么直接打开 SFTP 通道 * 如果当前选中的是 SSH 服务器 Tab那么直接打开 SFTP 通道
*/ */
private fun connectHost(host: Host, tab: SFTPTerminalTab) { fun connectHost(host: Host, tab: SFTPTerminalTab) {
val tabbed = tab.getData(TransportDataProviders.TransportPanel) val tabbed = tab.getData(TransportDataProviders.TransportPanel)
?.getData(TransportDataProviders.RightFileSystemTabbed) ?: return ?.getData(TransportDataProviders.RightFileSystemTabbed) ?: return

View File

@@ -127,6 +127,7 @@ termora.find-everywhere.double-shift-deprecated-instead=${termora.find-everywher
# Welcome # Welcome
termora.welcome.my-hosts=My hosts termora.welcome.my-hosts=My hosts
termora.welcome.contextmenu.open=Open termora.welcome.contextmenu.open=Open
termora.welcome.contextmenu.open-with-sftp=Open with SFTP
termora.welcome.contextmenu.open-in-new-window=${termora.tabbed.contextmenu.open-in-new-window} termora.welcome.contextmenu.open-in-new-window=${termora.tabbed.contextmenu.open-in-new-window}
termora.welcome.contextmenu.copy=${termora.copy} termora.welcome.contextmenu.copy=${termora.copy}
termora.welcome.contextmenu.remove=${termora.remove} termora.welcome.contextmenu.remove=${termora.remove}

View File

@@ -117,6 +117,7 @@ termora.settings.sftp.edit-command=编辑命令
# Welcome # Welcome
termora.welcome.my-hosts=我的主机 termora.welcome.my-hosts=我的主机
termora.welcome.contextmenu.open=打开 termora.welcome.contextmenu.open=打开
termora.welcome.contextmenu.open-with-sftp=使用 SFTP 打开
termora.welcome.contextmenu.copy=${termora.copy} termora.welcome.contextmenu.copy=${termora.copy}
termora.welcome.contextmenu.remove=${termora.remove} termora.welcome.contextmenu.remove=${termora.remove}
termora.welcome.contextmenu.rename=重命名 termora.welcome.contextmenu.rename=重命名

View File

@@ -116,6 +116,7 @@ termora.settings.about.termora=<html><b>${termora.title}</b> ({0}) 是一個跨
# Welcome # Welcome
termora.welcome.my-hosts=我的主機 termora.welcome.my-hosts=我的主機
termora.welcome.contextmenu.open=打開 termora.welcome.contextmenu.open=打開
termora.welcome.contextmenu.open-with-sftp=使用 SFTP 打開
termora.welcome.contextmenu.copy=複製 termora.welcome.contextmenu.copy=複製
termora.welcome.contextmenu.remove=${termora.remove} termora.welcome.contextmenu.remove=${termora.remove}
termora.welcome.contextmenu.rename=重新命名 termora.welcome.contextmenu.rename=重新命名