mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
fix: abnormal operation of transfer dialog
This commit is contained in:
@@ -222,7 +222,7 @@ class ApplicationRunner {
|
|||||||
UIManager.put("TabbedPane.tabHeight", UIManager.getInt("TitleBar.height") - 6)
|
UIManager.put("TabbedPane.tabHeight", UIManager.getInt("TitleBar.height") - 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SystemInfo.isLinux) {
|
if (SystemInfo.isLinux || SystemInfo.isWindows) {
|
||||||
UIManager.put("TitlePane.centerTitle", true)
|
UIManager.put("TitlePane.centerTitle", true)
|
||||||
UIManager.put("TitlePane.showIcon", false)
|
UIManager.put("TitlePane.showIcon", false)
|
||||||
UIManager.put("TitlePane.showIconInDialogs", false)
|
UIManager.put("TitlePane.showIconInDialogs", false)
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import app.termora.plugin.internal.ssh.SSHTerminalTab.Companion.SSHSession
|
|||||||
import app.termora.terminal.DataKey
|
import app.termora.terminal.DataKey
|
||||||
import app.termora.terminal.DataListener
|
import app.termora.terminal.DataListener
|
||||||
import app.termora.transfer.*
|
import app.termora.transfer.*
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties
|
||||||
import com.formdev.flatlaf.icons.FlatOptionPaneErrorIcon
|
import com.formdev.flatlaf.icons.FlatOptionPaneErrorIcon
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo
|
||||||
import com.jgoodies.forms.builder.FormBuilder
|
import com.jgoodies.forms.builder.FormBuilder
|
||||||
import com.jgoodies.forms.layout.FormLayout
|
import com.jgoodies.forms.layout.FormLayout
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@@ -20,17 +22,17 @@ import org.apache.sshd.client.session.ClientSession
|
|||||||
import org.apache.sshd.sftp.client.SftpClientFactory
|
import org.apache.sshd.sftp.client.SftpClientFactory
|
||||||
import org.jdesktop.swingx.JXBusyLabel
|
import org.jdesktop.swingx.JXBusyLabel
|
||||||
import org.jdesktop.swingx.JXHyperlink
|
import org.jdesktop.swingx.JXHyperlink
|
||||||
|
import org.jdesktop.swingx.JXTree
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
import java.awt.event.ActionEvent
|
import java.awt.event.*
|
||||||
import java.awt.event.KeyEvent
|
import java.net.URI
|
||||||
import java.awt.event.WindowAdapter
|
|
||||||
import java.awt.event.WindowEvent
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import kotlin.io.path.absolutePathString
|
import kotlin.io.path.absolutePathString
|
||||||
|
import kotlin.math.max
|
||||||
import kotlin.reflect.cast
|
import kotlin.reflect.cast
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
@@ -83,6 +85,7 @@ class TransferVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindo
|
|||||||
private fun initEvents() {
|
private fun initEvents() {
|
||||||
Disposer.register(tab, this)
|
Disposer.register(tab, this)
|
||||||
Disposer.register(this, disposable)
|
Disposer.register(this, disposable)
|
||||||
|
Disposer.register(disposable, transferManager)
|
||||||
|
|
||||||
connectingPanel.busyLabel.isBusy = true
|
connectingPanel.busyLabel.isBusy = true
|
||||||
|
|
||||||
@@ -103,8 +106,9 @@ class TransferVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindo
|
|||||||
downloadBtn.addActionListener(object : AbstractAction() {
|
downloadBtn.addActionListener(object : AbstractAction() {
|
||||||
override fun actionPerformed(e: ActionEvent) {
|
override fun actionPerformed(e: ActionEvent) {
|
||||||
val dialog = DownloadDialog()
|
val dialog = DownloadDialog()
|
||||||
|
dialog.iconImages = owner.iconImages
|
||||||
dialog.setLocationRelativeTo(downloadBtn)
|
dialog.setLocationRelativeTo(downloadBtn)
|
||||||
dialog.setLocation(dialog.x, downloadBtn.locationOnScreen.y + downloadBtn.height + 1)
|
dialog.setLocation(dialog.x, downloadBtn.locationOnScreen.y + downloadBtn.height + 2)
|
||||||
dialog.isVisible = true
|
dialog.isVisible = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -120,6 +124,12 @@ class TransferVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindo
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
questionBtn.addActionListener(object : AbstractAction() {
|
||||||
|
override fun actionPerformed(e: ActionEvent) {
|
||||||
|
Application.browse(URI.create("https://github.com/TermoraDev/termora/pull/690"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 立即连接
|
// 立即连接
|
||||||
connect()
|
connect()
|
||||||
}
|
}
|
||||||
@@ -219,30 +229,86 @@ class TransferVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class DownloadDialog() : JDialog() {
|
private inner class DownloadDialog() : JDialog() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
size = Dimension(UIManager.getInt("Dialog.width") - 150, UIManager.getInt("Dialog.height") - 100)
|
size = getMySize()
|
||||||
isModal = false
|
isModal = false
|
||||||
title = I18n.getString("termora.transport.sftp")
|
title = I18n.getString("termora.transport.sftp")
|
||||||
isUndecorated = true
|
|
||||||
layout = BorderLayout()
|
layout = BorderLayout()
|
||||||
|
|
||||||
|
if (SystemInfo.isMacOS) {
|
||||||
|
rootPane.putClientProperty("apple.awt.windowTitleVisible", false)
|
||||||
|
rootPane.putClientProperty("apple.awt.fullWindowContent", true)
|
||||||
|
rootPane.putClientProperty("apple.awt.transparentTitleBar", true)
|
||||||
|
}
|
||||||
|
|
||||||
add(createCenterPanel(), BorderLayout.CENTER)
|
add(createCenterPanel(), BorderLayout.CENTER)
|
||||||
val window = this
|
val window = this
|
||||||
|
|
||||||
addWindowFocusListener(object : WindowAdapter() {
|
|
||||||
override fun windowLostFocus(e: WindowEvent?) {
|
|
||||||
window.dispose()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
val inputMap = rootPane.getInputMap(WHEN_IN_FOCUSED_WINDOW)
|
val inputMap = rootPane.getInputMap(WHEN_IN_FOCUSED_WINDOW)
|
||||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close")
|
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close")
|
||||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, toolkit.menuShortcutKeyMaskEx), "close")
|
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, toolkit.menuShortcutKeyMaskEx), "close")
|
||||||
rootPane.actionMap.put("close", object : AnAction() {
|
rootPane.actionMap.put("close", object : AnAction() {
|
||||||
override fun actionPerformed(evt: AnActionEvent) {
|
override fun actionPerformed(evt: AnActionEvent) {
|
||||||
if (hasPopupMenus()) return
|
if (hasPopupMenus().not()) {
|
||||||
SwingUtilities.invokeLater { window.dispose() }
|
window.dispose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 判断失去焦点
|
||||||
|
val awtEventListener = object : AWTEventListener {
|
||||||
|
override fun eventDispatched(event: AWTEvent) {
|
||||||
|
if (event !is MouseEvent) return
|
||||||
|
if (event.id != MouseEvent.MOUSE_PRESSED) return
|
||||||
|
val ancestor = SwingUtilities.getWindowAncestor(event.component)
|
||||||
|
if (ancestor == window) return
|
||||||
|
if (ancestor is Window && getOwners(ancestor).contains(window)) return
|
||||||
|
// JTreeTable 比较特殊,要特别判断
|
||||||
|
if (isFocused && event.component is JXTree) return
|
||||||
|
window.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getOwners(window: Window): List<Window> {
|
||||||
|
val owners = mutableListOf<Window>()
|
||||||
|
var owner: Window? = window.owner
|
||||||
|
while (owner != null) {
|
||||||
|
owners.add(owner)
|
||||||
|
owner = owner.owner
|
||||||
|
}
|
||||||
|
return owners
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听全局事件
|
||||||
|
toolkit.addAWTEventListener(
|
||||||
|
awtEventListener,
|
||||||
|
MouseEvent.MOUSE_EVENT_MASK
|
||||||
|
)
|
||||||
|
|
||||||
|
addWindowListener(object : WindowAdapter() {
|
||||||
|
override fun windowClosed(e: WindowEvent) {
|
||||||
|
removeWindowListener(this)
|
||||||
|
toolkit.removeAWTEventListener(awtEventListener)
|
||||||
|
properties.putString("VisualWindow.DownloadDialog.location.width", width.toString())
|
||||||
|
properties.putString("VisualWindow.DownloadDialog.location.height", height.toString())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMySize(): Dimension {
|
||||||
|
val size = Dimension(UIManager.getInt("Dialog.width") - 150, UIManager.getInt("Dialog.height") - 100)
|
||||||
|
val width = properties.getString(
|
||||||
|
"VisualWindow.DownloadDialog.location.width",
|
||||||
|
size.width.toString()
|
||||||
|
).toIntOrNull() ?: size.width
|
||||||
|
val height = properties.getString(
|
||||||
|
"VisualWindow.DownloadDialog.location.height",
|
||||||
|
size.height.toString()
|
||||||
|
).toIntOrNull() ?: size.height
|
||||||
|
return Dimension(max(width, 250), max(height, 150))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasPopupMenus(): Boolean {
|
private fun hasPopupMenus(): Boolean {
|
||||||
@@ -290,6 +356,21 @@ class TransferVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindo
|
|||||||
return scrollPane
|
return scrollPane
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun addNotify() {
|
||||||
|
super.addNotify()
|
||||||
|
|
||||||
|
if (SystemInfo.isMacOS) {
|
||||||
|
NativeMacLibrary.setControlsVisible(this, false)
|
||||||
|
} else if (SystemInfo.isWindows || SystemInfo.isLinux) {
|
||||||
|
rootPane.putClientProperty(FlatClientProperties.FULL_WINDOW_CONTENT, true)
|
||||||
|
rootPane.putClientProperty(FlatClientProperties.TITLE_BAR_SHOW_ICONIFFY, false)
|
||||||
|
rootPane.putClientProperty(FlatClientProperties.TITLE_BAR_SHOW_ICON, false)
|
||||||
|
rootPane.putClientProperty(FlatClientProperties.TITLE_BAR_SHOW_MAXIMIZE, false)
|
||||||
|
rootPane.putClientProperty(FlatClientProperties.TITLE_BAR_SHOW_TITLE, false)
|
||||||
|
rootPane.putClientProperty(FlatClientProperties.TITLE_BAR_SHOW_CLOSE, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class MyInternalTransferManager() : InternalTransferManager {
|
private inner class MyInternalTransferManager() : InternalTransferManager {
|
||||||
|
|||||||
Reference in New Issue
Block a user