From 663e4bcb12adb17214a9fbe1f8938925c8aad501 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 6 Jul 2015 10:52:08 +0300 Subject: [PATCH] IDEA-134049 do not close action popup menu on click on toggle action * allow to toggle actions with space (cherry picked from commit 7f2fc156b51283d70d0bb5bfd237c639f7548554) --- .../intellij/ui/popup/PopupFactoryImpl.java | 77 +++++++++++++++++-- .../filter/StructureFilterPopupComponent.java | 2 + 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index 6ad38f60e760..ea0796235585 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -50,7 +50,10 @@ import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.popup.list.ListPopupImpl; import com.intellij.ui.popup.mock.MockConfirmation; import com.intellij.ui.popup.tree.TreePopupImpl; +import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; import com.intellij.util.PlatformIcons; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.WeakHashMap; import com.intellij.util.ui.EmptyIcon; @@ -65,6 +68,9 @@ import javax.swing.event.HyperlinkListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -218,6 +224,13 @@ public class PopupFactoryImpl extends JBPopupFactory { myDisposeCallback = disposeCallback; myComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); + registerAction("handleActionToggle1", KeyEvent.VK_SPACE, 0, new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + handleToggleAction(); + } + }); + addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { @@ -270,6 +283,52 @@ public class PopupFactoryImpl extends JBPopupFactory { ActionMenu.showDescriptionInStatusBar(true, myComponent, null); super.dispose(); } + + @Override + public void handleSelect(boolean handleFinalChoices, InputEvent e) { + final Object selectedValue = getList().getSelectedValue(); + final ActionPopupStep actionPopupStep = ObjectUtils.tryCast(getListStep(), ActionPopupStep.class); + + if (actionPopupStep != null) { + ToggleAction toggleAction = getToggleAction(selectedValue, actionPopupStep); + if (toggleAction != null) { + actionPopupStep.performAction(toggleAction, e != null ? e.getModifiers() : 0); + getList().repaint(); + return; + } + } + + super.handleSelect(handleFinalChoices, e); + } + + protected void handleToggleAction() { + final Object[] selectedValues = getList().getSelectedValues(); + + ListPopupStep listStep = getListStep(); + final ActionPopupStep actionPopupStep = ObjectUtils.tryCast(listStep, ActionPopupStep.class); + if (actionPopupStep == null) return; + + List filtered = ContainerUtil.mapNotNull(selectedValues, new Function() { + @Override + public ToggleAction fun(Object o) { + return getToggleAction(o, actionPopupStep); + } + }); + + for (ToggleAction action : filtered) { + actionPopupStep.performAction(action, 0); + } + + getList().repaint(); + } + + @Nullable + private static ToggleAction getToggleAction(@Nullable Object value, @NotNull ActionPopupStep actionPopupStep) { + ActionItem item = value instanceof ActionItem ? (ActionItem)value : null; + if (item == null) return null; + if (!actionPopupStep.isSelectable(item)) return null; + return item.getAction() instanceof ToggleAction ? (ToggleAction)item.getAction() : null; + } } @NotNull @@ -740,18 +799,24 @@ public class PopupFactoryImpl extends JBPopupFactory { myFinalRunnable = new Runnable() { @Override public void run() { - final AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation().clone(), - ActionManager.getInstance(), eventModifiers); - event.setInjectedContext(action.isInInjectedContext()); - if (ActionUtil.lastUpdateAndCheckDumb(action, event, false)) { - action.actionPerformed(event); - } + performAction(action, eventModifiers); } }; return FINAL_CHOICE; } } + public void performAction(@NotNull AnAction action, int modifiers) { + final DataManager mgr = DataManager.getInstance(); + final DataContext dataContext = myContext != null ? mgr.getDataContext(myContext) : mgr.getDataContext(); + final AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation().clone(), + ActionManager.getInstance(), modifiers); + event.setInjectedContext(action.isInInjectedContext()); + if (ActionUtil.lastUpdateAndCheckDumb(action, event, false)) { + action.actionPerformed(event); + } + } + @Override public Runnable getFinalRunnable() { return myFinalRunnable; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index 252bf4a23394..e90fdb873cc8 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -246,6 +246,8 @@ class StructureFilterPopupComponent extends FilterPopupComponent