001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.commands;
011:
012: import java.util.Collections;
013: import java.util.HashMap;
014: import java.util.Map;
015:
016: import org.eclipse.core.commands.IHandlerAttributes;
017: import org.eclipse.jface.action.IAction;
018: import org.eclipse.jface.util.IPropertyChangeListener;
019: import org.eclipse.jface.util.PropertyChangeEvent;
020: import org.eclipse.swt.widgets.Event;
021: import org.eclipse.ui.actions.RetargetAction;
022:
023: /**
024: * This class adapts instances of <code>IAction</code> to
025: * <code>IHandler</code>.
026: *
027: * @since 3.0
028: * @deprecated Please use the "org.eclipse.core.commands" plug-in instead.
029: * @see org.eclipse.jface.commands.ActionHandler
030: */
031: public final class ActionHandler extends AbstractHandler {
032:
033: /**
034: * The attribute name for the checked property of the wrapped action. This
035: * indicates whether the action should be displayed with as a checked check
036: * box.
037: */
038: private final static String ATTRIBUTE_CHECKED = "checked"; //$NON-NLS-1$
039:
040: /**
041: * The attribute name for the enabled property of the wrapped action.
042: */
043: private final static String ATTRIBUTE_ENABLED = "enabled"; //$NON-NLS-1$
044:
045: /**
046: * <p>
047: * The name of the attribute indicating whether the wrapped instance of
048: * <code>RetargetAction</code> has a handler.
049: * </p>
050: */
051: private final static String ATTRIBUTE_HANDLED = IHandlerAttributes.ATTRIBUTE_HANDLED;
052:
053: /**
054: * The attribute name for the identifier of the wrapped action. This is the
055: * action identifier, and not the command identifier.
056: */
057: private final static String ATTRIBUTE_ID = "id"; //$NON-NLS-1$
058:
059: /**
060: * The attribute name for the visual style of the wrapped action. The style
061: * can be things like a pull-down menu, a check box, a radio button or a
062: * push button.
063: */
064: private final static String ATTRIBUTE_STYLE = "style"; //$NON-NLS-1$
065:
066: /**
067: * The wrapped action. This value is never <code>null</code>.
068: */
069: private final IAction action;
070:
071: /**
072: * The map of attributes values. The keys are <code>String</code> values
073: * of the attribute names (given above). The values can be any type of
074: * <code>Object</code>.
075: *
076: * This map is always null if there are no IHandlerListeners registered.
077: *
078: */
079: private Map attributeValuesByName;
080:
081: /**
082: * The property change listener hooked on to the action. This is initialized
083: * when the first listener is attached to this handler, and is removed when
084: * the handler is disposed or the last listener is removed.
085: */
086: private IPropertyChangeListener propertyChangeListener;
087:
088: /**
089: * Creates a new instance of this class given an instance of
090: * <code>IAction</code>.
091: *
092: * @param action
093: * the action. Must not be <code>null</code>.
094: */
095: public ActionHandler(IAction action) {
096: if (action == null) {
097: throw new NullPointerException();
098: }
099:
100: this .action = action;
101: }
102:
103: /**
104: * @see org.eclipse.ui.commands.IHandler#addHandlerListener(org.eclipse.ui.commands.IHandlerListener)
105: * @since 3.1
106: */
107: public void addHandlerListener(IHandlerListener handlerListener) {
108: if (!hasListeners()) {
109: attachListener();
110: }
111:
112: super .addHandlerListener(handlerListener);
113: }
114:
115: /**
116: * When a listener is attached to this handler, then this registers a
117: * listener with the underlying action.
118: *
119: * @since 3.1
120: */
121: private final void attachListener() {
122: if (propertyChangeListener == null) {
123: attributeValuesByName = getAttributeValuesByNameFromAction();
124:
125: propertyChangeListener = new IPropertyChangeListener() {
126: public void propertyChange(
127: PropertyChangeEvent propertyChangeEvent) {
128: String property = propertyChangeEvent.getProperty();
129: if (IAction.ENABLED.equals(property)
130: || IAction.CHECKED.equals(property)
131: || IHandlerAttributes.ATTRIBUTE_HANDLED
132: .equals(property)) {
133:
134: Map previousAttributeValuesByName = attributeValuesByName;
135: attributeValuesByName = getAttributeValuesByNameFromAction();
136: if (!attributeValuesByName
137: .equals(previousAttributeValuesByName)) {
138: fireHandlerChanged(new HandlerEvent(
139: ActionHandler.this , true,
140: previousAttributeValuesByName));
141: }
142: }
143: }
144: };
145: }
146:
147: this .action.addPropertyChangeListener(propertyChangeListener);
148: }
149:
150: /**
151: * When no more listeners are registered, then this is used to removed the
152: * property change listener from the underlying action.
153: *
154: * @since 3.1
155: *
156: */
157: private final void detachListener() {
158: this .action
159: .removePropertyChangeListener(propertyChangeListener);
160: propertyChangeListener = null;
161: attributeValuesByName = null;
162: }
163:
164: /**
165: * Removes the property change listener from the action.
166: *
167: * @see org.eclipse.ui.commands.IHandler#dispose()
168: */
169: public void dispose() {
170: if (hasListeners()) {
171: action.removePropertyChangeListener(propertyChangeListener);
172: }
173: }
174:
175: /* (non-Javadoc)
176: * @see org.eclipse.ui.commands.IHandler#execute(java.util.Map)
177: */
178: public Object execute(Map parameterValuesByName)
179: throws ExecutionException {
180: if ((action.getStyle() == IAction.AS_CHECK_BOX)
181: || (action.getStyle() == IAction.AS_RADIO_BUTTON)) {
182: action.setChecked(!action.isChecked());
183: }
184: try {
185: action.runWithEvent(new Event());
186: } catch (Exception e) {
187: throw new ExecutionException(
188: "While executing the action, an exception occurred", e); //$NON-NLS-1$
189: }
190: return null;
191: }
192:
193: /**
194: * Returns the action associated with this handler
195: *
196: * @return the action associated with this handler (not null)
197: * @since 3.1
198: */
199: public IAction getAction() {
200: return action;
201: }
202:
203: /* (non-Javadoc)
204: * @see org.eclipse.ui.commands.IHandler#getAttributeValuesByName()
205: */
206: public Map getAttributeValuesByName() {
207: if (attributeValuesByName == null) {
208: return getAttributeValuesByNameFromAction();
209: }
210:
211: return attributeValuesByName;
212: }
213:
214: /**
215: * An accessor for the attribute names from the action. This reads out all
216: * of the attributes from an action into a local map.
217: *
218: * @return A map of the attribute values indexed by the attribute name. The
219: * attributes names are strings, but the values can by any object.
220: *
221: */
222: private Map getAttributeValuesByNameFromAction() {
223: Map map = new HashMap();
224: map.put(ATTRIBUTE_CHECKED, action.isChecked() ? Boolean.TRUE
225: : Boolean.FALSE);
226: map.put(ATTRIBUTE_ENABLED, action.isEnabled() ? Boolean.TRUE
227: : Boolean.FALSE);
228: boolean handled = true;
229: if (action instanceof RetargetAction) {
230: RetargetAction retargetAction = (RetargetAction) action;
231: handled = retargetAction.getActionHandler() != null;
232: }
233: map.put(ATTRIBUTE_HANDLED, handled ? Boolean.TRUE
234: : Boolean.FALSE);
235: map.put(ATTRIBUTE_ID, action.getId());
236: map.put(ATTRIBUTE_STYLE, new Integer(action.getStyle()));
237: return Collections.unmodifiableMap(map);
238: }
239:
240: /**
241: * @see org.eclipse.ui.commands.IHandler#removeHandlerListener(org.eclipse.ui.commands.IHandlerListener)
242: * @since 3.1
243: */
244: public void removeHandlerListener(IHandlerListener handlerListener) {
245: super .removeHandlerListener(handlerListener);
246:
247: if (!hasListeners()) {
248: detachListener();
249: }
250: }
251:
252: /* (non-Javadoc)
253: * @see java.lang.Object#toString()
254: */
255: public final String toString() {
256: final StringBuffer buffer = new StringBuffer();
257:
258: buffer.append("ActionHandler(action="); //$NON-NLS-1$
259: buffer.append(action);
260: buffer.append(')');
261:
262: return buffer.toString();
263: }
264: }
|