Maven+Ant: correct before run tasks updating (IDEA-44796,IDEA-44793,IDEA-42264)
[fedora-idea.git] / platform / lang-impl / src / com / intellij / execution / impl / BaseExecuteBeforeRunDialog.java
blob8472d0adb3fff541bc965a1f4185ea4118aff1e7
1 /*
2 * Copyright 2000-2010 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.execution.impl;
18 import com.intellij.execution.BeforeRunTask;
19 import com.intellij.execution.ExecutionBundle;
20 import com.intellij.execution.RunManager;
21 import com.intellij.execution.RunManagerEx;
22 import com.intellij.execution.configurations.ConfigurationFactory;
23 import com.intellij.execution.configurations.ConfigurationType;
24 import com.intellij.execution.configurations.RunConfiguration;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.ui.DialogWrapper;
27 import com.intellij.openapi.util.Key;
28 import com.intellij.ui.TreeSpeedSearch;
29 import com.intellij.ui.TreeToolTipHandler;
30 import com.intellij.ui.treeStructure.Tree;
31 import com.intellij.util.StringSetSpinAllocator;
32 import com.intellij.util.ui.UIUtil;
33 import com.intellij.util.ui.tree.TreeUtil;
35 import javax.swing.*;
36 import javax.swing.tree.DefaultMutableTreeNode;
37 import javax.swing.tree.TreeCellRenderer;
38 import javax.swing.tree.TreeNode;
39 import javax.swing.tree.TreePath;
40 import java.awt.*;
41 import java.awt.event.KeyAdapter;
42 import java.awt.event.KeyEvent;
43 import java.awt.event.MouseAdapter;
44 import java.awt.event.MouseEvent;
45 import java.util.ArrayList;
46 import java.util.Enumeration;
47 import java.util.Set;
50 public abstract class BaseExecuteBeforeRunDialog<T extends BeforeRunTask> extends DialogWrapper {
51 private final Project myProject;
52 private DefaultMutableTreeNode myRoot;
54 public BaseExecuteBeforeRunDialog(final Project project) {
55 super(project, true);
56 myProject = project;
59 @Override
60 protected void init() {
61 super.init();
62 setTitle(ExecutionBundle.message("execute.before.run.debug.dialog.title", getTargetDisplayString()));
65 protected JComponent createCenterPanel() {
66 JPanel panel = new JPanel(new BorderLayout());
68 myRoot = buildNodes();
69 final Tree tree = new Tree(myRoot);
71 final MyTreeCellRenderer cellRenderer = new MyTreeCellRenderer();
73 tree.setCellRenderer(cellRenderer);
74 tree.setRootVisible(false);
75 tree.setShowsRootHandles(true);
76 tree.setLineStyleAngled();
77 TreeToolTipHandler.install(tree);
78 TreeUtil.installActions(tree);
79 new TreeSpeedSearch(tree);
81 tree.addMouseListener(new MouseAdapter() {
82 public void mousePressed(MouseEvent e) {
83 int row = tree.getRowForLocation(e.getX(), e.getY());
84 if (row >= 0) {
85 Rectangle rowBounds = tree.getRowBounds(row);
86 cellRenderer.setBounds(rowBounds);
87 Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
89 checkBounds.setLocation(rowBounds.getLocation());
90 if (checkBounds.contains(e.getPoint())) {
91 toggleNode(tree, (DefaultMutableTreeNode)tree.getPathForRow(row).getLastPathComponent());
92 e.consume();
93 tree.setSelectionRow(row);
97 });
99 tree.addKeyListener(new KeyAdapter() {
100 public void keyPressed(KeyEvent e) {
101 if (e.getKeyCode() == KeyEvent.VK_SPACE) {
102 TreePath treePath = tree.getLeadSelectionPath();
103 DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent();
104 toggleNode(tree, node);
105 e.consume();
110 expacndChecked(tree);
112 JScrollPane scrollPane = new JScrollPane(tree);
113 scrollPane.setPreferredSize(new Dimension(400, 400));
114 panel.add(scrollPane, BorderLayout.CENTER);
115 return panel;
118 private static void expacndChecked(Tree tree) {
119 TreeNode root = (TreeNode)tree.getModel().getRoot();
120 Enumeration factories = root.children();
121 ArrayList<TreeNode[]> toExpand = new ArrayList<TreeNode[]>();
122 while (factories.hasMoreElements()) {
123 DefaultMutableTreeNode factoryNode = (DefaultMutableTreeNode)factories.nextElement();
124 Enumeration configurations = factoryNode.children();
125 while (configurations.hasMoreElements()) {
126 DefaultMutableTreeNode node = (DefaultMutableTreeNode)configurations.nextElement();
127 ConfigurationDescriptor config = (ConfigurationDescriptor)node.getUserObject();
128 if (config.isChecked()) {
129 toExpand.add(factoryNode.getPath());
130 break;
134 for (TreeNode[] treeNodes : toExpand) {
135 tree.expandPath(new TreePath(treeNodes));
139 private static void toggleNode(JTree tree, DefaultMutableTreeNode node) {
140 Descriptor descriptor = (Descriptor)node.getUserObject();
141 descriptor.setChecked(!descriptor.isChecked());
142 tree.repaint();
145 private DefaultMutableTreeNode buildNodes() {
146 DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Descriptor());
147 RunManager runManager = RunManager.getInstance(myProject);
148 final ConfigurationType[] configTypes = runManager.getConfigurationFactories();
150 for (final ConfigurationType type : configTypes) {
151 final Icon icon = type.getIcon();
152 DefaultMutableTreeNode typeNode = new DefaultMutableTreeNode(new ConfigurationTypeDescriptor(type, icon, isConfigurationAssigned(type)));
153 root.add(typeNode);
154 final Set<String> addedNames = StringSetSpinAllocator.alloc();
155 try {
156 RunConfiguration[] configurations = runManager.getConfigurations(type);
157 for (final RunConfiguration configuration : configurations) {
158 final String configurationName = configuration.getName();
159 if (addedNames.contains(configurationName)) {
160 // add only the first configuration if more than one has the same name
161 continue;
163 addedNames.add(configurationName);
164 typeNode.add(new DefaultMutableTreeNode(
165 new ConfigurationDescriptor(configuration, isConfigurationAssigned(configuration))));
168 finally {
169 StringSetSpinAllocator.dispose(addedNames);
173 return root;
177 private boolean isConfigurationAssigned(ConfigurationType type) {
178 final RunManagerEx runManager = RunManagerEx.getInstanceEx(myProject);
179 for (ConfigurationFactory factory : type.getConfigurationFactories()) {
180 final RunnerAndConfigurationSettingsImpl settings = ((RunManagerImpl)runManager).getConfigurationTemplate(factory);
181 if (isConfigurationAssigned(settings.getConfiguration())) return true;
183 return false;
186 private boolean isConfigurationAssigned(RunConfiguration configuration) {
187 final T task = RunManagerEx.getInstanceEx(myProject).getBeforeRunTask(configuration, getTaskID());
188 return task != null && isRunning(task);
191 protected void doOKAction() {
192 final RunManagerImpl runManager = (RunManagerImpl)RunManagerEx.getInstanceEx(myProject);
193 for (Enumeration nodes = myRoot.depthFirstEnumeration(); nodes.hasMoreElements(); ) {
194 final DefaultMutableTreeNode node = (DefaultMutableTreeNode)nodes.nextElement();
195 final Descriptor descriptor = (Descriptor)node.getUserObject();
196 final boolean isChecked = descriptor.isChecked();
198 if (descriptor instanceof ConfigurationTypeDescriptor) {
199 ConfigurationTypeDescriptor typeDesc = (ConfigurationTypeDescriptor)descriptor;
200 for (ConfigurationFactory factory : typeDesc.getConfigurationType().getConfigurationFactories()) {
201 RunnerAndConfigurationSettingsImpl settings = runManager.getConfigurationTemplate(factory);
202 update(settings.getConfiguration(), isChecked, runManager);
205 else if (descriptor instanceof ConfigurationDescriptor) {
206 ConfigurationDescriptor configDesc = (ConfigurationDescriptor)descriptor;
207 update(configDesc.getConfiguration(), isChecked, runManager);
211 ((RunManagerImpl)RunManagerEx.getInstanceEx(myProject)).fireBeforeRunTasksUpdated();
212 close(OK_EXIT_CODE);
215 protected abstract String getTargetDisplayString();
217 protected abstract Key<T> getTaskID();
219 protected abstract boolean isRunning(T task);
221 private void update(RunConfiguration config, boolean enabled, RunManagerImpl runManager) {
222 T task = runManager.getBeforeRunTask(config, getTaskID());
223 if (task == null) return;
225 if (enabled) {
226 task.setEnabled(true);
227 update(task);
229 else {
230 if (isRunning(task)) {
231 task.setEnabled(false);
232 clear(task);
234 // do not change the task otherwise
238 protected abstract void update(T task);
240 protected abstract void clear(T task);
242 private static class Descriptor {
243 private boolean myChecked;
245 public final boolean isChecked() {
246 return myChecked;
249 public final void setChecked(boolean checked) {
250 myChecked = checked;
254 private static final class ConfigurationTypeDescriptor extends Descriptor {
255 private final ConfigurationType myConfigurationType;
256 private final Icon myIcon;
258 public ConfigurationTypeDescriptor(ConfigurationType type, Icon icon, boolean isChecked) {
259 myConfigurationType = type;
260 myIcon = icon;
261 setChecked(isChecked);
264 public ConfigurationType getConfigurationType() {
265 return myConfigurationType;
268 public Icon getIcon() {
269 return myIcon;
273 private static final class ConfigurationDescriptor extends Descriptor {
274 private final RunConfiguration myConfiguration;
276 public ConfigurationDescriptor(RunConfiguration configuration, boolean isChecked) {
277 myConfiguration = configuration;
278 setChecked(isChecked);
281 public ConfigurationType getConfigurationFactory() {
282 return myConfiguration.getType();
285 public String getName() {
286 return myConfiguration.getName();
289 public RunConfiguration getConfiguration() {
290 return myConfiguration;
295 private static final class MyTreeCellRenderer extends JPanel implements TreeCellRenderer {
296 private final JLabel myLabel;
297 public final JCheckBox myCheckbox;
299 public MyTreeCellRenderer() {
300 super(new BorderLayout());
301 myCheckbox = new JCheckBox();
302 myLabel = new JLabel();
303 add(myCheckbox, BorderLayout.WEST);
304 add(myLabel, BorderLayout.CENTER);
307 public Component getTreeCellRendererComponent(JTree tree,
308 Object value,
309 boolean selected,
310 boolean expanded,
311 boolean leaf,
312 int row,
313 boolean hasFocus) {
314 DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
315 Descriptor descriptor = (Descriptor)node.getUserObject();
317 myCheckbox.setSelected(descriptor.isChecked());
319 myCheckbox.setBackground(UIUtil.getTreeTextBackground());
320 setBackground(selected ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeTextBackground());
321 Color foreground = selected ? UIUtil.getTreeSelectionForeground() : UIUtil.getTreeTextForeground();
322 setForeground(foreground);
323 myCheckbox.setForeground(foreground);
324 myLabel.setForeground(foreground);
325 myCheckbox.setEnabled(true);
327 if (descriptor instanceof ConfigurationTypeDescriptor) {
328 ConfigurationTypeDescriptor configurationTypeDescriptor = (ConfigurationTypeDescriptor)descriptor;
329 myLabel.setFont(tree.getFont());
330 myLabel.setText(configurationTypeDescriptor.getConfigurationType().getDisplayName());
331 myLabel.setIcon(configurationTypeDescriptor.getIcon());
333 else if (descriptor instanceof ConfigurationDescriptor) {
334 ConfigurationDescriptor configurationTypeDescriptor = (ConfigurationDescriptor)descriptor;
335 myLabel.setFont(tree.getFont());
336 myLabel.setText(configurationTypeDescriptor.getName());
337 myLabel.setIcon(null);
339 if (((ConfigurationTypeDescriptor)((DefaultMutableTreeNode)node.getParent()).getUserObject()).isChecked()) {
340 Color foregrnd = tree.getForeground();
341 Color backgrnd = tree.getBackground();
342 if (foregrnd == null) foregrnd = Color.black;
343 if (backgrnd == null) backgrnd = Color.white;
345 int red = (foregrnd.getRed() + backgrnd.getRed()) / 2;
346 int green = (foregrnd.getGreen() + backgrnd.getGreen()) / 2;
347 int blue = (foregrnd.getBlue() + backgrnd.getBlue()) / 2;
348 Color halftone = new Color(red, green, blue);
349 setForeground(halftone);
350 myCheckbox.setForeground(halftone);
351 myLabel.setForeground(halftone);
352 myCheckbox.setEnabled(false);
356 return this;