blob: b724ba1578db0c032557b8bd08754122b5bae7de [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 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.internal;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import org.eclipse.ui.WorkbenchException;
/**
* A workbench window pulldown action.
*/
public class WWinPluginPulldown extends WWinPluginAction {
/**
* The proxy for creating the menu. There is always a menu proxy. This value
* can't be <code>null</code>.
*/
private final IMenuCreator menuProxy;
private class MenuProxy implements IMenuCreator {
/**
* A wrapper for loading the menu that defends against possible
* exceptions triggered outside of the workbench.
*
* @since 3.0
*/
private class MenuLoader implements ISafeRunnable {
/**
* The parent for the menu to be created. This value is
* <code>null</code> if the parent is a menu.
*/
private final Control control;
/**
* The delegate from which to load the menu.
*/
private final IWorkbenchWindowPulldownDelegate delegate;
/**
* The loaded menu. This value is <code>null</code> if the load
* failed, or if it hasn't been loaded yet.
*/
private Menu menu = null;
/**
* The parent for the menu to be created. This value is
* <code>null</code> if the parent is a control.
*/
private final Menu parent;
/**
* Constructs a new instance of <code>MenuLoader</code>
*
* @param delegate
* The delegate from which the menu will be loaded; this
* value must not be <code>null</code>.
* @param parent
* The parent of the menu to be loaded; this value must
* not be <code>null</code>.
*/
private MenuLoader(
final IWorkbenchWindowPulldownDelegate2 delegate,
final Menu parent) {
this.delegate = delegate;
this.parent = parent;
this.control = null;
}
/**
* Constructs a new instance of <code>MenuLoader</code>
*
* @param delegate
* The delegate from which the menu will be loaded; this
* value must not be <code>null</code>.
* @param parent
* The parent of the menu to be loaded; this value must
* not be <code>null</code>.
*/
private MenuLoader(final IWorkbenchWindowPulldownDelegate delegate,
final Control parent) {
this.delegate = delegate;
this.parent = null;
this.control = parent;
}
/**
* Returns the menu loaded, if any.
*
* @return the loaded menu, or <code>null</code> if none.
*/
private Menu getMenu() {
return menu;
}
/**
* @see ISafeRunnable#handleException(java.lang.Throwable)
*/
public void handleException(Throwable exception) {
// Do nothing
}
/**
* @see ISafeRunnable#run()
*/
public void run() throws Exception {
if (parent == null) {
menu = delegate.getMenu(control);
} else {
menu = ((IWorkbenchWindowPulldownDelegate2) delegate)
.getMenu(parent);
}
}
}
/**
* @see IMenuCreator#getMenu(Control)
*/
public Menu getMenu(Control parent) {
IWorkbenchWindowPulldownDelegate delegate = getPulldownDelegate();
if (delegate != null) {
final MenuLoader menuLoader = new MenuLoader(delegate, parent);
SafeRunner.run(menuLoader);
return menuLoader.getMenu();
}
return null;
}
/**
* @see IMenuCreator#getMenu(Menu)
*/
public Menu getMenu(Menu parent) {
IWorkbenchWindowPulldownDelegate delegate = getPulldownDelegate();
if (delegate instanceof IWorkbenchWindowPulldownDelegate2) {
IWorkbenchWindowPulldownDelegate2 delegate2 = (IWorkbenchWindowPulldownDelegate2) delegate;
final MenuLoader menuLoader = new MenuLoader(delegate2, parent);
SafeRunner.run(menuLoader);
return menuLoader.getMenu();
}
return null;
}
/**
* @see IMenuCreator#dispose()
*/
public void dispose() {
// do nothing
}
}
/**
* Constructs a new instance of <code>WWinPluginPulldown</code>.
*
* @param actionElement
* The registry element from which the pulldown delegate should
* be created; must not be <code>null</code>.
* @param id
* The identifier of this action delegate; may be
* <code>null</code>.
* @param window
* The workbench window on which this pulldown should act; must
* not be <code>null</code>.
* @param style
* The style.
*/
public WWinPluginPulldown(IConfigurationElement actionElement,
IWorkbenchWindow window, String id, int style) {
super(actionElement, window, id, style);
menuProxy = new MenuProxy();
setMenuCreator(menuProxy);
}
/*
* (non-Javadoc) Method declared on PluginAction.
*/
protected IActionDelegate validateDelegate(Object obj)
throws WorkbenchException {
if (obj instanceof IWorkbenchWindowPulldownDelegate) {
return (IWorkbenchWindowPulldownDelegate) obj;
}
throw new WorkbenchException(
"Action must implement IWorkbenchWindowPulldownDelegate"); //$NON-NLS-1$
}
/**
* Returns the pulldown delegate. If it does not exist it is created. Can
* return <code>null</code> if delegate creation failed.
*/
protected IWorkbenchWindowPulldownDelegate getPulldownDelegate() {
IActionDelegate delegate = getDelegate();
if (delegate == null) {
createDelegate();
delegate = getDelegate();
}
return (IWorkbenchWindowPulldownDelegate) delegate;
}
}