/**
* 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.shared_ui.dialogs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IBaseLabelProvider;
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.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.dialogs.SelectionStatusDialog;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.python.pydev.shared_ui.SharedUiPlugin;
import org.python.pydev.shared_ui.tree.PyFilteredTree;
public class ProjectSelectionDialog extends SelectionStatusDialog {
private TreeViewer fTreeViewer;
private final static int WIDGET_HEIGHT = 250;
private final static int WIDGET_WIDTH = 300;
private String natureId;
private PatternFilter patternFilter;
private PyFilteredTree filteredTree;
private boolean multipleSelection;
/**
* May be set by the user to show projects differently (default is WorkbenchLabelProvider).
* Must be set before the dialog is opened.
*/
public IBaseLabelProvider labelProvider;
public ProjectSelectionDialog(Shell parentShell, String natureId) {
this(parentShell, natureId, false);
}
public ProjectSelectionDialog(Shell parentShell, String natureId, boolean multipleSelection) {
super(parentShell);
this.labelProvider = new WorkbenchLabelProvider();
setTitle("Select project");
setMessage("Select project");
this.multipleSelection = multipleSelection;
this.natureId = natureId;
int shellStyle = getShellStyle();
setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
}
/**
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea(Composite parent) {
// page group
Composite composite = (Composite) super.createDialogArea(parent);
Font font = parent.getFont();
composite.setFont(font);
createMessageArea(composite);
patternFilter = new PatternFilter();
filteredTree = PyFilteredTree.create(composite, patternFilter, true);
fTreeViewer = filteredTree.getViewer();
fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
doSelectionChanged(((IStructuredSelection) event.getSelection()).toArray());
}
});
fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
okPressed();
}
});
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.heightHint = WIDGET_HEIGHT;
data.widthHint = WIDGET_WIDTH;
fTreeViewer.getTree().setLayoutData(data);
fTreeViewer.setLabelProvider(labelProvider);
fTreeViewer.setContentProvider(new ArrayContentProvider());
fTreeViewer.getControl().setFont(font);
if (natureId != null) {
fTreeViewer.addFilter(new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (element instanceof IProject) {
IProject project = (IProject) element;
try {
return project.isOpen() && project.hasNature(natureId);
} catch (CoreException e) {
return false;
}
}
return true;
}
});
}
IProject[] input = ResourcesPlugin.getWorkspace().getRoot().getProjects();
fTreeViewer.setInput(input);
doSelectionChanged(new Object[0]);
Dialog.applyDialogFont(composite);
SharedUiPlugin.setCssId(parent, "py-project-selection-dialog", true);
return composite;
}
private void doSelectionChanged(Object[] objects) {
if (multipleSelection) {
if (objects.length == 0) {
updateStatus(new Status(IStatus.ERROR, "org.python.pydev.shared_ui", "Select one or more projects")); //$NON-NLS-1$
setSelectionResult(null);
} else {
updateStatus(new Status(IStatus.OK, "org.python.pydev.shared_ui", objects.length + " selected"));
setSelectionResult(objects);
}
} else {
if (objects.length != 1) {
updateStatus(new Status(IStatus.ERROR, "org.python.pydev.shared_ui", "Select one project")); //$NON-NLS-1$
setSelectionResult(null);
} else {
updateStatus(new Status(IStatus.OK, "org.python.pydev.shared_ui", objects.length + " selected"));
setSelectionResult(objects);
}
}
}
@Override
protected void updateStatus(IStatus status) {
super.updateStatus(status);
Control area = this.getDialogArea();
if (area != null) {
SharedUiPlugin.fixSelectionStatusDialogStatusLineColor(this, area.getBackground());
}
}
/**
* @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
*/
@Override
protected void computeResult() {
Tree tree = fTreeViewer.getTree();
TreeItem[] selection = tree.getSelection();
List<IProject> p = new ArrayList<>();
for (TreeItem treeItem : selection) {
Object data = treeItem.getData();
if (data instanceof IProject) {
p.add((IProject) data);
}
}
if (p.size() == 0) {
TreeItem[] items = tree.getItems();
if (items.length > 0) {
Object data = items[0].getData();
if (data instanceof IProject) {
p.add((IProject) data);
}
}
}
setSelectionResult(p.toArray(new IProject[0]));
}
}
final class ArrayContentProvider implements ITreeContentProvider {
@Override
public Object[] getChildren(Object element) {
if (element instanceof Object[]) {
Object[] list = (Object[]) element;
return list;
}
return new Object[0];
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return element instanceof Object[] && ((Object[]) element).length > 0;
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
@Override
public void dispose() {
//do nothing
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
//do nothing
}
}