blob: f7edd58f13bc3430930ed4cac5284ac3e0eb8c85 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.commands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.IExecutionListener;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.ParameterType;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.SerializationException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.internal.workbench.renderers.swt.IUpdateService;
import org.eclipse.e4.ui.model.application.ui.menu.MItem;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.commands.IElementReference;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.menus.MenuHelper;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.services.IServiceLocator;
/**
* A command service which delegates almost all responsibility to the parent
* service.
* <p>
* This class is not intended for use outside of the
* <code>org.eclipse.ui.workbench</code> plug-in.
* </p>
*
* @since 3.2
*/
public class SlaveCommandService implements ICommandService, IUpdateService {
private Collection fExecutionListeners = new ArrayList();
/**
* The collection of ICallbackReferences added through this service.
*
* @since 3.3
*/
private Set fCallbackCache = new HashSet();
private ICommandService fParentService;
/**
* The scoping constant added to callback registrations submitted through this
* service.
*
* @since 3.3
*/
private String fScopingName;
/**
* The object to scope. In theory, the service locator that would find this
* service.
*
* @since 3.3
*/
private IServiceLocator fScopingValue;
private IEclipseContext fContext;
/**
* Build the slave service.
*
* @param parent the parent service. This must not be <code>null</code>.
*/
public SlaveCommandService(ICommandService parent, String scopeName, IServiceLocator scopeValue) {
this(parent, scopeName, scopeValue, null);
}
public SlaveCommandService(ICommandService parent, String scopeName, IServiceLocator scopeValue,
IEclipseContext context) {
if (parent == null) {
throw new NullPointerException("The parent command service must not be null"); //$NON-NLS-1$
}
fParentService = parent;
fScopingName = scopeName;
fScopingValue = scopeValue;
fContext = context;
}
@Override
public void addExecutionListener(IExecutionListener listener) {
if (!fExecutionListeners.contains(listener)) {
fExecutionListeners.add(listener);
}
fParentService.addExecutionListener(listener);
}
@Override
public void defineUncategorizedCategory(String name, String description) {
fParentService.defineUncategorizedCategory(name, description);
}
@Override
public ParameterizedCommand deserialize(String serializedParameterizedCommand)
throws NotDefinedException, SerializationException {
return fParentService.deserialize(serializedParameterizedCommand);
}
@Override
public void dispose() {
if (!fExecutionListeners.isEmpty()) {
Object[] array = fExecutionListeners.toArray();
for (Object element : array) {
removeExecutionListener((IExecutionListener) element);
}
fExecutionListeners.clear();
}
if (!fCallbackCache.isEmpty()) {
Object[] array = fCallbackCache.toArray();
for (Object element : array) {
unregisterElement((IElementReference) element);
}
}
fScopingValue = null;
fContext = null;
fParentService = null;
}
@Override
public Category getCategory(String categoryId) {
return fParentService.getCategory(categoryId);
}
@Override
public Command getCommand(String commandId) {
return fParentService.getCommand(commandId);
}
@Override
public Category[] getDefinedCategories() {
return fParentService.getDefinedCategories();
}
@Override
public Collection getDefinedCategoryIds() {
return fParentService.getDefinedCategoryIds();
}
@Override
public Collection getDefinedCommandIds() {
return fParentService.getDefinedCommandIds();
}
@Override
public Command[] getDefinedCommands() {
return fParentService.getDefinedCommands();
}
@Override
public Collection getDefinedParameterTypeIds() {
return fParentService.getDefinedParameterTypeIds();
}
@Override
public ParameterType[] getDefinedParameterTypes() {
return fParentService.getDefinedParameterTypes();
}
@Override
public final String getHelpContextId(final Command command) throws NotDefinedException {
return fParentService.getHelpContextId(command);
}
@Override
public final String getHelpContextId(final String commandId) throws NotDefinedException {
return fParentService.getHelpContextId(commandId);
}
@Override
public ParameterType getParameterType(String parameterTypeId) {
return fParentService.getParameterType(parameterTypeId);
}
@Override
public void readRegistry() {
fParentService.readRegistry();
}
@Override
public void removeExecutionListener(IExecutionListener listener) {
fExecutionListeners.remove(listener);
fParentService.removeExecutionListener(listener);
}
@Override
public final void setHelpContextId(final IHandler handler, final String helpContextId) {
fParentService.setHelpContextId(handler, helpContextId);
}
@Override
public void refreshElements(String commandId, Map filter) {
fParentService.refreshElements(commandId, filter);
}
@Override
public IElementReference registerElementForCommand(ParameterizedCommand command, UIElement element)
throws NotDefinedException {
if (!command.getCommand().isDefined()) {
throw new NotDefinedException("Cannot define a callback for undefined command " //$NON-NLS-1$
+ command.getCommand().getId());
}
if (element == null) {
throw new NotDefinedException("No callback defined for command " //$NON-NLS-1$
+ command.getCommand().getId());
}
ElementReference ref = new ElementReference(command.getId(), element, command.getParameterMap());
registerElement(ref);
return ref;
}
@Override
public void registerElement(IElementReference elementReference) {
fCallbackCache.add(elementReference);
elementReference.getParameters().put(fScopingName, fScopingValue);
fParentService.registerElement(elementReference);
}
@Override
public void unregisterElement(IElementReference elementReference) {
fCallbackCache.remove(elementReference);
fParentService.unregisterElement(elementReference);
}
@Override
public Runnable registerElementForUpdate(ParameterizedCommand parameterizedCommand, final MItem item) {
UIElement element = new UIElement(fScopingValue) {
@Override
public void setText(String text) {
item.setLabel(text);
}
@Override
public void setTooltip(String text) {
item.setTooltip(text);
}
@Override
public void setIcon(ImageDescriptor desc) {
item.setIconURI(MenuHelper.getIconURI(desc, fContext));
}
@Override
public void setDisabledIcon(ImageDescriptor desc) {
item.getTransientData().put(IPresentationEngine.DISABLED_ICON_IMAGE_KEY,
MenuHelper.getIconURI(desc, fContext));
}
@Override
public void setHoverIcon(ImageDescriptor desc) {
// ignored
}
@Override
public void setChecked(boolean checked) {
item.setSelected(checked);
}
};
try {
final IElementReference reference = registerElementForCommand(parameterizedCommand, element);
return () -> unregisterElement(reference);
} catch (NotDefinedException e) {
WorkbenchPlugin.log(e);
}
return null;
}
}