/*******************************************************************************
 * 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.jface.action;

import org.eclipse.jface.action.ExternalActionManager.IBindingManagerCallback;
import org.eclipse.jface.bindings.Trigger;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.IKeyLookup;
import org.eclipse.jface.bindings.keys.KeyLookupFactory;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;

/**
 * A contribution item which delegates to an action.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 */
public class ActionContributionItem extends ContributionItem {

    /**
     * Mode bit: Show text on tool items, even if an image is present.
     * If this mode bit is not set, text is only shown on tool items if there is 
     * no image present.
     * 
     * @since 3.0
     */
    public static int MODE_FORCE_TEXT = 1;

    /** a string inserted in the middle of text that has been shortened */
    private static final String ellipsis = "..."; //$NON-NLS-1$

    private static boolean USE_COLOR_ICONS = true;

    /**
     * Returns whether color icons should be used in toolbars.
     * 
     * @return <code>true</code> if color icons should be used in toolbars, 
     *   <code>false</code> otherwise
     */
    public static boolean getUseColorIconsInToolbars() {
        return USE_COLOR_ICONS;
    }

    /**
     * Sets whether color icons should be used in toolbars.
     * 
     * @param useColorIcons <code>true</code> if color icons should be used in toolbars, 
     *   <code>false</code> otherwise
     */
    public static void setUseColorIconsInToolbars(boolean useColorIcons) {
        USE_COLOR_ICONS = useColorIcons;
    }

    /**
     * The presentation mode.
     */
    private int mode = 0;

    /**
     * The action.
     */
    private IAction action;

    /**
     * The listener for changes to the text of the action contributed by an
     * external source.
     */
    private final IPropertyChangeListener actionTextListener = new IPropertyChangeListener() {

        /**
         * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
         */
        public void propertyChange(PropertyChangeEvent event) {
            update(event.getProperty());
        }
    };

    /**
     * Remembers all images in use by this contribution item
     */
    private LocalResourceManager imageManager;
    
    /**
     * Listener for SWT button widget events.
     */
    private Listener buttonListener;

    /**
     * Listener for SWT menu item widget events.
     */
    private Listener menuItemListener;

