org.eclipse.emf.cdo.security.internal.ui.editor.TableSection.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.cdo.security.internal.ui.editor.TableSection.java

Source

/*
 * Copyright (c) 2013, 2015 Eike Stepper (Berlin, Germany) 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:
 *    Christian W. Damus (CEA LIST) - initial API and implementation
 */
package org.eclipse.emf.cdo.security.internal.ui.editor;

import org.eclipse.emf.cdo.security.Directory;
import org.eclipse.emf.cdo.security.Realm;
import org.eclipse.emf.cdo.security.SecurityFactory;
import org.eclipse.emf.cdo.security.SecurityPackage;
import org.eclipse.emf.cdo.security.internal.ui.messages.Messages;
import org.eclipse.emf.cdo.security.internal.ui.util.ActionBarsHelper;
import org.eclipse.emf.cdo.security.internal.ui.util.ObjectExistsConverter.ObjectWritableConverter;
import org.eclipse.emf.cdo.security.internal.ui.util.SecurityUIUtil;
import org.eclipse.emf.cdo.security.internal.ui.util.TableLabelProvider;
import org.eclipse.emf.cdo.ui.shared.SharedIcons;

import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.actions.SelectionListenerAction;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandActionDelegate;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;

import org.eclipse.core.databinding.beans.PojoProperties;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import java.util.Collections;

/**
 * Common framework for section parts of a form that present a list of
 * similar objects.  It presents buttons for adding and deleting
 * objects in the list.  The objects presented are the contents
 * (of the appropriate type) of some {@link Directory} in the security
 * realm model.
 *
 * @author Christian W. Damus (CEA LIST)
 */
public abstract class TableSection<T extends EObject> extends AbstractSectionPart<Directory> {
    private final Class<T> elementType;

    private final EClass elementEClass;

    private TableViewer viewer;

    public TableSection(Class<T> elementType, EClass elementEClass, EditingDomain domain,
            AdapterFactory adapterFactory) {
        super(Directory.class, SecurityPackage.Literals.DIRECTORY, domain, adapterFactory);
        this.elementType = elementType;
        this.elementEClass = elementEClass;
    }

