IDEA-259200 Run configuration templates dialog update

Edit Templates dialog extracted

GitOrigin-RevId: 8d03687452514ba38a70f99c4a58f257e0102e53
This commit is contained in:
Dmitry Avdeev
2021-02-08 17:42:33 +03:00
committed by intellij-monorepo-bot
parent 01a0f6ac38
commit 25ded78266
9 changed files with 121 additions and 251 deletions

View File

@@ -20,7 +20,6 @@ import com.intellij.ui.treeStructure.Tree
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import java.util.*
import javax.swing.tree.DefaultMutableTreeNode
import javax.swing.tree.TreePath
import kotlin.test.assertFalse
@@ -33,7 +32,7 @@ private val ORDER = arrayOf(CONFIGURATION_TYPE, //Application
CONFIGURATION, TEMPORARY_CONFIGURATION, CONFIGURATION_TYPE, //JUnit
FOLDER, //4
CONFIGURATION, CONFIGURATION, FOLDER, //5
CONFIGURATION, CONFIGURATION, TEMPORARY_CONFIGURATION, UNKNOWN //Defaults
CONFIGURATION, CONFIGURATION, TEMPORARY_CONFIGURATION
)
@RunsInEdt

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.execution.impl.ConfigurationSettingsEditorWrapper">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="5" bottom="0" right="0"/>
<constraints>
<xy x="59" y="60" width="647" height="196"/>
<xy x="59" y="60" width="748" height="196"/>
</constraints>
<properties/>
<border type="none"/>
@@ -11,7 +11,7 @@
<grid id="c4b52" binding="myComponentPlace" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -19,7 +19,7 @@
</grid>
<grid id="d489d" binding="myBeforeLaunchContainer" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
@@ -30,7 +30,7 @@
</grid>
<vspacer id="6092a">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="0" indent="0" use-parent-layout="false">
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="-1" height="10"/>
<preferred-size width="-1" height="10"/>
<maximum-size width="-1" height="10"/>
@@ -39,47 +39,13 @@
</vspacer>
<vspacer id="5c515">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="74e3f" binding="myDisclaimerPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="5" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none">
<size top="0" left="0" bottom="5" right="0"/>
</border>
<children>
<component id="7524e" class="javax.swing.JLabel" binding="myDisclaimerLabel" custom-create="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ExecutionBundle" key="template.disclaimer"/>
</properties>
</component>
<component id="f8bc8" class="javax.swing.JLabel" binding="myCreateNewRCLabel" custom-create="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="1" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ExecutionBundle" key="create.configuration"/>
</properties>
</component>
<component id="b364b" class="javax.swing.JSeparator">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="c4e4e" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>

View File

