diff --git a/src/main/kotlin/app/termora/NewHostDialogV2.kt b/src/main/kotlin/app/termora/NewHostDialogV2.kt index 6974e51..78eaf55 100644 --- a/src/main/kotlin/app/termora/NewHostDialogV2.kt +++ b/src/main/kotlin/app/termora/NewHostDialogV2.kt @@ -1,8 +1,10 @@ package app.termora import app.termora.account.AccountOwner +import app.termora.account.TeamRole import app.termora.actions.AnAction import app.termora.actions.AnActionEvent +import app.termora.database.OwnerType import app.termora.protocol.* import app.termora.transfer.ScaleIcon import com.formdev.flatlaf.extras.components.FlatToolBar @@ -13,9 +15,11 @@ import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.withContext import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.exception.ExceptionUtils +import org.jdesktop.swingx.SwingXUtilities import java.awt.BorderLayout import java.awt.CardLayout import java.awt.Dimension +import java.awt.Graphics import java.awt.Window import javax.swing.* @@ -144,10 +148,33 @@ class NewHostDialogV2( val provider = extension.getProtocolProvider() testConnectionBtn.isVisible = provider is ProtocolTester + preventImportantData() + } + + private fun preventImportantData() { + if (visitorMode()) { + for (component in SwingUtils.getDescendantsOfType(JComponent::class.java, cardPanel)) { + if (component is OutlinePasswordField) { + component.styleMap = component.styleMap.toMutableMap().apply { + put("showRevealButton", false) + } + } + } + } + } + + private fun visitorMode(): Boolean { + return accountOwner.isVisitorMode() } override fun createActions(): List { - return listOf(createOkAction(), testConnectionAction, CancelAction()) + val actions = mutableListOf() + if (visitorMode().not()) { + actions.add(createOkAction()) + actions.add(testConnectionAction) + } + actions.add(CancelAction()) + return actions } override fun createJButtonForAction(action: Action): JButton { @@ -238,5 +265,4 @@ class NewHostDialogV2( super.doOKAction() } - } \ No newline at end of file diff --git a/src/main/kotlin/app/termora/account/AccountHttp.kt b/src/main/kotlin/app/termora/account/AccountHttp.kt index 1ef7db2..8f9e96e 100644 --- a/src/main/kotlin/app/termora/account/AccountHttp.kt +++ b/src/main/kotlin/app/termora/account/AccountHttp.kt @@ -40,8 +40,8 @@ object AccountHttp { throw ResponseException(response.code, response) } - val text = response.use { response.body.use { it?.string() } } - if (text.isNullOrBlank()) { + val text = response.use { response.body.use { it.string() } } + if (text.isBlank()) { throw ResponseException(response.code, "response body is empty", response) } diff --git a/src/main/kotlin/app/termora/account/AccountManager.kt b/src/main/kotlin/app/termora/account/AccountManager.kt index 014375e..d663fad 100644 --- a/src/main/kotlin/app/termora/account/AccountManager.kt +++ b/src/main/kotlin/app/termora/account/AccountManager.kt @@ -54,24 +54,24 @@ class AccountManager private constructor() : ApplicationRunnerExtension { fun getOwnerIds() = account.teams.map { it.id }.toMutableList().apply { add(getAccountId()) }.toSet() fun getOwners(): Set { val owners = mutableSetOf() - owners.add(AccountOwner(getAccountId(), getEmail(), OwnerType.User)) + owners.add(AccountOwner(getAccountId(), getEmail(), OwnerType.User, StringUtils.EMPTY)) for (team in getTeams()) { - owners.add(AccountOwner(team.id, team.name, OwnerType.Team)) + owners.add(AccountOwner(team.id, team.name, OwnerType.Team, team.role)) } return owners } fun isFreePlan(): Boolean { - return isLocally() || getSubscription().plan == SubscriptionPlan.Free + return isLocally() || getSubscription().plan == SubscriptionPlan.Free.name } fun getSubscription(): Subscription { if (isLocally().not()) { val subscriptions = getSubscriptions() - val enterprises = getSubscriptions().filter { it.plan == SubscriptionPlan.Enterprise } - val teams = subscriptions.filter { it.plan == SubscriptionPlan.Team } - val pros = subscriptions.filter { it.plan == SubscriptionPlan.Pro } + val enterprises = getSubscriptions().filter { it.plan == SubscriptionPlan.Enterprise.name } + val teams = subscriptions.filter { it.plan == SubscriptionPlan.Team.name } + val pros = subscriptions.filter { it.plan == SubscriptionPlan.Pro.name } val now = System.currentTimeMillis() if (enterprises.any { it.endAt > now }) { @@ -83,16 +83,9 @@ class AccountManager private constructor() : ApplicationRunnerExtension { } } - return Subscription(id = "0", plan = SubscriptionPlan.Free, startAt = 0, endAt = 0) + return Subscription(id = "0", plan = SubscriptionPlan.Free.name, startAt = 0, endAt = 0) } - fun hasTeamFeature(): Boolean { - if (accountProperties.signed.not()) return false - val plan = getSubscription().plan - return SubscriptionPlan.Team == plan || SubscriptionPlan.Enterprise == plan - } - - /** * 刷新 Token */ diff --git a/src/main/kotlin/app/termora/account/AccountOption.kt b/src/main/kotlin/app/termora/account/AccountOption.kt index 5e2b34e..ff64770 100644 --- a/src/main/kotlin/app/termora/account/AccountOption.kt +++ b/src/main/kotlin/app/termora/account/AccountOption.kt @@ -123,7 +123,7 @@ class AccountOption : JPanel(BorderLayout()), OptionsPane.Option, Disposable { } val planBox = Box.createHorizontalBox() - planBox.add(JLabel(if (isLocally) "-" else subscription.plan.name)) + planBox.add(JLabel(if (isLocally) "-" else subscription.plan)) if (isFreePlan && isLocally.not()) { planBox.add(Box.createHorizontalStrut(16)) val upgrade = JXHyperlink(object : AnAction(I18n.getString("termora.settings.account.upgrade")) { diff --git a/src/main/kotlin/app/termora/account/AccountOwner.kt b/src/main/kotlin/app/termora/account/AccountOwner.kt index 430e7f5..137a930 100644 --- a/src/main/kotlin/app/termora/account/AccountOwner.kt +++ b/src/main/kotlin/app/termora/account/AccountOwner.kt @@ -1,5 +1,12 @@ package app.termora.account import app.termora.database.OwnerType +import org.apache.commons.lang3.StringUtils -data class AccountOwner(val id: String, val name: String, val type: OwnerType) \ No newline at end of file +data class AccountOwner(val id: String, val name: String, val type: OwnerType, val role: String) { + constructor(id: String, name: String, type: OwnerType) : this(id, name, type, StringUtils.EMPTY) + + fun isVisitorMode(): Boolean { + return type == OwnerType.Team && role == TeamRole.Visitor.name + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/termora/account/ServerManager.kt b/src/main/kotlin/app/termora/account/ServerManager.kt index 04eed7b..714b247 100644 --- a/src/main/kotlin/app/termora/account/ServerManager.kt +++ b/src/main/kotlin/app/termora/account/ServerManager.kt @@ -159,5 +159,5 @@ class ServerManager private constructor() { @Serializable - data class MeTeam(val id: String, val name: String, val role: TeamRole, val secretKey: String) + data class MeTeam(val id: String, val name: String, val role: String, val secretKey: String) } \ No newline at end of file diff --git a/src/main/kotlin/app/termora/account/Subscription.kt b/src/main/kotlin/app/termora/account/Subscription.kt index 53025bf..5a0600b 100644 --- a/src/main/kotlin/app/termora/account/Subscription.kt +++ b/src/main/kotlin/app/termora/account/Subscription.kt @@ -5,7 +5,7 @@ import kotlinx.serialization.Serializable @Serializable data class Subscription( val id: String, - val plan: SubscriptionPlan, + val plan: String, val startAt: Long, val endAt: Long, ) diff --git a/src/main/kotlin/app/termora/account/Team.kt b/src/main/kotlin/app/termora/account/Team.kt index afb5640..7757518 100644 --- a/src/main/kotlin/app/termora/account/Team.kt +++ b/src/main/kotlin/app/termora/account/Team.kt @@ -25,7 +25,7 @@ class Team( /** * 所属角色 */ - val role: TeamRole, + val role: String, ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/src/main/kotlin/app/termora/account/TeamRole.kt b/src/main/kotlin/app/termora/account/TeamRole.kt index a32e860..f3f9a0d 100644 --- a/src/main/kotlin/app/termora/account/TeamRole.kt +++ b/src/main/kotlin/app/termora/account/TeamRole.kt @@ -3,4 +3,5 @@ package app.termora.account enum class TeamRole { Member, Owner, + Visitor, } \ No newline at end of file diff --git a/src/main/kotlin/app/termora/database/DatabaseManager.kt b/src/main/kotlin/app/termora/database/DatabaseManager.kt index edd9961..b218bd7 100644 --- a/src/main/kotlin/app/termora/database/DatabaseManager.kt +++ b/src/main/kotlin/app/termora/database/DatabaseManager.kt @@ -409,7 +409,8 @@ class DatabaseManager private constructor() : Disposable { val accountOwner = AccountOwner( id = account.id, name = account.email, - type = OwnerType.User + type = OwnerType.User, + role = StringUtils.EMPTY, ) for (host in hostManager.hosts()) { diff --git a/src/main/kotlin/app/termora/highlight/KeywordHighlightDialog.kt b/src/main/kotlin/app/termora/highlight/KeywordHighlightDialog.kt index 85d6768..0bb948b 100644 --- a/src/main/kotlin/app/termora/highlight/KeywordHighlightDialog.kt +++ b/src/main/kotlin/app/termora/highlight/KeywordHighlightDialog.kt @@ -5,6 +5,7 @@ import app.termora.account.AccountManager import app.termora.account.AccountOwner import app.termora.database.OwnerType import com.formdev.flatlaf.extras.components.FlatTabbedPane +import org.apache.commons.lang3.StringUtils import java.awt.Dimension import java.awt.Window import javax.swing.BorderFactory @@ -45,25 +46,27 @@ class KeywordHighlightDialog(owner: Window) : DialogWrapper(owner) { AccountOwner( accountManager.getAccountId(), accountManager.getEmail(), - OwnerType.User + OwnerType.User, + StringUtils.EMPTY, ) ).apply { Disposer.register(disposable, this) } ) - if (accountManager.hasTeamFeature()) { - for (team in accountManager.getTeams()) { - tabbed.addTab( - team.name, - Icons.cwmUsers, - KeywordHighlightPanel( - AccountOwner( - team.id, - team.name, - OwnerType.Team - ) - ).apply { Disposer.register(disposable, this) }) - } +// if (accountManager.hasTeamFeature()) { + for (team in accountManager.getTeams()) { + tabbed.addTab( + team.name, + Icons.cwmUsers, + KeywordHighlightPanel( + AccountOwner( + team.id, + team.name, + OwnerType.Team, + team.role, + ) + ).apply { Disposer.register(disposable, this) }) } +// } return tabbed diff --git a/src/main/kotlin/app/termora/highlight/KeywordHighlightPanel.kt b/src/main/kotlin/app/termora/highlight/KeywordHighlightPanel.kt index b8641bc..40563b1 100644 --- a/src/main/kotlin/app/termora/highlight/KeywordHighlightPanel.kt +++ b/src/main/kotlin/app/termora/highlight/KeywordHighlightPanel.kt @@ -248,6 +248,9 @@ class KeywordHighlightPanel(private val accountOwner: AccountOwner) : JPanel(Bor table.addMouseListener(object : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { + if (accountOwner.isVisitorMode()) { + return + } if (SwingUtilities.isLeftMouseButton(e)) { val row = table.rowAtPoint(e.point) val column = table.columnAtPoint(e.point) @@ -299,7 +302,8 @@ class KeywordHighlightPanel(private val accountOwner: AccountOwner) : JPanel(Bor if (keywordHighlight.backgroundColor in 0..16) { if (keywordHighlight.backgroundColor == 0) { - dialog.backgroundColor.background = Color(colorPalette.getColor(TerminalColor.Basic.BACKGROUND)) + dialog.backgroundColor.background = + Color(colorPalette.getColor(TerminalColor.Basic.BACKGROUND)) dialog.backgroundColor.colorIndex = -1 } else { dialog.backgroundColor.color = @@ -402,7 +406,7 @@ class KeywordHighlightPanel(private val accountOwner: AccountOwner) : JPanel(Bor val panel = JPanel(BorderLayout()) panel.add(JScrollPane(table).apply { border = BorderFactory.createCompoundBorder( - BorderFactory.createEmptyBorder(8, 8, 8, 0), + BorderFactory.createEmptyBorder(8, 8, 8, if (accountOwner.isVisitorMode()) 8 else 0), BorderFactory.createMatteBorder(1, 1, 1, 1, DynamicColor.BorderColor) ) }, BorderLayout.CENTER) @@ -414,17 +418,18 @@ class KeywordHighlightPanel(private val accountOwner: AccountOwner) : JPanel(Bor "default:grow", "pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref" ) - panel.add( - FormBuilder.create().layout(layout) - .border(BorderFactory.createEmptyBorder(8, 8, 8, 8)) - .add(addBtn).xy(1, rows).apply { rows += step } - .add(editBtn).xy(1, rows).apply { rows += step } - .add(deleteBtn).xy(1, rows).apply { rows += step } - .add(importBtn).xy(1, rows).apply { rows += step } - .add(exportBtn).xy(1, rows).apply { rows += step } - .build(), - BorderLayout.EAST) - + if (accountOwner.isVisitorMode().not()) { + panel.add( + FormBuilder.create().layout(layout) + .border(BorderFactory.createEmptyBorder(8, 8, 8, 8)) + .add(addBtn).xy(1, rows).apply { rows += step } + .add(editBtn).xy(1, rows).apply { rows += step } + .add(deleteBtn).xy(1, rows).apply { rows += step } + .add(importBtn).xy(1, rows).apply { rows += step } + .add(exportBtn).xy(1, rows).apply { rows += step } + .build(), + BorderLayout.EAST) + } return panel } } diff --git a/src/main/kotlin/app/termora/keymgr/KeyManagerDialog.kt b/src/main/kotlin/app/termora/keymgr/KeyManagerDialog.kt index 1c254e0..f950b38 100644 --- a/src/main/kotlin/app/termora/keymgr/KeyManagerDialog.kt +++ b/src/main/kotlin/app/termora/keymgr/KeyManagerDialog.kt @@ -8,6 +8,7 @@ import app.termora.account.AccountManager import app.termora.account.AccountOwner import app.termora.database.OwnerType import com.formdev.flatlaf.extras.components.FlatTabbedPane +import org.apache.commons.lang3.StringUtils import java.awt.Dimension import java.awt.Window import javax.swing.BorderFactory @@ -65,13 +66,14 @@ class KeyManagerDialog( AccountOwner( accountManager.getAccountId(), accountManager.getEmail(), - OwnerType.User + OwnerType.User, + StringUtils.EMPTY, ) ) ) } - if (accountOwner != null && accountManager.hasTeamFeature()) { + if (accountOwner != null) { for (team in accountManager.getTeams()) { if (team.id == accountOwner.id) { tabbed.addTab( @@ -81,7 +83,8 @@ class KeyManagerDialog( AccountOwner( team.id, team.name, - OwnerType.Team + OwnerType.Team, + team.role, ) ) ) @@ -91,22 +94,22 @@ class KeyManagerDialog( } - - if (accountManager.hasTeamFeature()) { - for (team in accountManager.getTeams()) { - tabbed.addTab( - team.name, - Icons.cwmUsers, - KeyManagerPanel( - AccountOwner( - team.id, - team.name, - OwnerType.Team - ) +// if (accountManager.hasTeamFeature()) { + for (team in accountManager.getTeams()) { + tabbed.addTab( + team.name, + Icons.cwmUsers, + KeyManagerPanel( + AccountOwner( + team.id, + team.name, + OwnerType.Team, + team.role, ) ) - } + ) } +// } return tabbed diff --git a/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt b/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt index 784e125..bbd4d91 100644 --- a/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt +++ b/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt @@ -2,8 +2,10 @@ package app.termora.keymgr import app.termora.* import app.termora.account.AccountOwner +import app.termora.account.TeamRole import app.termora.actions.AnAction import app.termora.actions.AnActionEvent +import app.termora.database.OwnerType import app.termora.plugin.internal.ssh.SSHProtocolProvider import app.termora.tree.Filter import app.termora.tree.HostTreeNode @@ -56,6 +58,7 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay init { initView() initEvents() + preventImportantData() } @@ -89,15 +92,19 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay add(JScrollPane(keyPairTable).apply { border = BorderFactory.createMatteBorder(1, 1, 1, 1, DynamicColor.BorderColor) }, BorderLayout.CENTER) - add( - FormBuilder.create().layout(layout).padding(EmptyBorder(0, 12, 0, 0)) - .add(generateBtn).xy(1, rows).apply { rows += step } - .add(editBtn).xy(1, rows).apply { rows += step } - .add(importBtn).xy(1, rows).apply { rows += step } - .add(exportBtn).xy(1, rows).apply { rows += step } - .add(deleteBtn).xy(1, rows).apply { rows += step } - .add(sshCopyIdBtn).xy(1, rows).apply { rows += step } - .build(), BorderLayout.EAST) + + if (accountOwner.type == OwnerType.User || (accountOwner.type == OwnerType.Team && accountOwner.role != TeamRole.Visitor.name)) { + add( + FormBuilder.create().layout(layout).padding(EmptyBorder(0, 12, 0, 0)) + .add(generateBtn).xy(1, rows).apply { rows += step } + .add(editBtn).xy(1, rows).apply { rows += step } + .add(importBtn).xy(1, rows).apply { rows += step } + .add(exportBtn).xy(1, rows).apply { rows += step } + .add(deleteBtn).xy(1, rows).apply { rows += step } + .add(sshCopyIdBtn).xy(1, rows).apply { rows += step } + .build(), BorderLayout.EAST) + } + border = BorderFactory.createEmptyBorder(12, 12, 12, 12) } @@ -199,6 +206,17 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay } } + private fun preventImportantData() { + if (accountOwner.isVisitorMode()) { + generateBtn.isVisible = false + editBtn.isVisible = false + deleteBtn.isVisible = false + importBtn.isVisible = false + exportBtn.isVisible = false + sshCopyIdBtn.isVisible = false + } + } + private fun sshCopyId(evt: AnActionEvent) { val keyPairs = keyPairTable.selectedRows.map { keyPairTableModel.getOhKeyPair(it) } val publicKeys = mutableListOf>() diff --git a/src/main/kotlin/app/termora/plugin/internal/rdp/RDPHostOptionsPane.kt b/src/main/kotlin/app/termora/plugin/internal/rdp/RDPHostOptionsPane.kt index 030c3c1..6bd5abb 100644 --- a/src/main/kotlin/app/termora/plugin/internal/rdp/RDPHostOptionsPane.kt +++ b/src/main/kotlin/app/termora/plugin/internal/rdp/RDPHostOptionsPane.kt @@ -1,6 +1,7 @@ package app.termora.plugin.internal.rdp import app.termora.* +import app.termora.account.AccountOwner import app.termora.plugin.internal.BasicProxyOption import com.formdev.flatlaf.FlatClientProperties import com.formdev.flatlaf.extras.components.FlatComboBox @@ -17,7 +18,7 @@ import java.awt.event.ComponentEvent import java.awt.event.ItemEvent import javax.swing.* -internal open class RDPHostOptionsPane : OptionsPane() { +internal open class RDPHostOptionsPane(private val accountOwner: AccountOwner) : OptionsPane() { protected val generalOption = GeneralOption() protected val proxyOption = BasicProxyOption() protected val owner: Window get() = SwingUtilities.getWindowAncestor(this) diff --git a/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanel.kt b/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanel.kt index 16e91de..86e4493 100644 --- a/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanel.kt +++ b/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanel.kt @@ -2,11 +2,12 @@ package app.termora.plugin.internal.rdp import app.termora.Disposer import app.termora.Host +import app.termora.account.AccountOwner import app.termora.protocol.ProtocolHostPanel import java.awt.BorderLayout -class RDPProtocolHostPanel : ProtocolHostPanel() { - private val pane = RDPHostOptionsPane() +class RDPProtocolHostPanel(private val accountOwner: AccountOwner) : ProtocolHostPanel() { + private val pane = RDPHostOptionsPane(accountOwner) init { initView() diff --git a/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanelExtension.kt b/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanelExtension.kt index 38ffad4..21b926e 100644 --- a/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanelExtension.kt +++ b/src/main/kotlin/app/termora/plugin/internal/rdp/RDPProtocolHostPanelExtension.kt @@ -16,7 +16,7 @@ internal class RDPProtocolHostPanelExtension private constructor() : ProtocolHos } override fun createProtocolHostPanel(accountOwner: AccountOwner): ProtocolHostPanel { - return RDPProtocolHostPanel() + return RDPProtocolHostPanel(accountOwner) } override fun ordered(): Long { diff --git a/src/main/kotlin/app/termora/tag/TagDialog.kt b/src/main/kotlin/app/termora/tag/TagDialog.kt index c4db73a..680ee5e 100644 --- a/src/main/kotlin/app/termora/tag/TagDialog.kt +++ b/src/main/kotlin/app/termora/tag/TagDialog.kt @@ -46,27 +46,27 @@ class TagDialog(owner: Window, private val accountOwnerId: String = StringUtils. AccountOwner( accountManager.getAccountId(), accountManager.getEmail(), - OwnerType.User + OwnerType.User, + StringUtils.EMPTY, ) ).apply { Disposer.register(disposable, this) } ) - if (accountManager.hasTeamFeature()) { - for (team in accountManager.getTeams()) { - tabbed.addTab( - team.name, - Icons.cwmUsers, - TagPanel( - AccountOwner( - team.id, - team.name, - OwnerType.Team - ) - ).apply { Disposer.register(disposable, this) }) + for (team in accountManager.getTeams()) { + tabbed.addTab( + team.name, + Icons.cwmUsers, + TagPanel( + AccountOwner( + team.id, + team.name, + OwnerType.Team, + team.role, + ) + ).apply { Disposer.register(disposable, this) }) - if (accountOwnerId == team.id) { - tabbed.selectedIndex = tabbed.tabCount - 1 - } + if (accountOwnerId == team.id) { + tabbed.selectedIndex = tabbed.tabCount - 1 } } diff --git a/src/main/kotlin/app/termora/tag/TagPanel.kt b/src/main/kotlin/app/termora/tag/TagPanel.kt index 3dc445d..eff4ee8 100644 --- a/src/main/kotlin/app/termora/tag/TagPanel.kt +++ b/src/main/kotlin/app/termora/tag/TagPanel.kt @@ -2,6 +2,8 @@ package app.termora.tag import app.termora.* import app.termora.account.AccountOwner +import app.termora.account.TeamRole +import app.termora.database.OwnerType import com.jgoodies.forms.builder.FormBuilder import com.jgoodies.forms.layout.FormLayout import java.awt.BorderLayout @@ -9,7 +11,7 @@ import java.awt.Component import javax.swing.* import javax.swing.border.EmptyBorder -class TagPanel(accountOwner: AccountOwner) : JPanel(BorderLayout()), Disposable { +class TagPanel(private val accountOwner: AccountOwner) : JPanel(BorderLayout()), Disposable { private val owner get() = SwingUtilities.getWindowAncestor(this) @@ -23,6 +25,7 @@ class TagPanel(accountOwner: AccountOwner) : JPanel(BorderLayout()), Disposable init { initView() initEvents() + preventImportantData() } private fun initView() { @@ -108,6 +111,14 @@ class TagPanel(accountOwner: AccountOwner) : JPanel(BorderLayout()), Disposable } + private fun preventImportantData() { + if (accountOwner.isVisitorMode()) { + addBtn.isVisible = false + editBtn.isVisible = false + deleteBtn.isVisible = false + } + } + private fun createCenterPanel(): JComponent { val panel = JPanel(BorderLayout()) diff --git a/src/main/kotlin/app/termora/tree/NewHostTree.kt b/src/main/kotlin/app/termora/tree/NewHostTree.kt index d52d2ab..22d5cd9 100644 --- a/src/main/kotlin/app/termora/tree/NewHostTree.kt +++ b/src/main/kotlin/app/termora/tree/NewHostTree.kt @@ -3,6 +3,8 @@ package app.termora.tree import app.termora.* import app.termora.Application.ohMyJson import app.termora.account.AccountManager +import app.termora.account.Team +import app.termora.account.TeamRole import app.termora.actions.AnAction import app.termora.actions.AnActionEvent import app.termora.actions.OpenHostAction @@ -155,9 +157,9 @@ class NewHostTree : SimpleTree(), Disposable { val path: TreePath? = getPathForLocation(e.x, e.y) if (path != null) { val node: HostTreeNode = path.lastPathComponent as HostTreeNode - if (node.host.remark.isNotEmpty()){ + if (node.host.remark.isNotEmpty()) { toolTipText = node.host.remark - }else{ + } else { toolTipText = null } } else { @@ -181,7 +183,7 @@ class NewHostTree : SimpleTree(), Disposable { override fun actionPerformed(evt: AnActionEvent) { val lastNode = getLastSelectedPathNode() ?: return val folder = if (lastNode.isFolder) lastNode.parent ?: simpleTreeModel.root - else lastNode.parent ?: return + else lastNode.parent ?: return if (toolkit.systemClipboard.isDataFlavorAvailable(NodesTransferable.FLAVOR).not()) return val nodes = (toolkit.systemClipboard.getData(NodesTransferable.FLAVOR) as? List<*>) @@ -455,6 +457,33 @@ class NewHostTree : SimpleTree(), Disposable { }) + popupMenu.addPopupMenuListener(object : PopupMenuListener { + + override fun popupMenuWillBecomeVisible(e: PopupMenuEvent?) { + for (node in nodes) { + val team = TeamTreeNode.parentTeam(node) ?: continue + if (team.role == TeamRole.Visitor.name) { + copy.isEnabled = false + remove.isEnabled = false + rename.isEnabled = false + importMenu.isEnabled = false + newMenu.isEnabled = false + tagsMenu.isEnabled = false + break + } + } + } + + override fun popupMenuWillBecomeInvisible(e: PopupMenuEvent?) { + + } + + override fun popupMenuCanceled(e: PopupMenuEvent?) { + + } + + }) + val mnemonics = mapOf( refresh to KeyEvent.VK_R, newMenu to KeyEvent.VK_W, diff --git a/src/main/kotlin/app/termora/tree/NewHostTreeModel.kt b/src/main/kotlin/app/termora/tree/NewHostTreeModel.kt index f67c3d4..37c418b 100644 --- a/src/main/kotlin/app/termora/tree/NewHostTreeModel.kt +++ b/src/main/kotlin/app/termora/tree/NewHostTreeModel.kt @@ -61,11 +61,11 @@ class NewHostTreeModel private constructor() : SimpleTreeModel( // 如果是根,需要引入团队功能 if (parent == getRoot()) { - if (accountManager.hasTeamFeature()) { - for (team in accountManager.getTeams()) { - nodes[team.id] = TeamTreeNode(team) - } +// if (accountManager.hasTeamFeature()) { + for (team in accountManager.getTeams()) { + nodes[team.id] = TeamTreeNode(team) } +// } nodes[accountManager.getAccountId()] = HostTreeNode( Host( @@ -93,11 +93,11 @@ class NewHostTreeModel private constructor() : SimpleTreeModel( } if (parent == getRoot()) { - if (accountManager.hasTeamFeature()) { - for (team in accountManager.getTeams()) { - parent.add(nodes.getValue(team.id)) - } +// if (accountManager.hasTeamFeature()) { + for (team in accountManager.getTeams()) { + parent.add(nodes.getValue(team.id)) } +// } parent.add(nodes.getValue(accountManager.getAccountId())) } else { for (node in nodes.values) { diff --git a/src/main/kotlin/app/termora/tree/SimpleTree.kt b/src/main/kotlin/app/termora/tree/SimpleTree.kt index d4b3314..a2faa49 100644 --- a/src/main/kotlin/app/termora/tree/SimpleTree.kt +++ b/src/main/kotlin/app/termora/tree/SimpleTree.kt @@ -1,6 +1,7 @@ package app.termora.tree import app.termora.OutlineTextField +import app.termora.account.TeamRole import com.formdev.flatlaf.ui.FlatTreeUI import org.jdesktop.swingx.JXTree import java.awt.Dimension @@ -134,6 +135,13 @@ open class SimpleTree : JXTree() { } } + for (node in nodes) { + val team = TeamTreeNode.parentTeam(node) ?: continue + if (team.role == TeamRole.Visitor.name) { + return null + } + } + return MoveNodeTransferable(nodes) } @@ -153,9 +161,14 @@ open class SimpleTree : JXTree() { if (nodes.isEmpty()) return false if (!node.isFolder) return false + val team = TeamTreeNode.parentTeam(node) + if (team?.role == TeamRole.Visitor.name) { + return false + } + for (e in nodes) { // 禁止拖拽到自己的子下面 - if (path.equals(TreePath(e.path)) || TreePath(e.path).isDescendant(path)) { + if (path == TreePath(e.path) || TreePath(e.path).isDescendant(path)) { return false } @@ -333,7 +346,7 @@ open class SimpleTree : JXTree() { private inner class MyTreeUI : FlatTreeUI() { - override fun createNodeDimensions(): AbstractLayoutCache.NodeDimensions? { + override fun createNodeDimensions(): AbstractLayoutCache.NodeDimensions { return object : NodeDimensionsHandler() { override fun getNodeDimensions( value: Any?, row: Int, depth: Int, expanded: Boolean, diff --git a/src/main/kotlin/app/termora/tree/TeamTreeNode.kt b/src/main/kotlin/app/termora/tree/TeamTreeNode.kt index 41dd3ea..f36f2b1 100644 --- a/src/main/kotlin/app/termora/tree/TeamTreeNode.kt +++ b/src/main/kotlin/app/termora/tree/TeamTreeNode.kt @@ -26,4 +26,16 @@ class TeamTreeNode(val team: Team) : HostTreeNode( override fun toString(): String { return team.name } + + companion object { + fun parentTeam(node: SimpleTreeNode<*>?): Team? { + if (node is TeamTreeNode) { + return node.team + } else if (node == null) { + return null + } + return parentTeam(node.parent) + } + + } } \ No newline at end of file