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.RunnerAndConfigurationSettings
5 import com.intellij.execution.executors.ExecutorGroup
6 import com.intellij.execution.impl.EditConfigurationsDialog
7 import com.intellij.execution.impl.ProjectRunConfigurationConfigurable
8 import com.intellij.execution.impl.RunConfigurable
9 import com.intellij.execution.impl.SingleConfigurationConfigurable
10 import com.intellij.execution.runners.ExecutionEnvironment
11 import com.intellij.execution.ui.RunContentDescriptor
12 import com.intellij.icons.AllIcons
13 import com.intellij.ide.DataManager
14 import com.intellij.openapi.actionSystem.*
15 import com.intellij.openapi.options.Configurable
16 import com.intellij.openapi.project.Project
17 import com.intellij.openapi.util.Key
18 import com.intellij.openapi.util.text.HtmlBuilder
19 import com.intellij.openapi.util.text.HtmlChunk
20 import com.intellij.openapi.wm.ToolWindowManager
21 import com.intellij.ui.ColorUtil
22 import com.intellij.util.ui.JBUI
23 import org.jetbrains.annotations.ApiStatus
24 import org.jetbrains.annotations.Nls
25 import javax.swing.Icon
27 interface RunToolbarData {
29 @JvmField val RUN_TOOLBAR_DATA_KEY: DataKey<RunToolbarData> = DataKey.create("RUN_TOOLBAR_DATA_KEY")
30 @JvmField val RUN_TOOLBAR_POPUP_STATE_KEY: DataKey<Boolean> = DataKey.create("RUN_TOOLBAR_POPUP_STATE_KEY")
31 @JvmField val RUN_TOOLBAR_MAIN_STATE: DataKey<RunToolbarMainSlotState> = DataKey.create("RUN_TOOLBAR_MAIN_STATE")
33 internal fun prepareDescription(@Nls text: String, @Nls description: String): @Nls String {
34 return HtmlBuilder().append(text)
40 .wrapWith(HtmlChunk.font(ColorUtil.toHtmlColor(JBUI.CurrentTheme.Label.disabledForeground())))).toString()
45 var configuration: RunnerAndConfigurationSettings?
46 val environment: ExecutionEnvironment?
51 internal fun RunContentDescriptor.environment(): ExecutionEnvironment? {
52 return this.attachedContent?.component?.let {
53 ExecutionDataKeys.EXECUTION_ENVIRONMENT.getData(DataManager.getInstance().getDataContext(it))
57 internal fun AnActionEvent.runToolbarData(): RunToolbarData? {
58 return this.dataContext.runToolbarData()
61 fun DataContext.runToolbarData(): RunToolbarData? {
62 return this.getData(RunToolbarData.RUN_TOOLBAR_DATA_KEY)
65 fun AnActionEvent.mainState(): RunToolbarMainSlotState? {
66 return this.dataContext.getData(RunToolbarData.RUN_TOOLBAR_MAIN_STATE)
69 internal fun DataContext.configuration(): RunnerAndConfigurationSettings? {
70 return runToolbarData()?.configuration
73 private fun getConfiguration(dataContext: DataContext): RunnerAndConfigurationSettings? {
74 return dataContext.configuration()
77 internal fun AnActionEvent.isActiveProcess(): Boolean {
78 return this.environment() != null
81 internal fun AnActionEvent.setConfiguration(value: RunnerAndConfigurationSettings?) {
82 this.runToolbarData()?.configuration = value
85 internal fun DataContext.setConfiguration(value: RunnerAndConfigurationSettings?) {
86 runToolbarData()?.configuration = value
89 internal fun AnActionEvent.configuration(): RunnerAndConfigurationSettings? {
90 return runToolbarData()?.configuration
93 internal fun AnActionEvent.arrowIcon(): Icon? {
94 val isOpened = this.dataContext.getData(RunToolbarData.RUN_TOOLBAR_POPUP_STATE_KEY)
98 AllIcons.Toolbar.Collapse
101 AllIcons.Toolbar.Expand
106 fun ExecutionEnvironment.getDisplayName(): String? {
107 return this.contentToReuse?.displayName
110 fun AnActionEvent.environment(): ExecutionEnvironment? {
111 return runToolbarData()?.environment
114 fun ExecutionEnvironment.isRunning(): Boolean? {
115 return this.contentToReuse?.processHandler?.let {
116 !it.isProcessTerminating && !it.isProcessTerminated
121 fun AnActionEvent.isProcessTerminating(): Boolean {
122 return this.environment()?.isProcessTerminating() == true
125 fun ExecutionEnvironment.isProcessTerminating(): Boolean {
126 return this.contentToReuse?.processHandler?.isProcessTerminating == true
129 internal fun AnActionEvent.id(): String? {
130 return runToolbarData()?.id
133 internal fun ExecutionEnvironment.getRunToolbarProcess(): RunToolbarProcess? {
134 return ExecutorGroup.getGroupIfProxy(this.executor)?.let { executorGroup ->
135 RunToolbarProcess.getProcesses().firstOrNull {
136 it.executorId == executorGroup.id
139 RunToolbarProcess.getProcesses().firstOrNull {
140 it.executorId == this.executor.id
145 internal fun DataContext.editConfiguration() {
146 getData(CommonDataKeys.PROJECT)?.let {
147 EditConfigurationsDialog(it, createRunConfigurationConfigurable(it, this)).show()
151 internal fun ExecutionEnvironment.showToolWindowTab() {
152 ToolWindowManager.getInstance(this.project).getToolWindow(this.contentToReuse?.contentToolWindowId ?: this.executor.id)?.let {
153 val contentManager = it.contentManager
154 contentManager.contents.firstOrNull { it.executionId == this.executionId }?.let { content ->
155 contentManager.setSelectedContent(content)
161 private fun createRunConfigurationConfigurable(project: Project, dataContext: DataContext): RunConfigurable {
162 val settings: RunnerAndConfigurationSettings? = getConfiguration(dataContext)
164 fun updateActiveConfigurationFromSelected(configurable: Configurable?) {
166 if (it is SingleConfigurationConfigurable<*>) {
167 dataContext.setConfiguration(it.settings)
173 project.isDefault -> object : RunConfigurable(project) {
174 override fun getSelectedConfiguration(): RunnerAndConfigurationSettings? {
178 override fun updateActiveConfigurationFromSelected() {
179 updateActiveConfigurationFromSelected(getSelectedConfigurable())
182 else -> object : ProjectRunConfigurationConfigurable(project) {
183 override fun getSelectedConfiguration(): RunnerAndConfigurationSettings? {
187 override fun updateActiveConfigurationFromSelected() {
188 updateActiveConfigurationFromSelected(getSelectedConfigurable())