Run... Debug... actions instead of Execute configuration...
[fedora-idea.git] / lang-impl / src / com / intellij / execution / actions / ChooseRunConfigurationAction.java
blobed1cdb857010e19b97fd964e473f5964cd675469
1 package com.intellij.execution.actions;
3 import com.intellij.execution.*;
4 import com.intellij.execution.configurations.ConfigurationType;
5 import com.intellij.execution.executors.DefaultRunExecutor;
6 import com.intellij.execution.impl.EditConfigurationsDialog;
7 import com.intellij.execution.impl.RunDialog;
8 import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
9 import com.intellij.execution.runners.ProgramRunner;
10 import com.intellij.ide.DataManager;
11 import com.intellij.openapi.actionSystem.*;
12 import com.intellij.openapi.project.Project;
13 import com.intellij.openapi.ui.popup.ListSeparator;
14 import com.intellij.openapi.ui.popup.PopupStep;
15 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
16 import com.intellij.openapi.util.IconLoader;
17 import com.intellij.openapi.wm.ToolWindowId;
18 import com.intellij.ui.popup.list.ListPopupImpl;
19 import org.jetbrains.annotations.NotNull;
20 import org.jetbrains.annotations.Nullable;
22 import javax.swing.*;
23 import java.awt.event.ActionEvent;
24 import java.util.ArrayList;
25 import java.util.List;
27 /**
28 * @author spleaner
30 * TODO: advertise alternate executor (hold SHIFT)
32 public class ChooseRunConfigurationAction extends AnAction {
33 private static final Icon EDIT_ICON = IconLoader.getIcon("/actions/editSource.png");
34 private static final Icon SAVE_ICON = IconLoader.getIcon("/runConfigurations/saveTempConfig.png");
36 private Executor myCurrentExecutor;
38 @Override
39 public void actionPerformed(AnActionEvent e) {
40 final Project project = e.getData(PlatformDataKeys.PROJECT);
41 assert project != null;
43 final Executor executor = getDefaultExecutor();
44 assert executor != null;
46 final ListPopupImpl popup =
47 new ListPopupImpl(new ConfigurationListPopupStep(this, project, String.format("%s", executor.getActionName()))) {
49 registerActions(this, getInputMap(), getActionMap());
50 }};
52 popup.showCenteredInCurrentWindow(project);
55 private void registerActions(final ListPopupImpl listPopup, @NotNull final InputMap inputMap, @NotNull final ActionMap actionMap) {
56 inputMap.put(KeyStroke.getKeyStroke("shift pressed SHIFT"), "alternateExecutor");
57 inputMap.put(KeyStroke.getKeyStroke("released SHIFT"), "restoreDefaultExecutor");
58 inputMap.put(KeyStroke.getKeyStroke("shift ENTER"), "invokeAction");
60 actionMap.put("invokeAction", new AbstractAction() {
61 public void actionPerformed(ActionEvent e) {
62 listPopup.handleSelect(true);
64 });
66 actionMap.put("alternateExecutor", new AbstractAction() {
67 public void actionPerformed(ActionEvent e) {
68 myCurrentExecutor = getAlternateExecutor();
69 updatePresentation(listPopup);
71 });
73 actionMap.put("restoreDefaultExecutor", new AbstractAction() {
74 public void actionPerformed(ActionEvent e) {
75 myCurrentExecutor = getDefaultExecutor();
76 updatePresentation(listPopup);
78 });
81 private void updatePresentation(ListPopupImpl listPopup) {
82 final Executor executor = getCurrentExecutor();
83 if (executor != null) {
84 listPopup.setCaption(executor.getActionName());
88 @Nullable
89 protected Executor getDefaultExecutor() {
90 return DefaultRunExecutor.getRunExecutorInstance();
93 @Nullable
94 protected Executor getAlternateExecutor() {
95 return ExecutorRegistry.getInstance().getExecutorById(ToolWindowId.DEBUG);
98 @Nullable
99 protected Executor getCurrentExecutor() {
100 return myCurrentExecutor == null ? getDefaultExecutor() : myCurrentExecutor;
103 @Override
104 public void update(AnActionEvent e) {
105 final Presentation presentation = e.getPresentation();
106 final Project project = e.getData(PlatformDataKeys.PROJECT);
108 presentation.setEnabled(true);
109 if (project == null || project.isDisposed()) {
110 presentation.setEnabled(false);
111 presentation.setVisible(false);
112 return;
115 if (null == getDefaultExecutor()) {
116 presentation.setEnabled(false);
117 presentation.setVisible(false);
118 return;
121 presentation.setEnabled(true);
122 presentation.setVisible(true);
125 private abstract static class ItemWrapper<T> {
126 private T myValue;
128 protected ItemWrapper(@Nullable final T value) {
129 myValue = value;
132 public T getValue() {
133 return myValue;
136 public abstract Icon getIcon();
138 public abstract String getText();
140 public abstract void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull final DataContext context);
142 @Nullable
143 public ConfigurationType getType() {
144 return null;
147 public boolean available(Executor executor) {
148 return true;
151 public boolean hasActions() {
152 return false;
155 public PopupStep getNextStep(Project project, ChooseRunConfigurationAction action) {
156 return PopupStep.FINAL_CHOICE;
159 public static ItemWrapper wrap(@NotNull final Project project, @NotNull final RunnerAndConfigurationSettingsImpl settings) {
160 return new ItemWrapper<RunnerAndConfigurationSettingsImpl>(settings) {
161 @Override
162 public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
163 RunManagerEx.getInstanceEx(project).setSelectedConfiguration(getValue());
164 ExecutionUtil.executeConfiguration(project, getValue(), executor, DataManager.getInstance().getDataContext());
167 @Override
168 public ConfigurationType getType() {
169 return getValue().getType();
172 @Override
173 public Icon getIcon() {
174 return ExecutionUtil.getConfigurationIcon(project, getValue());
177 @Override
178 public String getText() {
179 return getValue().getName();
182 @Override
183 public boolean hasActions() {
184 return true;
187 @Override
188 public boolean available(Executor executor) {
189 return null != ExecutionUtil.getRunner(executor.getId(), getValue());
192 @Override
193 public PopupStep getNextStep(@NotNull final Project project, @NotNull final ChooseRunConfigurationAction action) {
194 return new ConfigurationActionsStep(project, action, getValue());
201 private static final class ConfigurationListPopupStep extends BaseListPopupStep<ItemWrapper> {
202 private Project myProject;
203 private ChooseRunConfigurationAction myAction;
205 private ConfigurationListPopupStep(@NotNull final ChooseRunConfigurationAction action,
206 @NotNull final Project project,
207 @NotNull final String title) {
208 super(title, createSettingsList(project));
209 myProject = project;
210 myAction = action;
213 private static ItemWrapper[] createSettingsList(@NotNull final Project project) {
214 final RunManagerEx manager = RunManagerEx.getInstanceEx(project);
216 final List<ItemWrapper> result = new ArrayList<ItemWrapper>();
218 //noinspection unchecked
219 result.add(new ItemWrapper(null) {
220 @Override
221 public Icon getIcon() {
222 return EDIT_ICON;
225 @Override
226 public String getText() {
227 return "Edit configurations...";
230 @Override
231 public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
232 new EditConfigurationsDialog(project).show();
236 final ConfigurationType[] factories = manager.getConfigurationFactories();
237 for (final ConfigurationType factory : factories) {
238 final RunnerAndConfigurationSettingsImpl[] configurations = manager.getConfigurationSettings(factory);
239 for (final RunnerAndConfigurationSettingsImpl configuration : configurations) {
240 result.add(ItemWrapper.wrap(project, configuration));
245 return result.toArray(new ItemWrapper[result.size()]);
248 @Override
249 public ListSeparator getSeparatorAbove(ItemWrapper value) {
250 final List<ItemWrapper> configurations = getValues();
251 final int index = configurations.indexOf(value);
252 if (index > 0 && index <= configurations.size() - 1) {
253 final ItemWrapper aboveConfiguration = index == 0 ? null : configurations.get(index - 1);
254 final ConfigurationType currentType = value.getType();
255 final ConfigurationType aboveType = aboveConfiguration == null ? null : aboveConfiguration.getType();
256 if (aboveType != currentType && currentType != null) {
257 return new ListSeparator(); // new ListSeparator(currentType.getDisplayName());
261 return null;
264 @Override
265 public boolean isSpeedSearchEnabled() {
266 return true;
269 @Override
270 public int getDefaultOptionIndex() {
271 final RunnerAndConfigurationSettings currentConfiguration = RunManager.getInstance(myProject).getSelectedConfiguration();
273 final List<ItemWrapper> list = getValues();
274 int i = 0;
275 for (final ItemWrapper wrapper : list) {
276 if (wrapper.getValue() == currentConfiguration) {
277 return i;
279 i++;
282 return super.getDefaultOptionIndex();
285 @Override
286 public PopupStep onChosen(final ItemWrapper wrapper, boolean finalChoice) {
287 final Executor executor = myAction.getCurrentExecutor();
288 assert executor != null;
290 if (finalChoice && wrapper.available(executor)) {
291 SwingUtilities.invokeLater(new Runnable() {
292 public void run() {
293 wrapper.perform(myProject, executor, DataManager.getInstance().getDataContext());
297 return FINAL_CHOICE;
299 else {
300 return wrapper.getNextStep(myProject, myAction);
304 @Override
305 public boolean hasSubstep(ItemWrapper selectedValue) {
306 return selectedValue.hasActions();
309 @NotNull
310 @Override
311 public String getTextFor(ItemWrapper value) {
312 return value.getText();
315 @Override
316 public Icon getIconFor(ItemWrapper value) {
317 return value.getIcon();
321 private static final class ConfigurationActionsStep extends BaseListPopupStep<ActionWrapper> {
322 private ConfigurationActionsStep(@NotNull final Project project,
323 ChooseRunConfigurationAction action,
324 @NotNull final RunnerAndConfigurationSettingsImpl settings) {
325 super("Actions", buildActions(project, action, settings));
328 private static ActionWrapper[] buildActions(@NotNull final Project project,
329 final ChooseRunConfigurationAction action,
330 @NotNull final RunnerAndConfigurationSettingsImpl settings) {
331 final List<ActionWrapper> result = new ArrayList<ActionWrapper>();
332 final Executor[] executors = ExecutorRegistry.getInstance().getRegisteredExecutors();
333 for (final Executor executor : executors) {
334 final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executor.getId(), settings.getConfiguration());
335 if (runner != null) {
336 result.add(new ActionWrapper(executor.getActionName(), executor.getIcon()) {
337 @Override
338 public void perform() {
339 RunManagerEx.getInstanceEx(project).setSelectedConfiguration(settings);
340 ExecutionUtil.executeConfiguration(project, settings, executor, DataManager.getInstance().getDataContext());
346 result.add(new ActionWrapper("Edit...", EDIT_ICON) {
347 @Override
348 public void perform() {
349 final Executor executor = action.getCurrentExecutor();
350 assert executor != null;
352 if (RunDialog.editConfiguration(project, settings, "Edit configuration settings", executor.getActionName(),
353 executor.getIcon())) {
354 RunManagerEx.getInstanceEx(project).setSelectedConfiguration(settings);
355 ExecutionUtil.executeConfiguration(project, settings, executor, DataManager.getInstance().getDataContext());
360 if (RunManager.getInstance(project).isTemporary(settings.getConfiguration())) {
361 result.add(new ActionWrapper("Save temp configuration", SAVE_ICON) {
362 @Override
363 public void perform() {
364 RunManager.getInstance(project).makeStable(settings.getConfiguration());
369 return result.toArray(new ActionWrapper[result.size()]);
372 @Override
373 public PopupStep onChosen(final ActionWrapper selectedValue, boolean finalChoice) {
374 SwingUtilities.invokeLater(new Runnable() {
375 public void run() {
376 selectedValue.perform();
380 return FINAL_CHOICE;
383 @Override
384 public Icon getIconFor(ActionWrapper aValue) {
385 return aValue.getIcon();
388 @NotNull
389 @Override
390 public String getTextFor(ActionWrapper value) {
391 return value.getName();
395 private abstract static class ActionWrapper {
396 private String myName;
397 private Icon myIcon;
399 private ActionWrapper(String name, Icon icon) {
400 myName = name;
401 myIcon = icon;
404 public abstract void perform();
406 public String getName() {
407 return myName;
410 public Icon getIcon() {
411 return myIcon;