/*******************************************************************************
* Copyright (c) 2000, 2005 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.gef.ui.actions;
import org.eclipse.jface.action.Action;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.gef.Disposable;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
/**
* Base class for actions involving a WorkbenchPart. The workbench part is useful for
* obtaining data needed by the action. For example, selection can be obtained using the
* part's site. Anything can potentially be obtained using
* {@link org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)}.
*/
public abstract class WorkbenchPartAction
extends Action
implements Disposable, UpdateAction
{
private IWorkbenchPart workbenchPart;
private boolean lazyEnablement = true;
/**
* Constructs a WorkbenchPartAction for the given part.
* @param part the workbench part
*/
public WorkbenchPartAction(IWorkbenchPart part) {
setWorkbenchPart(part);
init();
}
/**
* Constructs a WorkbenchPartAction for the given part and style.
* @param part the workbench part
* @param style one of <code>AS_PUSH_BUTTON</code>, <code>AS_CHECK_BOX</code>,
* <code>AS_DROP_DOWN_MENU</code>, <code>AS_RADIO_BUTTON</code>, and
* <code>AS_UNSPECIFIED</code>.
*/
public WorkbenchPartAction(IWorkbenchPart part, int style) {
super(null, style);
setWorkbenchPart(part);
init();
}
/**
* Calculates and returns the enabled state of this action.
* @return <code>true</code> if the action is enabled
*/
protected abstract boolean calculateEnabled();
/**
* Disposes the action when it is no longer needed.
*/
public void dispose() { }
/**
* Executes the given {@link Command} using the command stack. The stack is obtained by
* calling {@link #getCommandStack()}, which uses <code>IAdapatable</code> to retrieve the
* stack from the workbench part.
* @param command the command to execute
*/
protected void execute(Command command) {
if (command == null || !command.canExecute())
return;
getCommandStack().execute(command);
}
/**
* Returns the editor's command stack. This is done by asking the workbench part for its
* CommandStack via
* {@link org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)}.
* @return the command stack
*/
protected CommandStack getCommandStack() {
return (CommandStack)getWorkbenchPart().getAdapter(CommandStack.class);
}
/**
* Returns the workbench part given in the constructor
* @return the workbench part
*/
protected IWorkbenchPart getWorkbenchPart() {
return workbenchPart;
}
/**
* Initializes this action.
*/
protected void init() { }
/**
* Returns <code>true</code> if the action is enabled. If the action determines enablemenu
* lazily, then {@link #calculateEnabled()} is always called. Otherwise, the enablement
* state set using {@link Action#setEnabled(boolean)} is returned.
* @see #setLazyEnablementCalculation(boolean)
* @return <code>true</code> if the action is enabled
*/
public boolean isEnabled() {
if (lazyEnablement)
setEnabled(calculateEnabled());
return super.isEnabled();
}
/**
* Refreshes the properties of this action.
*/
protected void refresh() {
setEnabled(calculateEnabled());
}
/**
* Sets lazy calculation of the isEnabled property. If this value is set to
* <code>true</code>, then the action will always use {@link #calculateEnabled()} whenever
* {@link #isEnabled()} is called.
* <P>Sometimes a value of <code>false</code> can be used to improve performance and
* reduce the number of times {@link #calculateEnabled()} is called. However, the client
* must then call the {@link #update()} method at the proper times to force the update of
* enablement.
* <P>
* Sometimes a value of <code>true</code> can be used to improve performance. If an
* <code>Action</code> only appears in a dynamic context menu, then there is no reason to
* agressively update its enablement status because the user cannot see the Action.
* Instead, its enablement only needs to be determined when asked for, or <i>lazily</i>.
* <P>
* The default value for this setting is <code>true</code>.
* @param value <code>true</code> if the enablement should be lazy
*/
public void setLazyEnablementCalculation(boolean value) {
lazyEnablement = value;
}
/**
* Sets the workbench part.
* @param part the workbench part
*/
protected void setWorkbenchPart(IWorkbenchPart part) {
workbenchPart = part;
}
/**
* @see UpdateAction#update()
*/
public void update() {
refresh();
}
}