@@ -2,7 +2,6 @@
package com.intellij.execution.impl;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunConfigurationBase;
@@ -11,21 +10,16 @@ import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.RunConfigurationFragmentedEditor;
import com.intellij.execution.ui.RunnerAndConfigurationSettingsEditor;
import com.intellij.execution.ui.TargetAwareRunConfigurationEditor;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.HideableDecorator;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,19 +40,16 @@ public final class ConfigurationSettingsEditorWrapper extends SettingsEditor<Run
private JBCheckBox myIsAllowRunningInParallelCheckBox;
private JPanel myRCStoragePanel;
private final @Nullable RunConfigurationStorageUi myRCStorageUi;
private JPanel myDisclaimerPanel;
private JLabel myDisclaimerLabel;
private JLabel myCreateNewRCLabel;
private final BeforeRunStepsPanel myBeforeRunStepsPanel;
private final ConfigurationSettingsEditor myEditor;
private final HideableDecorator myDecorator;
public <T extends SettingsEditor> T selectExecutorAndGetEditor(ProgramRunner runner, Class<T> editorClass) {
public <T extends SettingsEditor<?>> T selectExecutorAndGetEditor(ProgramRunner<?> runner, Class<T> editorClass) {
return myEditor.selectExecutorAndGetEditor(runner, editorClass);
}
public <T extends SettingsEditor> T selectTabAndGetEditor(Class<T> editorClass) {
public <T extends SettingsEditor<?>> T selectTabAndGetEditor(Class<T> editorClass) {
return myEditor.selectTabAndGetEditor(editorClass);
}
@@ -110,8 +101,6 @@ public final class ConfigurationSettingsEditorWrapper extends SettingsEditor<Run
if (myRCStorageUi != null) {
myRCStorageUi.reset(settings);
}
myDisclaimerPanel.setVisible(settings.isTemplate() && ProjectManager.getInstance().getOpenProjects().length != 0);
}
@Override
@@ -200,40 +189,17 @@ public final class ConfigurationSettingsEditorWrapper extends SettingsEditor<Run
myDecorator.setTitle(title);
}
private void createUIComponents() {
myDisclaimerLabel = new JLabel(ExecutionBundle.message("template.disclaimer"), AllIcons.General.Warning, SwingConstants.LEADING);
myDisclaimerLabel.setBorder(JBUI.Borders.emptyBottom(2));
myCreateNewRCLabel = new LinkLabel<>(ExecutionBundle.message("create.configuration"), null, new LinkListener<>() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
RunConfigurationCreator creator =
DataManager.getInstance().getDataContext(myDisclaimerLabel).getData(RunConfigurationCreator.KEY);
if (creator != null) {
creator.createNewConfiguration(myEditor.getFactory().create().getFactory());
}
}
});
}
@Override
public void targetChanged(String targetName) {
myEditor.targetChanged(targetName);
}
private static void createConfiguration(JComponent component, RunnerAndConfigurationSettings settings) {
RunConfigurationCreator creator = DataManager.getInstance().getDataContext(component).getData(RunConfigurationCreator.KEY);
if (creator != null) {
creator.createNewConfiguration(settings.getFactory());
}
}
public static SettingsEditor<RunnerAndConfigurationSettings> createWrapper(@NotNull RunnerAndConfigurationSettings settings) {
SettingsEditor<?> configurationEditor = settings.getConfiguration().getConfigurationEditor();
//noinspection unchecked
return configurationEditor instanceof RunConfigurationFragmentedEditor<?>
? new RunnerAndConfigurationSettingsEditor(settings,
(RunConfigurationFragmentedEditor<RunConfigurationBase<?>>)configurationEditor,
(component) -> createConfiguration(component, settings))
(RunConfigurationFragmentedEditor<RunConfigurationBase<?>>)configurationEditor)
: new ConfigurationSettingsEditorWrapper(settings, (SettingsEditor<RunConfiguration>)configurationEditor);
}
}

View File

