org.eclipse.emf.eef.runtime.ui.widgets.ContainmentPropertiesEditingViewer.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.eef.runtime.ui.widgets.ContainmentPropertiesEditingViewer.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Obeo.
 * 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/

package org.eclipse.emf.eef.runtime.ui.widgets;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emf.eef.runtime.EEFRuntimePlugin;
import org.eclipse.emf.eef.runtime.api.component.IPropertiesEditionComponent;
import org.eclipse.emf.eef.runtime.api.notify.IPropertiesEditionEvent;
import org.eclipse.emf.eef.runtime.api.notify.IPropertiesEditionListener;
import org.eclipse.emf.eef.runtime.context.impl.DomainPropertiesEditionContext;
import org.eclipse.emf.eef.runtime.context.impl.EObjectPropertiesEditionContext;
import org.eclipse.emf.eef.runtime.impl.utils.EEFUtils;
import org.eclipse.emf.eef.runtime.ui.utils.EditingUtils;
import org.eclipse.emf.eef.runtime.ui.viewers.PropertiesEditionContentProvider;
import org.eclipse.emf.eef.runtime.ui.viewers.PropertiesEditionViewer;
import org.eclipse.emf.eef.runtime.ui.widgets.ReferencesTable.ReferencesTableListener;
import org.eclipse.emf.eef.runtime.ui.widgets.referencestable.ReferencesTableContentProvider;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.FormColors;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;

/**
 * @author <a href="mailto:goulwen.lefur@obeo.fr">Goulwen Le Fur</a>
 * 
 */
public class ContainmentPropertiesEditingViewer extends StructuredViewer {

    /**
     * Image for the add element button.
     */
    final protected static Image NEW_ELEMENT_IMG = EEFRuntimePlugin
            .getImage(EEFRuntimePlugin.ICONS_16x16 + "Add_16x16.gif"); //$NON-NLS-1$

    /**
     * Image for the delete element button.
     */
    final protected static Image DELETE_ELEMENT_IMG = EEFRuntimePlugin
            .getImage(EEFRuntimePlugin.ICONS_16x16 + "Delete_16x16.gif"); //$NON-NLS-1$

    /**
     * Image for the up button.
     */
    final protected static Image UP_ELEMENT_IMG = EEFRuntimePlugin
            .getImage(EEFRuntimePlugin.ICONS_16x16 + "ArrowUp_16x16.gif"); //$NON-NLS-1$

    /**
     * Image for the down button.
     */
    final protected static Image DOWN_ELEMENT_IMG = EEFRuntimePlugin
            .getImage(EEFRuntimePlugin.ICONS_16x16 + "ArrowDown_16x16.gif"); //$NON-NLS-1$

    private Composite control;

    private int kind;
    private String mode;
    private FormToolkit toolkit;
    private IPropertiesEditionComponent component;
    private Object viewerInput;

    private List<ReferencesTableListener> listeners;

    private boolean scrolledFormSearched;
    private ScrolledForm scrolledForm;

    private boolean refreshState;
    private CLabel title;
    private Button addButton;
    private Label helpButton;
    private FormColors colors;

    /**
     * Default container for SWT mode.
     * @param parent parent composite
     * @param kind kind of view
     */
    public ContainmentPropertiesEditingViewer(Composite parent, int kind) {
        super();
        this.kind = kind;
        this.listeners = new ArrayList<ReferencesTable.ReferencesTableListener>();
        this.scrolledFormSearched = false;

        control = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginLeft = -4;
        ((Composite) control).setLayout(layout);
        title = new CLabel((Composite) control, SWT.NONE);
        title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        addButton = new Button((Composite) control, SWT.PUSH);
        addButton.setImage(NEW_ELEMENT_IMG);
        addButton.addSelectionListener(new SelectionAdapter() {

            /**
             * {@inheritDoc}
             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             */
            public void widgetSelected(SelectionEvent e) {
                for (ReferencesTableListener listener : listeners) {
                    listener.handleAdd();
                }
            }

        });
    }

