net.enilink.komma.edit.ui.action.StaticSelectionCommandAction.java Source code

Java tutorial

Introduction

Here is the source code for net.enilink.komma.edit.ui.action.StaticSelectionCommandAction.java

Source

/**
 * <copyright> 
 *
 * Copyright (c) 2002, 2009 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 - Initial API and implementation
 *
 * </copyright>
 *
 * $Id: StaticSelectionCommandAction.java,v 1.7 2007/09/30 10:31:30 emerks Exp $
 */
package net.enilink.komma.edit.ui.action;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;

import net.enilink.komma.common.command.ICommand;
import net.enilink.komma.common.command.UnexecutableCommand;
import net.enilink.komma.edit.command.ICommandActionDelegate;
import net.enilink.komma.edit.command.IInputCallback;
import net.enilink.komma.edit.domain.AdapterFactoryEditingDomain;
import net.enilink.komma.edit.domain.IEditingDomain;
import net.enilink.komma.edit.ui.editor.InputCallbackDialog;
import net.enilink.komma.edit.ui.provider.ExtendedImageRegistry;

/**
 * This class is used as a basis for implementing an
 * {@link org.eclipse.jface.action.IAction} on the menubar, the toolbar, or a
 * pop-up menu by delegating all required behaviour to a {@link ICommand}, only
 * when it is guaranteed that the selection will not change during the life of
 * the action. In other words, the action itself would be created based on the
 * selection, and destroyed when the selection changed. All possible aspects of
 * the action are delegated to the command, namely the enablement state and, if
 * it implements {@link ICommandActionDelegate}, the text, the toolbar icon, and
 * the tool tip text; however, this need only be done once, at the time the
 * action is created.
 * 
 * <p>
 * Subclasses must provide an implementation for {@link #createActionCommand}
 * that creates the command to perform this action. They may also override
 * {@link #getDefaultImageDescriptor} to provide a default icon and
 * {@link #disable} to set the action's state when a command cannot be created.
 */
public abstract class StaticSelectionCommandAction extends AbstractActionHandler {
    /**
     * This records the editing domain of the current editor or viewer. For
     * global popups, we try to determine the editing domain from the selected
     * objects themselves.
     */
    protected IEditingDomain editingDomain;

    /**
     * This records the command.
     */
    protected ICommand command;

    /**
     * This constructs an instance for a command to be executed via
     * workbenchPart's editing domain.
     */
    public StaticSelectionCommandAction(IWorkbenchPart workbenchPart, ISelection selection) {
        super(workbenchPart, selection);
        editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(workbenchPart);
    }

    /**
     * This constructs an instance for a command to be executed via the given
     * editing domain.
     */
    public StaticSelectionCommandAction(IWorkbenchPart workbenchPart, IEditingDomain editingDomain,
            ISelection selection) {
        super(workbenchPart, selection);
        this.editingDomain = editingDomain;
    }

    /**
     * This should be implemented to create a command that performs the action.
     */
    protected abstract ICommand createActionCommand(IEditingDomain editingDomain, Collection<?> collection);

    /**
     * This extracts the objects from selection, invokes createActionCommand to
     * create the command, and then configures the action based on the result.
     */
    @Override
    public void refresh() {
        // only handle structured selections
        if (!(getSelection() instanceof IStructuredSelection)) {
            disable();
        } else {
            // convert the selection to a collection of the selected objects
            IStructuredSelection sselection = getStructuredSelection();
            List<?> list = sselection.toList();
            Collection<Object> collection = new ArrayList<Object>(list);

            // if the editing domain wasn't given by the workbench part, try to
            // get
            // it from the selection
            if (editingDomain == null) {
                for (Object o : collection) {
                    editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(o);
                    if (editingDomain != null) {
                        break;
                    }
                }
            }

            // if we found an editing domain, create command
            if (editingDomain != null) {
                command = createActionCommand(editingDomain, collection);
                setEnabled(command.canExecute());
            }

            // give up if we couldn't create the command; otherwise, use a
            // CommandActionDelegate to set the action's text, tool-tip, icon,
            // etc. or just use the default icon
            if (command == null || command == UnexecutableCommand.INSTANCE) {
                disable();
            } else if (!(command instanceof ICommandActionDelegate)) {
                if (getDefaultImageDescriptor() != null) {
                    setImageDescriptor(getDefaultImageDescriptor());
                }
            } else {
                ICommandActionDelegate commandActionDelegate = (ICommandActionDelegate) command;

                ImageDescriptor imageDescriptor = objectToImageDescriptor(commandActionDelegate.getImage());
                if (imageDescriptor != null) {
                    setImageDescriptor(imageDescriptor);
                } else if (getDefaultImageDescriptor() != null) {
                    setImageDescriptor(getDefaultImageDescriptor());
                }

                if (commandActionDelegate.getText() != null) {
                    setText(commandActionDelegate.getText());
                }

                if (commandActionDelegate.getDescription() != null) {
                    setDescription(commandActionDelegate.getDescription());
                }

                if (commandActionDelegate.getToolTipText() != null) {
                    setToolTipText(commandActionDelegate.getToolTipText());
                }
            }
        }
    }

    /**
     * This can be overridden to provide the image descriptor used when the
     * command does not provide one. This implementation simply returns null.
     */
    protected ImageDescriptor getDefaultImageDescriptor() {
        return null;
    }

    /**
     * This gets invoked when the selection is inappropriate or the command
     * cannot be created. It puts the action in the correct state for such error
     * conditions. This implementation disables the action and sets its icon to
     * the default.
     */
    protected void disable() {
        setEnabled(false);
        if (getDefaultImageDescriptor() != null) {
            setImageDescriptor(getDefaultImageDescriptor());
        }
    }

    @Override
    public void doRun(IProgressMonitor progressMonitor) {
        // this guard is for extra security, but should not be necessary
        if (editingDomain != null && command != null) {
            // use up the command
            try {
                editingDomain.getCommandStack().execute(command, progressMonitor, new IAdaptable() {
                    @Override
                    public Object getAdapter(Class adapter) {
                        if (IInputCallback.class.equals(adapter)) {
                            return new InputCallbackDialog(
                                    ((AdapterFactoryEditingDomain) editingDomain).getAdapterFactory());
                        }
                        return null;
                    }
                });
            } catch (ExecutionException e) {
                handle(e);
            }
        }
    }

    /**
     * If necessary, this converts any image representation into an image
     * descriptor.
     */
    protected ImageDescriptor objectToImageDescriptor(Object object) {
        return ExtendedImageRegistry.getInstance().getImageDescriptor(object);
    }
}