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 org.eclipse.core.runtime.IConfigurationElement;
013: import org.eclipse.core.runtime.ISafeRunnable;
014: import org.eclipse.core.runtime.SafeRunner;
015: import org.eclipse.jface.action.IMenuCreator;
016: import org.eclipse.swt.widgets.Control;
017: import org.eclipse.swt.widgets.Menu;
018: import org.eclipse.ui.IActionDelegate;
019: import org.eclipse.ui.IWorkbenchWindow;
020: import org.eclipse.ui.IWorkbenchWindowPulldownDelegate;
021: import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
022: import org.eclipse.ui.WorkbenchException;
023:
024: /**
025: * A workbench window pulldown action.
026: */
027: public class WWinPluginPulldown extends WWinPluginAction {
028:
029: /**
030: * The proxy for creating the menu. There is always a menu proxy. This value
031: * can't be <code>null</code>.
032: */
033: private final IMenuCreator menuProxy;
034:
035: private class MenuProxy implements IMenuCreator {
036:
037: /**
038: * A wrapper for loading the menu that defends against possible
039: * exceptions triggered outside of the workbench.
040: *
041: * @since 3.0
042: */
043: private class MenuLoader implements ISafeRunnable {
044:
045: /**
046: * The parent for the menu to be created. This value is
047: * <code>null</code> if the parent is a menu.
048: */
049: private final Control control;
050:
051: /**
052: * The delegate from which to load the menu.
053: */
054: private final IWorkbenchWindowPulldownDelegate delegate;
055:
056: /**
057: * The loaded menu. This value is <code>null</code> if the load
058: * failed, or if it hasn't been loaded yet.
059: */
060: private Menu menu = null;
061:
062: /**
063: * The parent for the menu to be created. This value is
064: * <code>null</code> if the parent is a control.
065: */
066: private final Menu parent;
067:
068: /**
069: * Constructs a new instance of <code>MenuLoader</code>
070: *
071: * @param delegate
072: * The delegate from which the menu will be loaded; this
073: * value must not be <code>null</code>.
074: * @param parent
075: * The parent of the menu to be loaded; this value must
076: * not be <code>null</code>.
077: */
078: private MenuLoader(
079: final IWorkbenchWindowPulldownDelegate2 delegate,
080: final Menu parent) {
081: this .delegate = delegate;
082: this .parent = parent;
083: this .control = null;
084: }
085:
086: /**
087: * Constructs a new instance of <code>MenuLoader</code>
088: *
089: * @param delegate
090: * The delegate from which the menu will be loaded; this
091: * value must not be <code>null</code>.
092: * @param parent
093: * The parent of the menu to be loaded; this value must
094: * not be <code>null</code>.
095: */
096: private MenuLoader(
097: final IWorkbenchWindowPulldownDelegate delegate,
098: final Control parent) {
099: this .delegate = delegate;
100: this .parent = null;
101: this .control = parent;
102: }
103:
104: /**
105: * Returns the menu loaded, if any.
106: *
107: * @return the loaded menu, or <code>null</code> if none.
108: */
109: private Menu getMenu() {
110: return menu;
111: }
112:
113: /**
114: * @see ISafeRunnable#handleException(java.lang.Throwable)
115: */
116: public void handleException(Throwable exception) {
117: // Do nothing
118: }
119:
120: /**
121: * @see ISafeRunnable#run()
122: */
123: public void run() throws Exception {
124: if (parent == null) {
125: menu = delegate.getMenu(control);
126: } else {
127: menu = ((IWorkbenchWindowPulldownDelegate2) delegate)
128: .getMenu(parent);
129: }
130: }
131: }
132:
133: /**
134: * @see IMenuCreator#getMenu(Control)
135: */
136: public Menu getMenu(Control parent) {
137: IWorkbenchWindowPulldownDelegate delegate = getPulldownDelegate();
138: if (delegate != null) {
139: final MenuLoader menuLoader = new MenuLoader(delegate,
140: parent);
141: SafeRunner.run(menuLoader);
142: return menuLoader.getMenu();
143: }
144:
145: return null;
146: }
147:
148: /**
149: * @see IMenuCreator#getMenu(Menu)
150: */
151: public Menu getMenu(Menu parent) {
152: IWorkbenchWindowPulldownDelegate delegate = getPulldownDelegate();
153:
154: if (delegate instanceof IWorkbenchWindowPulldownDelegate2) {
155: IWorkbenchWindowPulldownDelegate2 delegate2 = (IWorkbenchWindowPulldownDelegate2) delegate;
156: final MenuLoader menuLoader = new MenuLoader(delegate2,
157: parent);
158: SafeRunner.run(menuLoader);
159: return menuLoader.getMenu();
160: }
161:
162: return null;
163: }
164:
165: /**
166: * @see IMenuCreator#dispose()
167: */
168: public void dispose() {
169: // do nothing
170: }
171: }
172:
173: /**
174: * Constructs a new instance of <code>WWinPluginPulldown</code>.
175: *
176: * @param actionElement
177: * The registry element from which the pulldown delegate should
178: * be created; must not be <code>null</code>.
179: * @param id
180: * The identifier of this action delegate; may be
181: * <code>null</code>.
182: * @param window
183: * The workbench window on which this pulldown should act; must
184: * not be <code>null</code>.
185: * @param style
186: * The style.
187: */
188: public WWinPluginPulldown(IConfigurationElement actionElement,
189: IWorkbenchWindow window, String id, int style) {
190: super (actionElement, window, id, style);
191: menuProxy = new MenuProxy();
192: setMenuCreator(menuProxy);
193: }
194:
195: /*
196: * (non-Javadoc) Method declared on PluginAction.
197: */
198: protected IActionDelegate validateDelegate(Object obj)
199: throws WorkbenchException {
200: if (obj instanceof IWorkbenchWindowPulldownDelegate) {
201: return (IWorkbenchWindowPulldownDelegate) obj;
202: }
203:
204: throw new WorkbenchException(
205: "Action must implement IWorkbenchWindowPulldownDelegate"); //$NON-NLS-1$
206: }
207:
208: /**
209: * Returns the pulldown delegate. If it does not exist it is created. Can
210: * return <code>null</code> if delegate creation failed.
211: */
212: protected IWorkbenchWindowPulldownDelegate getPulldownDelegate() {
213: IActionDelegate delegate = getDelegate();
214: if (delegate == null) {
215: createDelegate();
216: delegate = getDelegate();
217: }
218: return (IWorkbenchWindowPulldownDelegate) delegate;
219: }
220: }
|