Skip to content

Commit 42b4664

Browse files
committed
fix tool window content management
1 parent f30140c commit 42b4664

File tree

14 files changed

+97
-54
lines changed

14 files changed

+97
-54
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.cycode.plugin.components.toolWindow
2+
3+
import com.cycode.plugin.components.toolWindow.components.treeView.TreeView
4+
import com.intellij.openapi.project.Project
5+
import javax.swing.JPanel
6+
7+
class CycodeContentTab(project: Project) {
8+
private val treeView = TreeView(project)
9+
10+
fun updateContent(rightPanel: JPanel): JPanel {
11+
treeView.refreshTree()
12+
return treeView.replaceRightPanel(rightPanel)
13+
}
14+
}

src/main/kotlin/com/cycode/plugin/components/toolWindow/CycodeToolWindowFactory.kt

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
package com.cycode.plugin.components.toolWindow
22

3-
import com.cycode.plugin.CycodeBundle
4-
import com.cycode.plugin.components.Component
53
import com.cycode.plugin.components.toolWindow.components.authContentTab.AuthContentTab
64
import com.cycode.plugin.components.toolWindow.components.loadingContentTab.LoadingContentTab
75
import com.cycode.plugin.components.toolWindow.components.scanContentTab.ScanContentTab
86
import com.cycode.plugin.icons.PluginIcons
9-
import com.cycode.plugin.services.CycodeService
107
import com.cycode.plugin.services.cycode
118
import com.cycode.plugin.services.pluginState
129
import com.intellij.openapi.application.ApplicationManager
1310
import com.intellij.openapi.application.WriteAction
1411
import com.intellij.openapi.project.DumbAware
1512
import com.intellij.openapi.project.Project
13+
import com.intellij.openapi.util.Disposer
1614
import com.intellij.openapi.wm.ToolWindow
1715
import com.intellij.openapi.wm.ToolWindowFactory
18-
import com.intellij.openapi.wm.ToolWindowManager
1916
import com.intellij.ui.content.Content
2017
import com.intellij.ui.content.ContentFactory
21-
18+
import javax.swing.JPanel
2219

2320
class CycodeToolWindowFactory : DumbAware, ToolWindowFactory {
2421

@@ -27,48 +24,58 @@ class CycodeToolWindowFactory : DumbAware, ToolWindowFactory {
2724
}
2825

2926
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
30-
createLoadingTabOnly(project)
27+
val service = cycode(project)
28+
29+
val contentTab = CycodeContentTab(project)
30+
TabManager.addTab(project, contentTab)
31+
32+
val defaultRightPanel = LoadingContentTab().getContent(service)
33+
val toolWindowContent = createToolWindowContent(contentTab.updateContent(defaultRightPanel))
34+
toolWindow.contentManager.addContent(toolWindowContent)
35+
36+
Disposer.register(service, toolWindowContent)
3137
}
3238

3339
override fun shouldBeAvailable(project: Project) = true
34-
}
3540

36-
private fun getCycodeToolWindow(project: Project): ToolWindow? {
37-
return ToolWindowManager.getInstance(project).getToolWindow(CycodeBundle.message("toolWindowId"))
38-
}
41+
object TabManager {
42+
private val toolWindowsTabs = mutableMapOf<Project, CycodeContentTab>()
3943

40-
private fun replaceToolWindowContent(project: Project, content: Content) {
41-
val window = getCycodeToolWindow(project) ?: return
42-
window.contentManager.removeAllContents(true)
43-
window.contentManager.addContent(content)
44-
}
44+
fun addTab(project: Project, tab: CycodeContentTab) {
45+
toolWindowsTabs[project] = tab
46+
}
4547

46-
private fun createToolWindowContent(project: Project, component: Component<CycodeService>): Content {
47-
return ContentFactory.SERVICE.getInstance()
48-
.createContent(component.getContent(cycode(project)), null, false)
49-
}
48+
fun getTab(project: Project): CycodeContentTab? {
49+
return toolWindowsTabs[project]
50+
}
5051

51-
private fun createLoadingTabOnly(project: Project) {
52-
replaceToolWindowContent(project, createToolWindowContent(project, LoadingContentTab()))
53-
}
52+
fun removeTab(project: Project) {
53+
toolWindowsTabs.remove(project)
54+
}
55+
}
5456

57+
}
5558