    /**
     * Constructor with toolkit for Form mode.
     * @param parent parent composite
     * @param kind kind of view
     * @param toolkit toolkit to use
     */
    public ContainmentPropertiesEditingViewer(Composite parent, int kind, FormToolkit toolkit) {
        super();
        this.kind = kind;
        this.toolkit = toolkit;
        this.listeners = new ArrayList<ReferencesTable.ReferencesTableListener>();
        this.scrolledFormSearched = false;

        control = toolkit.createComposite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(3, false);
        layout.marginLeft = -4;
        ((Composite) control).setLayout(layout);
        title = new CLabel((Composite) control, SWT.NONE);
        title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        EditingUtils.setEEFtype(title, "eef::ContainmentPropertiesEditingViewer::title");
        addButton = toolkit.createButton((Composite) control, "", SWT.PUSH);
        addButton.setImage(NEW_ELEMENT_IMG);
        addButton.addSelectionListener(new SelectionAdapter() {

            /**
             * {@inheritDoc}
             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             */
            public void widgetSelected(SelectionEvent e) {
                for (ReferencesTableListener listener : listeners) {
                    listener.handleAdd();
                }
            }

        });
        EditingUtils.setEEFtype(addButton, "eef::ContainmentPropertiesEditingViewer::addbutton");
        Control createHelpButton = FormUtils.createHelpButton(toolkit, control, "", "");
        if (createHelpButton instanceof Label) {
            helpButton = (Label) createHelpButton;
            GridData layoutData = new GridData();
            layoutData.widthHint = 0;
            createHelpButton.setLayoutData(layoutData);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#doFindInputItem(java.lang.Object)
     */
    @Override
    protected Widget doFindInputItem(Object element) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#doFindItem(java.lang.Object)
     */
    @Override
    protected Widget doFindItem(Object element) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#doUpdateItem(org.eclipse.swt.widgets.Widget,
     *      java.lang.Object, boolean)
     */
    @Override
    protected void doUpdateItem(Widget item, Object element, boolean fullMap) {
        // TODO Auto-generated method stub

    }

    /**
     * @param listener to add.
     */
    public void addListener(ReferencesTableListener listener) {
        listeners.add(listener);
    }

    /**
     * @param listener to remove.
     */
    public void removeListener(ReferencesTableListener listener) {
        listeners.remove(listener);
    }

    /**
     * @param mode the mode to set
     */
    public void setMode(String mode) {
        this.mode = mode;
    }

    /**
     * @return the component
     */
    public IPropertiesEditionComponent getPropertiesEditingComponent() {
        return component;
    }

    /**
     * @param component the component to set
     */
    public void setPropertiesEditingComponent(IPropertiesEditionComponent component) {
        this.component = component;
    }

    /**
     * @param text title of the widget.
     */
    public void setText(String text) {
        if (text != null) {
            title.setText(text);
        }
    }

    /**
     * @param text help of the widget
     */
    public void setHelpText(String text) {
        if (text != null && !"".equals(text)) {
            ((GridData) helpButton.getLayoutData()).widthHint = 25;
            helpButton.setToolTipText(text);
        } else {
            ((GridData) helpButton.getLayoutData()).widthHint = 0;
        }
    }

    /**
     * @param id
     */
    public void setID(Object id) {
        EditingUtils.setID(control, id);
        EditingUtils.setID(title, id);
        EditingUtils.setID(addButton, id);
    }

    /**
     * @param required whether the feature is required or not.
     */
    public void setRequired(boolean required) {
        if (required) {
            title.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
        } else {
            title.setFont(JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT));
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object)
     */
    @Override
    protected void internalRefresh(Object element) {
        clear();
        this.viewerInput = element;
        if (getContentProvider() != null) {
            refreshState = true;
            Object[] elements = getChildrenViewer(element);
            for (Object object : elements) {
                if (object instanceof EObject) {
                    Composite controlAsComposite = (Composite) control;
                    createChild((EObject) object, controlAsComposite);
                }
            }
            refreshState = false;
        }
        if (control.getLayoutData() instanceof GridData) {
            Composite parent = control.getParent();
            while (parent != null) {
                parent.layout(true);
                if (parent instanceof ScrolledComposite) {
                    parent = null;
                } else {
                    parent = parent.getParent();
                }
            }
            control.layout(true);

        }
        ScrolledForm owningScrolledForm = owningScrolledForm(control);
        if (owningScrolledForm != null) {
            owningScrolledForm.reflow(true);
        }

    }

    /**
     * @param element to process
     * @return the children of the element.
     */
    private Object[] getChildrenViewer(Object element) {
        ReferencesTableContentProvider propertiesEditionProvider = (ReferencesTableContentProvider) getContentProvider();
        Object[] elements = propertiesEditionProvider.getElements(element);
        return elements;
    }

    /**
     * @param elements
     * @param searched
     * @return
     */
    private int indexOf(Object searched) {
        Object[] elements = getChildrenViewer(viewerInput);
        for (int i = 0; i < elements.length; i++) {
            if (searched.equals(elements[i])) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Remove all the children elements of the viewer.
     */
    protected void clear() {
        for (Control child : control.getChildren()) {
            if (child instanceof ChildComposite) {
                child.dispose();
            }
        }
    }

    /**
     * @param composite
     * @return the ScrolledForm owning the current viewer <code>null</code> otherwise.
     */
    private ScrolledForm gettingOwningScrolledForm(Composite composite) {
        if (composite instanceof ScrolledForm) {
            return (ScrolledForm) composite;
        } else if (composite != null) {
            return owningScrolledForm(composite.getParent());
        } else {
            return null;
        }
    }

    /**
     * Search the ScrolledForm owning the current viewer. 
     * @param composite current viewer.
     * @return the ScrolledForm owning the current viewer <code>null</code> otherwise.
     */
    private ScrolledForm owningScrolledForm(Composite composite) {
        if (!scrolledFormSearched) {
            scrolledForm = gettingOwningScrolledForm(composite);
            scrolledFormSearched = true;
        }
        return scrolledForm;
    }

    /**
     * Creates a ChildComposite for the given EObject.
     * @param object EObject to display.
     * @param parent the viewer control.
     */
    private void createChild(EObject object, Composite parent) {
        ChildComposite child = new ChildComposite(parent, SWT.NONE);
        child.setInput(object);
    }

    private String labelTitle(Object object) {
        IItemLabelProvider labelProvider = (IItemLabelProvider) adapterFactory().adapt(object,
                IItemLabelProvider.class);
        String text = null;
        if (labelProvider != null)
            text = labelProvider.getText(object);
        else
            text = object.toString();
        return text;
    }

    private Image labelImage(Object object) {
        return new AdapterFactoryLabelProvider(adapterFactory()).getImage(object);
    }

    private AdapterFactory adapterFactory() {
        return component.getEditingContext().getAdapterFactory();
    }

    protected IContentProvider getInternContentProvider() {
        if (component != null && component.getEditingContext() != null) {
            if (mode == IPropertiesEditionComponent.LIVE_MODE) {
                return new PropertiesEditionContentProvider(adapterFactory(), mode,
                        EEFUtils.getEditingDomain(component.getEditingContext()));
            } else {
                try {
                    return new PropertiesEditionContentProvider(adapterFactory(), mode);
                } catch (InstantiationException e) {
                    throw new IllegalStateException("An EditingDomain must be defined for live mode.");
                }
            }
        } else {
            throw new IllegalStateException("A PropertiesEditingComponent must be defined for this widget.");
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#reveal(java.lang.Object)
     */
    @Override
    public void reveal(Object element) {
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#getSelectionFromWidget()
     */
    @Override
    protected List<?> getSelectionFromWidget() {
        return Collections.EMPTY_LIST;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(java.util.List,
     *      boolean)
     */
    @Override
    protected void setSelectionToWidget(List l, boolean reveal) {
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.jface.viewers.Viewer#getControl()
     */
    @Override
    public Control getControl() {
        return control;
    }

    private Color getColor(String key) {
        if (colors == null) {
            colors = new FormColors(control.getDisplay());
        }
        return colors.getColor(key);
    }

    private class ChildComposite extends Composite {

        private CLabel objectTitle;
        private PropertiesEditionViewer viewer;
        private EObject input;
        private IPropertiesEditionListener listener;

        public ChildComposite(Composite parent, int style) {
            super(parent, style);
            GridData compositeData = new GridData(GridData.FILL_BOTH);
            compositeData.horizontalSpan = 3;
            setLayoutData(compositeData);
            GridLayout layout = new GridLayout(4, false);
            layout.marginWidth = 5;
            layout.verticalSpacing = 5;
            setLayout(layout);
            Button removeButton;
            Button upButton;
            Button downButton;
            if (kind == 1) {
                setBackground(getColor(IFormColors.TB_BG));
                objectTitle = new CLabel(this, SWT.NONE);
                removeButton = toolkit.createButton(this, "", SWT.PUSH);
                upButton = toolkit.createButton(this, "", SWT.PUSH);
                downButton = toolkit.createButton(this, "", SWT.PUSH);
            } else {
                setBackground(JFaceColors.getBannerBackground(getDisplay()));
                objectTitle = new CLabel(this, SWT.NONE);
                objectTitle.setBackground(JFaceColors.getBannerBackground(getDisplay()));
                removeButton = new Button(this, SWT.PUSH);
                upButton = new Button(this, SWT.PUSH);
                downButton = new Button(this, SWT.PUSH);
            }
            EditingUtils.setEEFtype(objectTitle, "eef::ContainmentPropertiesEditingViewer::childtitle");
            EditingUtils.setEEFtype(removeButton, "eef::ContainmentPropertiesEditingViewer::removechildbutton");
            EditingUtils.setEEFtype(upButton, "eef::ContainmentPropertiesEditingViewer::upchildbutton");
            EditingUtils.setEEFtype(downButton, "eef::ContainmentPropertiesEditingViewer::downchildbutton");
            GridData labelData = new GridData(GridData.FILL_HORIZONTAL);
            objectTitle.setLayoutData(labelData);
            removeButton.setImage(DELETE_ELEMENT_IMG);
            removeButton.addSelectionListener(new SelectionAdapter() {

                /**
                 * {@inheritDoc}
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    for (ReferencesTableListener listener : listeners) {
                        listener.handleRemove(input);
                    }
                }

            });
            upButton.setImage(UP_ELEMENT_IMG);
            upButton.addSelectionListener(new SelectionAdapter() {

                /**
                 * {@inheritDoc}
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    for (ReferencesTableListener listener : listeners) {
                        int indexOf = indexOf(input);
                        if (indexOf > 0) {
                            listener.handleMove(input, indexOf, indexOf - 1);
                        }
                    }
                }

            });
            downButton.setImage(DOWN_ELEMENT_IMG);
            downButton.addSelectionListener(new SelectionAdapter() {

                /**
                 * {@inheritDoc}
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    for (ReferencesTableListener listener : listeners) {
                        int indexOf = indexOf(input);
                        if (indexOf > -1 && indexOf < (getChildrenViewer(viewerInput).length - 1)) {
                            listener.handleMove(input, indexOf, indexOf + 1);
                        }
                    }
                }

            });
            viewer = new PropertiesEditionViewer(this, null, SWT.NONE, kind);
            if (toolkit != null) {
                viewer.setToolkit(toolkit);
            }
            viewer.setContentProvider(getInternContentProvider());
            GridData data = new GridData(GridData.FILL_HORIZONTAL);
            data.horizontalSpan = 4;
            viewer.getControl().setLayoutData(data);
        }

        /**
         * Defines input of the viewer.
         * @param object the viewer input
         */
        public void setInput(EObject object) {
            this.input = object;
            if (component != null && component.getEditingContext() != null) {
                if (mode == IPropertiesEditionComponent.LIVE_MODE) {
                    viewer.setInput(new DomainPropertiesEditionContext(component.getEditingContext(), component,
                            EEFUtils.getEditingDomain(component.getEditingContext()), adapterFactory(),
                            (EObject) object));
                } else {
                    viewer.setInput(new EObjectPropertiesEditionContext(component.getEditingContext(), component,
                            (EObject) object, adapterFactory()));
                }
            } else {
                viewer.setInput(object);
            }
            listener = new IPropertiesEditionListener() {

                public void firePropertiesChanged(IPropertiesEditionEvent event) {
                    refreshTitle(input);
                }
            };
            ((PropertiesEditionContentProvider) viewer.getContentProvider()).addPropertiesListener(listener);
            refreshTitle(object);
        }

        /**
         * {@inheritDoc}
         * @see org.eclipse.swt.widgets.Widget#dispose()
         */
        @Override
        public void dispose() {
            if (listener != null) {
                ((PropertiesEditionContentProvider) viewer.getContentProvider()).removePropertiesListener(listener);
            }
            super.dispose();
        }

        /**
         * @return input of the viewer.
         */
        public EObject getInput() {
            return input;
        }

        public void refreshTitle(Object object) {
            objectTitle.setText(labelTitle(object));
            Image labelImage = labelImage(object);
            if (labelImage != null) {
                objectTitle.setImage(labelImage);
            }
        }

    }

}