001: /*******************************************************************************
002: * Copyright (c) 2000, 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.internal;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014:
015: import org.eclipse.core.runtime.IConfigurationElement;
016: import org.eclipse.jface.action.IAction;
017: import org.eclipse.jface.util.IPropertyChangeListener;
018: import org.eclipse.jface.util.PropertyChangeEvent;
019: import org.eclipse.jface.viewers.ISelection;
020: import org.eclipse.swt.events.HelpEvent;
021: import org.eclipse.swt.events.HelpListener;
022: import org.eclipse.swt.widgets.Event;
023: import org.eclipse.ui.IActionDelegate;
024: import org.eclipse.ui.IWorkbenchPart;
025: import org.eclipse.ui.IWorkbenchWindow;
026: import org.eclipse.ui.IWorkbenchWindowActionDelegate;
027: import org.eclipse.ui.WorkbenchException;
028: import org.eclipse.ui.actions.LabelRetargetAction;
029: import org.eclipse.ui.actions.RetargetAction;
030: import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
031:
032: /**
033: * This class extends regular plugin action with the additional requirement that
034: * the delegate has to implement interface
035: * {@link org.eclipse.ui.IWorkbenchWindowActionDelegate}. This interface has
036: * one additional method (init) whose purpose is to initialize the delegate with
037: * the window in which the action is intended to run.
038: */
039: public class WWinPluginAction extends PluginAction implements
040: IActionSetContributionItem {
041: /**
042: * The help listener assigned to this action, or <code>null</code> if none.
043: */
044: private HelpListener localHelpListener;
045:
046: private IWorkbenchWindow window;
047:
048: private String actionSetId;
049:
050: private RetargetAction retargetAction;
051:
052: private static ArrayList staticActionList = new ArrayList(50);
053:
054: /**
055: * Constructs a new <code>WWinPluginAction</code> object.
056: *
057: * @param actionElement the configuration element
058: * @param window the window to contribute to
059: * @param id the identifier
060: * @param style the style
061: */
062: public WWinPluginAction(IConfigurationElement actionElement,
063: IWorkbenchWindow window, String id, int style) {
064: super (actionElement, id, style);
065: this .window = window;
066:
067: // If config specifies a retarget action, create it now
068: String retarget = actionElement
069: .getAttribute(IWorkbenchRegistryConstants.ATT_RETARGET);
070: if (retarget != null
071: && Boolean.valueOf(retarget).booleanValue()) {
072: // create a retarget action
073: String allowLabelUpdate = actionElement
074: .getAttribute(IWorkbenchRegistryConstants.ATT_ALLOW_LABEL_UPDATE);
075: String label = actionElement
076: .getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
077:
078: if (allowLabelUpdate != null
079: && Boolean.valueOf(allowLabelUpdate).booleanValue()) {
080: retargetAction = new LabelRetargetAction(id, label,
081: style);
082: } else {
083: retargetAction = new RetargetAction(id, label, style);
084: }
085: retargetAction
086: .addPropertyChangeListener(new IPropertyChangeListener() {
087: public void propertyChange(
088: PropertyChangeEvent event) {
089: if (event.getProperty().equals(
090: IAction.ENABLED)) {
091: Object val = event.getNewValue();
092: if (val instanceof Boolean) {
093: setEnabled(((Boolean) val)
094: .booleanValue());
095: }
096: } else if (event.getProperty().equals(
097: IAction.CHECKED)) {
098: Object val = event.getNewValue();
099: if (val instanceof Boolean) {
100: setChecked(((Boolean) val)
101: .booleanValue());
102: }
103: } else if (event.getProperty().equals(
104: IAction.TEXT)) {
105: Object val = event.getNewValue();
106: if (val instanceof String) {
107: setText((String) val);
108: }
109: } else if (event.getProperty().equals(
110: IAction.TOOL_TIP_TEXT)) {
111: Object val = event.getNewValue();
112: if (val instanceof String) {
113: setToolTipText((String) val);
114: }
115: }
116: }
117: });
118: retargetAction.setEnabled(false);
119: setEnabled(false);
120: window.getPartService().addPartListener(retargetAction);
121: IWorkbenchPart activePart = window.getPartService()
122: .getActivePart();
123: if (activePart != null) {
124: retargetAction.partActivated(activePart);
125: }
126: } else {
127: // if we retarget the handler will look after selection changes
128: window.getSelectionService().addSelectionListener(this );
129: refreshSelection();
130: }
131: addToActionList(this );
132:
133: super .setHelpListener(new HelpListener() {
134: public void helpRequested(HelpEvent e) {
135: HelpListener listener = null;
136: if (retargetAction != null) {
137: listener = retargetAction.getHelpListener();
138: }
139: if (listener == null) {
140: // use our own help listener
141: listener = localHelpListener;
142: }
143: if (listener != null) {
144: // pass on the event
145: listener.helpRequested(e);
146: }
147: }
148: });
149: }
150:
151: /**
152: * Adds an item to the action list.
153: */
154: private static void addToActionList(WWinPluginAction action) {
155: staticActionList.add(action);
156: }
157:
158: /**
159: * Removes an item from the action list.
160: */
161: private static void removeFromActionList(WWinPluginAction action) {
162: staticActionList.remove(action);
163: }
164:
165: /**
166: * Creates any actions which belong to an activated plugin.
167: */
168: public static void refreshActionList() {
169: Iterator iter = staticActionList.iterator();
170: while (iter.hasNext()) {
171: WWinPluginAction action = (WWinPluginAction) iter.next();
172: if ((action.getDelegate() == null)
173: && action.isOkToCreateDelegate()) {
174: action.createDelegate();
175: // creating the delegate also refreshes its enablement
176: }
177: }
178: }
179:
180: /* (non-Javadoc)
181: * Method declared on PluginAction.
182: */
183: protected IActionDelegate validateDelegate(Object obj)
184: throws WorkbenchException {
185: if (obj instanceof IWorkbenchWindowActionDelegate) {
186: return (IWorkbenchWindowActionDelegate) obj;
187: }
188:
189: throw new WorkbenchException(
190: "Action must implement IWorkbenchWindowActionDelegate"); //$NON-NLS-1$
191: }
192:
193: /* (non-Javadoc)
194: * Method declared on PluginAction.
195: */
196: protected void initDelegate() {
197: super .initDelegate();
198: ((IWorkbenchWindowActionDelegate) getDelegate()).init(window);
199: }
200:
201: /**
202: * Disposes of the action and any resources held.
203: */
204: public void dispose() {
205: removeFromActionList(this );
206: if (retargetAction != null) {
207: window.getPartService().removePartListener(retargetAction);
208: retargetAction.dispose();
209: retargetAction = null;
210: }
211: window.getSelectionService().removeSelectionListener(this );
212: super .dispose();
213: }
214:
215: /**
216: * Returns the action set id.
217: */
218: public String getActionSetId() {
219: return actionSetId;
220: }
221:
222: /**
223: * Returns true if the window has been set.
224: * The window may be null after the constructor is called and
225: * before the window is stored. We cannot create the delegate
226: * at that time.
227: */
228: public boolean isOkToCreateDelegate() {
229: return super .isOkToCreateDelegate() && window != null
230: && retargetAction == null;
231: }
232:
233: /* (non-Javadoc)
234: * Method declared on IActionDelegate2.
235: */
236: public void runWithEvent(Event event) {
237: if (retargetAction == null) {
238: super .runWithEvent(event);
239: return;
240: }
241:
242: if (event != null) {
243: retargetAction.runWithEvent(event);
244: } else {
245: retargetAction.run();
246: }
247: }
248:
249: /**
250: * Sets the action set id.
251: */
252: public void setActionSetId(String newActionSetId) {
253: actionSetId = newActionSetId;
254: }
255:
256: /**
257: * The <code>WWinPluginAction</code> implementation of this method
258: * declared on <code>IAction</code> stores the help listener in
259: * a local field. The supplied listener is only used if there is
260: * no retarget action.
261: */
262: public void setHelpListener(HelpListener listener) {
263: localHelpListener = listener;
264: }
265:
266: /* (non-Javadoc)
267: * Method declared on IAction.
268: */
269: public void setChecked(boolean checked) {
270: super .setChecked(checked);
271: // This call may come from the SWT control event handler
272: // itself, so notify the retarget action to keep things
273: // in sync.
274: if (retargetAction != null) {
275: retargetAction.setChecked(checked);
276: }
277: }
278:
279: /**
280: * Refresh the selection for the action.
281: */
282: protected void refreshSelection() {
283: ISelection selection = window.getSelectionService()
284: .getSelection();
285: selectionChanged(selection);
286: }
287: }
|