cleanup: use CUSTOM_COMPONENT_PROPERTY property
[idea/community.git] / platform / lang-impl / src / com / intellij / execution / actions / RunConfigurationsComboBoxAction.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.execution.actions;
18
19 import com.intellij.execution.*;
20 import com.intellij.execution.configurations.ConfigurationType;
21 import com.intellij.icons.AllIcons;
22 import com.intellij.ide.DataManager;
23 import com.intellij.openapi.actionSystem.*;
24 import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
25 import com.intellij.openapi.project.DumbAware;
26 import com.intellij.openapi.project.DumbService;
27 import com.intellij.openapi.project.IndexNotReadyException;
28 import com.intellij.openapi.project.Project;
29 import com.intellij.ui.SizedIcon;
30 import com.intellij.util.ui.EmptyIcon;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33
34 import javax.swing.*;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38
39 public class RunConfigurationsComboBoxAction extends ComboBoxAction implements DumbAware {
40
41   public static final Icon CHECKED_ICON = new SizedIcon(AllIcons.Actions.Checked, 16, 16);
42   public static final Icon CHECKED_SELECTED_ICON = new SizedIcon(AllIcons.Actions.Checked_selected, 16, 16);
43   public static final Icon EMPTY_ICON = EmptyIcon.ICON_16;
44
45   @Override
46   public void actionPerformed(AnActionEvent e) {
47     ComboBoxButton button = (ComboBoxButton)e.getPresentation().getClientProperty(CUSTOM_COMPONENT_PROPERTY);
48     if (button == null || !button.isShowing()) return;
49     button.showPopup();
50   }
51
52   @Override
53   public void update(AnActionEvent e) {
54     Presentation presentation = e.getPresentation();
55     ComboBoxButton button = (ComboBoxButton)presentation.getClientProperty(CUSTOM_COMPONENT_PROPERTY);
56     Project project = e.getData(CommonDataKeys.PROJECT);
57     if (ActionPlaces.isMainMenuOrActionSearch(e.getPlace())) {
58       presentation.setDescription(ExecutionBundle.message("choose.run.configuration.action.description"));
59       presentation.setEnabled(button != null);
60       return;
61     }
62
63     try {
64       if (project == null || project.isDisposed() || !project.isInitialized()) {
65         updateButton(null, null, null, presentation);
66         presentation.setEnabled(false);
67       }
68       else {
69         if (DumbService.getInstance(project).isDumb()) {
70           presentation.setEnabled(false);
71           presentation.setText("");
72           presentation.setIcon(null);
73         }
74         else {
75           updateButton(ExecutionTargetManager.getActiveTarget(project),
76                        RunManagerEx.getInstanceEx(project).getSelectedConfiguration(),
77                        project,
78                        presentation);
79           presentation.setEnabled(true);
80         }
81       }
82     }
83     catch (IndexNotReadyException e1) {
84       presentation.setEnabled(false);
85     }
86   }
87
88   private static void updateButton(@Nullable ExecutionTarget target,
89                                    final @Nullable RunnerAndConfigurationSettings settings,
90                                    final @Nullable Project project,
91                                    final @NotNull Presentation presentation) {
92     if (project != null && target != null && settings != null) {
93       String name = settings.getName();
94       if (target != DefaultExecutionTarget.INSTANCE) {
95         name += " | " + target.getDisplayName();
96       } else {
97         if (!settings.canRunOn(target)) {
98           name += " | Nothing to run on";
99         }
100       }
101       presentation.setText(name, false);
102       setConfigurationIcon(presentation, settings, project);
103     }
104     else {
105       presentation.setText(""); // IDEA-21657
106       presentation.setIcon(null);
107     }
108   }
109
110   private static void setConfigurationIcon(final Presentation presentation,
111                                            final RunnerAndConfigurationSettings settings,
112                                            final Project project) {
113     try {
114       presentation.setIcon(RunManagerEx.getInstanceEx(project).getConfigurationIcon(settings));
115     }
116     catch (IndexNotReadyException ignored) {
117     }
118   }
119
120   @Override
121   public JComponent createCustomComponent(final Presentation presentation) {
122     ComboBoxButton button = new ComboBoxButton(presentation);
123     button.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
124     return button;
125   }
126
127
128   @Override
129   @NotNull
130   protected DefaultActionGroup createPopupActionGroup(final JComponent button) {
131     final DefaultActionGroup allActionsGroup = new DefaultActionGroup();
132     final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(button));
133     if (project != null) {
134       final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
135
136       allActionsGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_RUN_CONFIGURATIONS));
137       allActionsGroup.add(new SaveTemporaryAction());
138       allActionsGroup.addSeparator();
139
140       RunnerAndConfigurationSettings selected = RunManager.getInstance(project).getSelectedConfiguration();
141       if (selected != null) {
142         ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project);
143         for (ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selected)) {
144           allActionsGroup.add(new SelectTargetAction(project, eachTarget, eachTarget.equals(activeTarget)));
145         }
146         allActionsGroup.addSeparator();
147       }
148
149       final ConfigurationType[] types = runManager.getConfigurationFactories();
150       for (ConfigurationType type : types) {
151         final DefaultActionGroup actionGroup = new DefaultActionGroup();
152         Map<String,List<RunnerAndConfigurationSettings>> structure = runManager.getStructure(type);
153         for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : structure.entrySet()) {
154           DefaultActionGroup group = entry.getKey() != null ? new DefaultActionGroup(entry.getKey(), true) : actionGroup;
155           group.getTemplatePresentation().setIcon(AllIcons.Nodes.Folder);
156           for (RunnerAndConfigurationSettings settings : entry.getValue()) {
157             group.add(new SelectConfigAction(settings, project));
158           }
159           if (group != actionGroup) {
160             actionGroup.add(group);
161           }
162         }
163
164         allActionsGroup.add(actionGroup);
165         allActionsGroup.addSeparator();
166       }
167     }
168     return allActionsGroup;
169   }
170
171   private static class SaveTemporaryAction extends AnAction {
172
173     public SaveTemporaryAction() {
174       Presentation presentation = getTemplatePresentation();
175       presentation.setIcon(AllIcons.Actions.Menu_saveall);
176     }
177
178     @Override
179     public void actionPerformed(final AnActionEvent e) {
180       final Project project = e.getData(CommonDataKeys.PROJECT);
181       if (project != null) {
182         RunnerAndConfigurationSettings settings = chooseTempSettings(project);
183         if (settings != null) {
184           final RunManager runManager = RunManager.getInstance(project);
185           runManager.makeStable(settings);
186         }
187       }
188     }
189
190     @Override
191     public void update(final AnActionEvent e) {
192       final Presentation presentation = e.getPresentation();
193       final Project project = e.getData(CommonDataKeys.PROJECT);
194       if (project == null) {
195         disable(presentation);
196         return;
197       }
198       RunnerAndConfigurationSettings settings = chooseTempSettings(project);
199       if (settings == null) {
200         disable(presentation);
201       }
202       else {
203         presentation.setText(ExecutionBundle.message("save.temporary.run.configuration.action.name", settings.getName()));
204         presentation.setDescription(presentation.getText());
205         presentation.setVisible(true);
206         presentation.setEnabled(true);
207       }
208     }
209
210     private static void disable(final Presentation presentation) {
211       presentation.setEnabled(false);
212       presentation.setVisible(false);
213     }
214
215     @Nullable
216     private static RunnerAndConfigurationSettings chooseTempSettings(@NotNull Project project) {
217       RunnerAndConfigurationSettings selectedConfiguration = RunManager.getInstance(project).getSelectedConfiguration();
218       if (selectedConfiguration != null && selectedConfiguration.isTemporary()) {
219         return selectedConfiguration;
220       }
221       Iterator<RunnerAndConfigurationSettings> iterator = RunManager.getInstance(project).getTempConfigurationsList().iterator();
222       return iterator.hasNext() ? iterator.next() : null;
223     }
224   }
225
226   private static class SelectTargetAction extends AnAction {
227     private final Project myProject;
228     private final ExecutionTarget myTarget;
229
230     public SelectTargetAction(final Project project, final ExecutionTarget target, boolean selected) {
231       myProject = project;
232       myTarget = target;
233
234       String name = target.getDisplayName();
235       Presentation presentation = getTemplatePresentation();
236       presentation.setText(name, false);
237       presentation.setDescription("Select " + name);
238
239       presentation.setIcon(selected ? CHECKED_ICON : EMPTY_ICON);
240       presentation.setSelectedIcon(selected ? CHECKED_SELECTED_ICON : EMPTY_ICON);
241     }
242
243     @Override
244     public void actionPerformed(AnActionEvent e) {
245       ExecutionTargetManager.setActiveTarget(myProject, myTarget);
246       updateButton(ExecutionTargetManager.getActiveTarget(myProject),
247                    RunManagerEx.getInstanceEx(myProject).getSelectedConfiguration(),
248                    myProject,
249                    e.getPresentation());
250     }
251   }
252
253   private static class SelectConfigAction extends AnAction {
254     private final RunnerAndConfigurationSettings myConfiguration;
255     private final Project myProject;
256
257     public SelectConfigAction(final RunnerAndConfigurationSettings configuration, final Project project) {
258       myConfiguration = configuration;
259       myProject = project;
260       String name = configuration.getName();
261       if (name == null || name.length() == 0) {
262         name = " ";
263       }
264       final Presentation presentation = getTemplatePresentation();
265       presentation.setText(name, false);
266       final ConfigurationType type = configuration.getType();
267       if (type != null) {
268         presentation.setDescription("Select " + type.getConfigurationTypeDescription() + " '" + name + "'");
269       }
270       updateIcon(presentation);
271     }
272
273     private void updateIcon(final Presentation presentation) {
274       setConfigurationIcon(presentation, myConfiguration, myProject);
275     }
276
277     @Override
278     public void actionPerformed(final AnActionEvent e) {
279       RunManager.getInstance(myProject).setSelectedConfiguration(myConfiguration);
280       updateButton(ExecutionTargetManager.getActiveTarget(myProject), myConfiguration, myProject, e.getPresentation());
281     }
282
283     @Override
284     public void update(final AnActionEvent e) {
285       super.update(e);
286       updateIcon(e.getPresentation());
287     }
288   }
289 }