blob: c46db0b047c22f5d781a967cdb06c6f7c7191cc4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2087 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.wizards.buildpath;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.dltk.internal.ui.wizards.NewWizardMessages;
import org.eclipse.dltk.ui.dialogs.StatusInfo;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ILabelProvider;
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.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
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.swt.widgets.Tree;
import org.eclipse.ui.dialogs.NewFolderDialog;
import org.eclipse.ui.dialogs.SelectionStatusDialog;
import org.eclipse.ui.views.navigator.ResourceComparator;
/**
*/
public class MultipleFolderSelectionDialog extends SelectionStatusDialog
implements ISelectionChangedListener {
private CheckboxTreeViewer fViewer;
private ILabelProvider fLabelProvider;
private ITreeContentProvider fContentProvider;
private List fFilters;
private Object fInput;
private Button fNewFolderButton;
private IContainer fSelectedContainer;
private Set fExisting;
private Object fFocusElement;
public MultipleFolderSelectionDialog(Shell parent,
ILabelProvider labelProvider,
ITreeContentProvider contentProvider) {
super(parent);
fLabelProvider = labelProvider;
fContentProvider = contentProvider;
setSelectionResult(null);
setStatusLineAboveButtons(true);
int shellStyle = getShellStyle();
setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
fExisting = null;
fFocusElement = null;
fFilters = null;
}
public void setExisting(Object[] existing) {
fExisting = new HashSet();
for (int i = 0; i < existing.length; i++) {
fExisting.add(existing[i]);
}
}
/**
* Sets the tree input.
*
* @param input
* the tree input.
*/
public void setInput(Object input) {
fInput = input;
}
/**
* Adds a filter to the tree viewer.
*
* @param filter
* a filter.
*/
public void addFilter(ViewerFilter filter) {
if (fFilters == null)
fFilters = new ArrayList(4);
fFilters.add(filter);
}
/**
* Handles cancel button pressed event.
*/
@Override
protected void cancelPressed() {
setSelectionResult(null);
super.cancelPressed();
}
@Override
protected void computeResult() {
Object[] checked = fViewer.getCheckedElements();
if (fExisting == null) {
if (checked.length == 0) {
checked = null;
}
} else {
ArrayList res = new ArrayList();
for (int i = 0; i < checked.length; i++) {
Object elem = checked[i];
if (!fExisting.contains(elem)) {
res.add(elem);
}
}
if (!res.isEmpty()) {
checked = res.toArray();
} else {
checked = null;
}
}
setSelectionResult(checked);
}
private void access$superCreate() {
super.create();
}
@Override
public void create() {
BusyIndicator.showWhile(null, () -> {
access$superCreate();
fViewer.setCheckedElements(getInitialElementSelections().toArray());
fViewer.expandToLevel(2);
if (fExisting != null) {
for (Iterator iter = fExisting.iterator(); iter.hasNext();) {
fViewer.reveal(iter.next());
}
}
updateOKStatus();
});
}
/**
* Creates the tree viewer.
*
* @param parent
* the parent composite
* @return the tree viewer
*/
protected CheckboxTreeViewer createTreeViewer(Composite parent) {
fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
fViewer.setContentProvider(fContentProvider);
fViewer.setLabelProvider(fLabelProvider);
fViewer.addCheckStateListener(event -> updateOKStatus());
fViewer.setComparator(new ResourceComparator(ResourceComparator.NAME));
if (fFilters != null) {
for (int i = 0; i != fFilters.size(); i++)
fViewer.addFilter((ViewerFilter) fFilters.get(i));
}
fViewer.setInput(fInput);
return fViewer;
}
/**
*
*/
protected void updateOKStatus() {
computeResult();
if (getResult() != null) {
updateStatus(new StatusInfo());
} else {
updateStatus(new StatusInfo(IStatus.ERROR, "")); //$NON-NLS-1$
}
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
createMessageArea(composite);
CheckboxTreeViewer treeViewer = createTreeViewer(composite);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = convertWidthInCharsToPixels(60);
data.heightHint = convertHeightInCharsToPixels(18);
Tree treeWidget = treeViewer.getTree();
treeWidget.setLayoutData(data);
treeWidget.setFont(composite.getFont());
Button button = new Button(composite, SWT.PUSH);
button.setText(NewWizardMessages.MultipleFolderSelectionDialog_button);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
newFolderButtonPressed();
}
});
button.setFont(composite.getFont());
fNewFolderButton = button;
treeViewer.addSelectionChangedListener(this);
if (fExisting != null) {
Object[] existing = fExisting.toArray();
treeViewer.setGrayedElements(existing);
setInitialSelections(existing);
}
if (fFocusElement != null) {
treeViewer.setSelection(new StructuredSelection(fFocusElement),
true);
}
treeViewer.addCheckStateListener(event -> forceExistingChecked(event));
applyDialogFont(composite);
return composite;
}
protected void forceExistingChecked(CheckStateChangedEvent event) {
if (fExisting != null) {
Object elem = event.getElement();
if (fExisting.contains(elem)) {
fViewer.setChecked(elem, true);
}
}
}
private void updateNewFolderButtonState() {
IStructuredSelection selection = fViewer.getStructuredSelection();
fSelectedContainer = null;
if (selection.size() == 1) {
Object first = selection.getFirstElement();
if (first instanceof IContainer) {
fSelectedContainer = (IContainer) first;
}
}
fNewFolderButton.setEnabled(fSelectedContainer != null);
}
protected void newFolderButtonPressed() {
Object createdFolder = createFolder(fSelectedContainer);
if (createdFolder != null) {
CheckboxTreeViewer treeViewer = fViewer;
treeViewer.refresh(fSelectedContainer);
treeViewer.reveal(createdFolder);
treeViewer.setChecked(createdFolder, true);
treeViewer.setSelection(new StructuredSelection(createdFolder));
updateOKStatus();
}
}
protected Object createFolder(IContainer container) {
NewFolderDialog dialog = new NewFolderDialog(getShell(), container);
if (dialog.open() == Window.OK) {
return dialog.getResult()[0];
}
return null;
}
@Override
public void selectionChanged(SelectionChangedEvent event) {
updateNewFolderButtonState();
}
public void setInitialFocus(Object focusElement) {
fFocusElement = focusElement;
}
}