mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ActionManager: <action/> and <group/> "overrides" attribute
This commit is contained in:
+26
-3
@@ -85,15 +85,15 @@ public class DefaultActionGroup extends ActionGroup {
|
||||
* @param actionManager ActionManager instance
|
||||
*/
|
||||
public final void add(@NotNull AnAction action, @NotNull ActionManager actionManager) {
|
||||
add(action, new Constraints(Anchor.LAST, null), actionManager);
|
||||
add(action, Constraints.LAST, actionManager);
|
||||
}
|
||||
|
||||
public final void add(@NotNull AnAction action) {
|
||||
addAction(action, new Constraints(Anchor.LAST, null));
|
||||
addAction(action, Constraints.LAST);
|
||||
}
|
||||
|
||||
public final ActionInGroup addAction(@NotNull AnAction action) {
|
||||
return addAction(action, new Constraints(Anchor.LAST, null));
|
||||
return addAction(action, Constraints.LAST);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,6 +236,29 @@ public class DefaultActionGroup extends ActionGroup {
|
||||
myPairs.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces specified action with the new one.
|
||||
*/
|
||||
public boolean replaceAction(AnAction oldAction, AnAction newAction) {
|
||||
int index = mySortedChildren.indexOf(oldAction);
|
||||
if (index >= 0) {
|
||||
mySortedChildren.set(index, newAction);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < myPairs.size(); i++) {
|
||||
Pair<AnAction, Constraints> pair = myPairs.get(i);
|
||||
if (pair.first.equals(newAction)) {
|
||||
myPairs.set(i, Pair.create(newAction, pair.second));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns group's children in the order determined by constraints.
|
||||
*
|
||||
|
||||
@@ -111,4 +111,11 @@ public class EmptyAction extends AnAction {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class Group extends DefaultActionGroup {
|
||||
public Group() {
|
||||
super();
|
||||
getTemplatePresentation().setEnabledAndVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-22
@@ -67,45 +67,24 @@ public abstract class ActionManagerEx extends ActionManager {
|
||||
*
|
||||
* @return null if string cannot be parsed.
|
||||
*/
|
||||
|
||||
@Nullable
|
||||
|
||||
public static KeyStroke getKeyStroke(String s) {
|
||||
|
||||
KeyStroke result = null;
|
||||
|
||||
try {
|
||||
|
||||
result = KeyStroke.getKeyStroke(s);
|
||||
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
||||
//ok
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (result == null && s != null && s.length() >= 2 && s.charAt(s.length() - 2) == ' ') {
|
||||
|
||||
try {
|
||||
|
||||
String s1 = s.substring(0, s.length() - 1) + Character.toUpperCase(s.charAt(s.length() - 1));
|
||||
|
||||
result = KeyStroke.getKeyStroke(s1);
|
||||
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
||||
// ok
|
||||
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+64
-14
@@ -22,6 +22,7 @@ import com.intellij.ide.ActivityTracker;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.idea.IdeaLogger;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
@@ -47,7 +48,9 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -78,6 +81,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
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;
|
||||
|
||||
@@ -88,6 +92,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
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";
|
||||
@@ -123,6 +128,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
@NonNls public static final String VALUE_ATTR_NAME = "value";
|
||||
@NonNls public static final String ACTIONS_BUNDLE = "messages.ActionsBundle";
|
||||
@NonNls public static final String USE_SHORTCUT_OF_ATTR_NAME = "use-shortcut-of";
|
||||
@NonNls public static final String OVERRIDES_ATTR_NAME = "overrides";
|
||||
|
||||
private final List<ActionPopupMenuImpl> myPopups = new ArrayList<ActionPopupMenuImpl>();
|
||||
|
||||
@@ -208,9 +214,9 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
|
||||
|
||||
private void registerPluginActions() {
|
||||
final IdeaPluginDescriptor[] plugins = PluginManager.getPlugins();
|
||||
final IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins();
|
||||
for (IdeaPluginDescriptor plugin : plugins) {
|
||||
if (PluginManager.shouldSkipPlugin(plugin)) continue;
|
||||
if (PluginManagerCore.shouldSkipPlugin(plugin)) continue;
|
||||
final List<Element> elementList = plugin.getActionsDescriptionElements();
|
||||
if (elementList != null) {
|
||||
for (Element e : elementList) {
|
||||
@@ -412,11 +418,24 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
((KeymapManagerEx)myKeymapManager).bindShortcuts(element.getAttributeValue(USE_SHORTCUT_OF_ATTR_NAME), id);
|
||||
}
|
||||
|
||||
// register action
|
||||
registerAction(id, stub, pluginId);
|
||||
registerOrReplaceActionInner(element, id, stub, pluginId);
|
||||
return stub;
|
||||
}
|
||||
|
||||
private void registerOrReplaceActionInner(@NotNull Element element, @NotNull String id, @NotNull AnAction action, @Nullable PluginId pluginId) {
|
||||
synchronized (myLock) {
|
||||
if (Boolean.valueOf(element.getAttributeValue(OVERRIDES_ATTR_NAME)).booleanValue()) {
|
||||
if (getActionOrStub(id) == null) {
|
||||
throw new RuntimeException(element.getName() + " '" + id + "' doesn't override anything");
|
||||
}
|
||||
replaceAction(id, action, pluginId);
|
||||
}
|
||||
else {
|
||||
registerAction(id, action, pluginId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void processAbbreviationNode(Element e, String id) {
|
||||
final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
|
||||
if (!StringUtil.isEmpty(abbr)) {
|
||||
@@ -427,7 +446,8 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
|
||||
@Nullable
|
||||
private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
|
||||
@NonNls final String resBundleName = plugin != null && !plugin.getPluginId().getIdString().equals("com.intellij") ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
|
||||
@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);
|
||||
@@ -560,7 +580,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
}
|
||||
|
||||
if (id != null) {
|
||||
registerAction(id, group);
|
||||
registerOrReplaceActionInner(element, id, group, pluginId);
|
||||
}
|
||||
Presentation presentation = group.getTemplatePresentation();
|
||||
|
||||
@@ -593,7 +613,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
AnAction action = processActionElement(child, loader, pluginId);
|
||||
if (action != null) {
|
||||
assertActionIsGroupOrStub(action);
|
||||
((DefaultActionGroup)group).addAction(action, Constraints.LAST, this).setAsSecondary(isSecondary(child));
|
||||
addToGroupInner(group, action, Constraints.LAST, isSecondary(child));
|
||||
}
|
||||
}
|
||||
else if (SEPARATOR_ELEMENT_NAME.equals(name)) {
|
||||
@@ -602,7 +622,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
else if (GROUP_ELEMENT_NAME.equals(name)) {
|
||||
AnAction action = processGroupElement(child, loader, pluginId);
|
||||
if (action != null) {
|
||||
((DefaultActionGroup)group).add(action, this);
|
||||
addToGroupInner(group, action, Constraints.LAST, false);
|
||||
}
|
||||
}
|
||||
else if (ADD_TO_GROUP_ELEMENT_NAME.equals(name)) {
|
||||
@@ -611,7 +631,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
else if (REFERENCE_ELEMENT_NAME.equals(name)) {
|
||||
AnAction action = processReferenceElement(child, pluginId);
|
||||
if (action != null) {
|
||||
((DefaultActionGroup)group).addAction(action, Constraints.LAST, this).setAsSecondary(isSecondary(child));
|
||||
addToGroupInner(group, action, Constraints.LAST, isSecondary(child));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -679,8 +699,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
}
|
||||
|
||||
// anchor attribute
|
||||
final Anchor anchor = parseAnchor(element.getAttributeValue(ANCHOR_ELEMENT_NAME),
|
||||
actionName, pluginId);
|
||||
final Anchor anchor = parseAnchor(element.getAttributeValue(ANCHOR_ELEMENT_NAME), actionName, pluginId);
|
||||
if (anchor == null) {
|
||||
return;
|
||||
}
|
||||
@@ -689,8 +708,12 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
if (!checkRelativeToAction(relativeToActionId, anchor, actionName, pluginId)) {
|
||||
return;
|
||||
}
|
||||
final DefaultActionGroup group = (DefaultActionGroup)parentGroup;
|
||||
group.addAction(action, new Constraints(anchor, relativeToActionId), this).setAsSecondary(secondary);
|
||||
addToGroupInner(parentGroup, action, new Constraints(anchor, relativeToActionId), secondary);
|
||||
}
|
||||
|
||||
private void addToGroupInner(AnAction group, AnAction action, Constraints constraints, boolean secondary) {
|
||||
((DefaultActionGroup)group).addAction(action, constraints, this).setAsSecondary(secondary);
|
||||
myId2GroupId.putValue(myAction2Id.get(action), myAction2Id.get(group));
|
||||
}
|
||||
|
||||
public static boolean checkRelativeToAction(final String relativeToActionId,
|
||||
@@ -916,7 +939,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
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.toString() +
|
||||
reportActionError(pluginId, "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
|
||||
"; Registered action is " +
|
||||
myId2Action.get(actionId) + getPluginInfo(pluginId));
|
||||
return;
|
||||
@@ -1047,6 +1070,33 @@ 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) {
|
||||
boolean isGroup = oldAction instanceof ActionGroup;
|
||||
if (isGroup != newAction instanceof ActionGroup) {
|
||||
throw new IllegalStateException("cannot replace a group with an action and vice versa: " + actionId);
|
||||
}
|
||||
unregisterAction(actionId);
|
||||
if (isGroup) {
|
||||
myId2GroupId.values().remove(actionId);
|
||||
}
|
||||
}
|
||||
registerAction(actionId, newAction, pluginId);
|
||||
for (String groupId : myId2GroupId.get(actionId)) {
|
||||
DefaultActionGroup group = ObjectUtils.assertNotNull((DefaultActionGroup)getActionOrStub(groupId));
|
||||
group.replaceAction(oldAction, newAction);
|
||||
}
|
||||
return oldAction;
|
||||
}
|
||||
|
||||
private void flushActionPerformed() {
|
||||
final Set<AnAction> actions = myQueuedNotifications.keySet();
|
||||
for (final AnAction eachAction : actions) {
|
||||
|
||||
+4
-1
@@ -50,9 +50,12 @@ public class ActionBean {
|
||||
@Attribute(ActionManagerImpl.INTERNAL_ATTR_NAME)
|
||||
public boolean internal;
|
||||
|
||||
@Attribute("use-shortcut-of")
|
||||
@Attribute(ActionManagerImpl.USE_SHORTCUT_OF_ATTR_NAME)
|
||||
public boolean useShortcutOf;
|
||||
|
||||
@Attribute(ActionManagerImpl.KEYMAP_ATTR_NAME)
|
||||
public String keymap;
|
||||
|
||||
@Attribute(ActionManagerImpl.OVERRIDES_ATTR_NAME)
|
||||
public boolean overrides;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,13 @@ public interface Action extends DomElement {
|
||||
@Required
|
||||
GenericAttributeValue<String> getId();
|
||||
|
||||
/**
|
||||
* Returns the value of the overrides child.
|
||||
* Attribute overrides
|
||||
* @return the value of the overrides child.
|
||||
*/
|
||||
@NotNull
|
||||
GenericAttributeValue<Boolean> getOverrides();
|
||||
|
||||
/**
|
||||
* Returns the list of keyboard-shortcut children.
|
||||
|
||||
@@ -87,10 +87,22 @@ public interface Group extends Actions {
|
||||
@NotNull
|
||||
GenericAttributeValue<String> getText();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the id child.
|
||||
* Attribute id
|
||||
* @return the value of the id child.
|
||||
*/
|
||||
@NotNull
|
||||
GenericAttributeValue<String> getId();
|
||||
|
||||
/**
|
||||
* Returns the value of the overrides child.
|
||||
* Attribute overrides
|
||||
* @return the value of the overrides child.
|
||||
*/
|
||||
@NotNull
|
||||
GenericAttributeValue<Boolean> getOverrides();
|
||||
|
||||
/**
|
||||
* Returns the list of reference children.
|
||||
* @return the list of reference children.
|
||||
|
||||
Reference in New Issue
Block a user