feat: Octal Mode Support in the File Permissions Panel

This commit is contained in:
hstyi
2026-02-24 17:07:35 +08:00
committed by hstyi
parent fbb1a70fde
commit c0f3ea8556
6 changed files with 91 additions and 11 deletions

View File

@@ -1,13 +1,17 @@
package app.termora.transfer
import app.termora.DocumentAdaptor
import app.termora.I18n
import app.termora.OptionsPane.Companion.FORM_MARGIN
import app.termora.OutlineTextField
import com.jgoodies.forms.builder.FormBuilder
import com.jgoodies.forms.layout.FormLayout
import java.awt.BorderLayout
import java.awt.Dimension
import java.nio.file.attribute.PosixFilePermission
import java.util.*
import javax.swing.*
import javax.swing.event.DocumentEvent
import kotlin.math.max
class PosixFilePermissionPanel(private val permissions: Set<PosixFilePermission>) : JPanel(BorderLayout()) {
@@ -23,22 +27,16 @@ class PosixFilePermissionPanel(private val permissions: Set<PosixFilePermission>
private val otherWrite = JCheckBox(I18n.getString("termora.transport.permissions.write"))
private val otherExecute = JCheckBox(I18n.getString("termora.transport.permissions.execute"))
private val includeSubFolder = JCheckBox(I18n.getString("termora.transport.permissions.include-subfolder"))
private val octalTextField = OutlineTextField()
init {
initView()
initEvents()
}
private fun initView() {
ownerRead.isSelected = permissions.contains(PosixFilePermission.OWNER_READ)
ownerWrite.isSelected = permissions.contains(PosixFilePermission.OWNER_WRITE)
ownerExecute.isSelected = permissions.contains(PosixFilePermission.OWNER_EXECUTE)
groupRead.isSelected = permissions.contains(PosixFilePermission.GROUP_READ)
groupWrite.isSelected = permissions.contains(PosixFilePermission.GROUP_WRITE)
groupExecute.isSelected = permissions.contains(PosixFilePermission.GROUP_EXECUTE)
otherRead.isSelected = permissions.contains(PosixFilePermission.OTHERS_READ)
otherWrite.isSelected = permissions.contains(PosixFilePermission.OTHERS_WRITE)
otherExecute.isSelected = permissions.contains(PosixFilePermission.OTHERS_EXECUTE)
initCheckBox(permissions)
ownerRead.isFocusable = false
ownerWrite.isFocusable = false
@@ -51,6 +49,8 @@ class PosixFilePermissionPanel(private val permissions: Set<PosixFilePermission>
otherExecute.isFocusable = false
includeSubFolder.isFocusable = false
updateOctalMode()
add(createCenterPanel(), BorderLayout.CENTER)
preferredSize = Dimension(
@@ -60,11 +60,51 @@ class PosixFilePermissionPanel(private val permissions: Set<PosixFilePermission>
}
private fun initCheckBox(permissions: Set<PosixFilePermission>) {
ownerRead.isSelected = permissions.contains(PosixFilePermission.OWNER_READ)
ownerWrite.isSelected = permissions.contains(PosixFilePermission.OWNER_WRITE)
ownerExecute.isSelected = permissions.contains(PosixFilePermission.OWNER_EXECUTE)
groupRead.isSelected = permissions.contains(PosixFilePermission.GROUP_READ)
groupWrite.isSelected = permissions.contains(PosixFilePermission.GROUP_WRITE)
groupExecute.isSelected = permissions.contains(PosixFilePermission.GROUP_EXECUTE)
otherRead.isSelected = permissions.contains(PosixFilePermission.OTHERS_READ)
otherWrite.isSelected = permissions.contains(PosixFilePermission.OTHERS_WRITE)
otherExecute.isSelected = permissions.contains(PosixFilePermission.OTHERS_EXECUTE)
}
private fun initEvents() {
ownerRead.addActionListener { updateOctalMode() }
ownerWrite.addActionListener { updateOctalMode() }
ownerExecute.addActionListener { updateOctalMode() }
groupRead.addActionListener { updateOctalMode() }
groupWrite.addActionListener { updateOctalMode() }
groupExecute.addActionListener { updateOctalMode() }
otherRead.addActionListener { updateOctalMode() }
otherWrite.addActionListener { updateOctalMode() }
otherExecute.addActionListener { updateOctalMode() }
octalTextField.document.addDocumentListener(object : DocumentAdaptor() {
override fun changedUpdate(e: DocumentEvent) {
octalTextField.document.removeDocumentListener(this)
val text = octalTextField.text.trim()
val mode = text.toIntOrNull(radix = 8) ?: toOctalMode(getPermissions())
initCheckBox(fromOctalMode(mode))
octalTextField.document.addDocumentListener(this)
}
})
}
private fun updateOctalMode() {
octalTextField.text = toOctalMode(getPermissions()).toString(8)
}
private fun createCenterPanel(): JComponent {
val formMargin = FORM_MARGIN
val layout = FormLayout(
"default:grow, $formMargin, default:grow, $formMargin, default:grow",
"pref, $formMargin, pref, $formMargin, pref"
"pref, $formMargin, pref, $formMargin, pref, $formMargin, pref"
)
val builder = FormBuilder.create().layout(layout).debug(false)
@@ -92,7 +132,12 @@ class PosixFilePermissionPanel(private val permissions: Set<PosixFilePermission>
otherBox.border = BorderFactory.createTitledBorder(I18n.getString("termora.transport.permissions.others"))
builder.add(otherBox).xy(5, 3)
builder.add(includeSubFolder).xyw(1, 5, 5)
val box = Box.createHorizontalBox()
box.add(JLabel(I18n.getString("termora.transport.permissions.octal-mode") + ": "))
box.add(octalTextField)
builder.add(box).xyw(1, 5, 5)
builder.add(includeSubFolder).xyw(1, 7, 5)
return builder.build()
}
@@ -102,6 +147,36 @@ class PosixFilePermissionPanel(private val permissions: Set<PosixFilePermission>
return includeSubFolder.isSelected
}
fun toOctalMode(p: Set<PosixFilePermission>): Int {
var mode = 0
if (p.contains(PosixFilePermission.OWNER_READ)) mode = mode or 256
if (p.contains(PosixFilePermission.OWNER_WRITE)) mode = mode or 128
if (p.contains(PosixFilePermission.OWNER_EXECUTE)) mode = mode or 64
if (p.contains(PosixFilePermission.GROUP_READ)) mode = mode or 32
if (p.contains(PosixFilePermission.GROUP_WRITE)) mode = mode or 16
if (p.contains(PosixFilePermission.GROUP_EXECUTE)) mode = mode or 8
if (p.contains(PosixFilePermission.OTHERS_READ)) mode = mode or 4
if (p.contains(PosixFilePermission.OTHERS_WRITE)) mode = mode or 2
if (p.contains(PosixFilePermission.OTHERS_EXECUTE)) mode = mode or 1
return mode
}
fun fromOctalMode(mode: Int): Set<PosixFilePermission> {
val m = mode and 511 // 0777 == 511
val set = EnumSet.noneOf(PosixFilePermission::class.java)
if ((m and 256) != 0) set.add(PosixFilePermission.OWNER_READ)
if ((m and 128) != 0) set.add(PosixFilePermission.OWNER_WRITE)
if ((m and 64) != 0) set.add(PosixFilePermission.OWNER_EXECUTE)
if ((m and 32) != 0) set.add(PosixFilePermission.GROUP_READ)
if ((m and 16) != 0) set.add(PosixFilePermission.GROUP_WRITE)
if ((m and 8) != 0) set.add(PosixFilePermission.GROUP_EXECUTE)
if ((m and 4) != 0) set.add(PosixFilePermission.OTHERS_READ)
if ((m and 2) != 0) set.add(PosixFilePermission.OTHERS_WRITE)
if ((m and 1) != 0) set.add(PosixFilePermission.OTHERS_EXECUTE)
return set
}
fun getPermissions(): Set<PosixFilePermission> {
val permissions = mutableSetOf<PosixFilePermission>()

View File

@@ -352,6 +352,7 @@ termora.transport.table.contextmenu.new.file=New File
# Permission
termora.transport.permissions=Change Permissions
termora.transport.permissions.file-folder-permissions=File/Folder Permissions
termora.transport.permissions.octal-mode=Octal mode
termora.transport.permissions.read=Read
termora.transport.permissions.write=Write
termora.transport.permissions.execute=Execute

View File

@@ -352,6 +352,7 @@ termora.transport.table.contextmenu.new.file=Novo Arquivo
# Permission
termora.transport.permissions=Alterar Permissões
termora.transport.permissions.file-folder-permissions=Permissões de Arquivo/Pasta
termora.transport.permissions.octal-mode=Modo octal
termora.transport.permissions.read=Leitura
termora.transport.permissions.write=Escrita
termora.transport.permissions.execute=Execução

View File

@@ -304,6 +304,7 @@ termora.transport.table.contextmenu.new.file=Новый Файл
# Permission
termora.transport.permissions=Изменить Разрешения
termora.transport.permissions.file-folder-permissions=Файл/Папка Разрешения
termora.transport.permissions.octal-mode=Восьмеричный режим
termora.transport.permissions.read=Чтение
termora.transport.permissions.write=Запись
termora.transport.permissions.execute=Выполнение

View File

@@ -375,6 +375,7 @@ termora.transport.sftp.already-exists.actions=操作
# Permission
termora.transport.permissions=更改权限
termora.transport.permissions.file-folder-permissions=文件/文件夹权限
termora.transport.permissions.octal-mode=八进制模式
termora.transport.permissions.read=读取
termora.transport.permissions.write=写入
termora.transport.permissions.execute=执行

View File

@@ -364,6 +364,7 @@ termora.transport.sftp.already-exists.actions=操作
# permissions
termora.transport.permissions=更改權限
termora.transport.permissions.file-folder-permissions=檔案/資料夾權限
termora.transport.permissions.octal-mode=八進位模式
termora.transport.permissions.read=讀取
termora.transport.permissions.write=寫入
termora.transport.permissions.execute=執行