From 210af56ce4c57c7dfbbd09c9d8b4a21f91f5ebb4 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 14 Jan 2010 14:05:51 +0300 Subject: [PATCH] popups: handle final "onChosen" via focus manager --- .../debugger/actions/PsiMethodListPopupStep.java | 4 ++++ .../codeInsight/intention/impl/IntentionListStep.java | 9 +++++++-- .../actions/ChooseRunConfigurationAction.java | 12 +++--------- .../intellij/openapi/ui/ComboBoxTableRenderer.java | 16 ++++++++++++---- .../src/com/intellij/openapi/ui/popup/PopupStep.java | 6 ++++++ .../com/intellij/openapi/ui/popup/util/BaseStep.java | 11 +++++++++++ .../src/com/intellij/ui/popup/AbstractPopup.java | 13 +++++++++++++ .../src/com/intellij/ui/popup/PopupFactoryImpl.java | 19 ++++++++++--------- .../src/com/intellij/ui/popup/WizardPopup.java | 7 +++++++ .../src/com/intellij/ui/popup/list/ListPopupImpl.java | 2 ++ .../src/com/intellij/ui/popup/tree/TreePopupImpl.java | 1 + .../uiDesigner/actions/PaletteListPopupStep.java | 4 ++++ 12 files changed, 80 insertions(+), 24 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java b/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java index c0f16c2320..7a6fde9805 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java @@ -93,6 +93,10 @@ class PsiMethodListPopupStep implements ListPopupStep { return FINAL_CHOICE; } + public Runnable getFinalRunnable() { + return null; + } + public boolean hasSubstep(Object selectedValue) { return false; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index 9db9a3fca2..d1e22c23e3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -63,6 +63,7 @@ class IntentionListStep implements ListPopupStep return o1.getAction().getClass() == o2.getAction().getClass() && o1.getText().equals(o2.getText()); } }; + private Runnable myFinalRunnable; IntentionListStep(IntentionHintComponent intentionHintComponent, ShowIntentionsPass.IntentionsInfo intentions, Editor editor, PsiFile file, Project project) { @@ -163,8 +164,12 @@ class IntentionListStep implements ListPopupStep return FINAL_CHOICE; } + public Runnable getFinalRunnable() { + return myFinalRunnable; + } + private void applyAction(final IntentionActionWithTextCaching cachedAction) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + myFinalRunnable = new Runnable() { public void run() { HintManager.getInstance().hideAllHints(); ApplicationManager.getApplication().invokeLater(new Runnable() { @@ -180,7 +185,7 @@ class IntentionListStep implements ListPopupStep } }); } - }); + }; } private PopupStep getSubStep(final IntentionActionWithTextCaching action) { diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java index a855a6b4d4..93db0c5722 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java @@ -614,13 +614,11 @@ public class ChooseRunConfigurationAction extends AnAction { if (myAction.myEditConfiguration) { final Object o = wrapper.getValue(); if (o instanceof RunnerAndConfigurationSettingsImpl) { - SwingUtilities.invokeLater(new Runnable() { + return doFinalStep(new Runnable() { public void run() { myAction.editConfiguration(myProject, (RunnerAndConfigurationSettingsImpl)o); } }); - - return FINAL_CHOICE; } } @@ -628,7 +626,7 @@ public class ChooseRunConfigurationAction extends AnAction { assert executor != null; if (finalChoice && wrapper.available(executor)) { - SwingUtilities.invokeLater(new Runnable() { + return doFinalStep(new Runnable() { public void run() { if (executor == myAction.getAlternateExecutor()) { PropertiesComponent.getInstance().setValue(myAction.getAdKey(), Boolean.toString(true)); @@ -637,8 +635,6 @@ public class ChooseRunConfigurationAction extends AnAction { wrapper.perform(myProject, executor, DataManager.getInstance().getDataContext()); } }); - - return FINAL_CHOICE; } else { return wrapper.getNextStep(myProject, myAction); @@ -715,13 +711,11 @@ public class ChooseRunConfigurationAction extends AnAction { @Override public PopupStep onChosen(final ActionWrapper selectedValue, boolean finalChoice) { - SwingUtilities.invokeLater(new Runnable() { + return doFinalStep(new Runnable() { public void run() { selectedValue.perform(); } }); - - return FINAL_CHOICE; } @Override diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java index e32949479e..7210208d16 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java @@ -48,6 +48,8 @@ public class ComboBoxTableRenderer extends JLabel implements TableCellRendere protected EventListenerList myListenerList = new EventListenerList(); + private Runnable myFinalRunnable; + public ComboBoxTableRenderer(final T[] values) { myValues = values; setFont(UIUtil.getButtonFont()); @@ -71,14 +73,16 @@ public class ComboBoxTableRenderer extends JLabel implements TableCellRendere return value.toString(); } - protected void onChosen(@NotNull final T value) { + + + protected Runnable onChosen(@NotNull final T value) { stopCellEditing(value); - SwingUtilities.invokeLater(new Runnable() { + return new Runnable() { public void run() { stopCellEditing(value); } - }); + }; } @Override @@ -117,13 +121,17 @@ public class ComboBoxTableRenderer extends JLabel implements TableCellRendere } public PopupStep onChosen(T selectedValue, boolean finalChoice) { - ComboBoxTableRenderer.this.onChosen(selectedValue); + myFinalRunnable = ComboBoxTableRenderer.this.onChosen(selectedValue); return FINAL_CHOICE; } public void canceled() { ComboBoxTableRenderer.this.cancelCellEditing(); } + + public Runnable getFinalRunnable() { + return myFinalRunnable; + } }); popup.addListener(this); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupStep.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupStep.java index 7075e84dd6..2d9738d539 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupStep.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupStep.java @@ -102,4 +102,10 @@ public interface PopupStep { * @return true if the submenu for the first selectable item should be displayed automatically, false otherwise. */ boolean isAutoSelectionEnabled(); + + /** + * @return runnable to be executed when final step is chosen + */ + @Nullable + Runnable getFinalRunnable(); } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/util/BaseStep.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/util/BaseStep.java index 45a2904e3e..b2028f05b6 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/util/BaseStep.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/util/BaseStep.java @@ -22,6 +22,8 @@ import com.intellij.util.ui.UIUtil; public abstract class BaseStep implements PopupStep, SpeedSearchFilter, MnemonicNavigationFilter { + private Runnable myFinalRunnable; + public boolean isSpeedSearchEnabled() { return false; } @@ -58,4 +60,13 @@ public abstract class BaseStep implements PopupStep, SpeedSearchFilter, public MnemonicNavigationFilter getMnemonicNavigationFilter() { return this; } + + public Runnable getFinalRunnable() { + return myFinalRunnable; + } + + public PopupStep doFinalStep(Runnable runnable) { + myFinalRunnable = runnable; + return FINAL_CHOICE; + } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 3c2a8d22df..7a695c256e 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -115,6 +115,8 @@ public class AbstractPopup implements JBPopup { protected InputEvent myDisposeEvent; + protected Runnable myFinalRunnable; + protected final SpeedSearch mySpeedSearch = new SpeedSearch() { boolean searchFieldShown = false; protected void update() { @@ -456,6 +458,9 @@ public class AbstractPopup implements JBPopup { public void cancel(InputEvent e) { if (isDisposed()) return; + final Runnable finalRunnable = myFinalRunnable; + final IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(myOwner); + if (myPopup != null) { if (!canClose()) { return; @@ -496,6 +501,14 @@ public class AbstractPopup implements JBPopup { } Disposer.dispose(this, false); + + if (finalRunnable != null) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + focusManager.doWhenFocusSettlesDown(finalRunnable); + } + }); + } } 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 5df613d0a0..88f180e5de 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -408,6 +408,7 @@ public class PopupFactoryImpl extends JBPopupFactory { private final boolean myEnableMnemonics; private final int myDefaultOptionIndex; private final boolean myAutoSelectionEnabled; + private Runnable myFinalRunnable; private ActionPopupStep(@NotNull final List items, final String title, @@ -472,21 +473,21 @@ public class PopupFactoryImpl extends JBPopupFactory { return JBPopupFactory.getInstance().createActionsStep((ActionGroup)action, dataContext, myEnableMnemonics, false, null, myContext, false); } else { - // invokeLater is required to get a chance for the popup to hide in case the action called displays modal dialog - SwingUtilities.invokeLater(new Runnable() { + myFinalRunnable = new Runnable() { public void run() { - action.actionPerformed(new AnActionEvent(null, - dataContext, - ActionPlaces.UNKNOWN, - (Presentation)action.getTemplatePresentation().clone(), - ActionManager.getInstance(), - 0)); + action.actionPerformed( + new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, (Presentation)action.getTemplatePresentation().clone(), + ActionManager.getInstance(), 0)); } - }); + }; return FINAL_CHOICE; } } + public Runnable getFinalRunnable() { + return myFinalRunnable; + } + public boolean hasSubstep(final ActionItem selectedValue) { return selectedValue != null && selectedValue.isEnabled() && selectedValue.getAction() instanceof ActionGroup; } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java index d1cc96b721..b3647a9986 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java @@ -409,4 +409,11 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene } } + protected final void setFinalRunnable(Runnable runnable) { + if (getParent() == null) { + myFinalRunnable = runnable; + } else { + getParent().setFinalRunnable(runnable); + } + } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java index b971701693..e465726bc6 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java @@ -332,12 +332,14 @@ public class ListPopupImpl extends WizardPopup implements ListPopup { return false; } else { + setFinalRunnable(myStep.getFinalRunnable()); disposeAllParents(e); setIndexForShowingChild(-1); return true; } } + public void addListSelectionListener(ListSelectionListener listSelectionListener) { myList.addListSelectionListener(listSelectionListener); } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java index febbacb2c4..06d214216f 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java @@ -323,6 +323,7 @@ public class TreePopupImpl extends WizardPopup implements TreePopup { final PopupStep queriedStep = myStep.onChosen(userObject, handleFinalChoices); if (queriedStep == PopupStep.FINAL_CHOICE || !hasNextStep) { + setFinalRunnable(myStep.getFinalRunnable()); disposeAllParents(e); } else { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/PaletteListPopupStep.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/PaletteListPopupStep.java index 22b99c747b..c0917101db 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/PaletteListPopupStep.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/PaletteListPopupStep.java @@ -97,6 +97,10 @@ class PaletteListPopupStep implements ListPopupStep, SpeedSearchF return PopupStep.FINAL_CHOICE; } + public Runnable getFinalRunnable() { + return null; + } + public boolean hasSubstep(final ComponentItem selectedValue) { return false; } -- 2.11.4.GIT