| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.intellij.execution.actions; |
| |
| import com.intellij.execution.*; |
| import com.intellij.execution.configurations.ConfigurationType; |
| import com.intellij.execution.configurations.UnknownConfigurationType; |
| import com.intellij.execution.impl.EditConfigurationsDialog; |
| import com.intellij.execution.impl.RunDialog; |
| import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; |
| import com.intellij.execution.runners.ExecutionUtil; |
| import com.intellij.execution.runners.ProgramRunner; |
| import com.intellij.icons.AllIcons; |
| import com.intellij.ide.DataManager; |
| import com.intellij.ide.util.PropertiesComponent; |
| import com.intellij.idea.ActionsBundle; |
| import com.intellij.openapi.actionSystem.CommonDataKeys; |
| import com.intellij.openapi.actionSystem.DataContext; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.keymap.KeymapUtil; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.popup.ListPopupStep; |
| import com.intellij.openapi.ui.popup.ListSeparator; |
| import com.intellij.openapi.ui.popup.PopupStep; |
| import com.intellij.openapi.ui.popup.util.BaseListPopupStep; |
| import com.intellij.ui.popup.WizardPopup; |
| import com.intellij.ui.popup.list.ListPopupImpl; |
| import com.intellij.ui.popup.list.PopupListElementRenderer; |
| import com.intellij.ui.speedSearch.SpeedSearch; |
| import com.intellij.util.ui.UIUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.InputEvent; |
| import java.awt.event.MouseEvent; |
| import java.util.*; |
| import java.util.List; |
| |
| public class ChooseRunConfigurationPopup implements ExecutorProvider { |
| |
| private final Project myProject; |
| @NotNull private final String myAddKey; |
| @NotNull private final Executor myDefaultExecutor; |
| @Nullable private final Executor myAlternativeExecutor; |
| |
| private Executor myCurrentExecutor; |
| private boolean myEditConfiguration; |
| private final RunListPopup myPopup; |
| |
| public ChooseRunConfigurationPopup(@NotNull Project project, |
| @NotNull String addKey, |
| @NotNull Executor defaultExecutor, |
| @Nullable Executor alternativeExecutor) { |
| myProject = project; |
| myAddKey = addKey; |
| myDefaultExecutor = defaultExecutor; |
| myAlternativeExecutor = alternativeExecutor; |
| |
| myPopup = new RunListPopup(new ConfigurationListPopupStep(this, myProject, this, myDefaultExecutor.getActionName())); |
| } |
| |
| public void show() { |
| |
| final String adText = getAdText(myAlternativeExecutor); |
| if (adText != null) { |
| myPopup.setAdText(adText); |
| } |
| |
| myPopup.showCenteredInCurrentWindow(myProject); |
| } |
| |
| protected static boolean canRun(@NotNull final Executor executor, final RunnerAndConfigurationSettings settings) { |
| return ProgramRunnerUtil.getRunner(executor.getId(), settings) != null; |
| } |
| |
| @Nullable |
| protected String getAdText(final Executor alternateExecutor) { |
| final PropertiesComponent properties = PropertiesComponent.getInstance(); |
| if (alternateExecutor != null && !properties.isTrueValue(myAddKey)) { |
| return String |
| .format("Hold %s to %s", KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke("SHIFT")), alternateExecutor.getActionName()); |
| } |
| |
| if (!properties.isTrueValue("run.configuration.edit.ad")) { |
| return String.format("Press %s to Edit", KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke("F4"))); |
| } |
| |
| if (!properties.isTrueValue("run.configuration.delete.ad")) { |
| return String.format("Press %s to Delete configuration", KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke("DELETE"))); |
| } |
| |
| return null; |
| } |
| |
| private void registerActions(final RunListPopup popup) { |
| popup.registerAction("alternateExecutor", KeyStroke.getKeyStroke("shift pressed SHIFT"), new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| myCurrentExecutor = myAlternativeExecutor; |
| updatePresentation(); |
| } |
| }); |
| |
| popup.registerAction("restoreDefaultExecutor", KeyStroke.getKeyStroke("released SHIFT"), new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| myCurrentExecutor = myDefaultExecutor; |
| updatePresentation(); |
| } |
| }); |
| |
| |
| popup.registerAction("invokeAction", KeyStroke.getKeyStroke("shift ENTER"), new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| popup.handleSelect(true); |
| } |
| }); |
| |
| popup.registerAction("editConfiguration", KeyStroke.getKeyStroke("F4"), new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| myEditConfiguration = true; |
| popup.handleSelect(true); |
| } |
| }); |
| |
| |
| popup.registerAction("deleteConfiguration", KeyStroke.getKeyStroke("DELETE"), new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| popup.removeSelected(); |
| } |
| }); |
| |
| popup.registerAction("deleteConfiguration_bksp", KeyStroke.getKeyStroke("BACK_SPACE"), new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| SpeedSearch speedSearch = popup.getSpeedSearch(); |
| if (speedSearch.isHoldingFilter()) { |
| speedSearch.backspace(); |
| speedSearch.update(); |
| } |
| else { |
| popup.removeSelected(); |
| } |
| } |
| }); |
| |
| final Action action0 = createNumberAction(0, popup, myDefaultExecutor); |
| final Action action0_ = createNumberAction(0, popup, myAlternativeExecutor); |
| popup.registerAction("0Action", KeyStroke.getKeyStroke("0"), action0); |
| popup.registerAction("0Action_", KeyStroke.getKeyStroke("shift pressed 0"), action0_); |
| popup.registerAction("0Action1", KeyStroke.getKeyStroke("NUMPAD0"), action0); |
| popup.registerAction("0Action_1", KeyStroke.getKeyStroke("shift pressed NUMPAD0"), action0_); |
| |
| final Action action1 = createNumberAction(1, popup, myDefaultExecutor); |
| final Action action1_ = createNumberAction(1, popup, myAlternativeExecutor); |
| popup.registerAction("1Action", KeyStroke.getKeyStroke("1"), action1); |
| popup.registerAction("1Action_", KeyStroke.getKeyStroke("shift pressed 1"), action1_); |
| popup.registerAction("1Action1", KeyStroke.getKeyStroke("NUMPAD1"), action1); |
| popup.registerAction("1Action_1", KeyStroke.getKeyStroke("shift pressed NUMPAD1"), action1_); |
| |
| final Action action2 = createNumberAction(2, popup, myDefaultExecutor); |
| final Action action2_ = createNumberAction(2, popup, myAlternativeExecutor); |
| popup.registerAction("2Action", KeyStroke.getKeyStroke("2"), action2); |
| popup.registerAction("2Action_", KeyStroke.getKeyStroke("shift pressed 2"), action2_); |
| popup.registerAction("2Action1", KeyStroke.getKeyStroke("NUMPAD2"), action2); |
| popup.registerAction("2Action_1", KeyStroke.getKeyStroke("shift pressed NUMPAD2"), action2_); |
| |
| final Action action3 = createNumberAction(3, popup, myDefaultExecutor); |
| final Action action3_ = createNumberAction(3, popup, myAlternativeExecutor); |
| popup.registerAction("3Action", KeyStroke.getKeyStroke("3"), action3); |
| popup.registerAction("3Action_", KeyStroke.getKeyStroke("shift pressed 3"), action3_); |
| popup.registerAction("3Action1", KeyStroke.getKeyStroke("NUMPAD3"), action3); |
| popup.registerAction("3Action_1", KeyStroke.getKeyStroke("shift pressed NUMPAD3"), action3_); |
| } |
| |
| private void updatePresentation() { |
| myPopup.setCaption(getExecutor().getActionName()); |
| } |
| |
| static void execute(final ItemWrapper itemWrapper, final Executor executor) { |
| if (executor == null) { |
| return; |
| } |
| |
| final DataContext dataContext = DataManager.getInstance().getDataContext(); |
| final Project project = CommonDataKeys.PROJECT.getData(dataContext); |
| if (project != null) { |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| itemWrapper.perform(project, executor, dataContext); |
| } |
| }); |
| } |
| } |
| |
| void editConfiguration(@NotNull final Project project, @NotNull final RunnerAndConfigurationSettings configuration) { |
| final Executor executor = getExecutor(); |
| PropertiesComponent.getInstance().setValue("run.configuration.edit.ad", Boolean.toString(true)); |
| if (RunDialog.editConfiguration(project, configuration, "Edit configuration settings", executor)) { |
| RunManagerEx.getInstanceEx(project).setSelectedConfiguration(configuration); |
| ExecutionUtil.runConfiguration(configuration, executor); |
| } |
| } |
| |
| private static void deleteConfiguration(final Project project, @NotNull final RunnerAndConfigurationSettings configurationSettings) { |
| final RunManagerEx manager = RunManagerEx.getInstanceEx(project); |
| manager.removeConfiguration(configurationSettings); |
| } |
| |
| @Override |
| @NotNull |
| public Executor getExecutor() { |
| return myCurrentExecutor == null ? myDefaultExecutor : myCurrentExecutor; |
| } |
| |
| private static Action createNumberAction(final int number, final ListPopupImpl listPopup, final Executor executor) { |
| return new AbstractAction() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| if (listPopup.getSpeedSearch().isHoldingFilter()) |
| return; |
| for (final Object item : listPopup.getListStep().getValues()) { |
| if (item instanceof ItemWrapper && ((ItemWrapper)item).getMnemonic() == number) { |
| listPopup.setFinalRunnable(new Runnable() { |
| @Override |
| public void run() { |
| execute((ItemWrapper)item, executor); |
| } |
| }); |
| listPopup.closeOk(null); |
| } |
| } |
| } |
| }; |
| } |
| |
| private abstract static class Wrapper { |
| private int myMnemonic = -1; |
| private final boolean myAddSeparatorAbove; |
| private boolean myChecked; |
| |
| protected Wrapper(boolean addSeparatorAbove) { |
| myAddSeparatorAbove = addSeparatorAbove; |
| } |
| |
| public int getMnemonic() { |
| return myMnemonic; |
| } |
| |
| public boolean isChecked() { |
| return myChecked; |
| } |
| |
| public void setChecked(boolean checked) { |
| myChecked = checked; |
| } |
| |
| public void setMnemonic(int mnemonic) { |
| myMnemonic = mnemonic; |
| } |
| |
| public boolean addSeparatorAbove() { |
| return myAddSeparatorAbove; |
| } |
| |
| @Nullable |
| public abstract Icon getIcon(); |
| |
| public abstract String getText(); |
| |
| public boolean canBeDeleted() { |
| return false; |
| } |
| |
| @Override |
| public String toString() { |
| return "Wrapper[" + getText() + "]"; |
| } |
| } |
| |
| public abstract static class ItemWrapper<T> extends Wrapper { |
| private final T myValue; |
| private boolean myDynamic; |
| |
| |
| protected ItemWrapper(@Nullable final T value) { |
| this(value, false); |
| } |
| |
| protected ItemWrapper(@Nullable final T value, boolean addSeparatorAbove) { |
| super(addSeparatorAbove); |
| myValue = value; |
| } |
| |
| public T getValue() { |
| return myValue; |
| } |
| |
| public boolean isDynamic() { |
| return myDynamic; |
| } |
| |
| public void setDynamic(final boolean b) { |
| myDynamic = b; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) return true; |
| if (!(o instanceof ItemWrapper)) return false; |
| |
| ItemWrapper that = (ItemWrapper)o; |
| |
| if (myValue != null ? !myValue.equals(that.myValue) : that.myValue != null) return false; |
| |
| return true; |
| } |
| |
| @Override |
| public int hashCode() { |
| return myValue != null ? myValue.hashCode() : 0; |
| } |
| |
| public abstract void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull final DataContext context); |
| |
| @Nullable |
| public ConfigurationType getType() { |
| return null; |
| } |
| |
| public boolean available(Executor executor) { |
| return false; |
| } |
| |
| public boolean hasActions() { |
| return false; |
| } |
| |
| public PopupStep getNextStep(Project project, ChooseRunConfigurationPopup action) { |
| return PopupStep.FINAL_CHOICE; |
| } |
| |
| public static ItemWrapper wrap(@NotNull final Project project, |
| @NotNull final RunnerAndConfigurationSettings settings, |
| final boolean dynamic) { |
| final ItemWrapper result = wrap(project, settings); |
| result.setDynamic(dynamic); |
| return result; |
| } |
| |
| public static ItemWrapper wrap(@NotNull final Project project, @NotNull final RunnerAndConfigurationSettings settings) { |
| return new ItemWrapper<RunnerAndConfigurationSettings>(settings) { |
| @Override |
| public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) { |
| RunnerAndConfigurationSettings config = getValue(); |
| RunManagerEx.getInstanceEx(project).setSelectedConfiguration(config); |
| ExecutionUtil.runConfiguration(config, executor); |
| } |
| |
| @Override |
| public ConfigurationType getType() { |
| return getValue().getType(); |
| } |
| |
| @Override |
| public Icon getIcon() { |
| return RunManagerEx.getInstanceEx(project).getConfigurationIcon(getValue()); |
| } |
| |
| @Override |
| public String getText() { |
| return getValue().getName(); |
| } |
| |
| @Override |
| public boolean hasActions() { |
| return true; |
| } |
| |
| @Override |
| public boolean available(Executor executor) { |
| return ProgramRunnerUtil.getRunner(executor.getId(), getValue()) != null; |
| } |
| |
| @Override |
| public PopupStep getNextStep(@NotNull final Project project, @NotNull final ChooseRunConfigurationPopup action) { |
| return new ConfigurationActionsStep(project, action, getValue(), isDynamic()); |
| } |
| }; |
| } |
| |
| @Override |
| public boolean canBeDeleted() { |
| return !isDynamic() && getValue() instanceof RunnerAndConfigurationSettings; |
| } |
| } |
| |
| private static final class ConfigurationListPopupStep extends BaseListPopupStep<ItemWrapper> { |
| private final Project myProject; |
| private final ChooseRunConfigurationPopup myAction; |
| private int myDefaultConfiguration = -1; |
| |
| private ConfigurationListPopupStep(@NotNull final ChooseRunConfigurationPopup action, |
| @NotNull final Project project, |
| @NotNull final ExecutorProvider executorProvider, |
| @NotNull final String title) { |
| super(title, createSettingsList(project, executorProvider, true)); |
| myProject = project; |
| myAction = action; |
| |
| if (-1 == getDefaultOptionIndex()) { |
| myDefaultConfiguration = getDynamicIndex(); |
| } |
| } |
| |
| private int getDynamicIndex() { |
| int i = 0; |
| for (final ItemWrapper wrapper : getValues()) { |
| if (wrapper.isDynamic()) { |
| return i; |
| } |
| i++; |
| } |
| |
| return -1; |
| } |
| |
| @Override |
| public boolean isAutoSelectionEnabled() { |
| return false; |
| } |
| |
| @Override |
| public ListSeparator getSeparatorAbove(ItemWrapper value) { |
| if (value.addSeparatorAbove()) return new ListSeparator(); |
| |
| final List<ItemWrapper> configurations = getValues(); |
| final int index = configurations.indexOf(value); |
| if (index > 0 && index <= configurations.size() - 1) { |
| final ItemWrapper aboveConfiguration = configurations.get(index - 1); |
| |
| if (aboveConfiguration != null && aboveConfiguration.isDynamic() != value.isDynamic()) { |
| return new ListSeparator(); |
| } |
| |
| final ConfigurationType currentType = value.getType(); |
| final ConfigurationType aboveType = aboveConfiguration == null ? null : aboveConfiguration.getType(); |
| if (aboveType != currentType && currentType != null) { |
| return new ListSeparator(); // new ListSeparator(currentType.getDisplayName()); |
| } |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public boolean isSpeedSearchEnabled() { |
| return true; |
| } |
| |
| @Override |
| public int getDefaultOptionIndex() { |
| final RunnerAndConfigurationSettings currentConfiguration = RunManager.getInstance(myProject).getSelectedConfiguration(); |
| if (currentConfiguration == null && myDefaultConfiguration != -1) { |
| return myDefaultConfiguration; |
| } |
| |
| return currentConfiguration instanceof RunnerAndConfigurationSettingsImpl ? getValues() |
| .indexOf(ItemWrapper.wrap(myProject, currentConfiguration)) : -1; |
| } |
| |
| @Override |
| public PopupStep onChosen(final ItemWrapper wrapper, boolean finalChoice) { |
| if (myAction.myEditConfiguration) { |
| final Object o = wrapper.getValue(); |
| if (o instanceof RunnerAndConfigurationSettingsImpl) { |
| return doFinalStep(new Runnable() { |
| @Override |
| public void run() { |
| myAction.editConfiguration(myProject, (RunnerAndConfigurationSettings)o); |
| } |
| }); |
| } |
| } |
| |
| if (finalChoice && wrapper.available(myAction.getExecutor())) { |
| return doFinalStep(new Runnable() { |
| @Override |
| public void run() { |
| if (myAction.getExecutor() == myAction.myAlternativeExecutor) { |
| PropertiesComponent.getInstance().setValue(myAction.myAddKey, Boolean.toString(true)); |
| } |
| |
| wrapper.perform(myProject, myAction.getExecutor(), DataManager.getInstance().getDataContext()); |
| } |
| }); |
| } |
| else { |
| return wrapper.getNextStep(myProject, myAction); |
| } |
| } |
| |
| @Override |
| public boolean hasSubstep(ItemWrapper selectedValue) { |
| return selectedValue.hasActions(); |
| } |
| |
| @NotNull |
| @Override |
| public String getTextFor(ItemWrapper value) { |
| return value.getText(); |
| } |
| |
| @Override |
| public Icon getIconFor(ItemWrapper value) { |
| return value.getIcon(); |
| } |
| } |
| |
| private static final class ConfigurationActionsStep extends BaseListPopupStep<ActionWrapper> { |
| |
| @NotNull private final RunnerAndConfigurationSettings mySettings; |
| @NotNull private final Project myProject; |
| |
| private ConfigurationActionsStep(@NotNull final Project project, |
| ChooseRunConfigurationPopup action, |
| @NotNull final RunnerAndConfigurationSettings settings, final boolean dynamic) { |
| super(null, buildActions(project, action, settings, dynamic)); |
| myProject = project; |
| mySettings = settings; |
| } |
| |
| @NotNull |
| public RunnerAndConfigurationSettings getSettings() { |
| return mySettings; |
| } |
| |
| public String getName() { |
| return mySettings.getName(); |
| } |
| |
| public Icon getIcon() { |
| return RunManagerEx.getInstanceEx(myProject).getConfigurationIcon(mySettings); |
| } |
| |
| @Override |
| public ListSeparator getSeparatorAbove(ActionWrapper value) { |
| return value.addSeparatorAbove() ? new ListSeparator() : null; |
| } |
| |
| private static ActionWrapper[] buildActions(@NotNull final Project project, |
| final ChooseRunConfigurationPopup action, |
| @NotNull final RunnerAndConfigurationSettings settings, |
| final boolean dynamic) { |
| final List<ActionWrapper> result = new ArrayList<ActionWrapper>(); |
| |
| final ExecutionTarget active = ExecutionTargetManager.getActiveTarget(project); |
| for (final ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, settings)) { |
| result.add(new ActionWrapper(eachTarget.getDisplayName(), eachTarget.getIcon()) { |
| { |
| setChecked(eachTarget.equals(active)); |
| } |
| |
| @Override |
| public void perform() { |
| final RunManagerEx manager = RunManagerEx.getInstanceEx(project); |
| if (dynamic) { |
| manager.setTemporaryConfiguration(settings); |
| } |
| manager.setSelectedConfiguration(settings); |
| |
| ExecutionTargetManager.setActiveTarget(project, eachTarget); |
| ExecutionUtil.runConfiguration(settings, action.getExecutor()); |
| } |
| }); |
| } |
| |
| boolean isFirst = true; |
| for (final Executor executor : ExecutorRegistry.getInstance().getRegisteredExecutors()) { |
| final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executor.getId(), settings.getConfiguration()); |
| if (runner != null) { |
| result.add(new ActionWrapper(executor.getActionName(), executor.getIcon(), isFirst) { |
| @Override |
| public void perform() { |
| final RunManagerEx manager = RunManagerEx.getInstanceEx(project); |
| if (dynamic) { |
| manager.setTemporaryConfiguration(settings); |
| } |
| manager.setSelectedConfiguration(settings); |
| ExecutionUtil.runConfiguration(settings, executor); |
| } |
| }); |
| isFirst = false; |
| } |
| } |
| |
| result.add(new ActionWrapper("Edit...", AllIcons.Actions.EditSource, true) { |
| @Override |
| public void perform() { |
| final RunManagerEx manager = RunManagerEx.getInstanceEx(project); |
| if (dynamic) manager.setTemporaryConfiguration(settings); |
| action.editConfiguration(project, settings); |
| } |
| }); |
| |
| if (settings.isTemporary() || dynamic) { |
| result.add(new ActionWrapper("Save configuration", AllIcons.Actions.Menu_saveall) { |
| @Override |
| public void perform() { |
| final RunManagerEx manager = RunManagerEx.getInstanceEx(project); |
| if (dynamic) manager.setTemporaryConfiguration(settings); |
| manager.makeStable(settings); |
| } |
| }); |
| } |
| |
| return result.toArray(new ActionWrapper[result.size()]); |
| } |
| |
| @Override |
| public PopupStep onChosen(final ActionWrapper selectedValue, boolean finalChoice) { |
| return doFinalStep(new Runnable() { |
| @Override |
| public void run() { |
| selectedValue.perform(); |
| } |
| }); |
| } |
| |
| @Override |
| public Icon getIconFor(ActionWrapper aValue) { |
| return aValue.getIcon(); |
| } |
| |
| @NotNull |
| @Override |
| public String getTextFor(ActionWrapper value) { |
| return value.getText(); |
| } |
| } |
| |
| private abstract static class ActionWrapper extends Wrapper { |
| private final String myName; |
| private final Icon myIcon; |
| |
| private ActionWrapper(String name, Icon icon) { |
| this(name, icon, false); |
| } |
| |
| private ActionWrapper(String name, Icon icon, boolean addSeparatorAbove) { |
| super(addSeparatorAbove); |
| myName = name; |
| myIcon = icon; |
| } |
| |
| public abstract void perform(); |
| |
| @Override |
| public String getText() { |
| return myName; |
| } |
| |
| @Override |
| public Icon getIcon() { |
| return myIcon; |
| } |
| } |
| |
| private static class RunListElementRenderer extends PopupListElementRenderer { |
| private JLabel myLabel; |
| private final ListPopupImpl myPopup1; |
| private final boolean myHasSideBar; |
| |
| private RunListElementRenderer(ListPopupImpl popup, boolean hasSideBar) { |
| super(popup); |
| |
| myPopup1 = popup; |
| myHasSideBar = hasSideBar; |
| } |
| |
| @Override |
| protected JComponent createItemComponent() { |
| if (myLabel == null) { |
| myLabel = new JLabel(); |
| myLabel.setPreferredSize(new JLabel("8.").getPreferredSize()); |
| } |
| |
| final JComponent result = super.createItemComponent(); |
| result.add(myLabel, BorderLayout.WEST); |
| return result; |
| } |
| |
| @Override |
| protected void customizeComponent(JList list, Object value, boolean isSelected) { |
| super.customizeComponent(list, value, isSelected); |
| |
| myLabel.setVisible(myHasSideBar); |
| |
| ListPopupStep<Object> step = myPopup1.getListStep(); |
| boolean isSelectable = step.isSelectable(value); |
| myLabel.setEnabled(isSelectable); |
| myLabel.setIcon(null); |
| |
| if (isSelected) { |
| setSelected(myLabel); |
| } |
| else { |
| setDeselected(myLabel); |
| } |
| |
| if (value instanceof Wrapper) { |
| Wrapper wrapper = (Wrapper)value; |
| final int mnemonic = wrapper.getMnemonic(); |
| if (mnemonic != -1 && !myPopup1.getSpeedSearch().isHoldingFilter()) { |
| myLabel.setText(mnemonic + "."); |
| myLabel.setDisplayedMnemonicIndex(0); |
| } |
| else { |
| if (wrapper.isChecked()) { |
| myTextLabel.setIcon(isSelected ? RunConfigurationsComboBoxAction.CHECKED_SELECTED_ICON |
| : RunConfigurationsComboBoxAction.CHECKED_ICON); |
| } |
| else { |
| if (myTextLabel.getIcon() == null) { |
| myTextLabel.setIcon(RunConfigurationsComboBoxAction.EMPTY_ICON); |
| } |
| } |
| myLabel.setText(""); |
| } |
| } |
| } |
| } |
| |
| private class RunListPopup extends ListPopupImpl { |
| public RunListPopup(ListPopupStep step) { |
| super(step); |
| registerActions(this); |
| } |
| |
| protected RunListPopup(WizardPopup aParent, ListPopupStep aStep, Object parentValue) { |
| super(aParent, aStep, parentValue); |
| registerActions(this); |
| } |
| |
| @Override |
| protected WizardPopup createPopup(WizardPopup parent, PopupStep step, Object parentValue) { |
| return new RunListPopup(parent, (ListPopupStep)step, parentValue); |
| } |
| |
| @Override |
| public void handleSelect(boolean handleFinalChoices, InputEvent e) { |
| if (e instanceof MouseEvent && e.isShiftDown()) { |
| handleShiftClick(handleFinalChoices, e, this); |
| return; |
| } |
| |
| _handleSelect(handleFinalChoices, e); |
| } |
| |
| private void _handleSelect(boolean handleFinalChoices, InputEvent e) { |
| super.handleSelect(handleFinalChoices, e); |
| } |
| |
| protected void handleShiftClick(boolean handleFinalChoices, final InputEvent inputEvent, final RunListPopup popup) { |
| myCurrentExecutor = myAlternativeExecutor; |
| popup._handleSelect(handleFinalChoices, inputEvent); |
| } |
| |
| @Override |
| protected ListCellRenderer getListElementRenderer() { |
| boolean hasSideBar = false; |
| for (Object each : getListStep().getValues()) { |
| if (each instanceof Wrapper) { |
| if (((Wrapper)each).getMnemonic() != -1) { |
| hasSideBar = true; |
| break; |
| } |
| } |
| } |
| return new RunListElementRenderer(this, hasSideBar); |
| } |
| |
| public void removeSelected() { |
| final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); |
| if (!propertiesComponent.isTrueValue("run.configuration.delete.ad")) { |
| propertiesComponent.setValue("run.configuration.delete.ad", Boolean.toString(true)); |
| } |
| |
| final int index = getSelectedIndex(); |
| if (index == -1) { |
| return; |
| } |
| |
| final Object o = getListModel().get(index); |
| if (o != null && o instanceof ItemWrapper && ((ItemWrapper)o).canBeDeleted()) { |
| deleteConfiguration(myProject, (RunnerAndConfigurationSettings)((ItemWrapper)o).getValue()); |
| getListModel().deleteItem(o); |
| final List<Object> values = getListStep().getValues(); |
| values.remove(o); |
| |
| if (index < values.size()) { |
| onChildSelectedFor(values.get(index)); |
| } |
| else if (index - 1 >= 0) { |
| onChildSelectedFor(values.get(index - 1)); |
| } |
| } |
| } |
| } |
| |
| private static class FolderWrapper extends ItemWrapper<String> { |
| private final Project myProject; |
| private final ExecutorProvider myExecutorProvider; |
| private final List<RunnerAndConfigurationSettings> myConfigurations; |
| |
| private FolderWrapper(Project project, ExecutorProvider executorProvider, @Nullable String value, List<RunnerAndConfigurationSettings> configurations) { |
| super(value); |
| myProject = project; |
| myExecutorProvider = executorProvider; |
| myConfigurations = configurations; |
| } |
| |
| @Override |
| public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) { |
| RunnerAndConfigurationSettings selectedConfiguration = RunManagerEx.getInstanceEx(project).getSelectedConfiguration(); |
| if (myConfigurations.contains(selectedConfiguration)) { |
| RunManagerEx.getInstanceEx(project).setSelectedConfiguration(selectedConfiguration); |
| ExecutionUtil.runConfiguration(selectedConfiguration, myExecutorProvider.getExecutor()); |
| } |
| } |
| |
| @Nullable |
| @Override |
| public Icon getIcon() { |
| return AllIcons.Nodes.Folder; |
| } |
| |
| @Override |
| public String getText() { |
| return getValue(); |
| } |
| |
| @Override |
| public boolean hasActions() { |
| return true; |
| } |
| |
| @Override |
| public PopupStep getNextStep(Project project, ChooseRunConfigurationPopup action) { |
| List<ConfigurationActionsStep> steps = new ArrayList<ConfigurationActionsStep>(); |
| for (RunnerAndConfigurationSettings settings : myConfigurations) { |
| steps.add(new ConfigurationActionsStep(project, action, settings, false)); |
| } |
| return new FolderStep(myProject, myExecutorProvider, null, steps); |
| } |
| } |
| |
| private static final class FolderStep extends BaseListPopupStep<ConfigurationActionsStep> { |
| private final Project myProject; |
| private final ExecutorProvider myExecutorProvider; |
| |
| private FolderStep(Project project, ExecutorProvider executorProvider, String folderName, List<ConfigurationActionsStep> children |
| ) { |
| super(folderName, children, new ArrayList<Icon>()); |
| myProject = project; |
| myExecutorProvider = executorProvider; |
| } |
| |
| @Override |
| public PopupStep onChosen(final ConfigurationActionsStep selectedValue, boolean finalChoice) { |
| if (finalChoice) { |
| return doFinalStep(new Runnable() { |
| @Override |
| public void run() { |
| RunnerAndConfigurationSettings settings = selectedValue.getSettings(); |
| RunManagerEx.getInstanceEx(myProject).setSelectedConfiguration(settings); |
| ExecutionUtil.runConfiguration(settings, myExecutorProvider.getExecutor()); |
| } |
| }); |
| } else { |
| return selectedValue; |
| } |
| } |
| |
| @Override |
| public Icon getIconFor(ConfigurationActionsStep aValue) { |
| return aValue.getIcon(); |
| } |
| |
| @NotNull |
| @Override |
| public String getTextFor(ConfigurationActionsStep value) { |
| return value.getName(); |
| } |
| |
| @Override |
| public boolean hasSubstep(ConfigurationActionsStep selectedValue) { |
| return !selectedValue.getValues().isEmpty(); |
| } |
| } |
| |
| public static ItemWrapper[] createSettingsList(@NotNull Project project, @NotNull ExecutorProvider executorProvider, boolean createEditAction) { |
| List<ItemWrapper> result = new ArrayList<ItemWrapper>(); |
| |
| if (createEditAction) { |
| ItemWrapper<Void> edit = new ItemWrapper<Void>(null) { |
| @Override |
| public Icon getIcon() { |
| return AllIcons.Actions.EditSource; |
| } |
| |
| @Override |
| public String getText() { |
| return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text")); |
| } |
| |
| @Override |
| public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) { |
| if (new EditConfigurationsDialog(project) { |
| @Override |
| protected void init() { |
| setOKButtonText(executor.getStartActionText()); |
| setOKButtonIcon(executor.getIcon()); |
| myExecutor = executor; |
| super.init(); |
| } |
| }.showAndGet()) { |
| ApplicationManager.getApplication().invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration(); |
| if (configuration != null) { |
| ExecutionUtil.runConfiguration(configuration, executor); |
| } |
| } |
| }, project.getDisposed()); |
| } |
| } |
| |
| @Override |
| public boolean available(Executor executor) { |
| return true; |
| } |
| }; |
| edit.setMnemonic(0); |
| result.add(edit); |
| } |
| |
| RunManagerEx manager = RunManagerEx.getInstanceEx(project); |
| final RunnerAndConfigurationSettings selectedConfiguration = manager.getSelectedConfiguration(); |
| if (selectedConfiguration != null) { |
| boolean isFirst = true; |
| final ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project); |
| for (ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration)) { |
| result.add(new ItemWrapper<ExecutionTarget>(eachTarget, isFirst) { |
| { |
| setChecked(getValue().equals(activeTarget)); |
| } |
| |
| @Override |
| public Icon getIcon() { |
| return getValue().getIcon(); |
| } |
| |
| @Override |
| public String getText() { |
| return getValue().getDisplayName(); |
| } |
| |
| @Override |
| public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) { |
| ExecutionTargetManager.setActiveTarget(project, getValue()); |
| ExecutionUtil.runConfiguration(selectedConfiguration, executor); |
| } |
| |
| @Override |
| public boolean available(Executor executor) { |
| return true; |
| } |
| }); |
| isFirst = false; |
| } |
| } |
| |
| Map<RunnerAndConfigurationSettings, ItemWrapper> wrappedExisting = new LinkedHashMap<RunnerAndConfigurationSettings, ItemWrapper>(); |
| for (ConfigurationType type : manager.getConfigurationFactories()) { |
| if (!(type instanceof UnknownConfigurationType)) { |
| Map<String, List<RunnerAndConfigurationSettings>> structure = manager.getStructure(type); |
| for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : structure.entrySet()) { |
| if (entry.getValue().isEmpty()) { |
| continue; |
| } |
| |
| final String key = entry.getKey(); |
| if (key != null) { |
| boolean isSelected = entry.getValue().contains(selectedConfiguration); |
| if (isSelected) { |
| assert selectedConfiguration != null; |
| } |
| FolderWrapper folderWrapper = new FolderWrapper(project, executorProvider, |
| key + (isSelected ? " (mnemonic is to \"" + selectedConfiguration.getName() + "\")" : ""), |
| entry.getValue()); |
| if (isSelected) { |
| folderWrapper.setMnemonic(1); |
| } |
| result.add(folderWrapper); |
| } |
| else { |
| for (RunnerAndConfigurationSettings configuration : entry.getValue()) { |
| final ItemWrapper wrapped = ItemWrapper.wrap(project, configuration); |
| if (configuration == selectedConfiguration) { |
| wrapped.setMnemonic(1); |
| } |
| wrappedExisting.put(configuration, wrapped); |
| } |
| } |
| } |
| } |
| } |
| |
| populateWithDynamicRunners(result, wrappedExisting, project, manager, selectedConfiguration); |
| result.addAll(wrappedExisting.values()); |
| return result.toArray(new ItemWrapper[result.size()]); |
| } |
| |
| @NotNull |
| private static List<RunnerAndConfigurationSettings> populateWithDynamicRunners(final List<ItemWrapper> result, |
| Map<RunnerAndConfigurationSettings, ItemWrapper> existing, |
| final Project project, final RunManagerEx manager, |
| final RunnerAndConfigurationSettings selectedConfiguration) { |
| |
| final ArrayList<RunnerAndConfigurationSettings> contextConfigurations = new ArrayList<RunnerAndConfigurationSettings>(); |
| if (!EventQueue.isDispatchThread()) { |
| return Collections.emptyList(); |
| } |
| |
| final DataContext dataContext = DataManager.getInstance().getDataContext(); |
| final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); |
| |
| final List<ConfigurationFromContext> producers = PreferredProducerFind.getConfigurationsFromContext(context.getLocation(), |
| context, false); |
| if (producers == null) return Collections.emptyList(); |
| |
| Collections.sort(producers, ConfigurationFromContext.NAME_COMPARATOR); |
| |
| final RunnerAndConfigurationSettings[] preferred = {null}; |
| |
| int i = 2; // selectedConfiguration == null ? 1 : 2; |
| for (final ConfigurationFromContext fromContext : producers) { |
| final RunnerAndConfigurationSettings configuration = fromContext.getConfigurationSettings(); |
| if (existing.keySet().contains(configuration)) { |
| final ItemWrapper wrapper = existing.get(configuration); |
| if (wrapper.getMnemonic() != 1) { |
| wrapper.setMnemonic(i); |
| i++; |
| } |
| } |
| else { |
| if (selectedConfiguration != null && configuration.equals(selectedConfiguration)) continue; |
| contextConfigurations.add(configuration); |
| |
| if (preferred[0] == null) { |
| preferred[0] = configuration; |
| } |
| |
| //noinspection unchecked |
| final ItemWrapper wrapper = new ItemWrapper(configuration) { |
| @Override |
| public Icon getIcon() { |
| return RunManagerEx.getInstanceEx(project).getConfigurationIcon(configuration); |
| } |
| |
| @Override |
| public String getText() { |
| return configuration.getName(); |
| } |
| |
| @Override |
| public boolean available(Executor executor) { |
| return canRun(executor, configuration); |
| } |
| |
| @Override |
| public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) { |
| manager.setTemporaryConfiguration(configuration); |
| RunManagerEx.getInstanceEx(project).setSelectedConfiguration(configuration); |
| ExecutionUtil.runConfiguration(configuration, executor); |
| } |
| |
| @Override |
| public PopupStep getNextStep(@NotNull final Project project, @NotNull final ChooseRunConfigurationPopup action) { |
| return new ConfigurationActionsStep(project, action, configuration, isDynamic()); |
| } |
| |
| @Override |
| public boolean hasActions() { |
| return true; |
| } |
| }; |
| |
| wrapper.setDynamic(true); |
| wrapper.setMnemonic(i); |
| result.add(wrapper); |
| i++; |
| } |
| } |
| |
| return contextConfigurations; |
| } |
| } |