mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-15 18:02:58 +08:00
fix: SFTP path not jumping on Windows (#483)
This commit is contained in:
9
src/main/kotlin/app/termora/sftp/FileSystemProvider.kt
Normal file
9
src/main/kotlin/app/termora/sftp/FileSystemProvider.kt
Normal file
@@ -0,0 +1,9 @@
|
||||
package app.termora.sftp
|
||||
|
||||
import org.apache.commons.vfs2.FileSystem
|
||||
|
||||
|
||||
interface FileSystemProvider {
|
||||
fun getFileSystem(): FileSystem
|
||||
fun setFileSystem(fileSystem: FileSystem)
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import javax.swing.filechooser.FileSystemView
|
||||
import kotlin.io.path.absolutePathString
|
||||
|
||||
class FileSystemViewNav(
|
||||
private val fileSystem: org.apache.commons.vfs2.FileSystem,
|
||||
private val fileSystemProvider: FileSystemProvider,
|
||||
private val homeDirectory: FileObject
|
||||
) : JPanel(BorderLayout()) {
|
||||
|
||||
@@ -103,7 +103,7 @@ class FileSystemViewNav(
|
||||
add(layeredPane, BorderLayout.CENTER)
|
||||
|
||||
|
||||
if (SystemInfo.isWindows && fileSystem is LocalFileSystem) {
|
||||
if (SystemInfo.isWindows && fileSystemProvider.getFileSystem() is LocalFileSystem) {
|
||||
try {
|
||||
for (root in fileSystemView.roots) {
|
||||
history.add(root.absolutePath)
|
||||
@@ -174,9 +174,14 @@ class FileSystemViewNav(
|
||||
override fun actionPerformed(e: ActionEvent) {
|
||||
val name = textField.text.trim()
|
||||
if (name.isBlank()) return
|
||||
val fileSystem = fileSystemProvider.getFileSystem()
|
||||
try {
|
||||
if (fileSystem is LocalFileSystem && SystemUtils.IS_OS_WINDOWS) {
|
||||
changeSelectedPath(fileSystem.resolveFile("file://${name}"))
|
||||
val file = VFS.getManager().resolveFile("file://${name}")
|
||||
if (!StringUtils.equals(file.fileSystem.rootURI, fileSystemProvider.getFileSystem().rootURI)) {
|
||||
fileSystemProvider.setFileSystem(file.fileSystem)
|
||||
}
|
||||
changeSelectedPath(file)
|
||||
} else {
|
||||
changeSelectedPath(fileSystem.resolveFile(name))
|
||||
}
|
||||
@@ -192,6 +197,7 @@ class FileSystemViewNav(
|
||||
private fun showComboBoxPopup() {
|
||||
|
||||
comboBox.removeAllItems()
|
||||
val fileSystem = fileSystemProvider.getFileSystem()
|
||||
|
||||
for (text in history) {
|
||||
val path = if (SystemInfo.isWindows && fileSystem is LocalFileSystem) {
|
||||
|
||||
@@ -10,9 +10,13 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.swing.Swing
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import org.apache.commons.lang3.SystemUtils
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils
|
||||
import org.apache.commons.vfs2.FileObject
|
||||
import org.apache.commons.vfs2.FileSystem
|
||||
import org.apache.commons.vfs2.VFS
|
||||
import org.apache.commons.vfs2.provider.local.LocalFileSystem
|
||||
import org.jdesktop.swingx.JXBusyLabel
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.event.*
|
||||
@@ -22,14 +26,14 @@ import javax.swing.*
|
||||
|
||||
class FileSystemViewPanel(
|
||||
val host: Host,
|
||||
val fileSystem: org.apache.commons.vfs2.FileSystem,
|
||||
private var fileSystem: FileSystem,
|
||||
private val transportManager: TransportManager,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
) : JPanel(BorderLayout()), Disposable, DataProvider {
|
||||
) : JPanel(BorderLayout()), Disposable, DataProvider, FileSystemProvider {
|
||||
|
||||
private val properties get() = Database.getDatabase().properties
|
||||
private val sftp get() = Database.getDatabase().sftp
|
||||
private val table = FileSystemViewTable(fileSystem, transportManager, coroutineScope)
|
||||
private val table = FileSystemViewTable(this, transportManager, coroutineScope)
|
||||
private val disposed = AtomicBoolean(false)
|
||||
private var nextReloadTicks = emptyArray<Consumer<Unit>>()
|
||||
private val isLoading = AtomicBoolean(false)
|
||||
@@ -37,7 +41,7 @@ class FileSystemViewPanel(
|
||||
private val loadingPanel = LoadingPanel()
|
||||
private val layeredPane = LayeredPane()
|
||||
private val homeDirectory = getHomeDirectory()
|
||||
private val nav = FileSystemViewNav(fileSystem, homeDirectory)
|
||||
private val nav = FileSystemViewNav(this, homeDirectory)
|
||||
private var workdir = homeDirectory
|
||||
private val model get() = table.model as FileSystemViewTableModel
|
||||
private val showHiddenFilesKey = "termora.transport.host.${host.id}.show-hidden-files"
|
||||
@@ -173,7 +177,15 @@ class FileSystemViewPanel(
|
||||
}
|
||||
bookmarkBtn.isBookmark = !bookmarkBtn.isBookmark
|
||||
} else {
|
||||
changeWorkdir(fileSystem.resolveFile(e.actionCommand))
|
||||
if (fileSystem is LocalFileSystem && SystemUtils.IS_OS_WINDOWS) {
|
||||
val file = VFS.getManager().resolveFile("file://${e.actionCommand}")
|
||||
if (!StringUtils.equals(file.fileSystem.rootURI, fileSystem.rootURI)) {
|
||||
fileSystem = file.fileSystem
|
||||
}
|
||||
changeWorkdir(file)
|
||||
} else {
|
||||
changeWorkdir(fileSystem.resolveFile(e.actionCommand))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,6 +384,7 @@ class FileSystemViewPanel(
|
||||
}
|
||||
|
||||
private fun getHomeDirectory(): FileObject {
|
||||
val fileSystem = this.fileSystem
|
||||
if (fileSystem is MySftpFileSystem) {
|
||||
val host = fileSystem.getClientSession().getAttribute(SshClients.HOST_KEY)
|
||||
?: return fileSystem.resolveFile(fileSystem.getDefaultDir())
|
||||
@@ -429,6 +442,14 @@ class FileSystemViewPanel(
|
||||
return if (dataKey == SFTPDataProviders.FileSystemViewTable) table as T else null
|
||||
}
|
||||
|
||||
override fun getFileSystem(): FileSystem {
|
||||
return fileSystem
|
||||
}
|
||||
|
||||
override fun setFileSystem(fileSystem: FileSystem) {
|
||||
this.fileSystem = fileSystem
|
||||
}
|
||||
|
||||
private class LoadingPanel : JPanel() {
|
||||
private val busyLabel = JXBusyLabel()
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@Suppress("DuplicatedCode", "CascadeIf")
|
||||
class FileSystemViewTable(
|
||||
private val fileSystem: org.apache.commons.vfs2.FileSystem,
|
||||
private val fileSystemProvider: FileSystemProvider,
|
||||
private val transportManager: TransportManager,
|
||||
private val coroutineScope: CoroutineScope
|
||||
) : JTable(), Disposable {
|
||||
@@ -184,7 +184,7 @@ class FileSystemViewTable(
|
||||
val data = support.transferable.getTransferData(FileSystemTableRowTransferable.dataFlavor)
|
||||
return data is FileSystemTableRowTransferable && data.source != table
|
||||
} else if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
|
||||
return fileSystem !is LocalFileSystem
|
||||
return fileSystemProvider.getFileSystem() !is LocalFileSystem
|
||||
}
|
||||
|
||||
return false
|
||||
@@ -261,6 +261,7 @@ class FileSystemViewTable(
|
||||
private fun showContextMenu(rows: IntArray, e: MouseEvent) {
|
||||
val files = rows.map { model.getFileObject(it) }
|
||||
val hasParent = rows.contains(0)
|
||||
val fileSystem = fileSystemProvider.getFileSystem()
|
||||
|
||||
val popupMenu = FlatPopupMenu()
|
||||
val newMenu = JMenu(I18n.getString("termora.transport.table.contextmenu.new"))
|
||||
@@ -571,7 +572,7 @@ class FileSystemViewTable(
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
|
||||
runCatching {
|
||||
if (fileSystem is MySftpFileSystem) {
|
||||
if (fileSystemProvider.getFileSystem() is MySftpFileSystem) {
|
||||
deleteSftpPaths(paths, rm)
|
||||
} else {
|
||||
deleteRecursively(paths)
|
||||
@@ -594,7 +595,7 @@ class FileSystemViewTable(
|
||||
|
||||
private fun deleteSftpPaths(files: List<FileObject>, rm: Boolean = false) {
|
||||
if (rm) {
|
||||
val session = (this.fileSystem as MySftpFileSystem).getClientSession()
|
||||
val session = (this.fileSystemProvider.getFileSystem() as MySftpFileSystem).getClientSession()
|
||||
for (path in files) {
|
||||
session.executeRemoteCommand(
|
||||
"rm -rf '${path.absolutePathString()}'",
|
||||
|
||||
@@ -127,7 +127,7 @@ class SFTPPanel : JPanel(BorderLayout()), DataProvider, Disposable {
|
||||
return
|
||||
}
|
||||
|
||||
val fs = c.fileSystem
|
||||
val fs = c.getFileSystem()
|
||||
val root = transportManager.root
|
||||
|
||||
transportManager.lock.withLock {
|
||||
|
||||
Reference in New Issue
Block a user