/** * Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.ui.dialogs; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.python.pydev.editor.codecompletion.revisited.PythonPathHelper; import org.python.pydev.plugin.PydevPlugin; /** * Dialog to choose a Python module from a project * * @author Mikko Ohtamaa */ public class PythonModulePickerDialog extends ElementTreeSelectionDialog { public PythonModulePickerDialog(Shell parent, String title, String message, IProject project, boolean unitTesting) { super(parent, new WorkbenchLabelProvider(), new PythonModuleContentProvider()); setAllowMultiple(unitTesting); this.setEmptyListMessage("No Python modules in project " + project.getName()); this.setInput(project); this.setTitle(title); this.setMessage(message); // Do not allow multiple selection of packages / modules for non-Unittest runs if (!unitTesting) { this.setValidator(new ISelectionStatusValidator() { @Override public IStatus validate(Object selection[]) { if (selection.length >= 1) { if (selection[0] instanceof IFile) { IFile file = (IFile) selection[0]; return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Module " + file.getName() + " selected", null); } else if (selection[0] instanceof IFolder) { IFolder folder = (IFolder) selection[0]; if (folder.findMember("__main__.py") == null) { return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR, "Can't find '__main__' module in this folder.", null); } else { return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Module " + folder.getName() + " selected", null); } } } return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR, "No Python module selected", null); } }); } else { this.setValidator(new ISelectionStatusValidator() { @Override public IStatus validate(Object selection[]) { for (int i = 0; i < selection.length; i++) { if (!(selection[i] instanceof IFolder)) { continue; } IFolder folder = (IFolder) selection[i]; // Ignore .* folders, like .settings if (folder.getFileExtension() != null) { return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR, "Invalid selection: " + folder.getFileExtension(), null); } } if (selection.length == 1) { if (selection[0] instanceof IFile) { IFile file = (IFile) selection[0]; return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Module " + file.getName() + " selected", null); } else if (selection[0] instanceof IFolder) { IFolder folder = (IFolder) selection[0]; return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Package " + folder.getName() + " selected", null); } } else if (selection.length > 1) { return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Multiple items selected", null); } return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR, "Nothing selected", null); } }); } } } class PythonModuleContentProvider implements ITreeContentProvider { /** * Creates a new ContainerContentProvider. */ PythonModuleContentProvider() { } /** * The visual part that is using this content provider is about * to be disposed. Deallocate all allocated SWT resources. */ @Override public void dispose() { } /* * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ @Override public Object[] getChildren(Object element) { if (element instanceof IContainer) { IContainer container = (IContainer) element; if (container.isAccessible()) { try { List<IResource> children = new ArrayList<IResource>(); IResource[] members = container.members(); for (int i = 0; i < members.length; i++) { if (members[i] instanceof IFile) { IFile file = (IFile) members[i]; if (PythonPathHelper.isValidSourceFile(file)) { children.add(file); } } else if (members[i] instanceof IContainer) { 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) */ @Override public Object[] getElements(Object element) { return getChildren(element); } /* * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ @Override 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) */ @Override public boolean hasChildren(Object element) { return getChildren(element).length > 0; } /* * @see org.eclipse.jface.viewers.IContentProvider#inputChanged */ @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } }