com.rcpcompany.uibindings.navigator.internal.views.BaseEditorView.java Source code

Java tutorial

Introduction

Here is the source code for com.rcpcompany.uibindings.navigator.internal.views.BaseEditorView.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2013 The RCP Company 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:
 *     The RCP Company - initial API and implementation
 *******************************************************************************/
package com.rcpcompany.uibindings.navigator.internal.views;

import java.util.List;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.ViewPart;

import com.rcpcompany.uibindings.IManager;
import com.rcpcompany.uibindings.model.utils.BasicUtils;
import com.rcpcompany.uibindings.navigator.IEditorPart;
import com.rcpcompany.uibindings.navigator.IEditorPartContext;
import com.rcpcompany.uibindings.navigator.IEditorPartDescriptor;
import com.rcpcompany.uibindings.navigator.IEditorPartFactory;
import com.rcpcompany.uibindings.navigator.IEditorPartView;
import com.rcpcompany.uibindings.navigator.INavigatorManager;
import com.rcpcompany.uibindings.navigator.internal.Activator;
import com.rcpcompany.uibindings.navigator.internal.NavigatorConstants;
import com.rcpcompany.uibindings.navigator.internal.handlers.SelectEditorPartMenuContributor;
import com.rcpcompany.uibindings.utils.IBindingObjectInformation;
import com.rcpcompany.uibindings.utils.IGlobalNavigationManager.IGetSelectionTarget;
import com.rcpcompany.utils.logging.LogUtils;
import com.rcpcompany.utils.selection.SelectionUtils;

/**
 * The base view for editor parts.
 * 
 * @author Tonny Madsen, The RCP Company
 */
public class BaseEditorView extends ViewPart implements ISetSelectionTarget, IGetSelectionTarget, IEditorPartView {
    /**
     * The parent Composite for the current editor part - if any
     */
    /* package */Composite myParent;

    /**
     * The parent Composite from {@link IViewPart#createPartControl(Composite)}.
     */
    /* package */Composite myViewPartParent;

    /**
     * Whether this editor is currently pinned.
     * <p>
     * If the editor is pinned, it will not react to selection changes and a new editor is created
     * instead of reusing an existing editor.
     */
    /* package */boolean myIsPinned = INavigatorManager.Factory.getManager().isPinEditorByDefault();

    /**
     * The current editor part descriptor.
     */
    private/* package */IEditorPartDescriptor myCurrentDescriptor;

    /**
     * The current editor part for this editor.
     */
    /* package */IEditorPart myCurrentEditorPart = null;

    /**
     * The current base observable value of the editor.
     * <p>
     * The type of the value is based on the model type of the current editor descriptor.
     */
    /* package */IObservableValue myCurrentValue;

    /**
     * The factory context used in {@link IEditorPartFactory}.
     */
    private final IEditorPartContext myFactoryContext = new IEditorPartContext() {
        @Override
        public IWorkbenchPart getWorkbenchPart() {
            return BaseEditorView.this;
        }

        @Override
        public Composite getParent() {
            return myParent;
        };

        @Override
        public IObservableValue getCurrentValue() {
            return myCurrentValue;
        }

        @Override
        public IEditorPartDescriptor getDescriptor() {
            return getCurrentDescriptor();
        }
    };

    /**
     * Constructs and returns a editor container.
     */
    public BaseEditorView() {
    }

    @Override
    public void createPartControl(Composite parent) {
        myViewPartParent = parent;

        // final ISelectionService ss = getSite().getWorkbenchWindow().getSelectionService();
        // ss.addPostSelectionListener(mySelectionListener);
        // selectReveal(ss.getSelection());
    }

    @Override
    public void dispose() {
        cleanEditorPart();
        // final ISelectionService ss = getSite().getWorkbenchWindow().getSelectionService();
        // ss.removePostSelectionListener(mySelectionListener);
        super.dispose();
    }

    @Override
    public void activateView() {
        getSite().getPage().activate(this);
    }

    @Override
    public void setFocus() {
        myViewPartParent.setFocus();
    }

    @Override
    public void selectReveal(ISelection selection) {
        if (Activator.getDefault().TRACE_EDITOR_PARTS_LIFECYCLE) {
            LogUtils.debug(this, IBindingObjectInformation.Factory.getLongName(selection));
        }
        if (myCurrentEditorPart != null && isPinned())
            return;
        final List<EObject> list = SelectionUtils.computeSelection(selection, EObject.class);
        if (list.isEmpty())
            return;

        setCurrentObject(list.get(0));
    }

    @Override
    public ISelection getCurrentSelection() {
        if (myCurrentValue == null)
            return StructuredSelection.EMPTY;

        return new StructuredSelection(myCurrentValue.getValue());
    }

    @Override
    public EObject getCurrentObject() {
        if (myCurrentValue != null)
            return (EObject) myCurrentValue.getValue();
        return null;
    }

