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

Java tutorial

Introduction

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

Source

/*******************************************************************************
 * Copyright (c) 2008, 2011 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.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.eef.runtime.impl.utils.ModelViewerHelper;
import org.eclipse.emf.eef.runtime.ui.utils.EEFLabelProvider;
import org.eclipse.emf.eef.runtime.ui.utils.EEFRuntimeUIMessages;
import org.eclipse.emf.eef.runtime.ui.widgets.referencestable.ReferencesTableSettings;
import org.eclipse.emf.eef.runtime.ui.widgets.settings.AdvancedEEFEditorContentProvider;
import org.eclipse.emf.eef.runtime.ui.widgets.settings.EEFEditorSettings;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;

/**
 * This dialog shows the tree of all owned element by taking in account a filter
 * 
 * @author Patrick Tessier
 * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
 * @author <a href="mailto:stephane.bouchet@obeo.fr">Stephane Bouchet</a>
 * @author <a href="mailto:stephane.thibaudeau@obeo.fr">Stephane Thibaudeau</a>
 */
public abstract class ElementSelectionDialog extends Dialog implements IPropertiesFilteredWidget {

    /**
     * the label
     */
    protected Label label;

    /**
     * The selection tree.
     */
    protected Tree tree;

    /** title of the window */
    protected String title = EEFRuntimeUIMessages.TabElementTreeSelectionDialog_title;

    /**
     * filters
     */
    private List<ViewerFilter> viewerFilters;

    /**
     * business rules filters
     */
    private List<ViewerFilter> brFilters;

    /**
     * The adapter factory.
     */
    protected AdapterFactory adapterFactory;

    private Composite parent;

    private Object input;

    private IStructuredSelection selection;

    /**
     * Constructor with parent shell and Element.
     * 
     * @param parentElement
     *            the element where we look for a children
     * @param filters
     *            this is an array of filter see {@link ViewerFilter} or an example {@link OperationFilter}
     * @param title
     *            title of the window
     * @param createElement
     *            this is the listener to create an element
     * @param abstractElement
     *            it used to inform about if the element is abstract in this case the creation button does not
     *            appear
     * @param mainResource
     *            the main resource.
     */
    public ElementSelectionDialog(Object input, List<ViewerFilter> filters, List<ViewerFilter> brFilters,
            String title, AdapterFactory adapterFactory) {
        super(Display.getDefault().getActiveShell());
        // add the resize ability to the window
        setShellStyle(SWT.RESIZE | super.getShellStyle());
        this.input = input;
        this.viewerFilters = filters;
        this.brFilters = brFilters;
        this.title = title;
        this.adapterFactory = adapterFactory;
    }

    /**
     * Creates the dialog area.
     * 
     * @param parent
     *            composite.
     * @return control Control.
     */
    protected Control createDialogArea(Composite parent) {
        this.parent = parent;

        return fillModelpage(parent);
    }

    /**
     * Used to display a page
     * 
     * @param parent
     *            composite which contains the tree
     * @return the composite of this page
     */
    public Control fillModelpage(Composite parent) {
        Composite composite = new Composite(parent, SWT.None);
        GridLayout layout = new GridLayout();
        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        composite.setLayout(layout);

        // use pattern filter
        PatternFilter patternFilter = new TreeSelectionPatternFilter();
        patternFilter.setIncludeLeadingWildcard(true);

        FilteredTree filteredTree = new FilteredTree(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.RESIZE,
                patternFilter, true);
        // use of EMF facilities
        final TreeViewer treeViewer = filteredTree.getViewer();
        treeViewer.setFilters(new ViewerFilter[0]);
        treeViewer.setUseHashlookup(true);
        if (input instanceof EEFEditorSettings)
            treeViewer.setContentProvider(
                    new HideResourcesContentProvider(new AdvancedEEFEditorContentProvider(adapterFactory)));
        else
            treeViewer.setContentProvider(
                    new HideResourcesContentProvider(new AdapterFactoryContentProvider(adapterFactory)));

        ArrayList<ViewerFilter> filters = new ArrayList<ViewerFilter>();
        if (viewerFilters != null && !viewerFilters.isEmpty()) {
            for (ViewerFilter filter : viewerFilters) {
                filters.add(filter);
            }
        }
        // for now, add the businessRuleFilters to the 'normal' filters
        if (brFilters != null && !brFilters.isEmpty()) {
            for (ViewerFilter filter : brFilters) {
                filters.add(filter);
            }
        }
        filters.add(patternFilter);
        ViewerFilter[] v = filters.toArray(new ViewerFilter[filters.size()]);
        treeViewer.setFilters(v);
        treeViewer.setLabelProvider(new EEFLabelProvider() {

            @Override
            public Color getForeground(Object element) {
                if (input instanceof ReferencesTableSettings && element instanceof EObject
                        && ((ReferencesTableSettings) input).contains((EObject) element)) {
                    return getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
                }

                return super.getForeground(element);
            }

        });

        filteredTree.setLayoutData(new GridData(550, 300));
        // handle selection change
        if (input instanceof EEFEditorSettings) {
            treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
                public void selectionChanged(SelectionChangedEvent event) {
                    if (event.getSelection() instanceof IStructuredSelection) {
                        // Check selection
                        IStructuredSelection structuredSelection = (IStructuredSelection) event.getSelection();
                        if (structuredSelection != null && !structuredSelection.isEmpty()) {
                            Object o = structuredSelection.getFirstElement();
                            // Check type matching
                            Button okButton = getButton(IDialogConstants.OK_ID);
                            if (((List<?>) ((EEFEditorSettings) input).choiceOfValues(adapterFactory))
                                    .contains(o)) {
                                if (input instanceof ReferencesTableSettings) {
                                    if (o instanceof EObject
                                            && !((ReferencesTableSettings) input).contains((EObject) o)) {
                                        selection = structuredSelection;
                                        if (okButton != null) {
                                            okButton.setEnabled(true);
                                        }
                                    } else {
                                        // Reject selection
                                        if (okButton != null) {
                                            okButton.setEnabled(false);
                                        }
                                    }
                                } else {
                                    selection = structuredSelection;
                                    if (okButton != null) {
                                        okButton.setEnabled(true);
                                    }
                                }
                            } else {
                                // Reject selection
                                if (okButton != null) {
                                    okButton.setEnabled(false);
                                }
                            }
                        }

                    }
                }
            });

