From 10f16fcd919e4f846930eaa65943e373267f2039 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 11 Apr 2016 17:39:22 +0300 Subject: [PATCH] AnAction cleanup; ActionUtil: copyFrom(String), mergeFrom(String) --- .../diff/impl/DiffRequestProcessor.java | 3 +- .../diff/merge/MergeRequestProcessor.java | 3 +- .../openapi/actionSystem/AnAction.java | 59 +++++++++---------- .../actionSystem/CustomShortcutSet.java | 7 +-- .../openapi/actionSystem/EmptyAction.java | 10 +--- .../openapi/actionSystem/ex/ActionUtil.java | 53 ++++++++++++++++- 6 files changed, 88 insertions(+), 47 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java index 407cf54641ba..47b561534aaa 100644 --- a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java @@ -38,6 +38,7 @@ import com.intellij.internal.statistic.UsageTrigger; import com.intellij.internal.statistic.beans.ConvertUsagesUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -276,7 +277,7 @@ public abstract class DiffRequestProcessor implements Disposable { myToolbarStatusPanel.setContent(null); myToolbarPanel.setContent(null); myContentPanel.setContent(null); - myMainPanel.putClientProperty(AnAction.ourClientProperty, null); + ActionUtil.clearActions(myMainPanel); myActiveRequest.onAssigned(false); myActiveRequest = request; diff --git a/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java b/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java index f7ec57dc31ec..680a46a6f631 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/MergeRequestProcessor.java @@ -27,6 +27,7 @@ import com.intellij.ide.DataManager; import com.intellij.ide.impl.DataManagerImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.BooleanGetter; @@ -135,7 +136,7 @@ public abstract class MergeRequestProcessor implements Disposable { private void destroyViewer() { Disposer.dispose(myViewer); - myMainPanel.putClientProperty(AnAction.ourClientProperty, null); + ActionUtil.clearActions(myMainPanel); myContentPanel.setContent(null); myToolbarPanel.setContent(null); diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java index c681f6cbbbea..b0d172d82fa9 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java @@ -21,9 +21,10 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.PossiblyDumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.util.SmartList; +import com.intellij.util.ui.UIUtil; import org.intellij.lang.annotations.JdkConstants; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -66,15 +67,13 @@ import java.util.List; public abstract class AnAction implements PossiblyDumbAware { private static final Logger LOG = Logger.getInstance(AnAction.class); + public static final Key> ACTIONS_KEY = Key.create("AnAction.shortcutSet"); public static final AnAction[] EMPTY_ARRAY = new AnAction[0]; - @NonNls public static final String ourClientProperty = "AnAction.shortcutSet"; private Presentation myTemplatePresentation; private ShortcutSet myShortcutSet; private boolean myEnabledInModalContext; - - private static final ShortcutSet ourEmptyShortcutSet = new CustomShortcutSet(); private boolean myIsDefaultIcon = true; private boolean myWorksInInjected; private boolean myIsGlobal; // action is registered in ActionManager @@ -119,7 +118,7 @@ public abstract class AnAction implements PossiblyDumbAware { * @param icon Action's icon */ public AnAction(@Nullable String text, @Nullable String description, @Nullable Icon icon){ - myShortcutSet = ourEmptyShortcutSet; + myShortcutSet = CustomShortcutSet.EMPTY; myEnabledInModalContext = false; Presentation presentation = getTemplatePresentation(); presentation.setText(text); @@ -152,37 +151,35 @@ public abstract class AnAction implements PossiblyDumbAware { registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(keyCode, modifiers)), component); } - public final void registerCustomShortcutSet(@NotNull ShortcutSet shortcutSet, @Nullable final JComponent component, @Nullable Disposable parentDisposable) { + public final void registerCustomShortcutSet(@NotNull ShortcutSet shortcutSet, @Nullable JComponent component, @Nullable Disposable parentDisposable) { setShortcutSet(shortcutSet); - if (component != null){ - @SuppressWarnings("unchecked") - List actionList = (List)component.getClientProperty(ourClientProperty); - if (actionList == null){ - actionList = new SmartList(); - component.putClientProperty(ourClientProperty, actionList); - } - if (!actionList.contains(this)){ - actionList.add(this); - } + registerCustomShortcutSet(component, parentDisposable); + } - if (parentDisposable != null) { - Disposer.register(parentDisposable, new Disposable() { - @Override - public void dispose() { - unregisterCustomShortcutSet(component); - } - }); - } + public final void registerCustomShortcutSet(@Nullable JComponent component, @Nullable Disposable parentDisposable) { + if (component == null) return; + List actionList = UIUtil.getClientProperty(component, ACTIONS_KEY); + if (actionList == null) { + UIUtil.putClientProperty(component, ACTIONS_KEY, actionList = new SmartList()); + } + if (!actionList.contains(this)) { + actionList.add(this); + } + + if (parentDisposable != null) { + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + unregisterCustomShortcutSet(component); + } + }); } } - public final void unregisterCustomShortcutSet(JComponent component){ - if (component != null){ - @SuppressWarnings("unchecked") - List actionList = (List)component.getClientProperty(ourClientProperty); - if (actionList != null){ - actionList.remove(this); - } + public final void unregisterCustomShortcutSet(@Nullable JComponent component) { + List actionList = UIUtil.getClientProperty(component, ACTIONS_KEY); + if (actionList != null) { + actionList.remove(this); } } diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java index b0cd58e4f7c9..6511be92101f 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java @@ -26,6 +26,9 @@ import javax.swing.*; */ public final class CustomShortcutSet implements ShortcutSet { + + public static final CustomShortcutSet EMPTY = new CustomShortcutSet(Shortcut.EMPTY_ARRAY); + private final Shortcut[] myShortcuts; /** @@ -36,10 +39,6 @@ public final class CustomShortcutSet implements ShortcutSet { this(new KeyboardShortcut(keyStroke, null)); } - public CustomShortcutSet() { - myShortcuts = Shortcut.EMPTY_ARRAY; - } - /** * Creates CustomShortcutSet which contains specified keyboard and * mouse shortcuts. diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java index d552a851c12e..d63da5cbd078 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java @@ -62,15 +62,11 @@ public final class EmptyAction extends AnAction { } public static void setupAction(@NotNull AnAction action, @NotNull String id, @Nullable JComponent component) { - final AnAction emptyAction = ActionManager.getInstance().getAction(id); - action.copyFrom(emptyAction); - action.registerCustomShortcutSet(action.getShortcutSet(), component); + ActionUtil.mergeFrom(action, id).registerCustomShortcutSet(component, null); } - public static void registerActionShortcuts(JComponent component, final JComponent fromComponent) { - for (AnAction anAction : ActionUtil.getActions(fromComponent)) { - anAction.registerCustomShortcutSet(anAction.getShortcutSet(), component); - } + public static void registerActionShortcuts(@NotNull JComponent component, @NotNull JComponent fromComponent) { + ActionUtil.copyRegisteredShortcuts(component, fromComponent); } /** diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java index 1ce55d4c8f3b..221e732b13ad 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java @@ -22,7 +22,9 @@ import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ObjectUtils; import com.intellij.util.PausesStat; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -197,9 +199,17 @@ public class ActionUtil { @NotNull public static List getActions(@NotNull JComponent component) { - Object property = component.getClientProperty(AnAction.ourClientProperty); - //noinspection unchecked - return property == null ? Collections.emptyList() : (List)property; + return ObjectUtils.notNull(UIUtil.getClientProperty(component, AnAction.ACTIONS_KEY), Collections.emptyList()); + } + + public static void clearActions(@NotNull JComponent component) { + UIUtil.putClientProperty(component, AnAction.ACTIONS_KEY, null); + } + + public static void copyRegisteredShortcuts(@NotNull JComponent to, @NotNull JComponent from) { + for (AnAction anAction : getActions(from)) { + anAction.registerCustomShortcutSet(anAction.getShortcutSet(), to); + } } public static void registerForEveryKeyboardShortcut(@NotNull JComponent component, @@ -216,4 +226,41 @@ public class ActionUtil { } } } + + /** + * Convenience method for copying properties from a registered action + * + * @param actionId action id + */ + public static AnAction copyFrom(@NotNull AnAction action, @NotNull String actionId) { + action.copyFrom(ActionManager.getInstance().getAction(actionId)); + return action; + } + + /** + * Convenience method for merging not null properties from a registered action + * + * @param action action to merge to + * @param actionId action id to merge from + */ + public static AnAction mergeFrom(@NotNull AnAction action, @NotNull String actionId) { + //noinspection UnnecessaryLocalVariable + AnAction a1 = action; + AnAction a2 = ActionManager.getInstance().getAction(actionId); + Presentation p1 = a1.getTemplatePresentation(); + Presentation p2 = a2.getTemplatePresentation(); + p1.setIcon(ObjectUtils.chooseNotNull(p1.getIcon(), p2.getIcon())); + p1.setDisabledIcon(ObjectUtils.chooseNotNull(p1.getDisabledIcon(), p2.getDisabledIcon())); + p1.setSelectedIcon(ObjectUtils.chooseNotNull(p1.getSelectedIcon(), p2.getSelectedIcon())); + p1.setHoveredIcon(ObjectUtils.chooseNotNull(p1.getHoveredIcon(), p2.getHoveredIcon())); + if (StringUtil.isEmpty(p1.getText())) { + p1.setText(p2.getTextWithMnemonic(), p2.getDisplayedMnemonicIndex() >= 0); + } + p1.setDescription(ObjectUtils.chooseNotNull(p1.getDescription(), p2.getDescription())); + ShortcutSet ss1 = a1.getShortcutSet(); + if (ss1 == null || ss1 == CustomShortcutSet.EMPTY) { + a1.copyShortcutFrom(a2); + } + return a1; + } }