1 // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.execution.runToolbar
4 import com.intellij.execution.runToolbar.data.RWSlotManagerState
5 import com.intellij.execution.runToolbar.data.RWStateListener
6 import com.intellij.ide.DataManager
7 import com.intellij.openapi.actionSystem.ActionGroup
8 import com.intellij.openapi.actionSystem.AnAction
9 import com.intellij.openapi.actionSystem.DataProvider
10 import com.intellij.openapi.actionSystem.Presentation
11 import com.intellij.openapi.diagnostic.Logger
12 import com.intellij.openapi.project.Project
13 import com.intellij.openapi.util.Disposer
14 import com.intellij.openapi.wm.IdeFrame
15 import java.awt.event.ContainerEvent
16 import java.awt.event.ContainerListener
17 import javax.swing.SwingUtilities
19 class RunToolbarMainWidgetComponent(val presentation: Presentation, place: String, group: ActionGroup) :
20 FixWidthSegmentedActionToolbarComponent(place, group) {
22 private val LOG = Logger.getInstance(RunToolbarMainWidgetComponent::class.java)
23 private var counter: MutableMap<Project, Int> = mutableMapOf()
26 override fun logNeeded(): Boolean = RunToolbarProcess.logNeeded
28 private var project: Project? = null
30 if(field == value) return
42 private var popupController: RunToolbarPopupController? = null
44 private val componentListener = object : ContainerListener {
45 override fun componentAdded(e: ContainerEvent) {
46 rebuildPopupControllerComponent()
49 override fun componentRemoved(e: ContainerEvent) {
50 rebuildPopupControllerComponent()
54 private val managerStateListener = object : RWStateListener {
55 override fun stateChanged(state: RWSlotManagerState) {
60 private var state: RunToolbarMainSlotState? = null
62 private fun updateState() {
63 state = project?.let {
64 val slotManager = RunToolbarSlotManager.getInstance(it)
65 val value = when (slotManager.getState()) {
66 RWSlotManagerState.SINGLE_MAIN -> {
67 RunToolbarMainSlotState.PROCESS
69 RWSlotManagerState.SINGLE_PLAIN,
70 RWSlotManagerState.MULTIPLE -> {
71 if(isOpened) RunToolbarMainSlotState.CONFIGURATION else RunToolbarMainSlotState.INFO
73 RWSlotManagerState.INACTIVE -> {
74 RunToolbarMainSlotState.CONFIGURATION
76 RWSlotManagerState.MULTIPLE_WITH_MAIN -> {
77 if(isOpened) RunToolbarMainSlotState.PROCESS else RunToolbarMainSlotState.INFO
84 if(RunToolbarProcess.logNeeded) LOG.info("MAIN SLOT state updated: $state RunToolbar")
87 override fun traceState(lastIds: List<String>, filteredIds: List<String>, ides: List<String>) {
88 if(logNeeded() && filteredIds != lastIds) LOG.info("MAIN SLOT state: ${state} new filtered: ${filteredIds}} visible: $ides RunToolbar")
91 internal var isOpened = false
93 if(field == value) return
96 if(RunToolbarProcess.logNeeded) LOG.info("MAIN SLOT isOpened: $isOpened RunToolbar")
99 if (RunToolbarProcess.isExperimentalUpdatingEnabled) {
104 override fun isSuitableAction(action: AnAction): Boolean {
106 if(action is RTBarAction) {
107 action.checkMainSlotVisibility(it)
112 override fun addNotify() {
115 (SwingUtilities.getWindowAncestor(this) as? IdeFrame)?.project?.let {
118 RUN_CONFIG_WIDTH = RunToolbarSettings.getInstance(it).getRunConfigWidth()
123 override fun updateWidthHandler() {
124 super.updateWidthHandler()
126 RunToolbarSettings.getInstance(it).setRunConfigWidth(RUN_CONFIG_WIDTH)
130 private fun rebuildPopupControllerComponent() {
131 popupController?.let {
132 it.updateControllerComponents(components.filter{it is PopupControllerComponent}.toMutableList())
136 override fun removeNotify() {
141 private fun add(project: Project) {
142 popupController = RunToolbarPopupController(project, this)
144 val value = counter.getOrDefault(project, 0) + 1
145 counter[project] = value
146 val slotManager = RunToolbarSlotManager.getInstance(project)
147 DataManager.registerDataProvider(component, DataProvider { key ->
149 RunToolbarData.RUN_TOOLBAR_DATA_KEY.`is`(key) -> {
150 slotManager.mainSlotData
152 RunToolbarData.RUN_TOOLBAR_POPUP_STATE_KEY.`is`(key) -> {
155 RunToolbarData.RUN_TOOLBAR_MAIN_STATE.`is`(key) -> {
163 slotManager.stateListeners.addListener(managerStateListener)
164 slotManager.active = true
167 rebuildPopupControllerComponent()
168 addContainerListener(componentListener)
171 private fun remove(project: Project) {
172 RunToolbarSlotManager.getInstance(project).stateListeners.removeListener(managerStateListener)
173 counter[project]?.let {
174 val value = maxOf(it - 1, 0)
175 counter[project] = value
177 RunToolbarSlotManager.getInstance(project).active = false
178 counter.remove(project)
182 removeContainerListener(componentListener)
183 popupController?.let {
184 if(!Disposer.isDisposed(it)) {
188 popupController = null