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
;
23 import java
.awt
.event
.ActionEvent
;
24 import java
.util
.ArrayList
;
25 import java
.util
.List
;
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
;
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());
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);
66 actionMap
.put("alternateExecutor", new AbstractAction() {
67 public void actionPerformed(ActionEvent e
) {
68 myCurrentExecutor
= getAlternateExecutor();
69 updatePresentation(listPopup
);
73 actionMap
.put("restoreDefaultExecutor", new AbstractAction() {
74 public void actionPerformed(ActionEvent e
) {
75 myCurrentExecutor
= getDefaultExecutor();
76 updatePresentation(listPopup
);
81 private void updatePresentation(ListPopupImpl listPopup
) {
82 final Executor executor
= getCurrentExecutor();
83 if (executor
!= null) {
84 listPopup
.setCaption(executor
.getActionName());
89 protected Executor
getDefaultExecutor() {
90 return DefaultRunExecutor
.getRunExecutorInstance();
94 protected Executor
getAlternateExecutor() {
95 return ExecutorRegistry
.getInstance().getExecutorById(ToolWindowId
.DEBUG
);
99 protected Executor
getCurrentExecutor() {
100 return myCurrentExecutor
== null ?
getDefaultExecutor() : myCurrentExecutor
;
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);
115 if (null == getDefaultExecutor()) {
116 presentation
.setEnabled(false);
117 presentation
.setVisible(false);
121 presentation
.setEnabled(true);
122 presentation
.setVisible(true);
125 private abstract static class ItemWrapper
<T
> {
128 protected ItemWrapper(@Nullable final T value
) {
132 public T
getValue() {
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
);
143 public ConfigurationType
getType() {
147 public boolean available(Executor executor
) {
151 public boolean hasActions() {
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
) {
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());
168 public ConfigurationType
getType() {
169 return getValue().getType();
173 public Icon
getIcon() {
174 return ExecutionUtil
.getConfigurationIcon(project
, getValue());
178 public String
getText() {
179 return getValue().getName();
183 public boolean hasActions() {
188 public boolean available(Executor executor
) {
189 return null != ExecutionUtil
.getRunner(executor
.getId(), getValue());
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
));
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) {
221 public Icon
getIcon() {
226 public String
getText() {
227 return "Edit configurations...";
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()]);
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());
265 public boolean isSpeedSearchEnabled() {
270 public int getDefaultOptionIndex() {
271 final RunnerAndConfigurationSettings currentConfiguration
= RunManager
.getInstance(myProject
).getSelectedConfiguration();
273 final List
<ItemWrapper
> list
= getValues();
275 for (final ItemWrapper wrapper
: list
) {
276 if (wrapper
.getValue() == currentConfiguration
) {
282 return super.getDefaultOptionIndex();
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() {
293 wrapper
.perform(myProject
, executor
, DataManager
.getInstance().getDataContext());
300 return wrapper
.getNextStep(myProject
, myAction
);
305 public boolean hasSubstep(ItemWrapper selectedValue
) {
306 return selectedValue
.hasActions();
311 public String
getTextFor(ItemWrapper value
) {
312 return value
.getText();
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()) {
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
) {
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
) {
363 public void perform() {
364 RunManager
.getInstance(project
).makeStable(settings
.getConfiguration());
369 return result
.toArray(new ActionWrapper
[result
.size()]);
373 public PopupStep
onChosen(final ActionWrapper selectedValue
, boolean finalChoice
) {
374 SwingUtilities
.invokeLater(new Runnable() {
376 selectedValue
.perform();
384 public Icon
getIconFor(ActionWrapper aValue
) {
385 return aValue
.getIcon();
390 public String
getTextFor(ActionWrapper value
) {
391 return value
.getName();
395 private abstract static class ActionWrapper
{
396 private String myName
;
399 private ActionWrapper(String name
, Icon icon
) {
404 public abstract void perform();
406 public String
getName() {
410 public Icon
getIcon() {