blob: d8aeb0be095101629c63ca46ef49748ad6db4559 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.menus;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.CommandEvent;
import org.eclipse.core.commands.ICommandListener;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.State;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.Scheme;
import org.eclipse.jface.bindings.keys.IKeyLookup;
import org.eclipse.jface.bindings.keys.KeyBinding;
import org.eclipse.jface.bindings.keys.KeyLookupFactory;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.commands.RadioState;
import org.eclipse.jface.commands.ToggleState;
import org.eclipse.jface.contexts.IContextIds;
import org.eclipse.jface.menus.IMenuStateIds;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.SelectionEnabler;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.ActionExpression;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.expressions.LegacyActionExpressionWrapper;
import org.eclipse.ui.internal.expressions.LegacyActionSetExpression;
import org.eclipse.ui.internal.expressions.LegacyEditorContributionExpression;
import org.eclipse.ui.internal.expressions.LegacySelectionEnablerWrapper;
import org.eclipse.ui.internal.expressions.LegacyViewContributionExpression;
import org.eclipse.ui.internal.expressions.LegacyViewerContributionExpression;
import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
import org.eclipse.ui.internal.keys.BindingService;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.services.RegistryPersistence;
import org.eclipse.ui.keys.IBindingService;
/**
* <p>
* A static class for reading actions from the registry. Actions were the
* mechanism in 3.1 and earlier for contributing to menus and tool bars in the
* Eclipse workbench. They have since been replaced with commands.
* </p>
* <p>
* This class is not intended for use outside of the
* <code>org.eclipse.ui.workbench</code> plug-in.
* </p>
*
* @since 3.2
*/
public final class LegacyActionPersistence extends RegistryPersistence {
/**
* The index of the action set elements in the indexed array.
*
* @see LegacyActionPersistence#read()
*/
private static final int INDEX_ACTION_SETS = 0;
/**
* The index of the editor contribution elements in the indexed array.
*
* @see LegacyActionPersistence#read()
*/
private static final int INDEX_EDITOR_CONTRIBUTIONS = 1;
/**
* The index of the object contribution elements in the indexed array.
*
* @see LegacyActionPersistence#read()
*/
private static final int INDEX_OBJECT_CONTRIBUTIONS = 2;
/**
* The index of the view contribution elements in the indexed array.
*
* @see LegacyActionPersistence#read()
*/
private static final int INDEX_VIEW_CONTRIBUTIONS = 3;
/**
* The index of the viewer contribution elements in the indexed array.
*
* @see LegacyActionPersistence#read()
*/
private static final int INDEX_VIEWER_CONTRIBUTIONS = 4;
/**
* Reads the visibility element for a contribution from the
* <code>org.eclipse.ui.popupMenus</code> extension point.
*
* @param parentElement
* The contribution element which contains a visibility
* expression; must not be <code>null</code>.
* @param parentId
* The identifier of the parent contribution; may be
* <code>null</code>.
* @param warningsToLog
* The list of warnings to be logged; must not be
* <code>null</code>.
* @return An expression representing the visibility element; may be
* <code>null</code>.
*/
private static final Expression readVisibility(
final IConfigurationElement parentElement, final String parentId,
final List warningsToLog) {
final IConfigurationElement[] visibilityElements = parentElement
.getChildren(TAG_VISIBILITY);
if ((visibilityElements == null) || (visibilityElements.length == 0)) {
return null;
}
if (visibilityElements.length != 1) {
addWarning(warningsToLog,
"There can only be one visibility element", parentElement, //$NON-NLS-1$
parentId);
}
final IConfigurationElement visibilityElement = visibilityElements[0];
final ActionExpression visibilityActionExpression = new ActionExpression(
visibilityElement);
final LegacyActionExpressionWrapper wrapper = new LegacyActionExpressionWrapper(
visibilityActionExpression, null);
return wrapper;
}
/**
* The binding manager which should be populated with bindings from actions;
* must not be <code>null</code>.
*/
private final BindingService bindingService;
/**
* The command service which is providing the commands for the workbench;
* must not be <code>null</code>.
*/
private final ICommandService commandService;
/**
* The handler activations that have come from the registry. This is used to
* flush the activations when the registry is re-read. This value is never
* <code>null</code>
*/
private final Collection handlerActivations = new ArrayList();
/**
* The menu contributions that have come from the registry. This is used to
* flush the contributions when the registry is re-read. This value is never
* <code>null</code>
*/
private final Collection menuContributions = new ArrayList();
/**
* The service locator from which services can be retrieved in the future;
* must not be <code>null</code>.
*/
private final IWorkbenchWindow window;
/**
* Help action sets with enable/disable.
*/
private ICommandListener actionSetListener = new ICommandListener() {
public void commandChanged(CommandEvent commandEvent) {
Command cmd = commandEvent.getCommand();
String commandId = cmd.getId();
Binding binding = (Binding) commandIdToBinding.get(commandId);
if (binding != null) {
if (cmd.isEnabled()) {
if (!actionSetActiveBindings.contains(binding)) {
bindingService.addBinding(binding);
actionSetActiveBindings.add(binding);
}
} else if (actionSetActiveBindings.contains(binding)) {
bindingService.removeBinding(binding);
actionSetActiveBindings.remove(binding);
}
}
}
};
/**
* Map every commandId to its binding.
*/
private HashMap commandIdToBinding = new HashMap();
/**
* Which bindings do we currently have outstanding.
*/
private HashSet actionSetActiveBindings = new HashSet();
/**
* Constructs a new instance of {@link LegacyActionPersistence}.
*
* @param window
* The window from which the services should be retrieved; must
* not be <code>null</code>.
*/
public LegacyActionPersistence(final IWorkbenchWindow window) {
// TODO Blind casts are bad.
this.bindingService = (BindingService) window
.getService(IBindingService.class);
this.commandService = (ICommandService) window
.getService(ICommandService.class);
this.window = window;
}
/**
* Deactivates all of the activations made by this class, and then clears
* the collection. This should be called before every read.
*/
private final void clearActivations() {
final IHandlerService service = (IHandlerService) window
.getService(IHandlerService.class);
service.deactivateHandlers(handlerActivations);
final Iterator activationItr = handlerActivations.iterator();
while (activationItr.hasNext()) {
final IHandlerActivation activation = (IHandlerActivation) activationItr
.next();
final IHandler handler = activation.getHandler();
if (handler != null) {
handler.dispose();
}
}
handlerActivations.clear();
}
/**
* Removes all of the bindings made by this class, and then clears the
* collection. This should be called before every read.
*/
private final void clearBindings() {
Iterator i = commandIdToBinding.entrySet().iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry) i.next();
String commandId = (String) entry.getKey();
Binding binding = (Binding) entry.getValue();
commandService.getCommand(commandId).removeCommandListener(actionSetListener);
if (binding!=null && actionSetActiveBindings.contains(binding)) {
bindingService.removeBinding(binding);
}
}
commandIdToBinding.clear();
actionSetActiveBindings.clear();
}
/**
* Removes all of the image bindings made by this class, and then clears the
* collection. This should be called before every read.
*
*/
private final void clearImages() {
// TODO Implement
}
/**
* Removes all of the contributions made by this class, and then clears the
* collection. This should be called before every read.
*/
private final void clearMenus() {
menuContributions.clear();
}
/**
* Extracts any key bindings from the action. If such a binding exists, it
* is added to the binding manager.
*
* @param element
* The action from which the binding should be read; must not be
* <code>null</code>.
* @param command
* The fully-parameterized command for which a binding should be
* made; must not be <code>null</code>.
*/
private final void convertActionToBinding(
final IConfigurationElement element,
final ParameterizedCommand command, final List warningsToLog) {
// Figure out which accelerator text to use.
String acceleratorText = readOptional(element, ATT_ACCELERATOR);
if (acceleratorText == null) {
final String label = readOptional(element, ATT_LABEL);
if (label != null) {
acceleratorText = LegacyActionTools
.extractAcceleratorText(label);
}
}
// If there is some accelerator text, generate a key sequence from it.
if (acceleratorText != null) {
final IKeyLookup lookup = KeyLookupFactory.getSWTKeyLookup();
final int acceleratorInt = LegacyActionTools
.convertAccelerator(acceleratorText);
final int modifierMask = lookup.getAlt() | lookup.getCommand()
| lookup.getCtrl() | lookup.getShift();
final int modifierKeys = acceleratorInt & modifierMask;
final int naturalKey = acceleratorInt & ~modifierMask;
final KeyStroke keyStroke = KeyStroke.getInstance(modifierKeys,
naturalKey);
final KeySequence keySequence = KeySequence.getInstance(keyStroke);
final Scheme activeScheme = bindingService.getActiveScheme();
try {
final Binding binding = new KeyBinding(keySequence, command,
activeScheme.getId(), IContextIds.CONTEXT_ID_WINDOW,
null, null, null, Binding.SYSTEM);
commandIdToBinding.put(command.getCommand().getId(), binding);
if (command.getCommand().isEnabled()) {
bindingService.addBinding(binding);
actionSetActiveBindings.add(binding);
}
command.getCommand().addCommandListener(actionSetListener);
} catch (IllegalArgumentException e) {
addWarning(warningsToLog,
"invalid keybinding: " + e.getMessage(), element, //$NON-NLS-1$
command.getCommand().getId());
}
}
}
/**
* Determine which command to use. This is slightly complicated as actions
* do not have to have commands, but the new architecture requires it. As
* such, we will auto-generate a command for the action if the definitionId
* is missing or points to a command that does not yet exist. All such
* command identifiers are prefixed with AUTOGENERATED_COMMAND_ID_PREFIX.
*
* @param element
* The action element from which a command must be generated;
* must not be <code>null</code>.
* @param primaryId
* The primary identifier to use when auto-generating a command;
* must not be <code>null</code>.
* @param secondaryId
* The secondary identifier to use when auto-generating a
* command; must not be <code>null</code>.
* @param warningsToLog
* The collection of warnings logged while reading the extension
* point; must not be <code>null</code>.
* @return the fully-parameterized command; <code>null</code> if an error
* occurred.
*/
private final ParameterizedCommand convertActionToCommand(
final IConfigurationElement element, final String primaryId,
final String secondaryId, final List warningsToLog) {
String commandId = readOptional(element, ATT_DEFINITION_ID);
Command command = null;
if (commandId != null) {
command = commandService.getCommand(commandId);
}
final IActionCommandMappingService mappingService = (IActionCommandMappingService) window
.getService(IActionCommandMappingService.class);
String label = null;
if ((commandId == null) || (!command.isDefined())) {
// Add a mapping from this action id to the command id.
if (commandId == null && mappingService != null) {
commandId = mappingService.getGeneratedCommandId(primaryId,
secondaryId);
}
if (commandId == null) {
WorkbenchPlugin.log("MappingService unavailable"); //$NON-NLS-1$
return null;
}
// Read the label attribute.
label = readRequired(element, ATT_LABEL, warningsToLog,
"Actions require a non-empty label or definitionId", //$NON-NLS-1$
commandId);
if (label == null) {
label = WorkbenchMessages.LegacyActionPersistence_AutogeneratedCommandName;
}
/*
* Read the tooltip attribute. The tooltip is really the description
* of the command.
*/
final String tooltip = readOptional(element, ATT_TOOLTIP);
// Define the command.
command = commandService.getCommand(commandId);
final Category category = commandService.getCategory(null);
final String name = LegacyActionTools.removeAcceleratorText(Action
.removeMnemonics(label));
command.define(name, tooltip, category, null);
// TODO Decide the command state.
final String style = readOptional(element, ATT_STYLE);
if (STYLE_RADIO.equals(style)) {
final State state = new RadioState();
// TODO How to set the id?
final boolean checked = readBoolean(element, ATT_STATE, false);
state.setValue((checked) ? Boolean.TRUE : Boolean.FALSE);
command.addState(IMenuStateIds.STYLE, state);
} else if (STYLE_TOGGLE.equals(style)) {
final State state = new ToggleState();
final boolean checked = readBoolean(element, ATT_STATE, false);
state.setValue((checked) ? Boolean.TRUE : Boolean.FALSE);
command.addState(IMenuStateIds.STYLE, state);
}
}
// this allows us to look up a "commandId" give the contributionId
// and the actionId
if (mappingService != null && commandId != null) {
mappingService.map(mappingService.getGeneratedCommandId(primaryId,
secondaryId), commandId);
}
return new ParameterizedCommand(command, null);
}
/**
* <p>
* Extracts the handler information from the given action element. These are
* registered with the handler service. They are always active.
* </p>
*
* @param element
* The action element from which the handler should be read; must
* not be <code>null</code>.
* @param actionId
* The identifier of the action for which a handler is being
* created; must not be <code>null</code>.
* @param command
* The command for which this handler applies; must not be
* <code>null</code>.
* @param activeWhenExpression
* The expression controlling when the handler is active; may be
* <code>null</code>.
* @param viewId
* The view to which this handler is associated. This value is
* required if this is a view action; otherwise it can be
* <code>null</code>.
* @param warningsToLog
* The collection of warnings while parsing this extension point;
* must not be <code>null</code>.
*/
private final void convertActionToHandler(
final IConfigurationElement element, final String actionId,
final ParameterizedCommand command,
final Expression activeWhenExpression, final String viewId,
final List warningsToLog) {
// Check to see if this is a retargettable action.
final boolean retarget = readBoolean(element, ATT_RETARGET, false);
final boolean classAvailable = (element.getAttribute(ATT_CLASS) != null)
|| (element.getChildren(TAG_CLASS).length != 0);
// Read the class attribute.
String classString = readOptional(element, ATT_CLASS);
if (classAvailable && classString == null) {
classString = readOptional(element.getChildren(TAG_CLASS)[0],
ATT_CLASS);
}
if (retarget) {
if (classAvailable && !isPulldown(element)) {
addWarning(warningsToLog,
"The class was not null but retarget was set to true", //$NON-NLS-1$
element, actionId, ATT_CLASS, classString);
}
// Add a mapping from this action id to the command id.
final IActionCommandMappingService mappingService = (IActionCommandMappingService) window
.getService(IActionCommandMappingService.class);
if (mappingService != null) {
mappingService.map(actionId, command.getId());
} else {
// this is probably the shutdown case where the service has
// already disposed.
addWarning(
warningsToLog,
"Retarget service unavailable", //$NON-NLS-1$
element, actionId);
}
return; // This is nothing more to be done.
} else if (!classAvailable) {
addWarning(
warningsToLog,
"There was no class provided, and the action is not retargettable", //$NON-NLS-1$
element, actionId);
return; // There is nothing to be done.
}
// Read the enablesFor attribute, and enablement and selection elements.
SelectionEnabler enabler = null;
if (element.getAttribute(ATT_ENABLES_FOR) != null) {
enabler = new SelectionEnabler(element);
} else {
IConfigurationElement[] kids = element.getChildren(TAG_ENABLEMENT);
if (kids.length > 0) {
enabler = new SelectionEnabler(element);
}
}
final Expression enabledWhenExpression;
if (enabler == null) {
enabledWhenExpression = null;
} else {
enabledWhenExpression = new LegacySelectionEnablerWrapper(enabler,
window);
}
/*
* Create the handler. TODO The image style is read at the workbench
* level, but it is hard to communicate this information to this point.
* For now, I'll pass null, but this ultimately won't work.
*/
final ActionDelegateHandlerProxy handler = new ActionDelegateHandlerProxy(
element, ATT_CLASS, actionId, command, window, null,
enabledWhenExpression, viewId);
// Read the help context id.
final String helpContextId = readOptional(element, ATT_HELP_CONTEXT_ID);
if (helpContextId != null) {
commandService.setHelpContextId(handler, helpContextId);
}
// Activate the handler.
final String commandId = command.getId();
final IHandlerService service = (IHandlerService) window
.getService(IHandlerService.class);
final IHandlerActivation handlerActivation;
if (activeWhenExpression == null) {
handlerActivation = service.activateHandler(commandId, handler);
} else {
handlerActivation = service.activateHandler(commandId, handler,
activeWhenExpression);
}
handlerActivations.add(handlerActivation);
}
public final void dispose() {
super.dispose();
clear();
}
private void clear() {
clearActivations();
clearBindings();
clearImages();
clearMenus();
}
protected final boolean isChangeImportant(final IRegistryChangeEvent event) {
return !((event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_ACTION_SETS).length == 0)
&& (event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_EDITOR_ACTIONS).length == 0)
&& (event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_POPUP_MENU).length == 0) && (event
.getExtensionDeltas(PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_VIEW_ACTIONS).length == 0));
}
/**
* <p>
* Reads all of the actions from the deprecated extension points. Actions
* have been replaced with commands, command images, handlers, menu elements
* and action sets.
* </p>
* <p>
* TODO Before this method is called, all of the extension points must be
* cleared.
* </p>
*/
public final void read() {
clear();
LegacyActionPersistence.super.read();
// Create the extension registry mementos.
final IExtensionRegistry registry = Platform.getExtensionRegistry();
int actionSetCount = 0;
int editorContributionCount = 0;
int objectContributionCount = 0;
int viewContributionCount = 0;
int viewerContributionCount = 0;
final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];
// Sort the actionSets extension point.
final IConfigurationElement[] actionSetsExtensionPoint = registry
.getConfigurationElementsFor(EXTENSION_ACTION_SETS);
for (int i = 0; i < actionSetsExtensionPoint.length; i++) {
final IConfigurationElement element = actionSetsExtensionPoint[i];
final String name = element.getName();
if (TAG_ACTION_SET.equals(name)) {
addElementToIndexedArray(element, indexedConfigurationElements,
INDEX_ACTION_SETS, actionSetCount++);
}
}
// Sort the editorActions extension point.
final IConfigurationElement[] editorActionsExtensionPoint = registry
.getConfigurationElementsFor(EXTENSION_EDITOR_ACTIONS);
for (int i = 0; i < editorActionsExtensionPoint.length; i++) {
final IConfigurationElement element = editorActionsExtensionPoint[i];
final String name = element.getName();
if (TAG_EDITOR_CONTRIBUTION.equals(name)) {
addElementToIndexedArray(element, indexedConfigurationElements,
INDEX_EDITOR_CONTRIBUTIONS, editorContributionCount++);
}
}
// Sort the popupMenus extension point.
final IConfigurationElement[] popupMenusExtensionPoint = registry
.getConfigurationElementsFor(EXTENSION_POPUP_MENUS);
for (int i = 0; i < popupMenusExtensionPoint.length; i++) {
final IConfigurationElement element = popupMenusExtensionPoint[i];
final String name = element.getName();
if (TAG_OBJECT_CONTRIBUTION.equals(name)) {
addElementToIndexedArray(element, indexedConfigurationElements,
INDEX_OBJECT_CONTRIBUTIONS, objectContributionCount++);
} else if (TAG_VIEWER_CONTRIBUTION.equals(name)) {
addElementToIndexedArray(element, indexedConfigurationElements,
INDEX_VIEWER_CONTRIBUTIONS, viewerContributionCount++);
}
}
// Sort the viewActions extension point.
final IConfigurationElement[] viewActionsExtensionPoint = registry
.getConfigurationElementsFor(EXTENSION_VIEW_ACTIONS);
for (int i = 0; i < viewActionsExtensionPoint.length; i++) {
final IConfigurationElement element = viewActionsExtensionPoint[i];
final String name = element.getName();
if (TAG_VIEW_CONTRIBUTION.equals(name)) {
addElementToIndexedArray(element, indexedConfigurationElements,
INDEX_VIEW_CONTRIBUTIONS, viewContributionCount++);
}
}
readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],
actionSetCount);
readEditorContributions(
indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],
editorContributionCount);
readObjectContributions(
indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],
objectContributionCount);
readViewContributions(
indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],
viewContributionCount);
readViewerContributions(
indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],
viewerContributionCount);
}
/**
* Reads the actions, and defines all the necessary subcomponents in terms
* of the command architecture. For each action, there could be a command, a
* command image binding, a handler and a menu item.
*
* @param primaryId
* The identifier of the primary object to which this action
* belongs. This is used to auto-generate command identifiers
* when required. The <code>primaryId</code> must not be
* <code>null</code>.
* @param elements
* The action elements to be read; must not be <code>null</code>.
* @param warningsToLog
* The collection of warnings while parsing this extension point;
* must not be <code>null</code>.
* @param visibleWhenExpression
* The expression controlling visibility of the corresponding
* menu elements; may be <code>null</code>.
* @param viewId
* The view to which this handler is associated. This value is
* required if this is a view action; otherwise it can be
* <code>null</code>.
* @return References to the created menu elements; may be <code>null</code>,
* and may be empty.
*/
private final void readActions(final String primaryId,
final IConfigurationElement[] elements, final List warningsToLog,
final Expression visibleWhenExpression, final String viewId) {
for (int i = 0; i < elements.length; i++) {
final IConfigurationElement element = elements[i];
/*
* We might need the identifier to generate the command, so we'll
* read it out now.
*/
final String id = readRequired(element, ATT_ID, warningsToLog,
"Actions require an id"); //$NON-NLS-1$
if (id == null) {
continue;
}
// Try to break out the command part of the action.
final ParameterizedCommand command = convertActionToCommand(
element, primaryId, id, warningsToLog);
if (command == null) {
continue;
}
convertActionToHandler(element, id, command, visibleWhenExpression,
viewId, warningsToLog);
// TODO Read the overrideActionId attribute
convertActionToBinding(element, command, warningsToLog);
}
}
/**
* Reads all of the action and menu child elements from the given element.
*
* @param element
* The configuration element from which the actions and menus
* should be read; must not be <code>null</code>, but may be
* empty.
* @param id
* The identifier of the contribution being made. This could be
* an action set, an editor contribution, a view contribution, a
* viewer contribution or an object contribution. This value must
* not be <code>null</code>.
* @param warningsToLog
* The list of warnings already logged for this extension point;
* must not be <code>null</code>.
* @param visibleWhenExpression
* The expression controlling visibility of the corresponding
* menu elements; may be <code>null</code>.
* @param viewId
* The view to which this handler is associated. This value is
* required if this is a view action; otherwise it can be
* <code>null</code>.
* @return An array of references to the created menu elements. This value
* may be <code>null</code> if there was a problem parsing the
* configuration element.
*/
private final void readActionsAndMenus(
final IConfigurationElement element, final String id,
final List warningsToLog,
final Expression visibleWhenExpression, final String viewId) {
// Read its child elements.
final IConfigurationElement[] actionElements = element
.getChildren(TAG_ACTION);
readActions(id, actionElements,
warningsToLog, visibleWhenExpression, viewId);
}
/**
* Reads the deprecated actions from an array of elements from the action
* sets extension point.
*
* @param configurationElements
* The configuration elements in the extension point; must not be
* <code>null</code>, but may be empty.
* @param configurationElementCount
* The number of configuration elements that are really in the
* array.
*/
private final void readActionSets(
final IConfigurationElement[] configurationElements,
final int configurationElementCount) {
//
// this was an even dumber fix than modifying the path
//
// stupid navigate group
// SGroup nav = menuService.getGroup(STUPID_NAVIGATE);
// if (!nav.isDefined()) {
// nav.define(new SLocation(new SBar(SBar.TYPE_MENU, null)));
// }
// stupid navigate group
final List warningsToLog = new ArrayList(1);
for (int i = 0; i < configurationElementCount; i++) {
final IConfigurationElement element = configurationElements[i];
// Read the action set identifier.
final String id = readRequired(element, ATT_ID, warningsToLog,
"Action sets need an id"); //$NON-NLS-1$
if (id == null) {
continue;
}
// Read the label.
final String label = readRequired(element, ATT_LABEL,
warningsToLog, "Actions set need a label", //$NON-NLS-1$
id);
if (label == null) {
continue;
}
// Restrict the handler to when the action set is active.
final LegacyActionSetExpression expression = new LegacyActionSetExpression(
id, window);
// Read all of the child elements.
readActionsAndMenus(element, id,
warningsToLog, expression, null);
// Define the action set.
}
logWarnings(
warningsToLog,
"Warnings while parsing the action sets from the 'org.eclipse.ui.actionSets' extension point"); //$NON-NLS-1$
}
/**
* Reads the deprecated editor contributions from an array of elements from
* the editor actions extension point.
*
* @param configurationElements
* The configuration elements in the extension point; must not be
* <code>null</code>, but may be empty.
* @param configurationElementCount
* The number of configuration elements that are really in the
* array.
*/
private final void readEditorContributions(
final IConfigurationElement[] configurationElements,
final int configurationElementCount) {
final List warningsToLog = new ArrayList(1);
for (int i = 0; i < configurationElementCount; i++) {
final IConfigurationElement element = configurationElements[i];
// Read the editor contribution identifier.
final String id = readRequired(element, ATT_ID, warningsToLog,
"Editor contributions need an id"); //$NON-NLS-1$
if (id == null) {
continue;
}
/*
* Read the target id. This is the identifier of the editor with
* which these contributions are associated.
*/
final String targetId = readRequired(element, ATT_TARGET_ID,
warningsToLog, "Editor contributions need a target id", id); //$NON-NLS-1$
if (targetId == null) {
continue;
}
final Expression visibleWhenExpression = new LegacyEditorContributionExpression(
targetId, window);
// Read all of the child elements from the registry.
readActionsAndMenus(element, id, warningsToLog,
visibleWhenExpression, null);
}
logWarnings(
warningsToLog,
"Warnings while parsing the editor contributions from the 'org.eclipse.ui.editorActions' extension point"); //$NON-NLS-1$
}
/**
* Reads the deprecated object contributions from an array of elements from
* the popup menus extension point.
*
* @param configurationElements
* The configuration elements in the extension point; must not be
* <code>null</code>, but may be empty.
* @param configurationElementCount
* The number of configuration elements that are really in the
* array.
*/
private final void readObjectContributions(
final IConfigurationElement[] configurationElements,
final int configurationElementCount) {
final List warningsToLog = new ArrayList(1);
for (int i = 0; i < configurationElementCount; i++) {
final IConfigurationElement element = configurationElements[i];
// Read the object contribution identifier.
final String id = readRequired(element, ATT_ID, warningsToLog,
"Object contributions need an id"); //$NON-NLS-1$
if (id == null) {
continue;
}
// Read the object class. This influences the visibility.
final String objectClass = readRequired(element, ATT_OBJECTCLASS,
warningsToLog,
"Object contributions need an object class", id); //$NON-NLS-1$
if (objectClass == null) {
continue;
}
// TODO Read the name filter. This influences the visibility.
// final String nameFilter = readOptional(element,
// ATT_NAME_FILTER);
// TODO Read the object class. This influences the visibility.
// final boolean adaptable = readBoolean(element,
// ATT_ADAPTABLE,
// false);
// TODO Read the filter elements.
// TODO Read the enablement elements.
// TODO Figure out an appropriate visibility expression.
// Read the visibility element, if any.
final Expression visibleWhenExpression = readVisibility(element,
id, warningsToLog);
// Read all of the child elements from the registry.
readActionsAndMenus(element, id, warningsToLog,
visibleWhenExpression, null);
}
logWarnings(
warningsToLog,
"Warnings while parsing the object contributions from the 'org.eclipse.ui.popupMenus' extension point"); //$NON-NLS-1$
}
/**
* Reads the deprecated view contributions from an array of elements from
* the view actions extension point.
*
* @param configurationElements
* The configuration elements in the extension point; must not be
* <code>null</code>, but may be empty.
* @param configurationElementCount
* The number of configuration elements that are really in the
* array.
*/
private final void readViewContributions(
final IConfigurationElement[] configurationElements,
final int configurationElementCount) {
final List warningsToLog = new ArrayList(1);
for (int i = 0; i < configurationElementCount; i++) {
final IConfigurationElement element = configurationElements[i];
// Read the view contribution identifier.
final String id = readRequired(element, ATT_ID, warningsToLog,
"View contributions need an id"); //$NON-NLS-1$
if (id == null) {
continue;
}
/*
* Read the target id. This is the identifier of the view with which
* these contributions are associated.
*/
final String targetId = readRequired(element, ATT_TARGET_ID,
warningsToLog, "View contributions need a target id", id); //$NON-NLS-1$
if (targetId == null) {
continue;
}
final Expression visibleWhenExpression = new LegacyViewContributionExpression(
targetId, window);
// Read all of the child elements from the registry.
readActionsAndMenus(element, id, warningsToLog,
visibleWhenExpression, targetId);
}
logWarnings(
warningsToLog,
"Warnings while parsing the view contributions from the 'org.eclipse.ui.viewActions' extension point"); //$NON-NLS-1$
}
/**
* Reads the deprecated viewer contributions from an array of elements from
* the popup menus extension point.
*
* @param configurationElements
* The configuration elements in the extension point; must not be
* <code>null</code>, but may be empty.
* @param configurationElementCount
* The number of configuration elements that are really in the
* array.
*/
private final void readViewerContributions(
final IConfigurationElement[] configurationElements,
final int configurationElementCount) {
final List warningsToLog = new ArrayList(1);
for (int i = 0; i < configurationElementCount; i++) {
final IConfigurationElement element = configurationElements[i];
// Read the viewer contribution identifier.
final String id = readRequired(element, ATT_ID, warningsToLog,
"Viewer contributions need an id"); //$NON-NLS-1$
if (id == null) {
continue;
}
/*
* Read the target id. This is the identifier of the view with which
* these contributions are associated.
*/
final String targetId = readRequired(element, ATT_TARGET_ID,
warningsToLog, "Viewer contributions need a target id", id); //$NON-NLS-1$
if (targetId == null) {
continue;
}
// Read the visibility element, if any.
final Expression visibleWhenExpression = readVisibility(element,
id, warningsToLog);
final Expression menuVisibleWhenExpression = new LegacyViewerContributionExpression(
targetId, window, visibleWhenExpression);
// Read all of the child elements from the registry.
readActionsAndMenus(element, id, warningsToLog,
menuVisibleWhenExpression, targetId);
}
logWarnings(
warningsToLog,
"Warnings while parsing the viewer contributions from the 'org.eclipse.ui.popupMenus' extension point"); //$NON-NLS-1$
}
}