From 6aaed92f2ccca825e6284359580be37168108e40 Mon Sep 17 00:00:00 2001 From: hstyi Date: Wed, 15 Jan 2025 16:51:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20SFTP=20=E6=94=AF=E6=8C=81=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=9A=90=E8=97=8F=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/app/termora/Icons.kt | 2 ++ .../app/termora/transport/FileSystemPanel.kt | 36 +++++++++++++++++-- .../termora/transport/FileSystemTableModel.kt | 25 ++++++++++--- src/main/resources/i18n/messages.properties | 1 + .../resources/i18n/messages_zh_CN.properties | 1 + .../resources/i18n/messages_zh_TW.properties | 1 + src/main/resources/icons/eye.svg | 7 ++++ src/main/resources/icons/eyeClose.svg | 1 + src/main/resources/icons/eyeClose_dark.svg | 7 ++++ src/main/resources/icons/eye_dark.svg | 7 ++++ 10 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 src/main/resources/icons/eye.svg create mode 100644 src/main/resources/icons/eyeClose.svg create mode 100644 src/main/resources/icons/eyeClose_dark.svg create mode 100644 src/main/resources/icons/eye_dark.svg diff --git a/src/main/kotlin/app/termora/Icons.kt b/src/main/kotlin/app/termora/Icons.kt index 7d4a032..bad8ebc 100644 --- a/src/main/kotlin/app/termora/Icons.kt +++ b/src/main/kotlin/app/termora/Icons.kt @@ -8,6 +8,8 @@ object Icons { val moveDown by lazy { DynamicIcon("icons/moveDown.svg", "icons/moveDown_dark.svg") } val close by lazy { DynamicIcon("icons/close.svg", "icons/close_dark.svg") } val searchHistory by lazy { DynamicIcon("icons/searchHistory.svg", "icons/searchHistory_dark.svg") } + val eye by lazy { DynamicIcon("icons/eye.svg", "icons/eye_dark.svg") } + val eyeClose by lazy { DynamicIcon("icons/eyeClose.svg", "icons/eyeClose_dark.svg") } val matchCase by lazy { DynamicIcon("icons/matchCase.svg", "icons/matchCase_dark.svg") } val regex by lazy { DynamicIcon("icons/regex.svg", "icons/regex_dark.svg") } val vcs by lazy { DynamicIcon("icons/vcs.svg", "icons/vcs_dark.svg") } diff --git a/src/main/kotlin/app/termora/transport/FileSystemPanel.kt b/src/main/kotlin/app/termora/transport/FileSystemPanel.kt index 1400b03..ba889b1 100644 --- a/src/main/kotlin/app/termora/transport/FileSystemPanel.kt +++ b/src/main/kotlin/app/termora/transport/FileSystemPanel.kt @@ -6,6 +6,7 @@ import com.formdev.flatlaf.extras.components.FlatPopupMenu import com.formdev.flatlaf.extras.components.FlatToolBar import com.formdev.flatlaf.icons.FlatFileViewDirectoryIcon import com.formdev.flatlaf.icons.FlatFileViewFileIcon +import com.formdev.flatlaf.ui.FlatTableUI import com.formdev.flatlaf.util.SystemInfo import kotlinx.coroutines.* import kotlinx.coroutines.swing.Swing @@ -42,8 +43,7 @@ class FileSystemPanel( private val fileSystem: FileSystem, private val transportManager: TransportManager, private val host: Host -) : JPanel(BorderLayout()), Disposable, - FileSystemTransportListener.Provider { +) : JPanel(BorderLayout()), Disposable, FileSystemTransportListener.Provider { companion object { private val log = LoggerFactory.getLogger(FileSystemPanel::class.java) @@ -58,6 +58,10 @@ class FileSystemPanel( private val loadingPanel = LoadingPanel() private val bookmarkBtn = BookmarkButton() private val homeBtn = JButton(Icons.homeFolder) + private val showHiddenFilesBtn = JButton(Icons.eyeClose) + private val properties get() = Database.getDatabase().properties + private var isShowHiddenFiles = false + private val showHiddenFilesKey by lazy { "termora.transport.host.${host.id}.show-hidden-files" } val workdir get() = tableModel.workdir @@ -72,6 +76,8 @@ class FileSystemPanel( bookmarkBtn.name = "Host.${host.id}.Bookmarks" bookmarkBtn.isBookmark = bookmarkBtn.getBookmarks().contains(workdir.toString()) + table.setUI(FlatTableUI()) + table.rowHeight = UIManager.getInt("Table.rowHeight") table.autoResizeMode = JTable.AUTO_RESIZE_OFF table.fillsViewportHeight = true table.putClientProperty( @@ -121,6 +127,16 @@ class FileSystemPanel( }) parentBtn.toolTipText = I18n.getString("termora.transport.parent-folder") + showHiddenFilesBtn.toolTipText = I18n.getString("termora.transport.show-hidden-files") + + if (properties.getString(showHiddenFilesKey, "true").toBoolean()) { + showHiddenFilesBtn.icon = Icons.eye + tableModel.isShowHiddenFiles = true + } else { + showHiddenFilesBtn.icon = Icons.eyeClose + properties.putString(showHiddenFilesKey, "true") + tableModel.isShowHiddenFiles = false + } val toolbar = FlatToolBar() @@ -128,6 +144,7 @@ class FileSystemPanel( toolbar.add(Box.createHorizontalStrut(2)) toolbar.add(workdirTextField) toolbar.add(bookmarkBtn) + toolbar.add(showHiddenFilesBtn) toolbar.add(parentBtn) toolbar.add(JButton(Icons.refresh).apply { addActionListener { reload() } @@ -290,6 +307,21 @@ class FileSystemPanel( } } + showHiddenFilesBtn.addActionListener { + val showHiddenFiles = tableModel.isShowHiddenFiles + tableModel.isShowHiddenFiles = !showHiddenFiles + if (tableModel.isShowHiddenFiles) { + showHiddenFilesBtn.icon = Icons.eye + } else { + showHiddenFilesBtn.icon = Icons.eyeClose + } + } + + Disposer.register(this, object : Disposable { + override fun dispose() { + properties.putString(showHiddenFilesKey, "${tableModel.isShowHiddenFiles}") + } + }) } diff --git a/src/main/kotlin/app/termora/transport/FileSystemTableModel.kt b/src/main/kotlin/app/termora/transport/FileSystemTableModel.kt index 0cc188d..4b8aa84 100644 --- a/src/main/kotlin/app/termora/transport/FileSystemTableModel.kt +++ b/src/main/kotlin/app/termora/transport/FileSystemTableModel.kt @@ -45,13 +45,18 @@ class FileSystemTableModel(private val fileSystem: FileSystem) : DefaultTableMod private val propertyChangeListeners = mutableListOf() val isLocalFileSystem by lazy { FileSystems.getDefault() == fileSystem } + var isShowHiddenFiles = false + set(value) { + field = value + fireTableDataChanged() + } override fun getRowCount(): Int { - return files?.size ?: 0 + return getShownFiles().size } override fun getValueAt(row: Int, column: Int): Any { - val path = files?.get(row) ?: return StringUtils.EMPTY + val path = getShownFiles()[row] if (path.fileName == ".." && column != 0) { return StringUtils.EMPTY @@ -98,7 +103,7 @@ class FileSystemTableModel(private val fileSystem: FileSystem) : DefaultTableMod } fun getCacheablePath(index: Int): CacheablePath { - return files?.get(index) ?: throw IndexOutOfBoundsException() + return getShownFiles()[index] } override fun isCellEditable(row: Int, column: Int): Boolean { @@ -106,7 +111,8 @@ class FileSystemTableModel(private val fileSystem: FileSystem) : DefaultTableMod } override fun removeRow(row: Int) { - files?.removeAt(row) ?: return + val e = getShownFiles()[row] + files?.removeIf { it == e } fireTableRowsDeleted(row, row) } @@ -155,11 +161,19 @@ class FileSystemTableModel(private val fileSystem: FileSystem) : DefaultTableMod propertyChangeListeners.add(propertyChangeListener) } + private fun getShownFiles(): List { + if (isShowHiddenFiles) { + return files ?: emptyList() + } + return files?.filter { !it.isHidden } ?: emptyList() + } + open class CacheablePath(val path: Path) { val fileName by lazy { path.fileName.toString() } val extension by lazy { path.extension } open val isDirectory by lazy { path.isDirectory() } + open val isHidden by lazy { fileName != ".." && path.isHidden() } open val fileSize by lazy { path.fileSize() } open val lastModifiedTime by lazy { Files.getLastModifiedTime(path).toMillis() } open val owner by lazy { path.getOwner().toString() } @@ -216,6 +230,9 @@ class FileSystemTableModel(private val fileSystem: FileSystem) : DefaultTableMod override val isDirectory: Boolean get() = attributes.isDirectory + override val isHidden: Boolean + get() = fileName != ".." && fileName.startsWith(".") + override val fileSize: Long get() = attributes.size diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index 3d2617d..65e2ed1 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -211,6 +211,7 @@ termora.tools.multiple=Send commands to multiple sessions # Transport termora.transport.local=Local termora.transport.parent-folder=Parent Folder +termora.transport.show-hidden-files=Show hidden files termora.transport.file-already-exists=The file {0} already exists termora.transport.bookmarks=Bookmarks Manager diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties index bcccef2..9e54d14 100644 --- a/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -207,6 +207,7 @@ termora.macro.run=运行 # Transport termora.transport.local=本机 termora.transport.parent-folder=父文件夹 +termora.transport.show-hidden-files=显示隐藏文件 termora.transport.file-already-exists=文件 {0} 已存在 termora.transport.bookmarks=书签管理 diff --git a/src/main/resources/i18n/messages_zh_TW.properties b/src/main/resources/i18n/messages_zh_TW.properties index 7219957..a8ba220 100644 --- a/src/main/resources/i18n/messages_zh_TW.properties +++ b/src/main/resources/i18n/messages_zh_TW.properties @@ -201,6 +201,7 @@ termora.macro.run=運行 # Transport termora.transport.local=本機 termora.transport.parent-folder=父資料夾 +termora.transport.show-hidden-files=顯示隱藏文件 termora.transport.file-already-exists=檔案 {0} 已存在 termora.transport.bookmarks=書籤管理 diff --git a/src/main/resources/icons/eye.svg b/src/main/resources/icons/eye.svg new file mode 100644 index 0000000..96d12b9 --- /dev/null +++ b/src/main/resources/icons/eye.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/icons/eyeClose.svg b/src/main/resources/icons/eyeClose.svg new file mode 100644 index 0000000..7185afe --- /dev/null +++ b/src/main/resources/icons/eyeClose.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/resources/icons/eyeClose_dark.svg b/src/main/resources/icons/eyeClose_dark.svg new file mode 100644 index 0000000..3578a02 --- /dev/null +++ b/src/main/resources/icons/eyeClose_dark.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/icons/eye_dark.svg b/src/main/resources/icons/eye_dark.svg new file mode 100644 index 0000000..3578a02 --- /dev/null +++ b/src/main/resources/icons/eye_dark.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file