diff --git a/src/main/kotlin/app/termora/HostTree.kt b/src/main/kotlin/app/termora/HostTree.kt index 510a9f4..b3793b2 100644 --- a/src/main/kotlin/app/termora/HostTree.kt +++ b/src/main/kotlin/app/termora/HostTree.kt @@ -1,11 +1,14 @@ package app.termora +import app.termora.actions.AnActionEvent import app.termora.actions.NewHostAction import app.termora.actions.OpenHostAction +import app.termora.transport.SFTPAction import com.formdev.flatlaf.extras.components.FlatPopupMenu import com.formdev.flatlaf.icons.FlatTreeClosedIcon import com.formdev.flatlaf.icons.FlatTreeOpenIcon +import org.apache.commons.lang3.StringUtils import org.jdesktop.swingx.action.ActionManager import org.jdesktop.swingx.tree.DefaultXTreeCellRenderer import java.awt.Component @@ -350,6 +353,7 @@ class HostTree : JTree(), Disposable { val newHost = newMenu.add(I18n.getString("termora.welcome.contextmenu.new.host")) 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")) popupMenu.addSeparator() 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")) open.addActionListener { openHosts(it, false) } + openWithSFTP.addActionListener { openWithSFTP(it) } openInNewWindow.addActionListener { openHosts(it, true) } + // 如果选中了 SSH 服务器,那么才启用 + openWithSFTP.isEnabled = getSelectionNodes().any { it.protocol == Protocol.SSH } + rename.addActionListener { startEditingAtPath(TreePath(model.getPathToRoot(lastHost))) } @@ -503,6 +511,17 @@ class HostTree : JTree(), Disposable { 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) { expandPath(TreePath(model.getPathToRoot(node))) if (including) { diff --git a/src/main/kotlin/app/termora/transport/SFTPAction.kt b/src/main/kotlin/app/termora/transport/SFTPAction.kt index 464b58c..dfee745 100644 --- a/src/main/kotlin/app/termora/transport/SFTPAction.kt +++ b/src/main/kotlin/app/termora/transport/SFTPAction.kt @@ -13,31 +13,40 @@ class SFTPAction : AnAction("SFTP", Icons.folder) { 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 - } - } - - // 创建一个新的 - val tab = SFTPTerminalTab() - terminalTabbedManager.addTerminalTab(tab) + val tab = openOrCreateSFTPTerminalTab(evt) ?: return if (host != null) { 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 通道 */ - private fun connectHost(host: Host, tab: SFTPTerminalTab) { + fun connectHost(host: Host, tab: SFTPTerminalTab) { val tabbed = tab.getData(TransportDataProviders.TransportPanel) ?.getData(TransportDataProviders.RightFileSystemTabbed) ?: return diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index 280678a..187def6 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -127,6 +127,7 @@ termora.find-everywhere.double-shift-deprecated-instead=${termora.find-everywher # Welcome termora.welcome.my-hosts=My hosts 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.copy=${termora.copy} termora.welcome.contextmenu.remove=${termora.remove} diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties index 6ca8239..6a44489 100644 --- a/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -117,6 +117,7 @@ termora.settings.sftp.edit-command=编辑命令 # Welcome termora.welcome.my-hosts=我的主机 termora.welcome.contextmenu.open=打开 +termora.welcome.contextmenu.open-with-sftp=使用 SFTP 打开 termora.welcome.contextmenu.copy=${termora.copy} termora.welcome.contextmenu.remove=${termora.remove} termora.welcome.contextmenu.rename=重命名 diff --git a/src/main/resources/i18n/messages_zh_TW.properties b/src/main/resources/i18n/messages_zh_TW.properties index 4af91ca..0418274 100644 --- a/src/main/resources/i18n/messages_zh_TW.properties +++ b/src/main/resources/i18n/messages_zh_TW.properties @@ -116,6 +116,7 @@ termora.settings.about.termora=${termora.title} ({0}) 是一個跨 # Welcome termora.welcome.my-hosts=我的主機 termora.welcome.contextmenu.open=打開 +termora.welcome.contextmenu.open-with-sftp=使用 SFTP 打開 termora.welcome.contextmenu.copy=複製 termora.welcome.contextmenu.remove=${termora.remove} termora.welcome.contextmenu.rename=重新命名