summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java')
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java786
1 files changed, 411 insertions, 375 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
index 723956ef9daa..c5a9b01c4d21 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
@@ -39,6 +39,7 @@ import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.ProjectType;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
@@ -71,28 +72,6 @@ import java.util.*;
import java.util.List;
public final class ActionManagerImpl extends ActionManagerEx implements ApplicationComponent {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
- private static final int DEACTIVATED_TIMER_DELAY = 5000;
- private static final int TIMER_DELAY = 500;
- private static final int UPDATE_DELAY_AFTER_TYPING = 500;
-
- private final Object myLock = new Object();
- private final Map<String,Object> myId2Action = new THashMap<String, Object>();
- private final Map<PluginId, THashSet<String>> myPlugin2Id = new THashMap<PluginId, THashSet<String>>();
- private final TObjectIntHashMap<String> myId2Index = new TObjectIntHashMap<String>();
- private final Map<Object,String> myAction2Id = new THashMap<Object, String>();
- private final MultiMap<String,String> myId2GroupId = new MultiMap<String, String>();
- private final List<String> myNotRegisteredInternalActionIds = new ArrayList<String>();
- private MyTimer myTimer;
-
- private int myRegisteredActionsCount;
- private final List<AnActionListener> myActionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
- private String myLastPreformedActionId;
- private final KeymapManager myKeymapManager;
- private final DataManager myDataManager;
- private String myPrevPerformedActionId;
- private long myLastTimeEditorWasTypedIn = 0;
-
@NonNls public static final String ACTION_ELEMENT_NAME = "action";
@NonNls public static final String GROUP_ELEMENT_NAME = "group";
@NonNls public static final String ACTIONS_ELEMENT_NAME = "actions";
@@ -130,14 +109,32 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@NonNls public static final String USE_SHORTCUT_OF_ATTR_NAME = "use-shortcut-of";
@NonNls public static final String OVERRIDES_ATTR_NAME = "overrides";
@NonNls public static final String KEEP_CONTENT_ATTR_NAME = "keep-content";
-
+ @NonNls public static final String PROJECT_TYPE = "project-type";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
+ private static final int DEACTIVATED_TIMER_DELAY = 5000;
+ private static final int TIMER_DELAY = 500;
+ private static final int UPDATE_DELAY_AFTER_TYPING = 500;
+ private final Object myLock = new Object();
+ private final Map<String,AnAction> myId2Action = new THashMap<String, AnAction>();
+ private final Map<PluginId, THashSet<String>> myPlugin2Id = new THashMap<PluginId, THashSet<String>>();
+ private final TObjectIntHashMap<String> myId2Index = new TObjectIntHashMap<String>();
+ private final Map<Object,String> myAction2Id = new THashMap<Object, String>();
+ private final MultiMap<String,String> myId2GroupId = new MultiMap<String, String>();
+ private final List<String> myNotRegisteredInternalActionIds = new ArrayList<String>();
+ private final List<AnActionListener> myActionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private final KeymapManager myKeymapManager;
+ private final DataManager myDataManager;
private final List<ActionPopupMenuImpl> myPopups = new ArrayList<ActionPopupMenuImpl>();
-
private final Map<AnAction, DataContext> myQueuedNotifications = new LinkedHashMap<AnAction, DataContext>();
private final Map<AnAction, AnActionEvent> myQueuedNotificationsEvents = new LinkedHashMap<AnAction, AnActionEvent>();
-
+ private MyTimer myTimer;
+ private int myRegisteredActionsCount;
+ private String myLastPreformedActionId;
+ private String myPrevPerformedActionId;
+ private long myLastTimeEditorWasTypedIn = 0;
private Runnable myPreloadActionsRunnable;
private boolean myTransparentOnlyUpdate;
+ private int myActionsPreloaded = 0;
ActionManagerImpl(KeymapManager keymapManager, DataManager dataManager) {
myKeymapManager = keymapManager;
@@ -146,6 +143,257 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
registerPluginActions();
}
+ static AnAction convertStub(ActionStub stub) {
+ Object obj;
+ String className = stub.getClassName();
+ try {
+ Class<?> aClass = Class.forName(className, true, stub.getLoader());
+ obj = ReflectionUtil.newInstance(aClass);
+ }
+ catch (ClassNotFoundException e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException("class with name \"" + className + "\" not found", e, pluginId);
+ }
+ else {
+ throw new IllegalStateException("class with name \"" + className + "\" not found");
+ }
+ }
+ catch(UnsupportedClassVersionError e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException(e, pluginId);
+ }
+ else {
+ throw new IllegalStateException(e);
+ }
+ }
+ catch (Exception e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException("cannot create class \"" + className + "\"", e, pluginId);
+ }
+ else {
+ throw new IllegalStateException("cannot create class \"" + className + "\"", e);
+ }
+ }
+
+ if (!(obj instanceof AnAction)) {
+ throw new IllegalStateException("class with name '" + className + "' must be an instance of '" + AnAction.class.getName()+"'; got "+obj);
+ }
+
+ AnAction anAction = (AnAction)obj;
+ stub.initAction(anAction);
+ if (StringUtil.isNotEmpty(stub.getText())) {
+ anAction.getTemplatePresentation().setText(stub.getText());
+ }
+ String iconPath = stub.getIconPath();
+ if (iconPath != null) {
+ Class<? extends AnAction> actionClass = anAction.getClass();
+ setIconFromClass(actionClass, actionClass.getClassLoader(), iconPath, anAction.getTemplatePresentation(), stub.getPluginId());
+ }
+ return anAction;
+ }
+
+ private static void processAbbreviationNode(Element e, String id) {
+ final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
+ if (!StringUtil.isEmpty(abbr)) {
+ final AbbreviationManagerImpl abbreviationManager = ((AbbreviationManagerImpl)AbbreviationManager.getInstance());
+ abbreviationManager.register(abbr, id, true);
+ }
+ }
+
+ @Nullable
+ private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
+ @NonNls final String resBundleName = plugin != null && !"com.intellij".equals(plugin.getPluginId().getIdString())
+ ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
+ ResourceBundle bundle = null;
+ if (resBundleName != null) {
+ bundle = AbstractBundle.getResourceBundle(resBundleName, loader);
+ }
+ return bundle;
+ }
+
+ private static boolean isSecondary(Element element) {
+ return "true".equalsIgnoreCase(element.getAttributeValue(SECONDARY));
+ }
+
+ private static void setIcon(@Nullable final String iconPath,
+ @NotNull String className,
+ @NotNull ClassLoader loader,
+ @NotNull Presentation presentation,
+ final PluginId pluginId) {
+ if (iconPath == null) return;
+
+ try {
+ final Class actionClass = Class.forName(className, true, loader);
+ setIconFromClass(actionClass, loader, iconPath, presentation, pluginId);
+ }
+ catch (ClassNotFoundException e) {
+ LOG.error(e);
+ reportActionError(pluginId, "class with name \"" + className + "\" not found");
+ }
+ catch (NoClassDefFoundError e) {
+ LOG.error(e);
+ reportActionError(pluginId, "class with name \"" + className + "\" not found");
+ }
+ }
+
+ private static void setIconFromClass(@NotNull final Class actionClass,
+ @NotNull final ClassLoader classLoader,
+ @NotNull final String iconPath,
+ @NotNull Presentation presentation,
+ final PluginId pluginId) {
+ final IconLoader.LazyIcon lazyIcon = new IconLoader.LazyIcon() {
+ @Override
+ protected Icon compute() {
+ //try to find icon in idea class path
+ Icon icon = IconLoader.findIcon(iconPath, actionClass, true);
+ if (icon == null) {
+ icon = IconLoader.findIcon(iconPath, classLoader);
+ }
+
+ if (icon == null) {
+ reportActionError(pluginId, "Icon cannot be found in '" + iconPath + "', action '" + actionClass + "'");
+ }
+
+ return icon;
+ }
+
+ @Override
+ public String toString() {
+ return "LazyIcon@ActionManagerImpl (path: " + iconPath + ", action class: " + actionClass + ")";
+ }
+ };
+
+ if (!Registry.is("ide.lazyIconLoading")) {
+ lazyIcon.load();
+ }
+
+ presentation.setIcon(lazyIcon);
+ }
+
+ private static String loadDescriptionForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
+ final String value = element.getAttributeValue(DESCRIPTION);
+ if (bundle != null) {
+ @NonNls final String key = elementType + "." + id + ".description";
+ return CommonBundle.messageOrDefault(bundle, key, value == null ? "" : value);
+ } else {
+ return value;
+ }
+ }
+
+ private static String loadTextForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
+ final String value = element.getAttributeValue(TEXT_ATTR_NAME);
+ return CommonBundle.messageOrDefault(bundle, elementType + "." + id + "." + TEXT_ATTR_NAME, value == null ? "" : value);
+ }
+
+ public static boolean checkRelativeToAction(final String relativeToActionId,
+ @NotNull final Anchor anchor,
+ @NotNull final String actionName,
+ @Nullable final PluginId pluginId) {
+ if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) {
+ reportActionError(pluginId, actionName + ": \"relative-to-action\" cannot be null if anchor is \"after\" or \"before\"");
+ return false;
+ }
+ return true;
+ }
+
+ @Nullable
+ public static Anchor parseAnchor(final String anchorStr,
+ @Nullable final String actionName,
+ @Nullable final PluginId pluginId) {
+ if (anchorStr == null) {
+ return Anchor.LAST;
+ }
+
+ if (FIRST.equalsIgnoreCase(anchorStr)) {
+ return Anchor.FIRST;
+ }
+ else if (LAST.equalsIgnoreCase(anchorStr)) {
+ return Anchor.LAST;
+ }
+ else if (BEFORE.equalsIgnoreCase(anchorStr)) {
+ return Anchor.BEFORE;
+ }
+ else if (AFTER.equalsIgnoreCase(anchorStr)) {
+ return Anchor.AFTER;
+ }
+ else {
+ reportActionError(pluginId, actionName + ": anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\"");
+ return null;
+ }
+ }
+
+ private static void processMouseShortcutNode(Element element, String actionId, PluginId pluginId) {
+ String keystrokeString = element.getAttributeValue(KEYSTROKE_ATTR_NAME);
+ if (keystrokeString == null || keystrokeString.trim().isEmpty()) {
+ reportActionError(pluginId, "\"keystroke\" attribute must be specified for action with id=" + actionId);
+ return;
+ }
+ MouseShortcut shortcut;
+ try {
+ shortcut = KeymapUtil.parseMouseShortcut(keystrokeString);
+ }
+ catch (Exception ex) {
+ reportActionError(pluginId, "\"keystroke\" attribute has invalid value for action with id=" + actionId);
+ return;
+ }
+
+ String keymapName = element.getAttributeValue(KEYMAP_ATTR_NAME);
+ if (keymapName == null || keymapName.isEmpty()) {
+ reportActionError(pluginId, "attribute \"keymap\" should be defined");
+ return;
+ }
+ Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName);
+ if (keymap == null) {
+ reportActionError(pluginId, "keymap \"" + keymapName + "\" not found");
+ return;
+ }
+
+ final String removeOption = element.getAttributeValue(REMOVE_SHORTCUT_ATTR_NAME);
+ if (Boolean.valueOf(removeOption)) {
+ keymap.removeShortcut(actionId, shortcut);
+ } else {
+ keymap.addShortcut(actionId, shortcut);
+ }
+ }
+
+ private static void assertActionIsGroupOrStub(final AnAction action) {
+ if (!(action instanceof ActionGroup || action instanceof ActionStub)) {
+ LOG.error("Action : " + action + "; class: " + action.getClass());
+ }
+ }
+
+ private static void reportActionError(final PluginId pluginId, @NonNls @NotNull String message) {
+ if (pluginId == null) {
+ LOG.error(message);
+ }
+ else {
+ LOG.error(new PluginException(message, null, pluginId));
+ }
+ }
+
+ @NonNls
+ private static String getPluginInfo(@Nullable PluginId id) {
+ if (id != null) {
+ final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
+ if (plugin != null) {
+ String name = plugin.getName();
+ if (name == null) {
+ name = id.getIdString();
+ }
+ return " Plugin: " + name;
+ }
+ }
+ return "";
+ }
+
+ private static DataContext getContextBy(Component contextComponent) {
+ final DataManager dataManager = DataManager.getInstance();
+ return contextComponent != null ? dataManager.getDataContext(contextComponent) : dataManager.getDataContext();
+ }
+
@Override
public void initComponent() {}
@@ -213,7 +461,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return new ActionToolbarImpl(place, group, horizontal, decorateButtons, myDataManager, this, (KeymapManagerEx)myKeymapManager);
}
-
private void registerPluginActions() {
final IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins();
for (IdeaPluginDescriptor plugin : plugins) {
@@ -229,12 +476,28 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public AnAction getAction(@NotNull String id) {
- return getActionImpl(id, false);
+ return getActionImpl(id, false, null);
}
- private AnAction getActionImpl(String id, boolean canReturnStub) {
+ @Override
+ public AnAction getAction(@NonNls @NotNull String actionId, @Nullable ProjectType projectType) {
+ return getActionImpl(actionId, false, projectType);
+ }
+
+ private AnAction getActionImpl(String id, boolean canReturnStub, ProjectType projectType) {
synchronized (myLock) {
- AnAction action = (AnAction)myId2Action.get(id);
+ AnAction action;
+ Object o = myId2Action.get(id);
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof AnAction) {
+ action = (AnAction)o;
+ }
+ else {
+ //noinspection unchecked
+ action = ((Map<ProjectType, AnAction>)o).get(projectType);
+ }
if (!canReturnStub && action instanceof ActionStub) {
action = convert((ActionStub)action);
}
@@ -252,61 +515,14 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
LOG.assertTrue(myId2Action.containsKey(stub.getId()));
- AnAction action = (AnAction)myId2Action.remove(stub.getId());
+ AnAction action = myId2Action.remove(stub.getId());
LOG.assertTrue(action != null);
LOG.assertTrue(action.equals(stub));
- Object obj;
- String className = stub.getClassName();
- try {
- Class<?> aClass = Class.forName(className, true, stub.getLoader());
- obj = ReflectionUtil.newInstance(aClass);
- }
- catch (ClassNotFoundException e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException("class with name \"" + className + "\" not found", e, pluginId);
- }
- else {
- throw new IllegalStateException("class with name \"" + className + "\" not found");
- }
- }
- catch(UnsupportedClassVersionError e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException(e, pluginId);
- }
- else {
- throw new IllegalStateException(e);
- }
- }
- catch (Exception e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException("cannot create class \"" + className + "\"", e, pluginId);
- }
- else {
- throw new IllegalStateException("cannot create class \"" + className + "\"", e);
- }
- }
-
- if (!(obj instanceof AnAction)) {
- throw new IllegalStateException("class with name '" + className + "' must be an instance of '" + AnAction.class.getName()+"'; got "+obj);
- }
+ AnAction anAction = convertStub(stub);
- AnAction anAction = (AnAction)obj;
- stub.initAction(anAction);
- if (StringUtil.isNotEmpty(stub.getText())) {
- anAction.getTemplatePresentation().setText(stub.getText());
- }
- String iconPath = stub.getIconPath();
- if (iconPath != null) {
- Class<? extends AnAction> actionClass = anAction.getClass();
- setIconFromClass(actionClass, actionClass.getClassLoader(), iconPath, anAction.getTemplatePresentation(), stub.getPluginId());
- }
-
- myId2Action.put(stub.getId(), obj);
- myAction2Id.put(obj, stub.getId());
+ addToMap(stub.getId(), anAction, stub.getPluginId(), stub.getProjectType() == null ? null : new ProjectType(stub.getProjectType()));
+ myAction2Id.put(anAction, stub.getId());
return anAction;
}
@@ -334,7 +550,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public boolean isGroup(@NotNull String actionId) {
- return getActionImpl(actionId, true) instanceof ActionGroup;
+ return getActionImpl(actionId, true, null) instanceof ActionGroup;
}
@Override
@@ -344,7 +560,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public AnAction getActionOrStub(String id) {
- return getActionImpl(id, true);
+ return getActionImpl(id, true, null);
}
/**
@@ -386,7 +602,8 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return null;
}
- ActionStub stub = new ActionStub(className, id, text, loader, pluginId, iconPath);
+ String projectType = element.getAttributeValue(PROJECT_TYPE);
+ ActionStub stub = new ActionStub(className, id, text, loader, pluginId, iconPath, projectType);
Presentation presentation = stub.getTemplatePresentation();
presentation.setText(text);
@@ -441,99 +658,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void processAbbreviationNode(Element e, String id) {
- final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
- if (!StringUtil.isEmpty(abbr)) {
- final AbbreviationManagerImpl abbreviationManager = ((AbbreviationManagerImpl)AbbreviationManager.getInstance());
- abbreviationManager.register(abbr, id, true);
- }
- }
-
- @Nullable
- private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
- @NonNls final String resBundleName = plugin != null && !"com.intellij".equals(plugin.getPluginId().getIdString())
- ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
- ResourceBundle bundle = null;
- if (resBundleName != null) {
- bundle = AbstractBundle.getResourceBundle(resBundleName, loader);
- }
- return bundle;
- }
-
- private static boolean isSecondary(Element element) {
- return "true".equalsIgnoreCase(element.getAttributeValue(SECONDARY));
- }
-
- private static void setIcon(@Nullable final String iconPath,
- @NotNull String className,
- @NotNull ClassLoader loader,
- @NotNull Presentation presentation,
- final PluginId pluginId) {
- if (iconPath == null) return;
-
- try {
- final Class actionClass = Class.forName(className, true, loader);
- setIconFromClass(actionClass, loader, iconPath, presentation, pluginId);
- }
- catch (ClassNotFoundException e) {
- LOG.error(e);
- reportActionError(pluginId, "class with name \"" + className + "\" not found");
- }
- catch (NoClassDefFoundError e) {
- LOG.error(e);
- reportActionError(pluginId, "class with name \"" + className + "\" not found");
- }
- }
-
- private static void setIconFromClass(@NotNull final Class actionClass,
- @NotNull final ClassLoader classLoader,
- @NotNull final String iconPath,
- @NotNull Presentation presentation,
- final PluginId pluginId) {
- final IconLoader.LazyIcon lazyIcon = new IconLoader.LazyIcon() {
- @Override
- protected Icon compute() {
- //try to find icon in idea class path
- Icon icon = IconLoader.findIcon(iconPath, actionClass, true);
- if (icon == null) {
- icon = IconLoader.findIcon(iconPath, classLoader);
- }
-
- if (icon == null) {
- reportActionError(pluginId, "Icon cannot be found in '" + iconPath + "', action '" + actionClass + "'");
- }
-
- return icon;
- }
-
- @Override
- public String toString() {
- return "LazyIcon@ActionManagerImpl (path: " + iconPath + ", action class: " + actionClass + ")";
- }
- };
-
- if (!Registry.is("ide.lazyIconLoading")) {
- lazyIcon.load();
- }
-
- presentation.setIcon(lazyIcon);
- }
-
- private static String loadDescriptionForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
- final String value = element.getAttributeValue(DESCRIPTION);
- if (bundle != null) {
- @NonNls final String key = elementType + "." + id + ".description";
- return CommonBundle.messageOrDefault(bundle, key, value == null ? "" : value);
- } else {
- return value;
- }
- }
-
- private static String loadTextForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
- final String value = element.getAttributeValue(TEXT_ATTR_NAME);
- return CommonBundle.messageOrDefault(bundle, elementType + "." + id + "." + TEXT_ATTR_NAME, value == null ? "" : value);
- }
-
private AnAction processGroupElement(Element element, final ClassLoader loader, PluginId pluginId) {
final IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId);
ResourceBundle bundle = getActionsResourceBundle(loader, plugin);
@@ -723,43 +847,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
myId2GroupId.putValue(myAction2Id.get(action), myAction2Id.get(group));
}
- public static boolean checkRelativeToAction(final String relativeToActionId,
- @NotNull final Anchor anchor,
- @NotNull final String actionName,
- @Nullable final PluginId pluginId) {
- if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) {
- reportActionError(pluginId, actionName + ": \"relative-to-action\" cannot be null if anchor is \"after\" or \"before\"");
- return false;
- }
- return true;
- }
-
- @Nullable
- public static Anchor parseAnchor(final String anchorStr,
- @Nullable final String actionName,
- @Nullable final PluginId pluginId) {
- if (anchorStr == null) {
- return Anchor.LAST;
- }
-
- if (FIRST.equalsIgnoreCase(anchorStr)) {
- return Anchor.FIRST;
- }
- else if (LAST.equalsIgnoreCase(anchorStr)) {
- return Anchor.LAST;
- }
- else if (BEFORE.equalsIgnoreCase(anchorStr)) {
- return Anchor.BEFORE;
- }
- else if (AFTER.equalsIgnoreCase(anchorStr)) {
- return Anchor.AFTER;
- }
- else {
- reportActionError(pluginId, actionName + ": anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\"");
- return null;
- }
- }
-
@Nullable
public AnAction getParentGroup(final String groupId,
@Nullable final String actionName,
@@ -768,10 +855,10 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
reportActionError(pluginId, actionName + ": attribute \"group-id\" should be defined");
return null;
}
- AnAction parentGroup = getActionImpl(groupId, true);
+ AnAction parentGroup = getActionImpl(groupId, true, null);
if (parentGroup == null) {
reportActionError(pluginId, actionName + ": group with id \"" + groupId + "\" isn't registered; action will be added to the \"Other\" group");
- parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true);
+ parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true, null);
}
if (!(parentGroup instanceof DefaultActionGroup)) {
reportActionError(pluginId, actionName + ": group with id \"" + groupId + "\" should be instance of " + DefaultActionGroup.class.getName() +
@@ -850,40 +937,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void processMouseShortcutNode(Element element, String actionId, PluginId pluginId) {
- String keystrokeString = element.getAttributeValue(KEYSTROKE_ATTR_NAME);
- if (keystrokeString == null || keystrokeString.trim().isEmpty()) {
- reportActionError(pluginId, "\"keystroke\" attribute must be specified for action with id=" + actionId);
- return;
- }
- MouseShortcut shortcut;
- try {
- shortcut = KeymapUtil.parseMouseShortcut(keystrokeString);
- }
- catch (Exception ex) {
- reportActionError(pluginId, "\"keystroke\" attribute has invalid value for action with id=" + actionId);
- return;
- }
-
- String keymapName = element.getAttributeValue(KEYMAP_ATTR_NAME);
- if (keymapName == null || keymapName.isEmpty()) {
- reportActionError(pluginId, "attribute \"keymap\" should be defined");
- return;
- }
- Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName);
- if (keymap == null) {
- reportActionError(pluginId, "keymap \"" + keymapName + "\" not found");
- return;
- }
-
- final String removeOption = element.getAttributeValue(REMOVE_SHORTCUT_ATTR_NAME);
- if (Boolean.valueOf(removeOption)) {
- keymap.removeShortcut(actionId, shortcut);
- } else {
- keymap.addShortcut(actionId, shortcut);
- }
- }
-
@Nullable
private AnAction processReferenceElement(Element element, PluginId pluginId) {
if (!REFERENCE_ELEMENT_NAME.equals(element.getName())) {
@@ -902,7 +955,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return null;
}
- AnAction action = getActionImpl(ref, true);
+ AnAction action = getActionImpl(ref, true, null);
if (action == null) {
if (!myNotRegisteredInternalActionIds.contains(ref)) {
@@ -936,27 +989,15 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void assertActionIsGroupOrStub(final AnAction action) {
- if (!(action instanceof ActionGroup || action instanceof ActionStub)) {
- LOG.error("Action : " + action + "; class: " + action.getClass());
- }
- }
-
@Override
public void registerAction(@NotNull String actionId, @NotNull AnAction action, @Nullable PluginId pluginId) {
synchronized (myLock) {
- if (myId2Action.containsKey(actionId)) {
- reportActionError(pluginId, "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
- "; Registered action is " +
- myId2Action.get(actionId) + getPluginInfo(pluginId));
- return;
- }
+ if (!addToMap(actionId, action, pluginId, null)) return;
if (myAction2Id.containsKey(action)) {
reportActionError(pluginId, "action was already registered for another ID. ID is " + myAction2Id.get(action) +
getPluginInfo(pluginId));
return;
}
- myId2Action.put(actionId, action);
myId2Index.put(actionId, myRegisteredActionsCount++);
myAction2Id.put(action, actionId);
if (pluginId != null && !(action instanceof ActionGroup)){
@@ -971,28 +1012,31 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void reportActionError(final PluginId pluginId, @NonNls @NotNull String message) {
- if (pluginId == null) {
- LOG.error(message);
+ public boolean addToMap(String actionId, AnAction action, PluginId pluginId, ProjectType projectType) {
+ if (myId2Action.containsKey(actionId)) {
+ // make sure id+projectType is unique
+ AnAction o = myId2Action.get(actionId);
+ ChameleonAction chameleonAction;
+ if (o instanceof ChameleonAction) {
+ chameleonAction = (ChameleonAction)o;
+ }
+ else {
+ chameleonAction = new ChameleonAction(o, projectType);
+ myId2Action.put(actionId, chameleonAction);
+ }
+ AnAction old = chameleonAction.addAction(action, projectType);
+ if (old != null) {
+ reportActionError(pluginId,
+ "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
+ "; Registered action is " +
+ myId2Action.get(actionId) + getPluginInfo(pluginId));
+ return false;
+ }
}
else {
- LOG.error(new PluginException(message, null, pluginId));
- }
- }
-
- @NonNls
- private static String getPluginInfo(@Nullable PluginId id) {
- if (id != null) {
- final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
- if (plugin != null) {
- String name = plugin.getName();
- if (name == null) {
- name = id.getIdString();
- }
- return " Plugin: " + name;
- }
+ myId2Action.put(actionId, action);
}
- return "";
+ return true;
}
@Override
@@ -1067,6 +1111,12 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
+ //@Override
+ //public AnAction replaceAction(String actionId, @NotNull AnAction newAction) {
+ // synchronized (myLock) {
+ // return replaceAction(actionId, newAction, null);
+ // }
+ //}
@Override
public boolean isActionPopupStackEmpty() {
@@ -1078,13 +1128,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return myTransparentOnlyUpdate;
}
- //@Override
- //public AnAction replaceAction(String actionId, @NotNull AnAction newAction) {
- // synchronized (myLock) {
- // return replaceAction(actionId, newAction, null);
- // }
- //}
-
private AnAction replaceAction(@NotNull String actionId, @NotNull AnAction newAction, @Nullable PluginId pluginId) {
AnAction oldAction = getActionOrStub(actionId);
if (oldAction != null) {
@@ -1208,8 +1251,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private int myActionsPreloaded = 0;
-
public void preloadActions() {
if (myPreloadActionsRunnable == null) {
myPreloadActionsRunnable = new Runnable() {
@@ -1281,6 +1322,85 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
+ @Override
+ public ActionCallback tryToExecute(@NotNull final AnAction action, @NotNull final InputEvent inputEvent, @Nullable final Component contextComponent, @Nullable final String place,
+ boolean now) {
+
+ final Application app = ApplicationManager.getApplication();
+ assert app.isDispatchThread();
+
+ final ActionCallback result = new ActionCallback();
+ final Runnable doRunnable = new Runnable() {
+ @Override
+ public void run() {
+ tryToExecuteNow(action, inputEvent, contextComponent, place, result);
+ }
+ };
+
+ if (now) {
+ doRunnable.run();
+ } else {
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(doRunnable);
+ }
+
+ return result;
+ }
+
+ private void tryToExecuteNow(final AnAction action, final InputEvent inputEvent, final Component contextComponent, final String place, final ActionCallback result) {
+ final Presentation presentation = action.getTemplatePresentation().clone();
+
+ IdeFocusManager.findInstanceByContext(getContextBy(contextComponent)).doWhenFocusSettlesDown(new Runnable() {
+ @Override
+ public void run() {
+ final DataContext context = getContextBy(contextComponent);
+
+ AnActionEvent event = new AnActionEvent(
+ inputEvent, context,
+ place != null ? place : ActionPlaces.UNKNOWN,
+ presentation, ActionManagerImpl.this,
+ inputEvent.getModifiersEx()
+ );
+
+ ActionUtil.performDumbAwareUpdate(action, event, false);
+ if (!event.getPresentation().isEnabled()) {
+ result.setRejected();
+ return;
+ }
+
+ ActionUtil.lastUpdateAndCheckDumb(action, event, false);
+ if (!event.getPresentation().isEnabled()) {
+ result.setRejected();
+ return;
+ }
+
+ Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
+ if (component != null && !component.isShowing()) {
+ result.setRejected();
+ return;
+ }
+
+ fireBeforeActionPerformed(action, context, event);
+
+ UIUtil.addAwtListener(new AWTEventListener() {
+ @Override
+ public void eventDispatched(AWTEvent event) {
+ if (event.getID() == WindowEvent.WINDOW_OPENED ||event.getID() == WindowEvent.WINDOW_ACTIVATED) {
+ if (!result.isProcessed()) {
+ final WindowEvent we = (WindowEvent)event;
+ IdeFocusManager.findInstanceByComponent(we.getWindow()).doWhenFocusSettlesDown(result.createSetDoneRunnable());
+ }
+ }
+ }
+ }, AWTEvent.WINDOW_EVENT_MASK, result);
+
+ ActionUtil.performActionDumbAware(action, event);
+ result.setDone();
+ queueActionPerformedEvent(action, context, event);
+ }
+ });
+ }
+
private class MyTimer extends Timer implements ActionListener {
private final List<TimerListener> myTimerListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final List<TimerListener> myTransparentTimerListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -1371,88 +1491,4 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
}
-
- @Override
- public ActionCallback tryToExecute(@NotNull final AnAction action, @NotNull final InputEvent inputEvent, @Nullable final Component contextComponent, @Nullable final String place,
- boolean now) {
-
- final Application app = ApplicationManager.getApplication();
- assert app.isDispatchThread();
-
- final ActionCallback result = new ActionCallback();
- final Runnable doRunnable = new Runnable() {
- @Override
- public void run() {
- tryToExecuteNow(action, inputEvent, contextComponent, place, result);
- }
- };
-
- if (now) {
- doRunnable.run();
- } else {
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(doRunnable);
- }
-
- return result;
- }
-
- private void tryToExecuteNow(final AnAction action, final InputEvent inputEvent, final Component contextComponent, final String place, final ActionCallback result) {
- final Presentation presentation = action.getTemplatePresentation().clone();
-
- IdeFocusManager.findInstanceByContext(getContextBy(contextComponent)).doWhenFocusSettlesDown(new Runnable() {
- @Override
- public void run() {
- final DataContext context = getContextBy(contextComponent);
-
- AnActionEvent event = new AnActionEvent(
- inputEvent, context,
- place != null ? place : ActionPlaces.UNKNOWN,
- presentation, ActionManagerImpl.this,
- inputEvent.getModifiersEx()
- );
-
- ActionUtil.performDumbAwareUpdate(action, event, false);
- if (!event.getPresentation().isEnabled()) {
- result.setRejected();
- return;
- }
-
- ActionUtil.lastUpdateAndCheckDumb(action, event, false);
- if (!event.getPresentation().isEnabled()) {
- result.setRejected();
- return;
- }
-
- Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
- if (component != null && !component.isShowing()) {
- result.setRejected();
- return;
- }
-
- fireBeforeActionPerformed(action, context, event);
-
- UIUtil.addAwtListener(new AWTEventListener() {
- @Override
- public void eventDispatched(AWTEvent event) {
- if (event.getID() == WindowEvent.WINDOW_OPENED ||event.getID() == WindowEvent.WINDOW_ACTIVATED) {
- if (!result.isProcessed()) {
- final WindowEvent we = (WindowEvent)event;
- IdeFocusManager.findInstanceByComponent(we.getWindow()).doWhenFocusSettlesDown(result.createSetDoneRunnable());
- }
- }
- }
- }, AWTEvent.WINDOW_EVENT_MASK, result);
-
- ActionUtil.performActionDumbAware(action, event);
- result.setDone();
- queueActionPerformedEvent(action, context, event);
- }
- });
- }
-
- private static DataContext getContextBy(Component contextComponent) {
- final DataManager dataManager = DataManager.getInstance();
- return contextComponent != null ? dataManager.getDataContext(contextComponent) : dataManager.getDataContext();
- }
}