blob: be70490f2d161417e30cbbd80f6b782f96c5f160 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 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.commands;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.commands.IHandlerAttributes;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.actions.RetargetAction;
/**
* This class adapts instances of <code>IAction</code> to
* <code>IHandler</code>.
*
* @since 3.0
* @deprecated Please use the "org.eclipse.core.commands" plug-in instead.
* @see org.eclipse.jface.commands.ActionHandler
*/
public final class ActionHandler extends AbstractHandler {
/**
* The attribute name for the checked property of the wrapped action. This
* indicates whether the action should be displayed with as a checked check
* box.
*/
private final static String ATTRIBUTE_CHECKED = "checked"; //$NON-NLS-1$
/**
* The attribute name for the enabled property of the wrapped action.
*/
private final static String ATTRIBUTE_ENABLED = "enabled"; //$NON-NLS-1$
/**
* <p>
* The name of the attribute indicating whether the wrapped instance of
* <code>RetargetAction</code> has a handler.
* </p>
*/
private final static String ATTRIBUTE_HANDLED = IHandlerAttributes.ATTRIBUTE_HANDLED;
/**
* The attribute name for the identifier of the wrapped action. This is the
* action identifier, and not the command identifier.
*/
private final static String ATTRIBUTE_ID = "id"; //$NON-NLS-1$
/**
* The attribute name for the visual style of the wrapped action. The style
* can be things like a pull-down menu, a check box, a radio button or a
* push button.
*/
private final static String ATTRIBUTE_STYLE = "style"; //$NON-NLS-1$
/**
* The wrapped action. This value is never <code>null</code>.
*/
private final IAction action;
/**
* The map of attributes values. The keys are <code>String</code> values
* of the attribute names (given above). The values can be any type of
* <code>Object</code>.
*
* This map is always null if there are no IHandlerListeners registered.
*
*/
private Map attributeValuesByName;
/**
* The property change listener hooked on to the action. This is initialized
* when the first listener is attached to this handler, and is removed when
* the handler is disposed or the last listener is removed.
*/
private IPropertyChangeListener propertyChangeListener;
/**
* Creates a new instance of this class given an instance of
* <code>IAction</code>.
*
* @param action
* the action. Must not be <code>null</code>.
*/
public ActionHandler(IAction action) {
if (action == null) {
throw new NullPointerException();
}
this.action = action;
}
/**
* @see org.eclipse.ui.commands.IHandler#addHandlerListener(org.eclipse.ui.commands.IHandlerListener)
* @since 3.1
*/
public void addHandlerListener(IHandlerListener handlerListener) {
if (!hasListeners()) {
attachListener();
}
super.addHandlerListener(handlerListener);
}
/**
* When a listener is attached to this handler, then this registers a
* listener with the underlying action.
*
* @since 3.1
*/
private final void attachListener() {
if (propertyChangeListener == null) {
attributeValuesByName = getAttributeValuesByNameFromAction();
propertyChangeListener = new IPropertyChangeListener() {
public void propertyChange(
PropertyChangeEvent propertyChangeEvent) {
String property = propertyChangeEvent.getProperty();
if (IAction.ENABLED.equals(property)
|| IAction.CHECKED.equals(property)
|| IHandlerAttributes.ATTRIBUTE_HANDLED
.equals(property)) {
Map previousAttributeValuesByName = attributeValuesByName;
attributeValuesByName = getAttributeValuesByNameFromAction();
if (!attributeValuesByName
.equals(previousAttributeValuesByName)) {
fireHandlerChanged(new HandlerEvent(
ActionHandler.this, true,
previousAttributeValuesByName));
}
}
}
};
}
this.action.addPropertyChangeListener(propertyChangeListener);
}
/**
* When no more listeners are registered, then this is used to removed the
* property change listener from the underlying action.
*
* @since 3.1
*
*/
private final void detachListener() {
this.action.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener = null;
attributeValuesByName = null;
}
/**
* Removes the property change listener from the action.
*
* @see org.eclipse.ui.commands.IHandler#dispose()
*/
public void dispose() {
if (hasListeners()) {
action.removePropertyChangeListener(propertyChangeListener);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.commands.IHandler#execute(java.util.Map)
*/
public Object execute(Map parameterValuesByName) throws ExecutionException {
if ((action.getStyle() == IAction.AS_CHECK_BOX)
|| (action.getStyle() == IAction.AS_RADIO_BUTTON)) {
action.setChecked(!action.isChecked());
}
try {
action.runWithEvent(new Event());
} catch (Exception e) {
throw new ExecutionException(
"While executing the action, an exception occurred", e); //$NON-NLS-1$
}
return null;
}
/**
* Returns the action associated with this handler
*
* @return the action associated with this handler (not null)
* @since 3.1
*/
public IAction getAction() {
return action;
}
/* (non-Javadoc)
* @see org.eclipse.ui.commands.IHandler#getAttributeValuesByName()
*/
public Map getAttributeValuesByName() {
if (attributeValuesByName == null) {
return getAttributeValuesByNameFromAction();
}
return attributeValuesByName;
}
/**
* An accessor for the attribute names from the action. This reads out all
* of the attributes from an action into a local map.
*
* @return A map of the attribute values indexed by the attribute name. The
* attributes names are strings, but the values can by any object.
*
*/
private Map getAttributeValuesByNameFromAction() {
Map map = new HashMap();
map.put(ATTRIBUTE_CHECKED, action.isChecked() ? Boolean.TRUE
: Boolean.FALSE);
map.put(ATTRIBUTE_ENABLED, action.isEnabled() ? Boolean.TRUE
: Boolean.FALSE);
boolean handled = true;
if (action instanceof RetargetAction) {
RetargetAction retargetAction = (RetargetAction) action;
handled = retargetAction.getActionHandler() != null;
}
map.put(ATTRIBUTE_HANDLED, handled ? Boolean.TRUE : Boolean.FALSE);
map.put(ATTRIBUTE_ID, action.getId());
map.put(ATTRIBUTE_STYLE, new Integer(action.getStyle()));
return Collections.unmodifiableMap(map);
}
/**
* @see org.eclipse.ui.commands.IHandler#removeHandlerListener(org.eclipse.ui.commands.IHandlerListener)
* @since 3.1
*/
public void removeHandlerListener(IHandlerListener handlerListener) {
super.removeHandlerListener(handlerListener);
if (!hasListeners()) {
detachListener();
}
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public final String toString() {
final StringBuffer buffer = new StringBuffer();
buffer.append("ActionHandler(action="); //$NON-NLS-1$
buffer.append(action);
buffer.append(')');
return buffer.toString();
}
}