    @Override
    protected void createContents(Composite parent, FormToolkit toolkit) {
        parent.setLayout(new GridLayout());
        Table table = toolkit.createTable(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        viewer = new TableViewer(table);

        viewer.setContentProvider(new AdapterFactoryContentProvider(getAdapterFactory()));
        viewer.setLabelProvider(new TableLabelProvider(getAdapterFactory()));
        addFilters(viewer);
        forwardSelection(viewer);

        getContext().bindValue(ViewersObservables.observeInput(viewer), getValue());

        configureDragSupport(viewer);
        configureDropSupport(viewer);
    }

    @Override
    public void setFocus() {
        if (viewer != null) {
            viewer.getControl().setFocus();
        } else {
            super.setFocus();
        }
    }

    protected void addFilters(TableViewer viewer) {
        SecurityUIUtil.applyTypeFilter(viewer, elementEClass);
        SecurityUIUtil.applySupportedElementFilter(viewer, elementEClass);
    }

    @Override
    public boolean setFormInput(Object input) {
        if (elementType.isInstance(input)) {
            viewer.setSelection(new StructuredSelection(input), true);
            return true;
        } else if (input instanceof Directory && input == getDirectory(((Directory) input).getRealm())) {
            // It's my directory
            boolean result = super.setFormInput(input);
            checkForUnsupportedModelContent();
            return result;
        } else if (input instanceof Realm) {
            return setFormInput(getDirectory((Realm) input));
        }

        return false;
    }

    protected Directory getDirectory(Realm realm) {
        return SecurityUIUtil.getDirectory(realm, elementEClass);
    }

    @Override
    protected void createActionToolbar(Section section, FormToolkit toolkit) {
        ToolBarManager mgr = new ToolBarManager(SWT.FLAT);
        ToolBar toolbar = mgr.createControl(section);
        toolbar.setCursor(section.getDisplay().getSystemCursor(SWT.CURSOR_HAND));

        mgr.add(createAddNewAction());

        IAction deleteAction = createDeleteAction();
        mgr.add(deleteAction);
        if (deleteAction instanceof ISelectionChangedListener) {
            ISelectionChangedListener scl = (ISelectionChangedListener) deleteAction;
            viewer.addSelectionChangedListener(scl);
            scl.selectionChanged(new SelectionChangedEvent(viewer, viewer.getSelection()));
        }

        mgr.update(true);
        section.setTextClient(toolbar);

        ActionBarsHelper actionBarsHelper = new ActionBarsHelper(getEditorActionBars());
        ActionBarsHelper globalAction = actionBarsHelper.addGlobalAction(ActionFactory.DELETE.getId(),
                deleteAction);
        globalAction.install(viewer);
    }

    @SuppressWarnings("unchecked")
    protected IAction createAddNewAction() {
        Command dummy = createCreateNewCommand();
        ImageDescriptor image = null;

        if (dummy instanceof CommandActionDelegate) {
            image = ExtendedImageRegistry.getInstance()
                    .getImageDescriptor(((CommandActionDelegate) dummy).getImage());
        }

        IAction result = new Action(dummy.getLabel(), image) {
            @Override
            public void run() {
                final Command command = createCreateNewCommand();
                if (command.canExecute()) {
                    getEditingDomain().getCommandStack().execute(command);
                    viewer.getControl().getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            viewer.getControl().setFocus();
                            viewer.setSelection(new StructuredSelection(command.getResult().toArray()));
                        }
                    });
                }
            }
        };

        getContext().bindValue(PojoProperties.value("enabled").observe(getContext().getValidationRealm(), result), //$NON-NLS-1$
                getValue(), null, ObjectWritableConverter.createUpdateValueStrategy());

        return result;
    }

    protected Command createCreateNewCommand() {
        Object input = viewer.getInput();
        Directory parent = input instanceof Directory ? (Directory) input
                : SecurityFactory.eINSTANCE.createDirectory();
        Object child = EcoreUtil.create(elementEClass);
        CommandParameter param = new CommandParameter(parent, SecurityPackage.Literals.DIRECTORY__ITEMS, child);
        return CreateChildCommand.create(getEditingDomain(), parent, param, Collections.singleton(parent));
    }

    protected IAction createDeleteAction() {
        Command dummy = createDeleteCommand(EcoreUtil.create(elementEClass));

        return new SelectionListenerAction<EObject>(dummy.getLabel(),
                SharedIcons.getDescriptor("etool16/delete.gif")) //$NON-NLS-1$
        {
            @Override
            public void run() {
                Command delete = createDeleteCommand(getSelectedObject());
                if (delete.canExecute()) {
                    getEditingDomain().getCommandStack().execute(delete);
                }
            }

            @Override
            protected boolean updateSelection(IStructuredSelection selection) {
                return super.updateSelection(selection) && SecurityUIUtil.isEditable(getInput());
            }

            @Override
            protected Class<EObject> getType() {
                return EObject.class;
            }
        };
    }

    protected Command createDeleteCommand(EObject toDelete) {
        return DeleteCommand.create(getEditingDomain(), toDelete);
    }

    private void forwardSelection(StructuredViewer viewer) {
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                IManagedForm form = getManagedForm();
                if (form != null) {
                    form.fireSelectionChanged(TableSection.this, event.getSelection());
                }
            }
        });
    }

    protected void configureDragSupport(TableViewer viewer) {
        UIUtil.addDragSupport(viewer);
    }

    protected void configureDropSupport(final TableViewer viewer) {
        viewer.addDropSupport(DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY,
                new Transfer[] { LocalSelectionTransfer.getTransfer() }, new ViewerDropAdapter(viewer) {
                    {
                        // We don't want it to look like you can insert new elements, only drop onto existing elements
                        setFeedbackEnabled(false);
                    }

                    @Override
                    public boolean validateDrop(Object target, int operation, TransferData transferType) {
                        boolean result = false;

                        if (target instanceof EObject
                                && LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
                            EObject objectToDrop = getObjectToDrop(transferType);
                            if (objectToDrop != null) {
                                result = getDropReference((EObject) target, objectToDrop) != null;

                                if (result && (getCurrentEvent().operations | DND.DROP_COPY) != 0) {
                                    overrideOperation(DND.DROP_COPY);
                                }
                            }
                        }

                        return result;
                    }

                    @Override
                    public boolean performDrop(Object data) {
                        IStructuredSelection selection = (IStructuredSelection) data;
                        EObject objectToDrop = UIUtil.getElement(selection, EObject.class);
                        EObject target = (EObject) getCurrentTarget();

                        Command command = AddCommand.create(getEditingDomain(), target,
                                getDropReference(target, objectToDrop), selection.toList());

                        boolean result = execute(command);
                        if (result) {
                            viewer.getControl().setFocus();
                            viewer.setSelection(new StructuredSelection(target));
                        }

                        return result;
                    }

                    private EObject getObjectToDrop(TransferData transferType) {
                        return UIUtil.getElement(LocalSelectionTransfer.getTransfer().getSelection(),
                                EObject.class);
                    }
                });
    }

    protected EReference getDropReference(EObject target, EObject objectToDrop) {
        return null;
    }

    protected boolean execute(Command command) {
        boolean result = command.canExecute();
        if (result) {
            getEditingDomain().getCommandStack().execute(command);
        }

        return result;
    }

    protected void checkForUnsupportedModelContent() {
        if (getInput() == null) {
            getManagedForm().getMessageManager().addMessage(this, Messages.TableSection_2, null, IStatus.WARNING,
                    viewer.getControl());
        } else {
            // Anything not matching filters?
            if (viewer.getTable().getItemCount() < getInput().getItems().size()) {
                getManagedForm().getMessageManager().addMessage(this, Messages.TableSection_3, null,
                        IStatus.WARNING, viewer.getControl());
            }
        }
    }
}