            // handle double click to validate
            treeViewer.addDoubleClickListener(new IDoubleClickListener() {
                public void doubleClick(DoubleClickEvent event) {
                    if (selection != null && !selection.isEmpty()) {
                        Object o = selection.getFirstElement();
                        if (((List<?>) ((EEFEditorSettings) input).choiceOfValues(adapterFactory)).contains(o)
                                && input instanceof ReferencesTableSettings && o instanceof EObject
                                && !((ReferencesTableSettings) input).contains((EObject) o)) {
                            okPressed();
                        }
                    }
                }
            });
        }
        treeViewer.setInput(input);

        // Init selected element
        if (selection != null) {
            treeViewer.setSelection(selection);
        }

        return composite;

    }

    /**
     * ContentProvider which delegates almost everything to another ContentProvider.
     * The purpose is to hide the Resource and display only their contents
     *
     */
    private class HideResourcesContentProvider implements ITreeContentProvider {
        private ITreeContentProvider delegateContentProvider;

        public HideResourcesContentProvider(ITreeContentProvider delegateContentProvider) {
            this.delegateContentProvider = delegateContentProvider;
        }

        public Object[] getElements(Object inputElement) {
            // Retrieve elements provided by the delegate content provider
            Object[] elements = delegateContentProvider.getElements(inputElement);
            List<Object> newElements = new ArrayList<Object>();
            for (Object element : elements) {
                // When an element is a resource, return its contents instead of the resource itself
                if (element instanceof Resource) {
                    newElements.addAll(((Resource) element).getContents());
                } else {
                    newElements.add(element);
                }
            }
            return newElements.toArray();
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            delegateContentProvider.inputChanged(viewer, oldInput, newInput);
        }

        public Object[] getChildren(Object parentElement) {
            return delegateContentProvider.getChildren(parentElement);
        }

        public Object getParent(Object element) {
            return delegateContentProvider.getParent(element);
        }

        public boolean hasChildren(Object element) {
            return delegateContentProvider.hasChildren(element);
        }

        public void dispose() {
            delegateContentProvider.dispose();
        }
    }

    private class TreeSelectionPatternFilter extends PatternFilter {
        @Override
        protected boolean isParentMatch(Viewer viewer, Object element) {
            Object[] children = ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider())
                    .getChildren(element);
            // apply all filters
            if (viewerFilters != null && !viewerFilters.isEmpty() && children != null) {
                // if one child match, show the parent in tree
                for (ViewerFilter viewerFilter : viewerFilters) {
                    for (Object child : children) {
                        if (viewerFilter.select(viewer, null, child)) {
                            return super.isParentMatch(viewer, element);
                        }
                    }
                }
                return false;
            } else {
                return super.isParentMatch(viewer, element);
            }
        }

        @Override
        protected boolean isLeafMatch(Viewer viewer, Object element) {
            if (element instanceof EObject) {
                String labelText = ((EObject) element).toString();
                if (labelText != null) {
                    return wordMatches(labelText);
                }
            }
            return false;
        }
    }

    /**
     * Sets or clears the input for this dialog.
     */
    public void setInput(Object input) {
        this.input = input;
        this.refresh();
    }

    public void refresh() {
        parent.pack();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText(EEFRuntimeUIMessages.TabElementTreeSelectionDialog_shell_title + this.title);
    }

    /**
     * @see org.eclipse.jface.dialogs.Dialog#okPressed()
     */
    @Override
    protected void okPressed() {
        if (selection != null && !selection.isEmpty()) {
            process(selection);
            ModelViewerHelper.setLastSelection(selection);
        }
        super.okPressed();
    }

    public void setSelection(IStructuredSelection selection) {
        this.selection = selection;
    }

    public abstract void process(IStructuredSelection selection);

    public void addBusinessRuleFilter(ViewerFilter filter) {
        this.brFilters.add(filter);
    }

    public void addFilter(ViewerFilter filter) {
        this.viewerFilters.add(filter);
    }

    public void removeBusinessRuleFilter(ViewerFilter filter) {
        this.brFilters.remove(filter);
    }

    public void removeFilter(ViewerFilter filter) {
        this.viewerFilters.remove(filter);
    }

}