56-
private fun createAuthTabOnly(project: Project) {
57-
replaceToolWindowContent(project, createToolWindowContent(project, AuthContentTab()))
59+
private fun replaceToolWindowRightPanel(project: Project, panel: JPanel) {
60+
val contentTab = CycodeToolWindowFactory.TabManager.getTab(project) ?: return
61+
contentTab.updateContent(panel)
5862
}
5963

60-
private fun createScanTabOnly(project: Project) {
61-
replaceToolWindowContent(project, createToolWindowContent(project, ScanContentTab()))
64+
private fun createToolWindowContent(component: JPanel): Content {
65+
return ContentFactory.SERVICE.getInstance().createContent(component, null, false)
6266
}
6367

68+
6469
fun updateToolWindowState(project: Project) {
6570
val pluginState = pluginState()
71+
val service = cycode(project)
72+
6673
ApplicationManager.getApplication().invokeLater {
6774
WriteAction.run<Error> {
6875
if (pluginState.cliAuthed) {
69-
createScanTabOnly(project)
76+
replaceToolWindowRightPanel(project, ScanContentTab().getContent(service))
7077
} else {
71-
createAuthTabOnly(project)
78+
replaceToolWindowRightPanel(project, AuthContentTab().getContent(service))
7279
}
7380
}
7481
}

src/main/kotlin/com/cycode/plugin/components/toolWindow/components/scanContentTab/ScanContentTab.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.cycode.plugin.components.toolWindow.components.scanContentTab
33
import com.cycode.plugin.CycodeBundle
44
import com.cycode.plugin.components.Component
55
import com.cycode.plugin.components.common.createClickableLabel
6-
import com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.TreeView
76
import com.cycode.plugin.services.CycodeService
87
import com.intellij.util.ui.JBUI
98
import java.awt.GridBagConstraints
@@ -13,7 +12,7 @@ import javax.swing.JPanel
1312

1413
class ScanContentTab : Component<CycodeService>() {
1514
override fun getContent(service: CycodeService): JPanel {
16-
val rightPanel = JPanel().apply {
15+
return JPanel().apply {
1716
layout = GridBagLayout()
1817
add(add(JPanel().apply {
1918
add(createClickableLabel(CycodeBundle.message("scanTabTitleLabel")))
@@ -62,7 +61,5 @@ class ScanContentTab : Component<CycodeService>() {
6261
anchor = GridBagConstraints.NORTHWEST
6362
})
6463
}
65-
66-
return TreeView(service.project, rightPanel)
6764
}
6865
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView
1+
package com.cycode.plugin.components.toolWindow.components.treeView
22

3-
import com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes.AbstractNode
3+
import com.cycode.plugin.components.toolWindow.components.treeView.nodes.AbstractNode
44
import com.intellij.ui.ColoredTreeCellRenderer
55
import com.intellij.ui.JBColor
66
import com.intellij.ui.SimpleTextAttributes
Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView
1+
package com.cycode.plugin.components.toolWindow.components.treeView
22

33
import com.cycode.plugin.CycodeBundle
44
import com.cycode.plugin.cli.CliResult
@@ -7,7 +7,7 @@ import com.cycode.plugin.cli.models.scanResult.DetectionBase
77
import com.cycode.plugin.cli.models.scanResult.ScanResultBase
88
import com.cycode.plugin.cli.models.scanResult.sca.ScaDetection
99
import com.cycode.plugin.cli.models.scanResult.secret.SecretDetection
10-
import com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes.*
10+
import com.cycode.plugin.components.toolWindow.components.treeView.nodes.*
1111
import com.cycode.plugin.icons.PluginIcons
1212
import com.cycode.plugin.services.scanResults
1313
import com.intellij.openapi.project.Project
@@ -27,16 +27,23 @@ import javax.swing.tree.TreeSelectionModel
2727

2828
const val DIFFERENCE_BETWEEN_SCA_LINE_NUMBERS = 1
2929

30-
class TreeView(val project: Project, defaultRightPane: Component) : JPanel(GridLayout(1, 0)), TreeSelectionListener {
30+
class TreeView(
31+
val project: Project, defaultRightPane: Component? = null
32+
) : JPanel(GridLayout(1, 0)), TreeSelectionListener {
3133
private val tree: Tree
34+
35+
// dummyRootNode is a workaround to allow us to hide the root node of the tree
36+
private val dummyRootNode = createNode(DummyNode())
3237
private val rootNodes: RootNodes = RootNodes()
38+
39+
private val splitPane: JSplitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
40+
3341
private val scanResults = scanResults(project)
3442

3543
init {
36-
val top = createNode(DummyNode())
37-
createNodes(top)
44+
createNodes(dummyRootNode)
3845

39-
tree = Tree(top)
46+
tree = Tree(dummyRootNode)
4047
tree.setRootVisible(false)
4148
tree.setCellRenderer(TreeCellRenderer())
4249

@@ -45,17 +52,17 @@ class TreeView(val project: Project, defaultRightPane: Component) : JPanel(GridL
4552

4653
val treeView = JBScrollPane(tree)
4754

48-
val splitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
4955
flattenJSplitPane(splitPane)
50-
5156
splitPane.leftComponent = treeView
52-
splitPane.rightComponent = defaultRightPane
57+
splitPane.resizeWeight = 0.5
5358

5459
val minimumSize = Dimension(400, 100)
55-
defaultRightPane.minimumSize = minimumSize
5660
treeView.minimumSize = minimumSize
5761

58-
splitPane.resizeWeight = 0.5
62+
if (defaultRightPane != null) {
63+
splitPane.rightComponent = defaultRightPane
64+
defaultRightPane.minimumSize = minimumSize
65+
}
5966

6067
add(splitPane)
6168
}
@@ -168,6 +175,18 @@ class TreeView(val project: Project, defaultRightPane: Component) : JPanel(GridL
168175
createDetectionNodes(CliScanType.Sca, scaDetections.result, ::createScaDetectionNode)
169176
}
170177

178+
fun replaceRightPanel(newRightPanel: Component): TreeView {
179+
splitPane.rightComponent = newRightPanel
180+
return this
181+
}
182+
183+
fun refreshTree() {
184+
// TODO(MarshalX): is possible to optimize this to only update the nodes that have changed
185+
dummyRootNode.removeAllChildren()
186+
createNodes(dummyRootNode)
187+
tree.updateUI()
188+
}
189+
171190
private fun createNodes(top: DefaultMutableTreeNode) {
172191
rootNodes.createNodes(top)
173192
createSecretDetectionNodes()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import javax.swing.Icon
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import com.cycode.plugin.cli.models.scanResult.sca.ScaDetection
44
import com.cycode.plugin.cli.models.scanResult.secret.SecretDetection
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import com.cycode.plugin.CycodeBundle
44
import javax.swing.Icon
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import javax.swing.Icon
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import com.cycode.plugin.CycodeBundle
44
import com.cycode.plugin.cli.CliScanType
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import javax.swing.Icon
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView.nodes
1+
package com.cycode.plugin.components.toolWindow.components.treeView.nodes
22

33
import javax.swing.tree.DefaultMutableTreeNode
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.cycode.plugin.components.toolWindow.components.scanContentTab.components.treeView
1+
package com.cycode.plugin.components.toolWindow.components.treeView
22

33
import com.intellij.openapi.fileEditor.FileEditorManager
44
import com.intellij.openapi.fileEditor.OpenFileDescriptor

src/main/kotlin/com/cycode/plugin/services/CycodeService.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.cycode.plugin.services
22

33
import com.cycode.plugin.CycodeBundle
4+
import com.cycode.plugin.components.toolWindow.CycodeToolWindowFactory
45
import com.cycode.plugin.components.toolWindow.updateToolWindowState
56
import com.cycode.plugin.utils.CycodeNotifier
7+
import com.intellij.openapi.Disposable
68
import com.intellij.openapi.components.Service
79
import com.intellij.openapi.fileEditor.FileEditorManager
810
import com.intellij.openapi.progress.ProgressIndicator
@@ -12,7 +14,7 @@ import com.intellij.psi.PsiDocumentManager
1214

1315

1416
@Service(Service.Level.PROJECT)
15-
class CycodeService(val project: Project) {
17+
class CycodeService(val project: Project) : Disposable {
1618
private val cliService = cli(project)
1719
private val cliDownloadService = cliDownload()
1820

@@ -108,4 +110,8 @@ class CycodeService(val project: Project) {
108110

109111
startPathScaScan(projectRoot)
110112
}
113+
114+
override fun dispose() {
115+
CycodeToolWindowFactory.TabManager.removeTab(project)
116+
}
111117
}

0 commit comments

Comments
 (0)