es.cv.gvcase.emf.ui.common.dialogs.ChooseDialog.java Source code

Java tutorial

Introduction

Here is the source code for es.cv.gvcase.emf.ui.common.dialogs.ChooseDialog.java

Source

/***********************************************************************
 * Copyright (c) 2007 Anyware Technologies
 * 
 * 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:
 *    Anyware Technologies - initial API and implementation
 *    Francisco Javier Cano Muoz (Prodevelop) - improved initial selection
 **********************************************************************/

package es.cv.gvcase.emf.ui.common.dialogs;

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

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.SWT;
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.Shell;
import org.eclipse.ui.dialogs.SelectionDialog;

import es.cv.gvcase.emf.common.util.EMFUtil;
import es.cv.gvcase.emf.ui.common.composites.EObjectChooserComposite;
import es.cv.gvcase.emf.ui.common.composites.SearchableTreeComposite;
import es.cv.gvcase.emf.ui.common.providers.TreeArrayContentProvider;
import es.cv.gvcase.emf.ui.common.utils.DataPath;

/**
 * The dialog used to choose between the different objects
 * 
 * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
 * @author <a href="mailto:fjcano@prodevelop.es">Francisco Javier Cano Muoz</a>
 */
public class ChooseDialog extends SelectionDialog {

    /**
     * The default width of a dialog
     */
    private int DEFAULT_DIALOG_WIDTH = 400;

    /**
     * The default height of a dialog
     */
    private int DEFAULT_DIALOG_HEIGHT = 300;

    /**
     * The minimum width of a dialog
     */
    private int MIN_DIALOG_WIDTH = 300;

    /**
     * The minimum height of a dialog
     */
    private int MIN_DIALOG_HEIGHT = 300;

    private SearchableTreeComposite tree;

    private ILabelProvider labelProvider;

    private IStructuredContentProvider contentProvider;

    private ITreeContentProvider groupedTreeContentProvider;

    private ITreeContentProvider resourceTreeContentProvider;

    private Object[] objects;

    private List<DataPath> paths;

    /**
     * Flag to set the selection tree as single or multi selection.
     */
    private boolean singleSelection = true;

    /**
     * Indicates whether the selection tree must be single selection.
     * 
     * @return
     */
    protected boolean isSingleSelection() {
        return singleSelection;
    }

    /**
     * Constructor
     * 
     * @param parentShell
     *            the paren shell
     * @param objects
     *            The available objects
     */
    public ChooseDialog(Shell parentShell, Object[] objects) {
        this(parentShell, objects, true);
    }

    /**
     * Constructor
     * 
     * @param parentShell
     *            the paren shell
     * @param objects
     *            The available objects
     * @param singleSelection
     *            Flag to set the selection tree as single or multi selection
     */
    public ChooseDialog(Shell parentShell, Object[] objects, boolean singleSelection) {
        this(parentShell, objects, singleSelection, null);
    }

    public ChooseDialog(Shell parentShell, Object[] objects, boolean singleSelection,
            ITreeContentProvider groupedContentProvider) {
        this(parentShell, objects, singleSelection, null, groupedContentProvider);
    }

    public ChooseDialog(Shell parentShell, Object[] objects, boolean singleSelection,
            ITreeContentProvider groupedContentProvider, ITreeContentProvider resourceContentProvider) {
        super(parentShell);

        this.objects = replaceNulls(objects);
        this.singleSelection = singleSelection;
        this.groupedTreeContentProvider = groupedContentProvider;
        this.resourceTreeContentProvider = resourceContentProvider;
        this.paths = new ArrayList<DataPath>();

        setTitle("Object selection");
        setMessage("Choose an object in the list");
        setShellStyle(getShellStyle() | SWT.RESIZE);
    }

    private Object[] replaceNulls(Object[] objects) {
        List<Object> l = new ArrayList<Object>();

        if (objects == null)
            return l.toArray();

        for (Object o : objects) {
            if (o == null) {
                l.add(new EObjectChooserComposite.NullObject());
            } else {
                l.add(o);
            }
        }
        return l.toArray();
    }

    /**
     * @see org.eclipse.ui.dialogs.SelectionDialog#configureShell(org.eclipse.swt.widgets.Shell)
     */
    protected void configureShell(Shell shell) {
        shell.setMinimumSize(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT);

        super.configureShell(shell);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Control createContents(Composite parent) {
        Control c = super.createContents(parent);

        // by default, ok button is not enabled. Only will be enabled if has
        // elements in the selection or when select an element
        getOkButton().setEnabled(false);

        // Doesn't expand all the tree looking for the element to be selected,
        // due to it's heavy for huge models
        // tree.getTreeViewer().expandAll();
        // for (Object o : selection) {
        // tree.getTreeViewer().expandToLevel(o, 1);
        // }

        // if there are no elements in the selection, nothing to do. In other
        // case, if selection has a null, change it for a NullObject element. In
        // other case, return the selection
        List selection = getInitialElementSelections();

        if (selection.isEmpty()) {
            return c;
        } else {
            List list = null;
            if (selection.size() == 1 && selection.get(0) == null) {
                list = new ArrayList();
                list.add(new EObjectChooserComposite.NullObject());
            } else {
                list = selection;
            }
            tree.setInitialSelection(new StructuredSelection(list));
        }

        return c;
    }

    /**
     * Create the Dialog area
     * 
     * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
     */
    protected Control createDialogArea(Composite parent) {
        // Dialog
        Composite dialogComposite = (Composite) super.createDialogArea(parent);

        GridLayout dialogLayout = new GridLayout();
        dialogLayout.marginWidth = 10;
        dialogLayout.marginHeight = 10;
        GridData dialogLayoutData = new GridData(GridData.FILL_BOTH);
        dialogLayoutData.widthHint = DEFAULT_DIALOG_WIDTH;
        dialogLayoutData.heightHint = DEFAULT_DIALOG_HEIGHT;
        dialogComposite.setLayout(dialogLayout);
        dialogComposite.setLayoutData(dialogLayoutData);

        tree = createTree(dialogComposite);
        tree.setLayoutData(new GridData(GridData.FILL_BOTH));
        if (this.contentProvider != null) {
            tree.setContentProvider(this.contentProvider);
        } else {
            tree.setContentProvider(getTreeContentProvider());
        }
        if (groupedTreeContentProvider != null) {
            tree.setGroupedContentProvider(groupedTreeContentProvider);
        }
        if (resourceTreeContentProvider != null) {
            tree.setResourceContentProvider(resourceTreeContentProvider);
        }
        if (this.labelProvider != null) {
            tree.setLabelProvider(this.labelProvider);
        } else {
            tree.setLabelProvider(EMFUtil.getAdapterFactoryLabelProvider());
        }

        tree.setInput(this.objects);

        hookListeners();

        return dialogComposite;
    }

    @Override
    protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
        if (id == IDialogConstants.OK_ID) {
            return super.createButton(parent, id, label, false);
        }
        return super.createButton(parent, id, label, defaultButton);
    }

