package org.python.pydev.ui.dialogs; /******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * * copied from org.eclipse.ui.internal.ide.misc.ContainerSelectionGroup * so that we can just get the current project! * *******************************************************************************/ import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; 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.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; 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.model.WorkbenchLabelProvider; import org.eclipse.ui.part.DrillDownComposite; /** * Workbench-level composite for choosing a container. */ public class ProjectFolderSelectionGroup extends Composite { /** * Provides content for a tree viewer that shows only containers. */ public static class CopiedContainerContentProvider implements ITreeContentProvider { private boolean showClosedProjects = true; /** * Creates a new ContainerContentProvider. */ public CopiedContainerContentProvider() { } /** * The visual part that is using this content provider is about * to be disposed. Deallocate all allocated SWT resources. */ public void dispose() { } /* * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ public Object[] getChildren(Object element) { if (element instanceof IWorkspace) { // check if closed projects should be shown IProject[] allProjects = ((IWorkspace) element).getRoot().getProjects(); if (showClosedProjects) return allProjects; ArrayList accessibleProjects = new ArrayList(); for (int i = 0; i < allProjects.length; i++) { if (allProjects[i].isOpen()) { accessibleProjects.add(allProjects[i]); } } return accessibleProjects.toArray(); } else if (element instanceof IContainer) { IContainer container = (IContainer) element; if (container.isAccessible()) { try { List children = new ArrayList(); IResource[] members = container.members(); for (int i = 0; i < members.length; i++) { if (members[i].getType() != IResource.FILE) { children.add(members[i]); } } return children.toArray(); } catch (CoreException e) { // this should never happen because we call #isAccessible before invoking #members } } } return new Object[0]; } /* * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ public Object[] getElements(Object element) { return getChildren(element); } /* * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ public Object getParent(Object element) { if (element instanceof IResource) return ((IResource) element).getParent(); return null; } /* * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) */ public boolean hasChildren(Object element) { return getChildren(element).length > 0; } /* * @see org.eclipse.jface.viewers.IContentProvider#inputChanged */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } /** * Specify whether or not to show closed projects in the tree * viewer. Default is to show closed projects. * * @param show boolean if false, do not show closed projects in the tree */ public void showClosedProjects(boolean show) { showClosedProjects = show; } } // The listener to notify of events private 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; TreeViewer treeViewer; // sizing constants private static final int SIZING_SELECTION_PANE_WIDTH = 320; private static final int SIZING_SELECTION_PANE_HEIGHT = 300; private IProject project; /** * 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 ProjectFolderSelectionGroup(Composite parent, Listener listener, boolean allowNewContainerName, String message, boolean showClosedProjects, IProject project) { this(parent, listener, allowNewContainerName, message, showClosedProjects, SIZING_SELECTION_PANE_HEIGHT, project); } /** * 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 */ private ProjectFolderSelectionGroup(Composite parent, Listener listener, boolean allowNewContainerName, String message, boolean showClosedProjects, int heightHint, IProject project) { super(parent, SWT.NONE); this.project = project; this.listener = listener; this.allowNewContainerName = allowNewContainerName; this.showClosedProjects = showClosedProjects; createContents(message, heightHint); } /** * The container selection has changed in the tree view. Update the container name field value and notify all listeners. */ public void containerSelectionChanged(IContainer container) { selectedContainer = container; if (allowNewContainerName) { if (container == null) containerNameField.setText("");//$NON-NLS-1$ else containerNameField.setText(container.getFullPath().makeRelative().toString()); } // fire an event so the parent can update its controls if (listener != null) { Event changeEvent = new Event(); changeEvent.type = SWT.Selection; changeEvent.widget = this; listener.handleEvent(changeEvent); } } /** * Creates the contents of the composite. */ public void createContents(String message) { createContents(message, SIZING_SELECTION_PANE_HEIGHT); } /** * Creates the contents of the composite. * * @param heightHint height hint for the drill down composite */ public void createContents(String message, int heightHint) { GridLayout layout = new GridLayout(); layout.marginWidth = 0; setLayout(layout); setLayoutData(new GridData(GridData.FILL_BOTH)); Label label = new Label(this, SWT.WRAP); label.setText(message); label.setFont(this.getFont()); if (allowNewContainerName) { containerNameField = new Text(this, SWT.SINGLE | SWT.BORDER); containerNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); containerNameField.addListener(SWT.Modify, listener); 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 * @return a new drill down viewer */ protected void createTreeViewer(int heightHint) { // Create drill down. DrillDownComposite drillDown = new DrillDownComposite(this, SWT.BORDER); GridData spec = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); spec.widthHint = SIZING_SELECTION_PANE_WIDTH; spec.heightHint = heightHint; drillDown.setLayoutData(spec); // Create tree viewer inside drill down. treeViewer = new TreeViewer(drillDown, SWT.NONE); drillDown.setChildTree(treeViewer); // // //ALL THAT JUST SO THAT WE CAN SET THAT WE JUST WANT THE SPECIFIED PROJECT!!!!!! // // CopiedContainerContentProvider cp = new CopiedContainerContentProvider() { public Object[] getChildren(Object element) { if (element instanceof IWorkspace) { return new Object[] { project }; } else if (element instanceof IContainer) { IContainer container = (IContainer) element; if (container.isAccessible()) { try { List children = new ArrayList(); IResource[] members = container.members(); for (int i = 0; i < members.length; i++) { if (members[i].getType() != IResource.FILE) { children.add(members[i]); } } return children.toArray(); } catch (CoreException e) { // this should never happen because we call #isAccessible before invoking #members } } } return new Object[0]; } }; cp.showClosedProjects(showClosedProjects); treeViewer.setContentProvider(cp); treeViewer.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider()); treeViewer.setSorter(new ViewerSorter()); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); containerSelectionChanged((IContainer) selection.getFirstElement()); // allow null } }); treeViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { Object item = ((IStructuredSelection) selection).getFirstElement(); if (treeViewer.getExpandedState(item)) treeViewer.collapseToLevel(item, 1); else treeViewer.expandToLevel(item, 1); } } }); // This has to be done after the viewer has been laid out treeViewer.setInput(ResourcesPlugin.getWorkspace()); } /** * 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. */ public IPath getContainerFullPath() { if (allowNewContainerName) { String pathName = containerNameField.getText(); if (pathName == null || pathName.length() < 1) return null; else //The user may not have made this absolute so do it for them return (new Path(pathName)).makeAbsolute(); } else { if (selectedContainer == null) return null; else return selectedContainer.getFullPath(); } } /** * Gives focus to one of the widgets in the group, as determined by the group. */ public void setInitialFocus() { if (allowNewContainerName) containerNameField.setFocus(); else treeViewer.getTree().setFocus(); } /** * Sets the selected existing container. */ public void setSelectedContainer(IContainer container) { selectedContainer = container; //expand to and select the specified container List itemsToExpand = new ArrayList(); IContainer parent = container.getParent(); while (parent != null) { itemsToExpand.add(0, parent); parent = parent.getParent(); } treeViewer.setExpandedElements(itemsToExpand.toArray()); treeViewer.setSelection(new StructuredSelection(container), true); } }