de.walware.ecommons.emf.ui.forms.EObjectListProperty.java Source code

Java tutorial

Introduction

Here is the source code for de.walware.ecommons.emf.ui.forms.EObjectListProperty.java

Source

/*=============================================================================#
 # Copyright (c) 2012-2014 Stephan Wahlbrink (WalWare.de) 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:
 #     Stephan Wahlbrink - initial API and implementation
 #=============================================================================*/

package de.walware.ecommons.emf.ui.forms;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.databinding.edit.IEMFEditListProperty;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.IViewerNotification;
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.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;

import de.walware.ecommons.emf.core.util.IEMFEditContext;
import de.walware.ecommons.ui.components.ButtonGroup;
import de.walware.ecommons.ui.content.ElementSourceSelectionProvider;
import de.walware.ecommons.ui.util.MenuUtil;
import de.walware.ecommons.ui.util.ViewerUtil;
import de.walware.ecommons.ui.util.ViewerUtil.TableComposite;

public class EObjectListProperty extends EFProperty {

    private class LabelProvider extends AdapterFactoryLabelProvider {

        protected Viewer fViewer;
        protected AdapterFactoryContentProvider.ViewerRefresh fViewerRefresh;

        public LabelProvider(final AdapterFactory adapterFactory, final Viewer viewer) {
            super(adapterFactory);

            fViewer = viewer;
        }

        @Override
        public void notifyChanged(final Notification notification) {
            if (fViewer != null && fViewer.getControl() != null && !fViewer.getControl().isDisposed()
                    && notification instanceof IViewerNotification) {
                final IViewerNotification viewerNotification = (IViewerNotification) notification;
                if (viewerNotification.isLabelUpdate()) {
                    if (fViewerRefresh == null) {
                        fViewerRefresh = new AdapterFactoryContentProvider.ViewerRefresh(fViewer);
                    }
                    if (fViewerRefresh.addNotification(viewerNotification)) {
                        fViewer.getControl().getDisplay().asyncExec(fViewerRefresh);
                    }
                }
            }
            super.notifyChanged(notification);
        }

    }

    private class AddHandler extends ButtonGroup.AddHandler {

        private MenuManager fMenuManager;

        public AddHandler() {
        }

        @Override
        public boolean run(final IStructuredSelection selection) {
            if (fMenuManager == null) {
                fMenuManager = new MenuManager();
            } else {
                fMenuManager.removeAll();
            }
            fillMenu(fMenuManager);

            final Menu menu = fMenuManager.createContextMenu(getControl());
            MenuUtil.setPullDownPosition(menu, getControl());
            menu.setVisible(true);
            return false;
        }

        protected void fillMenu(final MenuManager menuManager) {
            final EditingDomain editingDomain = getEditingDomain();
            final EObject base = (EObject) getBaseObservable().getValue();
            if (base == null) {
                return;
            }
            final Collection<?> descriptors = editingDomain.getNewChildDescriptors(base, null);
            for (final Object descriptor : descriptors) {
                if (!(descriptor instanceof CommandParameter)) {
                    continue;
                }
                final CommandParameter parameter = (CommandParameter) descriptor;
                if (parameter.getEStructuralFeature() != getEFeature()) {
                    continue;
                }
                final IContributionItem item = new EditCommandContributionItem(parameter, editingDomain,
                        getBaseObservable()) {
                    @Override
                    protected void executed(final Collection<?> result) {
                        final Iterator<?> iter = result.iterator();
                        if (iter.hasNext()) {
                            final Object value = iter.next();
                            if (fModelObservable.contains(value)) {
                                fSingleSelectionObservable.setValue(value);
                            }
                        }
                    }
                };
                menuManager.add(item);
            }
        }

        @Override
        public void widgetDisposed(final DisposeEvent e) {
            if (fMenuManager != null) {
                fMenuManager.dispose();
            }
        }

    }

    private TableComposite fWidget;
    private ButtonGroup<EObject> fButtonGroup;

    private IObservableList fModelObservable;

    private ElementSourceSelectionProvider fSelectionProvider;
    private IObservableValue fSingleSelectionObservable;

    public EObjectListProperty(final String label, final String tooltip, final EClass eClass,
            final EStructuralFeature eFeature) {
        super(label, tooltip, eClass, eFeature);
    }

    @Override
    public void create(final Composite parent, final IEFFormPage page) {
        fWidget = page.getToolkit().createPropSingleColumnTable(parent, 10, 25);

        fWidget.viewer.setContentProvider(new ObservableListContentProvider());
        fWidget.viewer.setLabelProvider(new LabelProvider(page.getEditor().getAdapterFactory(), fWidget.viewer));

        fButtonGroup = new ButtonGroup<EObject>(parent);
        fButtonGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));

        customizeButtonGroup(fButtonGroup);
    }

    protected void customizeButtonGroup(final ButtonGroup<EObject> buttonGroup) {
        buttonGroup.addAddButton(new AddHandler());
        buttonGroup.addDeleteButton(null);
        buttonGroup.addSeparator();
        buttonGroup.addUpButton(null);
        buttonGroup.addDownButton(null);
    }

    @Override
    public Control getControl() {
        return fWidget;
    }

    public TableViewer getViewer() {
        return fWidget.viewer;
    }

    @Override
    public void bind(final IEMFEditContext context) {
        super.bind(context);

        final IEMFEditListProperty emfProperty = EMFEditProperties.list(getEditingDomain(), getEFeature());
        fModelObservable = emfProperty.observeDetail(getBaseObservable());
        ((IObserving) fModelObservable).getObserved();

        fWidget.viewer.setInput(fModelObservable);
        fButtonGroup.connectTo(fWidget.viewer, fModelObservable, null);

        register(fWidget.table, IEFPropertyExpressions.EOBJECT_LIST_ID);
        fSelectionProvider = new ElementSourceSelectionProvider(fWidget.viewer, this);
        ViewerUtil.setSelectionProvider(fWidget.table, fSelectionProvider);

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

        fSingleSelectionObservable = ViewersObservables.observeSinglePostSelection(fWidget.viewer);

        fButtonGroup.updateState();
    }

    @Override
    public IObservableList getPropertyObservable() {
        return fModelObservable;
    }

    public IObservableValue getSingleSelectionObservable() {
        return fSingleSelectionObservable;
    }

    public ISelectionProvider getSelectionProvider() {
        return fSelectionProvider;
    }

}