gov.redhawk.ui.editor.ScaFormPage.java Source code

Java tutorial

Introduction

Here is the source code for gov.redhawk.ui.editor.ScaFormPage.java

Source

/**
 * This file is protected by Copyright. 
 * Please refer to the COPYRIGHT file distributed with this source distribution.
 * 
 * This file is part of REDHAWK IDE.
 * 
 * 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.
 *
 */

package gov.redhawk.ui.editor;

import gov.redhawk.internal.ui.ScaPluginImages;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter;
import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter;
import org.eclipse.emf.edit.ui.provider.UnwrappingSelectionProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;

/**
 * The Class ScaFormPage.
 */
public abstract class ScaFormPage extends FormPage implements IMenuListener, IEditingDomainProvider {
    private boolean fNewStyleHeader = true;
    private Control fLastFocusControl;
    private Resource input;
    private final Adapter listener = new AdapterImpl() {
        /**
         * {@inheritDoc}
         */
        @Override
        public void notifyChanged(final Notification msg) {
            switch (msg.getFeatureID(Resource.class)) {
            case Resource.RESOURCE__IS_LOADED:
                final Resource resource = (Resource) msg.getNotifier();
                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                    @Override
                    public void run() {
                        if (!isDisposed()) {
                            refresh(resource);
                        }
                    }

                });
                break;
            default:
                break;
            }
        }
    };

    private boolean disposed;

    /**
    * Instantiates a new sca form page.
    * 
    * @param editor the editor
    * @param id the id
    * @param title the title
    */
    public ScaFormPage(final SCAFormEditor editor, final String id, final String title) {
        super(editor, id, title);
        this.fLastFocusControl = null;
    }

    /**
     * @param resource
     */
    protected abstract void refresh(final Resource resource);

    /**
     * Instantiates a new sca form page.
     * 
     * @param editor the editor
     * @param id the id
     * @param title the title
     * @param newStyleHeader the new style header
     */
    public ScaFormPage(final SCAFormEditor editor, final String id, final String title,
            final boolean newStyleHeader) {
        this(editor, id, title);
        this.fNewStyleHeader = newStyleHeader;
    }

    /**
     * @return the common editing domain provided by the parent editor
     */
    @Override
    public EditingDomain getEditingDomain() {
        return getEditor().getEditingDomain();
    }

    /**
     * @return the common command stack provided by the parent editor
     */
    protected BasicCommandStack getCommandStack() {
        if (getEditingDomain() == null) {
            return null;
        }
        return ((BasicCommandStack) getEditingDomain().getCommandStack());
    }

    /**
     * Executes a command on the editing domain command stack
     * 
     * @param command
     */
    protected void execute(final Command command) {
        getCommandStack().execute(command);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void createFormContent(final IManagedForm managedForm) {
        final ScrolledForm form = managedForm.getForm();
        final FormToolkit toolkit = managedForm.getToolkit();
        // FormColors colors = toolkit.getColors();
        // form.getForm().setSeparatorColor(colors.getColor(FormColors.TB_BORDER));
        if (this.fNewStyleHeader) {
            // createNewStyleHeader(form, colors);
            toolkit.decorateFormHeading(form.getForm());
        }

        final IToolBarManager manager = form.getToolBarManager();
        // Create the group marker so that additional buttons can be added to this group
        // and be to the left of the help button.
        manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

        getEditor().contributeToToolbar(manager);

        final String href = getHelpResource();
        if (href != null) {
            final Action helpAction = new Action("help") { //$NON-NLS-1$
                @Override
                public void run() {
                    BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
                        @Override
                        public void run() {
                            PlatformUI.getWorkbench().getHelpSystem().displayHelp(href);
                        }
                    });
                }
            };
            helpAction.setToolTipText("Help");
            helpAction.setImageDescriptor(ScaPluginImages.DESC_HELP);
            manager.add(helpAction);
        }
        // check to see if our form parts are contributing actions
        final IFormPart[] parts = managedForm.getParts();
        for (int i = 0; i < parts.length; i++) {
            if (parts[i] instanceof IAdaptable) {
                final IAdaptable adapter = (IAdaptable) parts[i];
                final IAction[] actions = (IAction[]) adapter.getAdapter(IAction[].class);
                if (actions != null) {
                    for (int j = 0; j < actions.length; j++) {
                        form.getToolBarManager().add(actions[j]);
                    }
                }
            }
        }
        form.updateToolBar();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SCAFormEditor getEditor() {
        return (SCAFormEditor) super.getEditor();
    }

    /**
     * Gets the help resource.
     * 
     * @return the help resource
     */
    protected String getHelpResource() {
        return null;
    }

    /**
     * This creates a context menu for the viewer and adds a listener as well
     * registering the menu for extension.
     */
    protected void createContextMenuFor(final StructuredViewer viewer) {
        final MenuManager contextMenu = new MenuManager("#PopUp");
        contextMenu.add(new Separator("additions"));
        contextMenu.setRemoveAllWhenShown(true);
        contextMenu.addMenuListener(this);
        final Menu menu = contextMenu.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(contextMenu, new UnwrappingSelectionProvider(viewer));

        final int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
        final Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() };
        viewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(viewer));
        viewer.addDropSupport(dndOperations, transfers,
                new EditingDomainViewerDropAdapter(getEditingDomain(), viewer));
    }

    /**
     * Gets the focus control.
     * 
     * @return the focus control
     */
    protected Control getFocusControl() {
        final IManagedForm form = getManagedForm();
        if (form == null) {
            return null;
        }
        final Control control = form.getForm();
        if (control == null || control.isDisposed()) {
            return null;
        }
        final Display display = control.getDisplay();
        final Control focusControl = display.getFocusControl();
        if (focusControl == null || focusControl.isDisposed()) {
            return null;
        }
        return focusControl;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void createPartControl(final Composite parent) {
        super.createPartControl(parent);
        // Dynamically add focus listeners to all the forms children in order
        // to track the last focus control
        final IManagedForm managedForm = getManagedForm();
        if (managedForm != null) {
            addLastFocusListeners(managedForm.getForm());
        }
    }

    /**
     * Programatically and recursively add focus listeners to the specified
     * composite and its children that track the last control to have focus
     * before a page change or the editor lost focus.
     * 
     * @param composite the composite
     */
    public void addLastFocusListeners(final Composite composite) {
        final Control[] controls = composite.getChildren();
        for (int i = 0; i < controls.length; i++) {
            final Control control = controls[i];
            // Add a focus listener if the control is any one of the below types
            // Note that the controls listed below represent all the controls
            // currently in use by all form pages in PDE. In the future,
            // more controls will have to be added.
            // Could not add super class categories of controls because it
            // would include things like tool bars that we don't want to track
            // focus for.
            if ((control instanceof Text) || (control instanceof Button) || (control instanceof Combo)
                    || (control instanceof CCombo) || (control instanceof Tree) || (control instanceof Table)
                    || (control instanceof Spinner) || (control instanceof Link) || (control instanceof List)
                    || (control instanceof TabFolder) || (control instanceof CTabFolder)
                    || (control instanceof Hyperlink) || (control instanceof FilteredTree)) {
                addLastFocusListener(control);
            }
            if (control instanceof Composite) {
                // Recursively add focus listeners to this composites children
                addLastFocusListeners((Composite) control);
            }
        }
    }

    /**
     * Add a focus listener to the specified control that tracks the last
     * control to have focus on this page. When focus is gained by this control,
     * it registers itself as the last control to have focus. The last control
     * to have focus is stored in order to be restored after a page change or
     * editor loses focus.
     * 
     * @param control the control
     */
    private void addLastFocusListener(final Control control) {
        control.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(final FocusEvent e) {
                // NO-OP
            }

            @Override
            public void focusLost(final FocusEvent e) {
                ScaFormPage.this.fLastFocusControl = control;
            }
        });
    }

    /**
     * Set the focus on the last control to have focus before a page change or
     * the editor lost focus.
     */
    public void updateFormSelection() {
        if ((this.fLastFocusControl != null) && !this.fLastFocusControl.isDisposed()) {
            // Set focus on the control
            this.fLastFocusControl.setFocus();
            // If the control is a Text widget, select its contents
            if (this.fLastFocusControl instanceof Text) {
                final Text text = (Text) this.fLastFocusControl;
                text.setSelection(0, text.getText().length());
            }
        } else {
            // No focus control set
            // Fallback on managed form selection mechanism by setting the
            // focus on this page itself.
            // The managed form will set focus on the first managed part.
            // Most likely this will turn out to be a section.
            // In order for this to work properly, we must override the
            // sections setFocus() method and set focus on a child control
            // (preferrably first) that can practically take focus.
            setFocus();
        }
    }

    /**
     * Gets the last focus control.
     * 
     * @return the last focus control
     */
    public Control getLastFocusControl() {
        return this.fLastFocusControl;
    }

    /**
     * Sets the last focus control.
     * 
     * @param control the control
     */
    public void setLastFocusControl(final Control control) {
        this.fLastFocusControl = control;
    }

    /**
     * Used to align the section client / decriptions of two section headers
     * horizontally adjacent to each other. The misalignment is caused by one
     * section header containing toolbar icons and the other not.
     * 
     * @param masterSection the master section
     * @param detailsSection the details section
     */
    public void alignSectionHeaders(final Section masterSection, final Section detailsSection) {
        detailsSection.descriptionVerticalSpacing += masterSection.getTextClientHeightDifference();
    }

    /*
     * (non-Javadoc)
     * @seeorg.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.
     * IProgressMonitor)
     */
    @Override
    public final void doSave(final IProgressMonitor monitor) {
        // nothing to do here - this is handled by the parent editor
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#doSaveAs()
     */
    @Override
    public final void doSaveAs() {
        // nothing to do here - this is handled by the parent editor
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#isDirty()
     */
    @Override
    public boolean isDirty() {
        if (getCommandStack() == null) {
            return false;
        }
        return getCommandStack().isSaveNeeded();
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
     */
    @Override
    public final boolean isSaveAsAllowed() {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void menuAboutToShow(final IMenuManager manager) {
        // pass the request to show the context menu on to the parent editor
        getEditor().getActionBarContributor().menuAboutToShow(manager);
        // final IEditorActionBarContributor contributor =
        // if (contributor instanceof EditingDomainActionBarContributor) {
        // ((EditingDomainActionBarContributor)
        // contributor).menuAboutToShow(manager);
        // }
    }

    protected Resource getInput() {
        return this.input;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose() {
        if (isDisposed()) {
            return;
        }
        this.disposed = true;
        this.removeResourceListener(this.input);
        super.dispose();
    }

    /**
     * @since 4.0
     */
    public boolean isDisposed() {
        return this.disposed;
    }

    /**
     * This is used by the parent to pass information on the input to be used to
     * the editor part
     * 
     * @param selection
     */
    public void setInput(final Resource input) {
        removeResourceListener(this.input);
        this.input = input;
        addResourceListener(this.input);
        refresh(this.input);
    }

    protected void addResourceListener(final Resource resource) {
        if (resource != null) {
            resource.eAdapters().add(this.listener);
        }
    }

    protected void removeResourceListener(final Resource resource) {
        if (resource != null) {
            resource.eAdapters().remove(this.listener);
        }
    }

    /**
     * @since 2.1
     */
    public void setSelection(final ISelection selection) {
        if (this.isActive()) {
            this.getEditor().setSelection(selection);
        }
    }

    /**
     * @since 2.1
     */
    public ISelection getSelection() {
        final ISelectionProvider provider = (ISelectionProvider) this.getAdapter(ISelectionProvider.class);
        if (provider != null) {
            return provider.getSelection();
        }
        return null;
    }
}