@@ -2,23 +2,17 @@
package com.intellij.execution.impl
import com.intellij.execution.ExecutionBundle
import com.intellij.execution.configurations.ConfigurationType
import com.intellij.execution.configurations.ConfigurationTypeUtil
import com.intellij.ide.IdeBundle
import com.intellij.openapi.actionSystem.ActionToolbarPosition
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.ui.AnActionButton
import com.intellij.ui.JBColor
import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.ToolbarDecorator
import com.intellij.ui.components.JBPanelWithEmptyText
import com.intellij.ui.components.labels.ActionLink
import com.intellij.util.IconUtil
import com.intellij.ui.components.ActionLink
import com.intellij.util.ui.JBDimension
import com.intellij.util.ui.JBUI
import java.awt.FlowLayout
import java.awt.BorderLayout
import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.tree.DefaultMutableTreeNode
@@ -40,7 +34,6 @@ open class ProjectRunConfigurationConfigurable(project: Project, runDialog: RunD
.addExtraAction(AnActionButton.fromAction(MyCopyAction()))
.addExtraAction(AnActionButton.fromAction(MySaveAction()))
.addExtraAction(AnActionButton.fromAction(MyEditTemplatesAction()))
.addExtraAction(AnActionButton.fromAction(MyCreateFolderAction()))
.addExtraAction(AnActionButton.fromAction(MySortFolderAction()))
.setMinimumSize(JBDimension(200, 200))
@@ -53,32 +46,17 @@ open class ProjectRunConfigurationConfigurable(project: Project, runDialog: RunD
ExecutionBundle.message("move.down.action.name"),
ExecutionBundle.message("run.configuration.create.folder.text"))
.setForcedDnD()
val panel = toolbarDecorator!!.createPanel()
val panel = JPanel(BorderLayout())
panel.background = JBColor.background()
panel.add(toolbarDecorator!!.createPanel(), BorderLayout.CENTER)
val actionLink = ActionLink("Edit Configuration Templates...") { showTemplatesDialog(project, selectedConfigurationType) }
actionLink.border = JBUI.Borders.empty(10)
actionLink.background = JBColor.background()
panel.add(actionLink, BorderLayout.SOUTH)
initTree()
return panel
}
override fun createTipPanelAboutAddingNewRunConfiguration(configurationType: ConfigurationType?): JPanel {
if (!project.isDefault && DumbService.isDumb(project) &&
(configurationType == null || !ConfigurationTypeUtil.isEditableInDumbMode(configurationType)))
return JBPanelWithEmptyText().withEmptyText(IdeBundle.message("empty.text.this.view.is.not.available.until.indices.are.built"))
val messagePanel = JPanel(FlowLayout(FlowLayout.LEFT, 0, 0))
messagePanel.border = JBUI.Borders.empty(30, 0, 0, 0)
messagePanel.add(JLabel(ExecutionBundle.message("empty.run.configuration.panel.text.label1")))
val addIcon = ActionLink("", IconUtil.getAddIcon(), toolbarAddAction)
addIcon.border = JBUI.Borders.empty(0, 3, 0, 3)
messagePanel.add(addIcon)
val configurationTypeDescription = when {
configurationType != null -> configurationType.configurationTypeDescription
else -> ExecutionBundle.message("run.configuration.default.type.description")
}
messagePanel.add(JLabel(ExecutionBundle.message("empty.run.configuration.panel.text.label3", configurationTypeDescription)))
return messagePanel
}
override fun addRunConfigurationsToModel(model: DefaultMutableTreeNode) {
for ((type, folderMap) in runManager.getConfigurationsGroupedByTypeAndFolder(true)) {
val typeNode = DefaultMutableTreeNode(type)

View File

@@ -58,10 +58,6 @@ import javax.swing.*
import javax.swing.event.DocumentEvent
import javax.swing.tree.*
internal val TEMPLATES_NODE_USER_OBJECT = object : Any() {
override fun toString() = ExecutionBundle.message("run.configuration.templates.node.name")
}
private const val INITIAL_VALUE_KEY = "initialValue"
private val LOG = logger<RunConfigurable>()
@@ -70,7 +66,6 @@ internal fun getUserObjectName(userObject: Any): String {
@Suppress("HardCodedStringLiteral")
return when {
userObject is ConfigurationType -> userObject.displayName
userObject === TEMPLATES_NODE_USER_OBJECT -> ExecutionBundle.message("run.configuration.templates.node.name")
userObject is ConfigurationFactory -> userObject.name
userObject is SingleConfigurationConfigurable<*> -> userObject.nameText
userObject is RunnerAndConfigurationSettingsImpl -> userObject.name
@@ -205,27 +200,6 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
addRunConfigurationsToModel(root)
// add templates
val templates = DefaultMutableTreeNode(TEMPLATES_NODE_USER_OBJECT)
for (type in ConfigurationType.CONFIGURATION_TYPE_EP.extensionList.filter { it !is VirtualConfigurationType }) {
val configurationFactories = type.configurationFactories
val typeNode = DefaultMutableTreeNode(type)
templates.add(typeNode)
if (configurationFactories.size != 1) {
for (factory in configurationFactories) {
typeNode.add(DefaultMutableTreeNode(factory))
}
}
}
if (templates.childCount > 0) {
root.add(templates)
if (project.isDefault) {
SwingUtilities.invokeLater {
expandTemplatesNode(templates)
}
}
}
tree.addTreeSelectionListener {
val selectionPath = tree.selectionPath
if (selectionPath != null) {
@@ -239,33 +213,15 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
showFolderField(node, userObject)
}
else if (userObject is ConfigurationFactory) {
val parent = node.parent as DefaultMutableTreeNode
if (!parent.isRoot) {
showTemplateConfigurable(userObject)
}
else if (userObject is ConfigurationType) {
drawPressAddButtonMessage(userObject as ConfigurationType)
}
else {
drawPressAddButtonMessage(null)
}
}
else if (userObject === TEMPLATES_NODE_USER_OBJECT) {
drawPressAddButtonMessage(null)
showTemplateConfigurable(userObject)
}
else if (userObject is ConfigurationType) {
val parent = node.parent as DefaultMutableTreeNode
if (parent.isRoot && !project.isDefault) {
drawPressAddButtonMessage(userObject)
val factories = userObject.configurationFactories
if (factories.size == 1) {
showTemplateConfigurable(factories[0])
}
else {
val factories = userObject.configurationFactories
if (factories.size == 1) {
showTemplateConfigurable(factories[0])
}
else {
drawPressAddButtonMessage(userObject)
}
drawPressAddButtonMessage(userObject)
}
}
}
@@ -401,8 +357,6 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
val userObject2 = o2.userObject
when {
userObject1 is ConfigurationType && userObject2 is ConfigurationType -> (userObject1).displayName.compareTo(userObject2.displayName, true)
userObject1 === TEMPLATES_NODE_USER_OBJECT && userObject2 is ConfigurationType -> 1
userObject2 === TEMPLATES_NODE_USER_OBJECT && userObject1 is ConfigurationType -> - 1
else -> 0
}
}
@@ -455,12 +409,6 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
private fun drawPressAddButtonMessage(configurationType: ConfigurationType?) {
val panel = JPanel(BorderLayout())
if (!(configurationType is UnknownConfigurationType)) {
createTipPanelAboutAddingNewRunConfiguration(configurationType)?.let {
panel.add(it, BorderLayout.CENTER)
}
}
if (configurationType == null) {
val wrapper = JPanel(BorderLayout())
if (project.isDefault || !DumbService.isDumb(project)) {
@@ -491,8 +439,6 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
rightPanel.repaint()
}
protected open fun createTipPanelAboutAddingNewRunConfiguration(configurationType: ConfigurationType?): JComponent? = null
protected open fun createLeftPanel(): JComponent {
initTree()
return ScrollPaneFactory.createScrollPane(tree)
@@ -528,7 +474,7 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
return bottomPanel
}
private val selectedConfigurationType: ConfigurationType?
protected val selectedConfigurationType: ConfigurationType?
get() {
val configurationTypeNode = selectedConfigurationTypeNode
return if (configurationTypeNode != null) configurationTypeNode.userObject as ConfigurationType else null
@@ -625,13 +571,6 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
confirmationDeletionFromPopup.putClientProperty(INITIAL_VALUE_KEY, confirmationDeletionFromPopup.isSelected)
runDashboardTypesPanel.apply()
for (configurable in storedComponents.values) {
if (configurable.isModified) {
configurable.apply()
}
}
additionalSettings.forEach { it.first.apply() }
manager.setOrder(Comparator.comparingInt(ToIntFunction { settingsToOrder.getInt(it) }), isApplyAdditionalSortByTypeAndGroup = false)
@@ -644,6 +583,14 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
tree.repaint()
}
protected fun applyTemplates() {
for (configurable in storedComponents.values) {
if (configurable.isModified) {
configurable.apply()
}
}
}
fun updateActiveConfigurationFromSelected() {
val selectedConfigurable = selectedConfigurable
if (selectedConfigurable is SingleConfigurationConfigurable<*>) {
@@ -1278,30 +1225,7 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
ExecutionBundle.message("run.configuration.edit.default.configuration.settings.description"),
AllIcons.General.Settings), PossiblyDumbAware {
override fun actionPerformed(e: AnActionEvent) {
var templates = TreeUtil.findNodeWithObject(TEMPLATES_NODE_USER_OBJECT, tree.model, root) ?: return
selectedConfigurationType?.let {
templates = TreeUtil.findNodeWithObject(it, tree.model, templates) ?: return
}
expandTemplatesNode(templates as DefaultMutableTreeNode? ?: return)
}
override fun update(e: AnActionEvent) {
var isEnabled = TreeUtil.findNodeWithObject(TEMPLATES_NODE_USER_OBJECT, tree.model, root) != null
val path = tree.selectionPath
if (path != null) {
var o = path.lastPathComponent
if (o is DefaultMutableTreeNode && isVirtualConfiguration(o)) {
isEnabled = false
}
if (o is DefaultMutableTreeNode && o.userObject == TEMPLATES_NODE_USER_OBJECT) {
isEnabled = false
}
o = path.parentPath.lastPathComponent
if (o is DefaultMutableTreeNode && o.userObject == TEMPLATES_NODE_USER_OBJECT) {
isEnabled = false
}
}
e.presentation.isEnabled = isEnabled
showTemplatesDialog(project, selectedConfigurationType)
}
override fun isDumbAware(): Boolean {
@@ -1310,13 +1234,6 @@ open class RunConfigurable @JvmOverloads constructor(protected val project: Proj
}
}
private fun expandTemplatesNode(templatesNode: DefaultMutableTreeNode) {
val path = TreeUtil.getPath(root, templatesNode)
tree.expandPath(path)
TreeUtil.selectInTree(templatesNode, true, tree)
tree.scrollPathToVisible(path)
}
protected inner class MyCreateFolderAction : DumbAwareAction(ExecutionBundle.message("run.configuration.create.folder.text"),
ExecutionBundle.message("run.configuration.create.folder.description"),
AllIcons.Actions.NewFolder) {

View File

@@ -36,10 +36,6 @@ internal class RunConfigurableTreeRenderer(private val runManager: RunManagerImp
append(name, simpleTextAttributes)
icon = userObject.icon
}
userObject === TEMPLATES_NODE_USER_OBJECT -> {
append(name, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES)
icon = AllIcons.General.Settings
}
userObject is String -> {
// folder
append(name, SimpleTextAttributes.REGULAR_ATTRIBUTES)

View File

@@ -0,0 +1,80 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.impl
import com.intellij.codeInsight.hint.HintUtil
import com.intellij.execution.ExecutionBundle
import com.intellij.execution.configurations.ConfigurationType
import com.intellij.execution.configurations.VirtualConfigurationType
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.options.ex.SingleConfigurableEditor
import com.intellij.openapi.project.Project
import com.intellij.ui.IdeBorderFactory
import com.intellij.ui.SideBorder
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.tree.TreeUtil
import java.awt.BorderLayout
import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.tree.DefaultMutableTreeNode
fun showTemplatesDialog(project: Project, selectedConfigurationType: ConfigurationType?) {
val configurable = RunConfigurationTemplatesConfigurable(project, selectedConfigurationType)
object: SingleConfigurableEditor(project, configurable) {
override fun getStyle(): DialogStyle {
return DialogStyle.COMPACT
}
}.show()
}
class RunConfigurationTemplatesConfigurable(project: Project, val configurationType: ConfigurationType?) : RunConfigurable(project) {
fun selectTypeNode(configurationType: ConfigurationType?) {
configurationType?.let {
val node = TreeUtil.findNodeWithObject(it, tree.model, root) ?: return
expandTemplatesNode(node as DefaultMutableTreeNode)
}
}
private fun expandTemplatesNode(templatesNode: DefaultMutableTreeNode) {
val path = TreeUtil.getPath(root, templatesNode)
tree.expandPath(path)
TreeUtil.selectInTree(templatesNode, true, tree)
tree.scrollPathToVisible(path)
}
override fun addRunConfigurationsToModel(model: DefaultMutableTreeNode) {
// add templates
for (type in ConfigurationType.CONFIGURATION_TYPE_EP.extensionList.filter { it !is VirtualConfigurationType }) {
val configurationFactories = type.configurationFactories
val typeNode = DefaultMutableTreeNode(type)
root.add(typeNode)
if (configurationFactories.size != 1) {
for (factory in configurationFactories) {
typeNode.add(DefaultMutableTreeNode(factory))
}
}
}
}
override fun apply() {
applyTemplates()
}
override fun createComponent(): JComponent {
val component = super.createComponent()
val label = JLabel(ExecutionBundle.message("templates.disclaimer"))
label.border = JBUI.Borders.empty(10)
val panel = JPanel(BorderLayout())
panel.add(label, BorderLayout.WEST)
panel.border = IdeBorderFactory.createBorder(SideBorder.BOTTOM)
panel.background = EditorColorsManager.getInstance().globalScheme.getColor(HintUtil.PROMOTION_PANE_KEY)
component!!.add(panel, BorderLayout.NORTH)
selectTypeNode(configurationType)
return component
}
override fun getDisplayName(): String {
return ExecutionBundle.message("configurable.name.run.debug.configuration.templates")
}
}

View File

@@ -1,39 +1,31 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.ui;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.impl.RunConfigurationStorageUi;
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.function.Consumer;
public class RunnerAndConfigurationSettingsEditor extends SettingsEditor<RunnerAndConfigurationSettings> implements
TargetAwareRunConfigurationEditor {
private final RunConfigurationFragmentedEditor<RunConfigurationBase<?>> myConfigurationEditor;
private final Consumer<? super JComponent> myConfigurationCreator;
private final @Nullable RunConfigurationStorageUi myRCStorageUi;
public RunnerAndConfigurationSettingsEditor(RunnerAndConfigurationSettings settings,
RunConfigurationFragmentedEditor<RunConfigurationBase<?>> configurationEditor,
Consumer<? super JComponent> configurationCreator) {
RunConfigurationFragmentedEditor<RunConfigurationBase<?>> configurationEditor) {
super(settings.createFactory());
myConfigurationEditor = configurationEditor;
myConfigurationCreator = configurationCreator;
myConfigurationEditor.addSettingsEditorListener(editor -> fireEditorStateChanged());
Disposer.register(this, myConfigurationEditor);
@@ -78,15 +70,6 @@ public class RunnerAndConfigurationSettingsEditor extends SettingsEditor<RunnerA
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTH;
c.insets = JBUI.emptyInsets();
c.fill = GridBagConstraints.NONE;
c.weightx = 0;
c.weighty = 0;
panel.add(createDisclaimer(), c);
c.gridx = 0;
c.gridy = 1;
c.anchor = GridBagConstraints.EAST;
c.insets = JBUI.insets(5, 0, 5, 0);
c.fill = GridBagConstraints.NONE;
@@ -95,7 +78,7 @@ public class RunnerAndConfigurationSettingsEditor extends SettingsEditor<RunnerA
panel.add(myRCStorageUi.createComponent(), c);
c.gridx = 0;
c.gridy = 2;
c.gridy = 1;
c.anchor = GridBagConstraints.NORTH;
c.insets = JBUI.emptyInsets();
c.fill = GridBagConstraints.BOTH;
@@ -105,19 +88,4 @@ public class RunnerAndConfigurationSettingsEditor extends SettingsEditor<RunnerA
return panel;
}
private JComponent createDisclaimer() {
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel(ExecutionBundle.message("template.disclaimer"), AllIcons.General.Warning, SwingConstants.LEADING);
label.setBorder(JBUI.Borders.emptyRight(JBUI.scale(10)));
panel.add(label, BorderLayout.WEST);
panel.add(new LinkLabel<>(ExecutionBundle.message("create.configuration"), null, new LinkListener<>() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
myConfigurationCreator.accept(panel);
}
}), BorderLayout.EAST);
panel.setBorder(JBUI.Borders.empty(JBUI.scale(3), 0, JBUI.scale(7), 0));
return panel;
}
}

View File

@@ -46,8 +46,6 @@ run.configuration.norunner.selected.label=No runner selected
run.configuration.configuration.tab.title=Configuration
run.configuration.startup.connection.rab.title=Startup/Connection
template.disclaimer=Template. The values saved here will be used for new configurations of the same type
create.configuration=Create configuration
add.new.run.configuration.action2.name=Add New Configuration
add.new.before.run.task.name=Add New Task
add.new.run.configuration.action.name=Add New ''{0}'' Configuration
@@ -593,4 +591,6 @@ state.widget.stop.action.item.name={0}: {1}
state.widget.stop.process.action.item.name=Stop {0}
module.not.specified=module not specified
sdk.of.0.module=SDK of ''{0}'' module
newest.sdk.from.0.module.1.choice.0.1.test.dependencies=newest SDK from ''{0}'' module{1, choice, 0#|1# test} dependencies
newest.sdk.from.0.module.1.choice.0.1.test.dependencies=newest SDK from ''{0}'' module{1, choice, 0#|1# test} dependencies
templates.disclaimer=Templates are used to create new configurations. Changing a template does not affect the existing configurations.
configurable.name.run.debug.configuration.templates=Run/Debug Configuration Templates