    /**
     * Listener for action property change notifications.
     */
    private final IPropertyChangeListener propertyListener = new IPropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent event) {
            actionPropertyChange(event);
        }
    };

    /**
     * Listener for SWT tool item widget events.
     */
    private Listener toolItemListener;

    /**
     * The widget created for this item; <code>null</code>
     * before creation and after disposal.
     */
    private Widget widget = null;

    /**
     * Creates a new contribution item from the given action. The id of the
     * action is used as the id of the item.
     * 
     * @param action
     *            the action
     */
    public ActionContributionItem(IAction action) {
        super(action.getId());
        this.action = action;
    }

    /**
     * Handles a property change event on the action (forwarded by nested listener).
     */
    private void actionPropertyChange(final PropertyChangeEvent e) {
        // This code should be removed. Avoid using free asyncExec

        if (isVisible() && widget != null) {
            Display display = widget.getDisplay();
            if (display.getThread() == Thread.currentThread()) {
                update(e.getProperty());
            } else {
                display.asyncExec(new Runnable() {
                    public void run() {
                        update(e.getProperty());
                    }
                });
            }

        }
    }

    /**
     * Compares this action contribution item with another object.
     * Two action contribution items are equal if they refer to the identical Action.
     */
    public boolean equals(Object o) {
        if (!(o instanceof ActionContributionItem)) {
            return false;
        }
        return action.equals(((ActionContributionItem) o).action);
    }

    /**
     * The <code>ActionContributionItem</code> implementation of this
     * <code>IContributionItem</code> method creates an SWT <code>Button</code> for
     * the action using the action's style. If the action's checked property has
     * been set, the button is created and primed to the value of the checked
     * property.
     */
    public void fill(Composite parent) {
        if (widget == null && parent != null) {
            int flags = SWT.PUSH;
            if (action != null) {
                if (action.getStyle() == IAction.AS_CHECK_BOX)
                    flags = SWT.TOGGLE;
                if (action.getStyle() == IAction.AS_RADIO_BUTTON)
                    flags = SWT.RADIO;
            }

            Button b = new Button(parent, flags);
            b.setData(this);
            b.addListener(SWT.Dispose, getButtonListener());
            // Don't hook a dispose listener on the parent
            b.addListener(SWT.Selection, getButtonListener());
            if (action.getHelpListener() != null)
                b.addHelpListener(action.getHelpListener());
            widget = b;

            update(null);

            // Attach some extra listeners.
            action.addPropertyChangeListener(propertyListener);
            if (action != null) {
                String commandId = action.getActionDefinitionId();
                ExternalActionManager.ICallback callback = ExternalActionManager
                        .getInstance().getCallback();

                if ((callback != null) && (commandId != null)) {
                    callback.addPropertyChangeListener(commandId,
                            actionTextListener);
                }
            }
        }
    }

    /**
     * The <code>ActionContributionItem</code> implementation of this
     * <code>IContributionItem</code> method creates an SWT <code>MenuItem</code>
     * for the action using the action's style. If the action's checked property has
     * been set, a button is created and primed to the value of the checked
     * property. If the action's menu creator property has been set, a cascading
     * submenu is created.
     */
    public void fill(Menu parent, int index) {
        if (widget == null && parent != null) {
            Menu subMenu = null;
            int flags = SWT.PUSH;
            if (action != null) {
                int style = action.getStyle();
                if (style == IAction.AS_CHECK_BOX)
                    flags = SWT.CHECK;
                else if (style == IAction.AS_RADIO_BUTTON)
                    flags = SWT.RADIO;
                else if (style == IAction.AS_DROP_DOWN_MENU) {
                    IMenuCreator mc = action.getMenuCreator();
                    if (mc != null) {
                        subMenu = mc.getMenu(parent);
                        flags = SWT.CASCADE;
                    }
                }
            }

            MenuItem mi = null;
            if (index >= 0)
                mi = new MenuItem(parent, flags, index);
            else
                mi = new MenuItem(parent, flags);
            widget = mi;

            mi.setData(this);
            mi.addListener(SWT.Dispose, getMenuItemListener());
            mi.addListener(SWT.Selection, getMenuItemListener());
            if (action.getHelpListener() != null)
                mi.addHelpListener(action.getHelpListener());

            if (subMenu != null)
                mi.setMenu(subMenu);

            update(null);

            // Attach some extra listeners.
            action.addPropertyChangeListener(propertyListener);
            if (action != null) {
                String commandId = action.getActionDefinitionId();
                ExternalActionManager.ICallback callback = ExternalActionManager
                        .getInstance().getCallback();

                if ((callback != null) && (commandId != null)) {
                    callback.addPropertyChangeListener(commandId,
                            actionTextListener);
                }
            }
        }
    }

    /**
     * The <code>ActionContributionItem</code> implementation of this ,
     * <code>IContributionItem</code> method creates an SWT <code>ToolItem</code>
     * for the action using the action's style. If the action's checked property has
     * been set, a button is created and primed to the value of the checked
     * property. If the action's menu creator property has been set, a drop-down
     * tool item is created.
     */
    public void fill(ToolBar parent, int index) {
        if (widget == null && parent != null) {
            int flags = SWT.PUSH;
            if (action != null) {
                int style = action.getStyle();
                if (style == IAction.AS_CHECK_BOX)
                    flags = SWT.CHECK;
                else if (style == IAction.AS_RADIO_BUTTON)
                    flags = SWT.RADIO;
                else if (style == IAction.AS_DROP_DOWN_MENU)
                    flags = SWT.DROP_DOWN;
            }

            ToolItem ti = null;
            if (index >= 0)
                ti = new ToolItem(parent, flags, index);
            else
                ti = new ToolItem(parent, flags);
            ti.setData(this);
            ti.addListener(SWT.Selection, getToolItemListener());
            ti.addListener(SWT.Dispose, getToolItemListener());

            widget = ti;

            update(null);

            // Attach some extra listeners.
            action.addPropertyChangeListener(propertyListener);
            if (action != null) {
                String commandId = action.getActionDefinitionId();
                ExternalActionManager.ICallback callback = ExternalActionManager
                        .getInstance().getCallback();

                if ((callback != null) && (commandId != null)) {
                    callback.addPropertyChangeListener(commandId,
                            actionTextListener);
                }
            }
        }
    }

    /**
     * Returns the action associated with this contribution item.
     *
     * @return the action
     */
    public IAction getAction() {
        return action;
    }

    /**
     * Returns the listener for SWT button widget events.
     * 
     * @return a listener for button events
     */
    private Listener getButtonListener() {
        if (buttonListener == null) {
            buttonListener = new Listener() {
                public void handleEvent(Event event) {
                    switch (event.type) {
                    case SWT.Dispose:
                        handleWidgetDispose(event);
                        break;
                    case SWT.Selection:
                        Widget ew = event.widget;
                        if (ew != null) {
                            handleWidgetSelection(event, ((Button) ew)
                                    .getSelection());
                        }
                        break;
                    }
                }
            };
        }
        return buttonListener;
    }

    /**
     * Returns the listener for SWT menu item widget events.
     * 
     * @return a listener for menu item events
     */
    private Listener getMenuItemListener() {
        if (menuItemListener == null) {
            menuItemListener = new Listener() {
                public void handleEvent(Event event) {
                    switch (event.type) {
                    case SWT.Dispose:
                        handleWidgetDispose(event);
                        break;
                    case SWT.Selection:
                        Widget ew = event.widget;
                        if (ew != null) {
                            handleWidgetSelection(event, ((MenuItem) ew)
                                    .getSelection());
                        }
                        break;
                    }
                }
            };
        }
        return menuItemListener;
    }

    /**
     * Returns the presentation mode, which is the bitwise-or of the 
     * <code>MODE_*</code> constants.  The default mode setting is 0, meaning
     * that for menu items, both text and image are shown (if present), but for
     * tool items, the text is shown only if there is no image.
     * 
     * @return the presentation mode settings
     * 
     * @since 3.0
     */
    public int getMode() {
        return mode;
    }

    /**
     * Returns the listener for SWT tool item widget events.
     * 
     * @return a listener for tool item events
     */
    private Listener getToolItemListener() {
        if (toolItemListener == null) {
            toolItemListener = new Listener() {
                public void handleEvent(Event event) {
                    switch (event.type) {
                    case SWT.Dispose:
                        handleWidgetDispose(event);
                        break;
                    case SWT.Selection:
                        Widget ew = event.widget;
                        if (ew != null) {
                            handleWidgetSelection(event, ((ToolItem) ew)
                                    .getSelection());
                        }
                        break;
                    }
                }
            };
        }
        return toolItemListener;
    }

    /**
     * Handles a widget dispose event for the widget corresponding to this item.
     */
    private void handleWidgetDispose(Event e) {
        // Check if our widget is the one being disposed.
        if (e.widget == widget) {
            // Dispose of the menu creator.
            if (action.getStyle() == IAction.AS_DROP_DOWN_MENU) {
                IMenuCreator mc = action.getMenuCreator();
                if (mc != null) {
                    mc.dispose();
                }
            }

            // Unhook all of the listeners.
            action.removePropertyChangeListener(propertyListener);
            if (action != null) {
                String commandId = action.getActionDefinitionId();
                ExternalActionManager.ICallback callback = ExternalActionManager
                        .getInstance().getCallback();

                if ((callback != null) && (commandId != null)) {
                    callback.removePropertyChangeListener(commandId,
                            actionTextListener);
                }
            }

            // Clear the widget field.
            widget = null;
            
            disposeOldImages();
        }
    }

    /**
     * Handles a widget selection event.
     */
    private void handleWidgetSelection(Event e, boolean selection) {

        Widget item = e.widget;
        if (item != null) {
            int style = item.getStyle();

            if ((style & (SWT.TOGGLE | SWT.CHECK)) != 0) {
                if (action.getStyle() == IAction.AS_CHECK_BOX) {
                    action.setChecked(selection);
                }
            } else if ((style & SWT.RADIO) != 0) {
                if (action.getStyle() == IAction.AS_RADIO_BUTTON) {
                    action.setChecked(selection);
                }
            } else if ((style & SWT.DROP_DOWN) != 0) {
                if (e.detail == 4) { // on drop-down button
                    if (action.getStyle() == IAction.AS_DROP_DOWN_MENU) {
                        IMenuCreator mc = action.getMenuCreator();
                        ToolItem ti = (ToolItem) item;
                        // we create the menu as a sub-menu of "dummy" so that we can use
                        // it in a cascading menu too.
                        // If created on a SWT control we would get an SWT error...
                        //Menu dummy= new Menu(ti.getParent());
                        //Menu m= mc.getMenu(dummy);
                        //dummy.dispose();
                        if (mc != null) {
                            Menu m = mc.getMenu(ti.getParent());
                            if (m != null) {
                                // position the menu below the drop down item
                                Rectangle b = ti.getBounds();
                                Point p = ti.getParent().toDisplay(
                                        new Point(b.x, b.y + b.height));
                                m.setLocation(p.x, p.y); // waiting for SWT 0.42
                                m.setVisible(true);
                                return; // we don't fire the action
                            }
                        }
                    }
                }
            }

            // Ensure action is enabled first.
            // See 1GAN3M6: ITPUI:WINNT - Any IAction in the workbench can be executed while disabled.
            if (action.isEnabled()) {
                boolean trace = Policy.TRACE_ACTIONS;

                long ms = System.currentTimeMillis();
                if (trace)
                    System.out.println("Running action: " + action.getText()); //$NON-NLS-1$

                action.runWithEvent(e);

                if (trace)
                    System.out.println((System.currentTimeMillis() - ms)
                            + " ms to run action: " + action.getText()); //$NON-NLS-1$
            }
        }
    }

    /* (non-Javadoc)
     * Method declared on Object.
     */
    public int hashCode() {
        return action.hashCode();
    }

    /**
     * Returns whether the given action has any images.
     * 
     * @param actionToCheck the action
     * @return <code>true</code> if the action has any images, <code>false</code> if not
     */
    private boolean hasImages(IAction actionToCheck) {
        return actionToCheck.getImageDescriptor() != null
                || actionToCheck.getHoverImageDescriptor() != null
                || actionToCheck.getDisabledImageDescriptor() != null;
    }

    /**
     * Returns whether the command corresponding to this action
     * is active.
     */
    private boolean isCommandActive() {
        IAction actionToCheck = getAction();

        if (actionToCheck != null) {
            String commandId = actionToCheck.getActionDefinitionId();
            ExternalActionManager.ICallback callback = ExternalActionManager
                    .getInstance().getCallback();

            if (callback != null)
                return callback.isActive(commandId);
        }
        return true;
    }

    /**
     * The action item implementation of this <code>IContributionItem</code>
     * method returns <code>true</code> for menu items and <code>false</code>
     * for everything else.
     */
    public boolean isDynamic() {
        if (widget instanceof MenuItem) {
            //Optimization. Only recreate the item is the check or radio style has changed. 
            boolean itemIsCheck = (widget.getStyle() & SWT.CHECK) != 0;
            boolean actionIsCheck = getAction() != null
                    && getAction().getStyle() == IAction.AS_CHECK_BOX;
            boolean itemIsRadio = (widget.getStyle() & SWT.RADIO) != 0;
            boolean actionIsRadio = getAction() != null
                    && getAction().getStyle() == IAction.AS_RADIO_BUTTON;
            return (itemIsCheck != actionIsCheck)
                    || (itemIsRadio != actionIsRadio);
        }
        return false;
    }

    /* (non-Javadoc)
     * Method declared on IContributionItem.
     */
    public boolean isEnabled() {
        return action != null && action.isEnabled();
    }

    /**
     * Returns <code>true</code> if this item is allowed to enable,
     * <code>false</code> otherwise.
     * 
     * @return if this item is allowed to be enabled
     * @since 2.0
     */
    protected boolean isEnabledAllowed() {
        if (getParent() == null)
            return true;
        Boolean value = getParent().getOverrides().getEnabled(this);
        return (value == null) ? true : value.booleanValue();
    }

    /**
     * The <code>ActionContributionItem</code> implementation of this 
     * <code>ContributionItem</code> method extends the super implementation
     * by also checking whether the command corresponding to this action is active.
     */
    public boolean isVisible() {
        return super.isVisible() && isCommandActive();
    }

    /**
     * Sets the presentation mode, which is the bitwise-or of the 
     * <code>MODE_*</code> constants.
     * 
     * @param mode the presentation mode settings
     * 
     * @since 3.0
     */
    public void setMode(int mode) {
        this.mode = mode;
        update();
    }

    /**
     * The action item implementation of this <code>IContributionItem</code>
     * method calls <code>update(null)</code>.
     */
    public final void update() {
        update(null);
    }

    /**
     * Synchronizes the UI with the given property.
     *
     * @param propertyName the name of the property, or <code>null</code> meaning all applicable
     *   properties 
     */
    public void update(String propertyName) {
        if (widget != null) {
            // determine what to do			
            boolean textChanged = propertyName == null
                    || propertyName.equals(IAction.TEXT);
            boolean imageChanged = propertyName == null
                    || propertyName.equals(IAction.IMAGE);
            boolean tooltipTextChanged = propertyName == null
                    || propertyName.equals(IAction.TOOL_TIP_TEXT);
            boolean enableStateChanged = propertyName == null
                    || propertyName.equals(IAction.ENABLED)
                    || propertyName
                            .equals(IContributionManagerOverrides.P_ENABLED);
            boolean checkChanged = (action.getStyle() == IAction.AS_CHECK_BOX || action
                    .getStyle() == IAction.AS_RADIO_BUTTON)
                    && (propertyName == null || propertyName
                            .equals(IAction.CHECKED));

            if (widget instanceof ToolItem) {
                ToolItem ti = (ToolItem) widget;
                String text = action.getText();
                // the set text is shown only if there is no image or if forced by MODE_FORCE_TEXT
                boolean showText = text != null
                        && ((getMode() & MODE_FORCE_TEXT) != 0 || !hasImages(action));

                // only do the trimming if the text will be used
                if (showText && text != null) {
                    text = Action.removeAcceleratorText(text);
                    text = Action.removeMnemonics(text);
                }

                if (textChanged) {
                    String textToSet = showText ? text : ""; //$NON-NLS-1$
                    boolean rightStyle = (ti.getParent().getStyle() & SWT.RIGHT) != 0;
                    if (rightStyle || !ti.getText().equals(textToSet)) {
                        // In addition to being required to update the text if it
                        // gets nulled out in the action, this is also a workaround 
                        // for bug 50151: Using SWT.RIGHT on a ToolBar leaves blank space
                        ti.setText(textToSet);
                    }
                }

                if (imageChanged) {
                    // only substitute a missing image if it has no text
                    updateImages(!showText);
                }

                if (tooltipTextChanged || textChanged) {
                    String toolTip = action.getToolTipText();
                    // if the text is showing, then only set the tooltip if different
                    if (!showText || toolTip != null && !toolTip.equals(text)) {
                        ti.setToolTipText(toolTip);
                    } else {
                        ti.setToolTipText(null);
                    }
                }

                if (enableStateChanged) {
                    boolean shouldBeEnabled = action.isEnabled()
                            && isEnabledAllowed();

                    if (ti.getEnabled() != shouldBeEnabled)
                        ti.setEnabled(shouldBeEnabled);
                }

                if (checkChanged) {
                    boolean bv = action.isChecked();

                    if (ti.getSelection() != bv)
                        ti.setSelection(bv);
                }
                return;
            }

            if (widget instanceof MenuItem) {
                MenuItem mi = (MenuItem) widget;

                if (textChanged) {
                    int accelerator = 0;
					String acceleratorText = null;
					IAction updatedAction = getAction();
					String text = null;
					accelerator = updatedAction.getAccelerator();
					ExternalActionManager.ICallback callback = ExternalActionManager
							.getInstance().getCallback();

					// Block accelerators that are already in use.
					if ((accelerator != 0) && (callback != null)
                            && (callback.isAcceleratorInUse(accelerator))) {
                        accelerator = 0;
					}

					/*
					 * Process accelerators on GTK in a special way to avoid Bug
					 * 42009. We will override the native input method by
					 * allowing these reserved accelerators to be placed on the
					 * menu. We will only do this for "Ctrl+Shift+[0-9A-FU]".
					 */
					final String commandId = updatedAction
							.getActionDefinitionId();
					if (("gtk".equals(SWT.getPlatform())) && (callback instanceof IBindingManagerCallback) //$NON-NLS-1$
							&& (commandId != null)) {
						final IBindingManagerCallback bindingManagerCallback = (IBindingManagerCallback) callback;
						final IKeyLookup lookup = KeyLookupFactory.getDefault();
						final TriggerSequence[] triggerSequences = bindingManagerCallback
								.getActiveBindingsFor(commandId);
						for (int i = 0; i < triggerSequences.length; i++) {
							final TriggerSequence triggerSequence = triggerSequences[i];
							final Trigger[] triggers = triggerSequence
									.getTriggers();
							if (triggers.length == 1) {
								final Trigger trigger = triggers[0];
								if (trigger instanceof KeyStroke) {
									final KeyStroke currentKeyStroke = (KeyStroke) trigger;
									final int currentNaturalKey = currentKeyStroke
											.getNaturalKey();
									if ((currentKeyStroke.getModifierKeys() == (lookup
											.getCtrl() | lookup.getShift()))
											&& ((currentNaturalKey >= '0' && currentNaturalKey <= '9')
													|| (currentNaturalKey >= 'A' && currentNaturalKey <= 'F') || (currentNaturalKey == 'U'))) {
										accelerator = currentKeyStroke
												.getModifierKeys()
												| currentNaturalKey;
										acceleratorText = triggerSequence
												.format();
										break;
									}
								}
							}
						}
					}

                    if (accelerator == 0) {
                        if ((callback != null) && (commandId != null)) {
                            acceleratorText = callback
                                    .getAcceleratorText(commandId);
                        }
                    } else {
                        acceleratorText = Action
                                .convertAccelerator(accelerator);
                    }

                    IContributionManagerOverrides overrides = null;

                    if (getParent() != null)
                        overrides = getParent().getOverrides();

                    if (overrides != null)
                        text = getParent().getOverrides().getText(this);

                    mi.setAccelerator(accelerator);

                    if (text == null)
                        text = updatedAction.getText();

                    if (text == null)
                        text = ""; //$NON-NLS-1$
                    else
                        text = Action.removeAcceleratorText(text);

                    if (acceleratorText == null)
                        mi.setText(text);
                    else
                        mi.setText(text + '\t' + acceleratorText);
                }

                if (imageChanged)
                    updateImages(false);

                if (enableStateChanged) {
                    boolean shouldBeEnabled = action.isEnabled()
                            && isEnabledAllowed();

                    if (mi.getEnabled() != shouldBeEnabled)
                        mi.setEnabled(shouldBeEnabled);
                }

                if (checkChanged) {
                    boolean bv = action.isChecked();

                    if (mi.getSelection() != bv)
                        mi.setSelection(bv);
                }

                return;
            }

            if (widget instanceof Button) {
                Button button = (Button) widget;

                if (imageChanged && updateImages(false))
                    textChanged = false; // don't update text if it has an image

                if (textChanged) {
                    String text = action.getText();
                    if (text == null)
                        text = ""; //$NON-NLS-1$
                    else
                        text = Action.removeAcceleratorText(text);
                    button.setText(text);
                }

                if (tooltipTextChanged)
                    button.setToolTipText(action.getToolTipText());

                if (enableStateChanged) {
                    boolean shouldBeEnabled = action.isEnabled()
                            && isEnabledAllowed();

                    if (button.getEnabled() != shouldBeEnabled)
                        button.setEnabled(shouldBeEnabled);
                }

                if (checkChanged) {
                    boolean bv = action.isChecked();

                    if (button.getSelection() != bv)
                        button.setSelection(bv);
                }
                return;
            }
        }
    }

    /**
     * Updates the images for this action.
     *
     * @param forceImage <code>true</code> if some form of image is compulsory,
     *  and <code>false</code> if it is acceptable for this item to have no image
     * @return <code>true</code> if there are images for this action, <code>false</code> if not
     */
    private boolean updateImages(boolean forceImage) {

        ResourceManager parentResourceManager = JFaceResources.getResources();
        
        if (widget instanceof ToolItem) {
            if (USE_COLOR_ICONS) {
                ImageDescriptor image = action.getHoverImageDescriptor();
                if (image == null) {
                    image = action.getImageDescriptor();
                }
                ImageDescriptor disabledImage = action
                        .getDisabledImageDescriptor();

                // Make sure there is a valid image.
                if (image == null && forceImage) {
                    image = ImageDescriptor.getMissingImageDescriptor();
                }
        
                LocalResourceManager localManager = new LocalResourceManager(parentResourceManager);
                
                // performance: more efficient in SWT to set disabled and hot image before regular image
                ((ToolItem) widget).setDisabledImage(disabledImage == null ? null : localManager.createImageWithDefault(disabledImage));
                ((ToolItem) widget).setImage(image == null ? null : localManager.createImageWithDefault(image));

                disposeOldImages();
                imageManager = localManager;
                
                return image != null;
            }
            ImageDescriptor image = action.getImageDescriptor();
            ImageDescriptor hoverImage = action
                    .getHoverImageDescriptor();
            ImageDescriptor disabledImage = action
                    .getDisabledImageDescriptor();

            // If there is no regular image, but there is a hover image,
            // convert the hover image to gray and use it as the regular image.
            if (image == null && hoverImage != null) {
                image = ImageDescriptor.createWithFlags(action.getHoverImageDescriptor(), SWT.IMAGE_GRAY); 
            } else {
                // If there is no hover image, use the regular image as the hover image,
                // and convert the regular image to gray
                if (hoverImage == null && image != null) {
                    hoverImage = image;
                    image = ImageDescriptor.createWithFlags(action.getImageDescriptor(), SWT.IMAGE_GRAY);
                }
            }

            // Make sure there is a valid image.
            if (hoverImage == null && image == null && forceImage) {
                image = ImageDescriptor.getMissingImageDescriptor();
            }

            // Create a local resource manager to remember the images we've allocated for this tool item
            LocalResourceManager localManager = new LocalResourceManager(parentResourceManager);
            
            // performance: more efficient in SWT to set disabled and hot image before regular image
            ((ToolItem) widget).setDisabledImage(disabledImage == null? null : localManager.createImageWithDefault(disabledImage));
            ((ToolItem) widget).setHotImage(hoverImage == null? null : localManager.createImageWithDefault(hoverImage));
            ((ToolItem) widget).setImage(image == null? null : localManager.createImageWithDefault(image));

            // Now that we're no longer referencing the old images, clear them out.
            disposeOldImages();
            imageManager = localManager;
            
            return image != null;
        } else if (widget instanceof Item || widget instanceof Button) {
            
            // Use hover image if there is one, otherwise use regular image.
            ImageDescriptor image = action.getHoverImageDescriptor();
            if (image == null) {
                image = action.getImageDescriptor();
            }
            // Make sure there is a valid image.
            if (image == null && forceImage) {
                image = ImageDescriptor.getMissingImageDescriptor();
            }
            
            // Create a local resource manager to remember the images we've allocated for this widget
            LocalResourceManager localManager = new LocalResourceManager(parentResourceManager);
            
            if (widget instanceof Item) {
                ((Item) widget).setImage(image == null ? null : localManager.createImageWithDefault(image));
            } else if (widget instanceof Button) {
                ((Button) widget).setImage(image == null ? null : localManager.createImageWithDefault(image));
            }
            
            // Now that we're no longer referencing the old images, clear them out.
            disposeOldImages();
            imageManager = localManager;
            
            return image != null;
        }
        return false;
    }

    /**
     * Dispose any images allocated for this contribution item
     */
    private void disposeOldImages() {
        if (imageManager != null) {
            imageManager.dispose();
            imageManager = null;
        }
    }

    /**
     * Shorten the given text <code>t</code> so that its length doesn't
     * exceed the given width. The default implementation replaces characters
     * in the center of the original string with an ellipsis ("..."). Override
     * if you need a different strategy.
     */
    protected String shortenText(String textValue, ToolItem item) {
        if (textValue == null)
            return null;

        GC gc = new GC(item.getParent());

        int maxWidth = item.getImage().getBounds().width * 4;

        if (gc.textExtent(textValue).x < maxWidth) {
            gc.dispose();
            return textValue;
        }

        for (int i = textValue.length(); i > 0; i--) {
            String test = textValue.substring(0, i);
            test = test + ellipsis;
            if (gc.textExtent(test).x < maxWidth) {
                gc.dispose();
                return test;
            }

        }
        gc.dispose();
        //If for some reason we fall through abort
        return textValue;
    }
}
