/******************************************************************************* * Copyright (c) 2005, 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.application; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.ICoolBarManager; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.ui.IMemento; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; /** * Public base class for configuring the action bars of a workbench window. * <p> * An application should declare a subclass of <code>ActionBarAdvisor</code> * and override methods to configure a window's action bars to suit the needs of the * particular application. * </p> * <p> * The following advisor methods are called at strategic points in the * workbench's lifecycle (all occur within the dynamic scope of the call * to {@link PlatformUI#createAndRunWorkbench PlatformUI.createAndRunWorkbench}): * <ul> * <li><code>fillActionBars</code> - called after <code>WorkbenchWindowAdvisor.preWindowOpen</code> * to configure a window's action bars</li> * </ul> * </p> * * @see WorkbenchWindowAdvisor#createActionBarAdvisor(IActionBarConfigurer) * * @since 3.1 */ public class ActionBarAdvisor { /** * Bit flag for {@link #fillActionBars fillActionBars} indicating that the * operation is not filling the action bars of an actual workbench window, * but rather a proxy (used for perspective customization). */ public static final int FILL_PROXY = 0x01; /** * Bit flag for {@link #fillActionBars fillActionBars} indicating that the * operation is supposed to fill (or describe) the workbench window's menu * bar. */ public static final int FILL_MENU_BAR = 0x02; /** * Bit flag for {@link #fillActionBars fillActionBars} indicating that the * operation is supposed to fill (or describe) the workbench window's cool * bar. */ public static final int FILL_COOL_BAR = 0x04; /** * Bit flag for {@link #fillActionBars fillActionBars} indicating that the * operation is supposed to fill (or describe) the workbench window's status * line. */ public static final int FILL_STATUS_LINE = 0x08; private IActionBarConfigurer actionBarConfigurer; private Map actions = new HashMap(); /** * Creates a new action bar advisor to configure a workbench * window's action bars via the given action bar configurer. * * @param configurer the action bar configurer */ public ActionBarAdvisor(IActionBarConfigurer configurer) { Assert.isNotNull(configurer); actionBarConfigurer = configurer; } /** * Returns the action bar configurer. * * @return the action bar configurer */ protected IActionBarConfigurer getActionBarConfigurer() { return actionBarConfigurer; } /** * Configures the action bars using the given action bar configurer. * Under normal circumstances, <code>flags</code> does not include * <code>FILL_PROXY</code>, meaning this is a request to fill the action * bars of the corresponding workbench window; the * remaining flags indicate which combination of * the menu bar (<code>FILL_MENU_BAR</code>), * the tool bar (<code>FILL_COOL_BAR</code>), * and the status line (<code>FILL_STATUS_LINE</code>) are to be filled. * <p> * If <code>flags</code> does include <code>FILL_PROXY</code>, then this * is a request to describe the actions bars of the given workbench window * (which will already have been filled); * again, the remaining flags indicate which combination of the menu bar, * the tool bar, and the status line are to be described. * The actions included in the proxy action bars can be the same instances * as in the actual window's action bars. Calling <code>ActionFactory</code> * to create new action instances is not recommended, because these * actions internally register listeners with the window and there is no * opportunity to dispose of these actions. * </p> * <p> * This method is called just after {@link WorkbenchWindowAdvisor#preWindowOpen()}. * Clients must not call this method directly (although super calls are okay). * The default implementation calls <code>makeActions</code> if * <code>FILL_PROXY</code> is specified, then calls <code>fillMenuBar</code>, * <code>fillCoolBar</code>, and <code>fillStatusLine</code> * if the corresponding flags are specified. * </p> * <p> * Subclasses may override, but it is recommended that they override the * methods mentioned above instead. * </p> * * @param flags bit mask composed from the constants * {@link #FILL_MENU_BAR FILL_MENU_BAR}, * {@link #FILL_COOL_BAR FILL_COOL_BAR}, * {@link #FILL_STATUS_LINE FILL_STATUS_LINE}, * and {@link #FILL_PROXY FILL_PROXY} */ public void fillActionBars(int flags) { if ((flags & FILL_PROXY) == 0) { makeActions(actionBarConfigurer.getWindowConfigurer().getWindow()); } if ((flags & FILL_MENU_BAR) != 0) { fillMenuBar(actionBarConfigurer.getMenuManager()); } if ((flags & FILL_COOL_BAR) != 0) { fillCoolBar(actionBarConfigurer.getCoolBarManager()); } if ((flags & FILL_STATUS_LINE) != 0) { fillStatusLine(actionBarConfigurer.getStatusLineManager()); } } /** * Instantiates the actions used in the fill methods. * Use {@link #register(IAction)} to register the action with the key binding service * and add it to the list of actions to be disposed when the window is closed. * * @param window the window containing the action bars */ protected void makeActions(IWorkbenchWindow window) { // do nothing } /** * Registers the given action with the key binding service * (by calling {@link IActionBarConfigurer#registerGlobalAction(IAction)}), * and adds it to the list of actions to be disposed when the window is closed. * <p> * In order to participate in key bindings, the action must have an action * definition id (aka command id), and a corresponding command extension. * See the <code>org.eclipse.ui.commands</code> extension point documentation * for more details. * </p> * * @param action the action to register, this cannot be <code>null</code> * * @see IAction#setActionDefinitionId(String) * @see #disposeAction(IAction) */ protected void register(IAction action) { Assert.isNotNull(action, "Action must not be null"); //$NON-NLS-1$ String id = action.getId(); Assert.isNotNull(id, "Action must not have null id"); //$NON-NLS-1$ getActionBarConfigurer().registerGlobalAction(action); actions.put(id, action); } /** * Returns the action with the given id, or <code>null</code> if not found. * * @param id the action id * @return the action with the given id, or <code>null</code> if not found * @see IAction#getId() */ protected IAction getAction(String id) { return (IAction) actions.get(id); } /** * Fills the menu bar with the main menus for the window. * <p> * The default implementation does nothing. * Subclasses may override. * </p> * * @param menuBar the menu manager for the menu bar */ protected void fillMenuBar(IMenuManager menuBar) { // do nothing } /** * Fills the cool bar with the main toolbars for the window. * <p> * The default implementation does nothing. * Subclasses may override. * </p> * * @param coolBar the cool bar manager */ protected void fillCoolBar(ICoolBarManager coolBar) { // do nothing } /** * Fills the status line with the main status line contributions * for the window. * <p> * The default implementation does nothing. * Subclasses may override. * </p> * * @param statusLine the status line manager */ protected void fillStatusLine(IStatusLineManager statusLine) { // do nothing } /** * Returns whether the menu with the given id is an application menu of the * given window. This is used during OLE "in place" editing. Application * menus should be preserved during menu merging. All other menus may be * removed from the window. * <p> * The default implementation returns false. Subclasses may override. * </p> * * @param menuId the menu id * @return <code>true</code> for application menus, and <code>false</code> * for part-specific menus */ public boolean isApplicationMenu(String menuId) { // default: not an application menu return false; } /** * Disposes this action bar advisor. * Called when the window is being closed. * This should dispose any allocated resources and remove any added listeners. * <p> * The default implementation calls <code>disposeActions()</code>. * Subclasses may extend. * </p> */ public void dispose() { disposeActions(); } /** * Disposes all actions added via <code>register(IAction)</code> * using <code>disposeAction(IAction)</code>. */ protected void disposeActions() { for (Iterator i = actions.values().iterator(); i.hasNext();) { IAction action = (IAction) i.next(); disposeAction(action); } actions.clear(); } /** * Disposes the given action. * <p> * The default implementation checks whether the action is an instance * of <code>ActionFactory.IWorkbenchAction</code> and calls its * <code>dispose()</code> method if so. * Subclasses may extend. * </p> * * @param action the action to dispose */ protected void disposeAction(IAction action) { if (action instanceof ActionFactory.IWorkbenchAction) { ((ActionFactory.IWorkbenchAction) action).dispose(); } } /** * Saves arbitrary application-specific state information * for this action bar advisor. * <p> * The default implementation simply returns an OK status. * Subclasses may extend or override. * </p> * * @param memento the memento in which to save the advisor's state * @return a status object indicating whether the save was successful * @since 3.1 */ public IStatus saveState(IMemento memento) { return Status.OK_STATUS; } /** * Restores arbitrary application-specific state information * for this action bar advisor. * <p> * The default implementation simply returns an OK status. * Subclasses may extend or override. * </p> * * @param memento the memento from which to restore the advisor's state * @return a status object indicating whether the restore was successful * @since 3.1 */ public IStatus restoreState(IMemento memento) { return Status.OK_STATUS; } }