    /**
     * Updates the editor when the current object changes
     * 
     * @param obj the new current object of the editor
     */
    @Override
    public void setCurrentObject(final EObject obj) {
        final IEditorPartDescriptor desc = INavigatorManager.Factory.getManager().getEditorPartDescriptor(obj);
        if (Activator.getDefault().TRACE_EDITOR_PARTS_LIFECYCLE) {
            LogUtils.debug(this, "Descriptor found: " + obj + "\n-> " + desc);
        }
        /*
         * Iff we have the same descriptor and the current editor can accept changes in the object,
         * then just change the object without re-creating the editor part... Otherwise go the long
         * route and first dispose and then re-create the editor part.
         */
        if (desc == myCurrentDescriptor
                && ((myCurrentEditorPart != null && myCurrentEditorPart.canAcceptObjectChanges())
                        || (myCurrentValue != null && BasicUtils.equals(obj, myCurrentValue.getValue())))) {
            /*
             * The editor part itself did not change... just update the observable value.
             */
            if (myCurrentValue != null) {
                if (Activator.getDefault().TRACE_EDITOR_PARTS_LIFECYCLE) {
                    LogUtils.debug(this, "Editor part value changed to " + obj);
                }
                BusyIndicator.showWhile(myParent.getDisplay(), new Runnable() {
                    public void run() {
                        myCurrentValue.setValue(obj);
                    }
                });
                final IBindingObjectInformation info = IBindingObjectInformation.Factory
                        .createObjectInformation((EObject) myCurrentValue.getValue(), null);
                setPartName(info.getName() + ": " + getCurrentDescriptor().getName());
            }
            return;
        }

        /*
         * No new descriptor....
         */
        if (desc == null)
            return;

        if (Activator.getDefault().TRACE_EDITOR_PARTS_LIFECYCLE) {
            LogUtils.debug(this, "Editor part description\n" + myCurrentDescriptor + "\n-> " + desc);
        }

        cleanEditorPart();

        /*
         * - create the observable value for the editor part based on the type of the editor
         * descriptor
         */
        myCurrentValue = new WritableValue(obj, obj.eClass());
        IManager.Factory.getManager().startMonitorObservableDispose(myCurrentValue, this);
        setCurrentDescriptor(desc);

        /*
         * - create the editor part itself
         * 
         * If it fails, the clean up again...
         */
        final IEditorPartFactory factory = desc.getFactory().getObject();
        try {
            if (factory != null) {
                myParent = new Composite(myViewPartParent, SWT.NONE);
                myParent.setLayout(new FillLayout());
                try {
                    BusyIndicator.showWhile(myParent.getDisplay(), new Runnable() {
                        public void run() {
                            myCurrentEditorPart = factory.createEditorPart(myFactoryContext);
                        }
                    });
                } catch (final Exception ex) {
                    LogUtils.error(factory, "Error detected during editor creation", ex);
                }
                myViewPartParent.layout(true);
            }
            if (getCurrentDescriptor() == null) {
                LogUtils.error(factory, "Editor Part Factory returned null");
            }
        } catch (final Exception ex) {
            LogUtils.error(factory, ex);
        }

        if (myCurrentEditorPart == null) {
            if (Activator.getDefault().TRACE_EDITOR_PARTS_LIFECYCLE) {
                LogUtils.debug(this, "Failed");
            }
            cleanEditorPart();
            setPartName("");
            setTitleImage(null);
            return;
        }

        /*
         * - Update the view part info
         */
        final IBindingObjectInformation info = IBindingObjectInformation.Factory
                .createObjectInformation((EObject) myCurrentValue.getValue(), null);
        setPartName(info.getName() + ": " + getCurrentDescriptor().getName());
        Image image = null;
        if (image == null && getCurrentDescriptor().getImage() != null) {
            getCurrentDescriptor().getImage().getImage();
        }
        if (image == null) {
            image = info.getImage();
        }
        setTitleImage(image);
    }

    /**
     * 
     */
    private void cleanEditorPart() {
        /*
         * - Clean up after the previous editor part
         */
        if (myCurrentEditorPart != null) {
            myCurrentEditorPart.dispose();
            if (!myViewPartParent.isDisposed()) {
                for (final Control c : myViewPartParent.getChildren()) {
                    c.dispose();
                }
            }
        }
        if (myCurrentValue != null && !myCurrentValue.isDisposed()) {
            IManager.Factory.getManager().stopMonitorObservableDispose(myCurrentValue);
            myCurrentValue.dispose();
        }
        myCurrentValue = null;
        myCurrentEditorPart = null;
        setCurrentDescriptor(null);
    }

    @Override
    public void setPinned(boolean pinned) {
        myIsPinned = pinned;
    }

    @Override
    public boolean isPinned() {
        return myIsPinned;
    }

    /**
     * Sets the current descriptor.
     * 
     * @param desciptor the current descriptor to set
     */
    public void setCurrentDescriptor(IEditorPartDescriptor desciptor) {
        myCurrentDescriptor = desciptor;

        /*
         * Make all select editor parts update themselves...
         */
        final ICommandService commandService = (ICommandService) getSite().getService(ICommandService.class);
        commandService.refreshElements(NavigatorConstants.SELECT_EDITOR_PART_COMMAND, null);
    }

    /**
     * Returns the current descriptor.
     * 
     * @return the current descriptor
     */
    @Override
    public IEditorPartDescriptor getCurrentDescriptor() {
        return myCurrentDescriptor;
    }

    /**
     * Selection lister that simply updated the current selection of the editor.
     */
    private final ISelectionListener mySelectionListener = new ISelectionListener() {
        @Override
        public void selectionChanged(IWorkbenchPart part, ISelection selection) {
            /*
             * The changes that results from this part is ignoreed.
             */
            if (part == BaseEditorView.this)
                return;
            selectReveal(selection);
        }
    };

    private SelectEditorPartMenuContributor mySelectEditorPartFactoryItem;
}