    protected ITreeContentProvider getTreeContentProvider() {
        return new TreeArrayContentProvider();
    }

    protected SearchableTreeComposite createTree(Composite parent) {
        SearchableTreeComposite tree = new SearchableTreeComposite(parent,
                isSingleSelection() ? SWT.SINGLE : SWT.MULTI, selectAfterRefreshTree());
        return tree;
    }

    protected boolean selectAfterRefreshTree() {
        return true;
    }

    protected void changeItemHandle(SelectionChangedEvent event) {
        if (event.getSelection() instanceof IStructuredSelection) {
            IStructuredSelection selection = (IStructuredSelection) event.getSelection();
            if (selection.isEmpty()) {
                getOkButton().setEnabled(false);
                return;
            }
            for (Object o : selection.toList()) {
                if (!((checkSelectionValid(o)) || (o instanceof EObjectChooserComposite.NullObject))) {
                    getOkButton().setEnabled(false);
                    return;
                }
            }
            getOkButton().setEnabled(true);
            if (selection instanceof TreeSelection) {
                TreeSelection ts = (TreeSelection) selection;
                modifySelectionPath(ts);
            }
            return;
        }
        getOkButton().setEnabled(false);
        return;
    }

    protected boolean checkSelectionValid(Object o) {
        return true;
    }

    /**
     * This method had the UI listeners on the SWT widgets
     */
    private void hookListeners() {
        tree.getTreeViewer().addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                changeItemHandle(event);
            }

        });
        tree.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() {

            public void doubleClick(DoubleClickEvent event) {
                if (getOkButton().isEnabled()) {
                    okPressed();
                }
            }

        });
    }

    /**
     * Gets the initial selected elements. Before returning the selected
     * elements, all nested Arrays and Collections are de-nested.
     */
    @Override
    protected List<?> getInitialElementSelections() {
        List initialElementsSelection = new ArrayList();
        // get the normal initial selection
        List superInitialElementsSelection = super.getInitialElementSelections();
        // find any nested List in the initial selection and de-nest them
        if (superInitialElementsSelection != null) {
            for (Object object : superInitialElementsSelection) {
                // an array can contain more objects
                if (object instanceof Object[]) {
                    Object[] objects = (Object[]) object;
                    for (Object innerObject : objects) {
                        initialElementsSelection.add(innerObject);
                    }
                }
                // a Collection can contain more objects
                else if (object instanceof Collection) {
                    Collection objects = (Collection) object;
                    for (Object innerObject : objects) {
                        initialElementsSelection.add(innerObject);
                    }
                }
                // a regular object that is neither an Array or a Collection is
                // added to the selection as-is
                else {
                    initialElementsSelection.add(object);
                }
            }
        }
        return initialElementsSelection;
    }

    /**
     * Set the provider that displays the objects
     * 
     * @param provider
     *            the LabelProvider
     */
    public void setLabelProvider(ILabelProvider provider) {
        this.labelProvider = provider;
    }

    public void setContentProvider(IStructuredContentProvider provider) {
        this.contentProvider = provider;
    }

    /**
     * @see org.eclipse.jface.dialogs.Dialog#okPressed()
     */
    protected void okPressed() {
        IStructuredSelection selection = (IStructuredSelection) tree.getTreeViewer().getSelection();
        List<Object> filteredSelection = new ArrayList<Object>();
        for (Object o : selection.toList()) {
            filteredSelection.add(o);
        }
        setResult(filteredSelection);
        super.okPressed();
    }

    protected void modifySelectionPath(TreeSelection ts) {
        paths.clear();

        for (Object o : ts.toList()) {
            DataPath dp = new DataPath(o, ts.getPathsFor(o)[0], getAllowedTypesInThePath());
            paths.add(dp);
        }
    }

    protected List<?> getAllowedTypesInThePath() {
        return Collections.singletonList(Object.class);
    }

    public List<DataPath> getPaths() {
        return paths;
    }

    public DataPath getPathForElement(Object obj) {
        for (DataPath dp : paths) {
            if (dp.getElement() == obj) {
                return dp;
            }
        }

        return null;
    }

    protected Object[] getElements() {
        return objects;
    }

    public SearchableTreeComposite getTreeComposite() {
        return tree;
    }

}