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
;
36 import javax
.swing
.tree
.DefaultMutableTreeNode
;
37 import javax
.swing
.tree
.TreeCellRenderer
;
38 import javax
.swing
.tree
.TreeNode
;
39 import javax
.swing
.tree
.TreePath
;
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
;
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
) {
60 protected void 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());
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());
93 tree
.setSelectionRow(row
);
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
);
110 expacndChecked(tree
);
112 JScrollPane scrollPane
= new JScrollPane(tree
);
113 scrollPane
.setPreferredSize(new Dimension(400, 400));
114 panel
.add(scrollPane
, BorderLayout
.CENTER
);
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());
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());
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
)));
154 final Set
<String
> addedNames
= StringSetSpinAllocator
.alloc();
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
163 addedNames
.add(configurationName
);
164 typeNode
.add(new DefaultMutableTreeNode(
165 new ConfigurationDescriptor(configuration
, isConfigurationAssigned(configuration
))));
169 StringSetSpinAllocator
.dispose(addedNames
);
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;
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();
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;
226 task
.setEnabled(true);
230 if (isRunning(task
)) {
231 task
.setEnabled(false);
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() {
249 public final void setChecked(boolean 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
;
261 setChecked(isChecked
);
264 public ConfigurationType
getConfigurationType() {
265 return myConfigurationType
;
268 public Icon
getIcon() {
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
,
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);