gov.redhawk.ui.parts.ContainerSelectionGroup.java Source code

Java tutorial

Introduction

Here is the source code for gov.redhawk.ui.parts.ContainerSelectionGroup.java

Source

/**
 * This file is protected by Copyright. 
 * Please refer to the COPYRIGHT file distributed with this source distribution.
 * 
 * This file is part of REDHAWK IDE.
 * 
 * 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.
 *
 */
/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Igor Fedorenko <igorfie@yahoo.com> -
 *           Fix for Bug 136921 [IDE] New File dialog locks for 20 seconds
 *******************************************************************************/
package gov.redhawk.ui.parts;

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

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
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.TreeViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.misc.ContainerContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.DrillDownComposite;

/**
 * Workbench-level composite for choosing a container.
 */
public class ContainerSelectionGroup extends Composite {
    // the message to display at the top of this dialog
    private static final String DEFAULT_MSG_NEW_ALLOWED = IDEWorkbenchMessages.ContainerGroup_message;

    private static final String DEFAULT_MSG_SELECT_ONLY = IDEWorkbenchMessages.ContainerGroup_selectFolder;

    // sizing constants
    private static final int SIZING_SELECTION_PANE_WIDTH = 320;

    private static final int SIZING_SELECTION_PANE_HEIGHT = 300;

    // The listener to notify of events
    private final Listener listener;

    // Enable user to type in new container name
    private boolean allowNewContainerName = true;

    // show all projects by default
    private boolean showClosedProjects = true;

    // Last selection made by user
    private IContainer selectedContainer;

    // handle on parts
    private Text containerNameField;

    private TreeViewer treeViewer;

    private final IProject root;

    /**
     * Creates a new instance of the widget.
     * 
     * @param parent The parent widget of the group.
     * @param listener A listener to forward events to. Can be null if no
     *            listener is required.
     * @param allowNewContainerName Enable the user to type in a new container
     *            name instead of just selecting from the existing ones.
     */
    public ContainerSelectionGroup(final Composite parent, final Listener listener, final IProject root,
            final boolean allowNewContainerName) {
        this(parent, listener, root, allowNewContainerName, null);
    }

    /**
     * Creates a new instance of the widget.
     * 
     * @param parent The parent widget of the group.
     * @param listener A listener to forward events to. Can be null if no
     *            listener is required.
     * @param allowNewContainerName Enable the user to type in a new container
     *            name instead of just selecting from the existing ones.
     * @param message The text to present to the user.
     */
    public ContainerSelectionGroup(final Composite parent, final Listener listener, final IProject root,
            final boolean allowNewContainerName, final String message) {
        this(parent, listener, root, allowNewContainerName, message, true);
    }

    /**
     * Creates a new instance of the widget.
     * 
     * @param parent The parent widget of the group.
     * @param listener A listener to forward events to. Can be null if no
     *            listener is required.
     * @param allowNewContainerName Enable the user to type in a new container
     *            name instead of just selecting from the existing ones.
     * @param message The text to present to the user.
     * @param showClosedProjects Whether or not to show closed projects.
     */
    public ContainerSelectionGroup(final Composite parent, final Listener listener, final IProject root,
            final boolean allowNewContainerName, final String message, final boolean showClosedProjects) {
        this(parent, listener, root, allowNewContainerName, message, showClosedProjects,
                ContainerSelectionGroup.SIZING_SELECTION_PANE_HEIGHT,
                ContainerSelectionGroup.SIZING_SELECTION_PANE_WIDTH);
    }

    /**
     * Creates a new instance of the widget.
     * 
     * @param parent The parent widget of the group.
     * @param listener A listener to forward events to. Can be null if no
     *            listener is required.
     * @param allowNewContainerName Enable the user to type in a new container
     *            name instead of just selecting from the existing ones.
     * @param message The text to present to the user.
     * @param showClosedProjects Whether or not to show closed projects.
     * @param heightHint height hint for the drill down composite
     * @param widthHint width hint for the drill down composite
     */
    public ContainerSelectionGroup(final Composite parent, final Listener listener, final IProject root, // SUPPRESS CHECKSTYLE Parameters
            final boolean allowNewContainerName, final String message, final boolean showClosedProjects,
            final int heightHint, final int widthHint) {
        super(parent, SWT.NONE);
        this.listener = listener;
        this.root = root;
        this.allowNewContainerName = allowNewContainerName;
        this.showClosedProjects = showClosedProjects;
        if (message != null) {
            createContents(message, heightHint, widthHint);
        } else if (allowNewContainerName) {
            createContents(ContainerSelectionGroup.DEFAULT_MSG_NEW_ALLOWED, heightHint, widthHint);
        } else {
            createContents(ContainerSelectionGroup.DEFAULT_MSG_SELECT_ONLY, heightHint, widthHint);
        }
    }

    /**
     * The container selection has changed in the tree view. Update the
     * container name field value and notify all listeners.
     * 
     * @param container The container that changed
     */
    public void containerSelectionChanged(final IContainer container) {
        this.selectedContainer = container;

        if (this.allowNewContainerName) {
            if (container == null) {
                this.containerNameField.setText(this.root.getName());
            } else {
                final String text = TextProcessor.process(container.getFullPath().makeRelative().toString());
                this.containerNameField.setText(text);
                this.containerNameField.setToolTipText(text);
            }
        }

        // fire an event so the parent can update its controls
        if (this.listener != null) {
            final Event changeEvent = new Event();
            changeEvent.type = SWT.Selection;
            changeEvent.widget = this;
            this.listener.handleEvent(changeEvent);
        }
    }

    /**
     * Creates the contents of the composite.
     * 
     * @param message
     */
    public void createContents(final String message) {
        createContents(message, ContainerSelectionGroup.SIZING_SELECTION_PANE_HEIGHT,
                ContainerSelectionGroup.SIZING_SELECTION_PANE_WIDTH);
    }

    /**
     * Creates the contents of the composite.
     * 
     * @param message
     * @param heightHint
     * @param widthHint
     */
    public void createContents(final String message, final int heightHint, final int widthHint) {
        final GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        setLayout(layout);
        setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        final Label label = new Label(this, SWT.WRAP);
        label.setText(message);
        label.setFont(this.getFont());

        if (this.allowNewContainerName) {
            this.containerNameField = new Text(this, SWT.SINGLE | SWT.BORDER);
            final GridData gd = new GridData(GridData.FILL_HORIZONTAL);
            gd.widthHint = widthHint;
            this.containerNameField.setLayoutData(gd);
            this.containerNameField.addListener(SWT.Modify, this.listener);
            this.containerNameField.setFont(this.getFont());
        } else {
            // filler...
            new Label(this, SWT.NONE);
        }

        createTreeViewer(heightHint);
        Dialog.applyDialogFont(this);
    }

    /**
     * Returns a new drill down viewer for this dialog.
     * 
     * @param heightHint height hint for the drill down composite
     */
    protected void createTreeViewer(final int heightHint) {
        // Create drill down.
        final DrillDownComposite drillDown = new DrillDownComposite(this, SWT.BORDER);
        final GridData spec = new GridData(SWT.FILL, SWT.FILL, true, true);
        spec.widthHint = ContainerSelectionGroup.SIZING_SELECTION_PANE_WIDTH;
        spec.heightHint = heightHint;
        drillDown.setLayoutData(spec);

        // Create tree viewer inside drill down.
        this.treeViewer = new TreeViewer(drillDown, SWT.NONE);
        drillDown.setChildTree(this.treeViewer);
        final ContainerContentProvider cp = new ContainerContentProvider();
        cp.showClosedProjects(this.showClosedProjects);
        this.treeViewer.setContentProvider(cp);
        this.treeViewer.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider());
        this.treeViewer.setComparator(new ViewerComparator());
        this.treeViewer.setUseHashlookup(true);
        this.treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(final SelectionChangedEvent event) {
                final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                containerSelectionChanged((IContainer) selection.getFirstElement()); // allow null
            }
        });
        this.treeViewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(final DoubleClickEvent event) {
                final ISelection selection = event.getSelection();
                if (selection instanceof IStructuredSelection) {
                    final Object item = ((IStructuredSelection) selection).getFirstElement();
                    if (item == null) {
                        return;
                    }
                    if (ContainerSelectionGroup.this.treeViewer.getExpandedState(item)) {
                        ContainerSelectionGroup.this.treeViewer.collapseToLevel(item, 1);
                    } else {
                        ContainerSelectionGroup.this.treeViewer.expandToLevel(item, 1);
                    }
                }
            }
        });

        // This has to be done after the viewer has been laid out
        this.treeViewer.setInput(this.root);
    }

    /**
     * Returns the currently entered container name. Null if the field is empty.
     * Note that the container may not exist yet if the user entered a new
     * container name in the field.
     * 
     * @return IPath
     */
    public IPath getContainerFullPath() {
        if (this.allowNewContainerName) {
            final String pathName = this.containerNameField.getText();
            if (pathName == null || pathName.length() < 1) {
                return null;
            }
            // The user may not have made this absolute so do it for them
            return (new Path(TextProcessor.deprocess(pathName))).makeAbsolute();

        }
        if (this.selectedContainer == null) {
            return null;
        }
        return this.selectedContainer.getFullPath();

    }

    /**
     * Gives focus to one of the widgets in the group, as determined by the
     * group.
     */
    public void setInitialFocus() {
        if (this.allowNewContainerName) {
            this.containerNameField.setFocus();
        } else {
            this.treeViewer.getTree().setFocus();
        }
    }

    /**
     * Sets the selected existing container.
     * 
     * @param container
     */
    public void setSelectedContainer(final IContainer container) {
        this.selectedContainer = container;

        // expand to and select the specified container
        final List<IContainer> itemsToExpand = new ArrayList<IContainer>();
        IContainer parent = container.getParent();
        while (parent != null) {
            itemsToExpand.add(0, parent);
            parent = parent.getParent();
        }
        this.treeViewer.setExpandedElements(itemsToExpand.toArray());
        this.treeViewer.setSelection(new StructuredSelection(container), true);
    }
}