/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.ui.common.actions;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.INullSelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.teiid.core.designer.PluginUtil;
import org.teiid.designer.ui.common.AbstractUiPlugin;
import org.teiid.designer.ui.common.InternalUiConstants.Actions;
import org.teiid.designer.ui.common.UiConstants;
import org.teiid.designer.ui.common.eventsupport.SelectionUtilities;
import org.teiid.designer.ui.common.graphics.ImageImageDescriptor;
import org.teiid.designer.ui.common.viewsupport.UiBusyIndicator;
/**
* AbstractAction
*
* @since 8.0
*/
public abstract class AbstractAction extends Action
implements INullSelectionListener, ISelectionChangedListener {
///////////////////////////////////////////////////////////////////////////////////////////////
// FIELDS
///////////////////////////////////////////////////////////////////////////////////////////////
/** The localization identifier for the accelerator. */
private String acceleratorId;
/** The localization identifier for the description. */
private String descriptionId;
/** The path/file identifier for the disabled image. */
private String disabledImageId;
/** The identifier for the help context. */
private String helpId;
/** The path/file identifier for the hover image. */
private String hoverImageId;
/** The path/file identifier for the image. */
private String imageId;
/** The plugin associated with this action. Used for logging and localization. */
private AbstractUiPlugin plugin;
/** The current selection or <code>null</code>. */
private ISelection selection;
/** The current event or <code>null</code> if last event was a workbench selection. */
private SelectionChangedEvent selectionEvent;
/** The localization identifier for the label text. */
private String textId;
/** The localization identifier for the tool tip text. */
private String tipId;
/** Plugin's utility used for logging and localization. */
private PluginUtil pluginUtils;
/** Allow subclass to veto use of a wait-cursor */
private boolean useWaitCursor = true;
/**
* The workbench part containing the selection or <code>null</code> if last selection was not a
* workbench selection.
*/
private IWorkbenchPart part;
///////////////////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
///////////////////////////////////////////////////////////////////////////////////////////////
/**
* Constructs an <code>AbstractAction</code> setting properties found in the plugin's
* resource bundle.
* @param thePlugin the plugin associated with this action
*/
public AbstractAction(AbstractUiPlugin thePlugin) {
plugin = thePlugin;
init();
}
/**
* Constructs an <code>AbstractAction</code> setting properties found in the plugin's
* resource bundle.
* @param thePlugin the plugin associated with this action
* @param theStyle the style as defined by constants in {@link org.eclipse.jface.action.IAction}
*/
public AbstractAction(AbstractUiPlugin thePlugin,
int theStyle) {
// just pass empty string to super as init() will set text via properties
super("", theStyle); //$NON-NLS-1$
plugin = thePlugin;
init();
}
///////////////////////////////////////////////////////////////////////////////////////////////
// METHODS
///////////////////////////////////////////////////////////////////////////////////////////////
/**
* Notifies the action that it is no longer needed. The action should dispose of any system resources.
* After calling this method, the action is considered unusable.
*/
public void dispose() {
}
/**
* Gets the localization identifier for the accelerator.
* @return the localization identifier
*/
public String getAcceleratorId() {
return acceleratorId;
}
/**
* Gets the <code>ResourceBundle</code> key for the given property identifier.
* The identifier should be a constant found in {@link UiConstants.Actions}.
* @param thePropertyId the action property whose bundle key is being requested
* @return the bundle key
*/
private String getActionPropertyKey(String thePropertyId) {
return new StringBuffer().append(getId())
.append(Actions.DELIMITER)
.append(thePropertyId)
.toString();
}
/**
* Gets the localization identifier for the description.
* @return the localization identifier
*/
public String getDescriptionId() {
return descriptionId;
}
/**
* Gets the disabled image path/file identifier used to create the {@link ImageDescriptor}.
* @return the image path/file identifier
*/
public String getDisabledImageId() {
return disabledImageId;
}
/**
* Gets the help context identifier used in workbench help.
* @return the localization identifier
*/
public String getHelpContextId() {
return helpId;
}
/**
* Gets the hover image path/file identifier used to create the {@link ImageDescriptor}.
* @return the image path/file identifier
*/
public String getHoverImageId() {
return hoverImageId;
}
/**
* Gets the image path/file identifier used to create the {@link ImageDescriptor}.
* @return the image path/file identifier
*/
public String getImageId() {
return imageId;
}
/**
* Gets the plugin associated with this action.
* @return the plugin
*/
public AbstractUiPlugin getPlugin() {
return plugin;
}
/**
* Gets the utilities class used for logging and localization.
* @return the plugin utilities
*/
protected PluginUtil getPluginUtils() {
return pluginUtils;
}
/**
* Gets the selected object in the current selection. If more than one object is selected, the first
* is returned.
* @return the selected object or <code>null</code> if none selected
*/
public Object getSelectedObject() {
return SelectionUtilities.getSelectedObject(selection);
}
/**
* Gets all objects in the current selection.
* @return the list of all selected objects or an empty list
*/
public List getSelectedObjects() {
return SelectionUtilities.getSelectedObjects(selection);
}
/**
* Gets the current workbench selection.
* @return the current selection or <code>null</code>
*/
public ISelection getSelection() {
return selection;
}
/**
* Gets the current selection event.
* @return the selection event or <code>null</code>
*/
public SelectionChangedEvent getSelectionEvent() {
return selectionEvent;
}
/**
* Gets the localization identifier for the label text.
* @return the localization identifier
*/
public String getTextId() {
return textId;
}
/**
* Gets the localization identifier for the tool tip text.
* @return the localization identifier
*/
public String getToolTipId() {
return tipId;
}
/**<p>
* </p>
* @since 4.0
*/
protected IWorkbenchPart getPart() {
return part;
}
/**
* Initialization only done at construction. Sets action properties based on information in the plugin
* <code>ResourceBundle</code>.
*/
protected void init() {
pluginUtils = plugin.getPluginUtil();
// initialize id which is used in getting the properties below
setId(getClass().getName());
// initialize accelerator (must do before setting text)
String key = getActionPropertyKey(Actions.ACCELERATOR);
if (pluginUtils.keyExists(key)) {
setAcceleratorId(key);
}
// initialize description
key = getActionPropertyKey(Actions.DESCRIPTION);
if (pluginUtils.keyExists(key)) {
setDescriptionId(key);
}
// initialize disabledImage
key = getActionPropertyKey(Actions.DISABLED_IMAGE);
if (pluginUtils.keyExists(key)) {
setDisabledImageId(key);
}
// initialize help context id
key = getActionPropertyKey(Actions.HELP);
if (pluginUtils.keyExists(key)) {
setHelpContextId(key);
}
// initialize hover image
key = getActionPropertyKey(Actions.HOVER_IMAGE);
if (pluginUtils.keyExists(key)) {
setHoverImageId(key);
}
// initialize image
key = getActionPropertyKey(Actions.IMAGE);
if (pluginUtils.keyExists(key)) {
setImageId(key);
}
// initialize text
key = getActionPropertyKey(Actions.TEXT);
if (pluginUtils.keyExists(key)) {
setTextId(key);
}
// initialize tooltip
key = getActionPropertyKey(Actions.TOOLTIP);
if (pluginUtils.keyExists(key)) {
setToolTipTextId(key);
}
}
/**
* Indicates if the current selection is empty.
* @return <code>true</code> if there is no object selected; <code>false</code> otherwise.
*/
public boolean isEmptySelection() {
return ((selection == null) || selection.isEmpty());
}
/**
* Indicates if the current selection has multiple objects selected.
* @return <code>true</code> if multiple objects are selected; <code>false</code> otherwise.
*/
public boolean isMultiSelection() {
return SelectionUtilities.isMultiSelection(selection);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
@Override
public void selectionChanged(SelectionChangedEvent theEvent) {
selection = theEvent.getSelection();
this.part = null;
selectionEvent = theEvent;
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
*/
@Override
public void selectionChanged(IWorkbenchPart thePart,
ISelection theSelection) {
this.part = thePart;
selection = theSelection;
selectionEvent = null;
}
/**
* Sets the localization identifier for the accelerator. Causes the accelerator to be changed.
* <strong>The accelerator is actually set when the text identifier is set.</strong>
* <p>
* Here are some example properties file entries for setting accelerator:
* <ul>
* <li>org.teiid.designer.ui.action.MyAction.accelerator=Ctrl+M
* <li>org.teiid.designer.ui.action.YourAction.accelerator=Alt+Y
* <li>org.teiid.designer.ui.action.TheirAction.accelerator=Shift+T
* <li>org.teiid.designer.ui.action.OurAction.accelerator=Command+O
* <li>org.teiid.designer.ui.action.FindAction.accelerator=F3
* </ul>
* @param theId the localization identifier
* @see #setTextId(String)
*/
public void setAcceleratorId(String theId) {
acceleratorId = theId;
}
/**
* Sets the localization identifier for the description. Causes the description to be changed.
* If <code>null</code> is passed in the description is changed to an empty string.
* @param theId the localization identifier
*/
public void setDescriptionId(String theId) {
descriptionId = theId;
setDescription((theId != null) ? pluginUtils.getString(theId)
: ""); //$NON-NLS-1$
}
/**
* Sets the disabled {@link ImageDescriptor} by using the given <code>Image</code>.
* @param theImage the image being used to create the disabled <code>ImageDescriptor</code>
*/
public void setDisabledImage(Image theImage) {
setDisabledImageDescriptor(new ImageImageDescriptor(theImage));
}
/**
* Sets the path/file identifier for the disabled image. Causes the {@link ImageDescriptor} to change.
* @param theId the image identifier
*/
public void setDisabledImageId(String theId) {
disabledImageId = theId;
ImageDescriptor descriptor = null;
if (theId != null) {
descriptor = plugin.getImageDescriptor(pluginUtils.getString(theId));
}
super.setDisabledImageDescriptor(descriptor);
}
/**
* Sets the identifier used for context sensitive help.
* @param theId the context help identifier
*/
public void setHelpContextId(String theId) {
helpId = theId;
part.getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(this, theId);
}
/**
* Sets the hover {@link ImageDescriptor} by using the given <code>Image</code>.
* @param theImage the image being used to create the hover <code>ImageDescriptor</code>
*/
public void setHoverImage(Image theImage) {
setHoverImageDescriptor(new ImageImageDescriptor(theImage));
}
/**
* Sets the path/file identifier for the hover image. Causes the {@link ImageDescriptor} to change.
* @param theId the image identifier
*/
public void setHoverImageId(String theId) {
hoverImageId = theId;
ImageDescriptor descriptor = null;
if (theId != null) {
descriptor = plugin.getImageDescriptor(pluginUtils.getString(theId));
}
super.setHoverImageDescriptor(descriptor);
}
/**
* Sets the {@link ImageDescriptor} by using the given <code>Image</code>.
* @param theImage the image being used to create the <code>ImageDescriptor</code>
*/
public void setImage(Image theImage) {
setImageDescriptor(new ImageImageDescriptor(theImage));
}
/**
* Sets the path/file identifier for the image. Causes the {@link ImageDescriptor} to change.
* @param theId the image identifier
*/
public void setImageId(String theId) {
imageId = theId;
ImageDescriptor descriptor = null;
if (theId != null) {
descriptor = plugin.getImageDescriptor(pluginUtils.getString(theId));
}
super.setImageDescriptor(descriptor);
}
/**
* Sets the utility object used for resource bundle lookups and logging. Defaults to use
* <code>org.teiid.designer.ui.UiPlugin</code>.
* @param theUtil the utility instance
*/
public void setPluginUtil(PluginUtil theUtil) {
pluginUtils = theUtil;
}
/**
* Sets the localization identifier for the label text. Causes the label text to be changed.
* If <code>null</code> is passed in the text is changed to an empty string. Also, if an accelerator
* identifier has been set, the accelerator is set.
* @param theId the localization identifier
*/
public void setTextId(String theId) {
textId = theId;
// get the label text
String label = (theId != null) ? pluginUtils.getString(theId)
: ""; //$NON-NLS-1$
// if accelerator exists add it to the text of the label in the format required by
// org.eclipse.jface.action.Action.
if (acceleratorId != null) {
String acceleratorText = pluginUtils.getString(acceleratorId);
if ((acceleratorText != null) && acceleratorText.length() > 0) {
label += "@" + acceleratorText; //$NON-NLS-1$
}
}
setText(label);
}
/**
* Sets the localization identifier for the tool tip text. Causes the tool tip text to be changed.
* If <code>null</code> is passed in the tooltip text is changed to an empty string.
* @param theId the localization identifier
*/
public void setToolTipTextId(String theId) {
tipId = theId;
setToolTipText((theId != null) ? pluginUtils.getString(theId)
: ""); //$NON-NLS-1$
}
/**
* Allow subclass to veto or reinstate using a wait-cursor.
*
* @param flag use wait-cursor if true, not if false
*/
protected void setUseWaitCursor(boolean flag) {
this.useWaitCursor = flag;
}
/**
* Force subclass to implement a doRun() method which is a substitute for the run() method
* which is declared as final in this class to force usage of a wait-cursor.
*/
protected abstract void doRun();
/**
* This method is called in the run() method of AbstractAction to give the actions a hook into canceling
* the run at the last minute.
*/
protected boolean preRun() {
return true;
}
/**
* Subclasses implement a doRun() method which substitutes for run(). run() is here and
* runs doRun() as a Runnable, in order to pass the Runnable to BusyIndicator which will
* display a wait-cursor.
*/
@Override
public final void run() {
if( preRun() ) {
if (useWaitCursor) {
Runnable runnable = new Runnable() {
@Override
public void run() {
doRun();
}
};
UiBusyIndicator.showWhile(null, runnable);
} else {
doRun();
}
}
postRun();
}
/**
* This method is called in the run() method of AbstractAction to give the actions a way to
* implement post processing behavior, for example cleaning up state that is created during
* the run.
*
*/
protected void postRun() {
// no action
}
}