| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.ui.wizards.buildpaths; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| 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.core.runtime.IStatus; |
| |
| import org.eclipse.core.resources.IContainer; |
| |
| 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.ui.dialogs.NewFolderDialog; |
| import org.eclipse.ui.dialogs.SelectionStatusDialog; |
| import org.eclipse.ui.views.navigator.ResourceComparator; |
| |
| import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; |
| import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; |
| |
| /** |
| */ |
| public class MultipleFolderSelectionDialog extends SelectionStatusDialog implements ISelectionChangedListener { |
| |
| private CheckboxTreeViewer fViewer; |
| |
| private ILabelProvider fLabelProvider; |
| private ITreeContentProvider fContentProvider; |
| private List<ViewerFilter> fFilters; |
| |
| private Object fInput; |
| private Button fNewFolderButton; |
| private IContainer fSelectedContainer; |
| private Set<Object> fExisting; |
| private Object fFocusElement; |
| |
| public MultipleFolderSelectionDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider) { |
| super(parent); |
| fLabelProvider= labelProvider; |
| fContentProvider= contentProvider; |
| |
| setSelectionResult(null); |
| setStatusLineAboveButtons(true); |
| |
| fExisting= null; |
| fFocusElement= null; |
| fFilters= null; |
| } |
| |
| public void setExisting(Object[] existing) { |
| fExisting= new HashSet<>(); |
| fExisting.addAll(Arrays.asList(existing)); |
| } |
| |
| /** |
| * 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(); |
| } |
| |
| /* |
| * @see SelectionStatusDialog#computeResult() |
| */ |
| @Override |
| protected void computeResult() { |
| Object[] checked= fViewer.getCheckedElements(); |
| if (fExisting == null) { |
| if (checked.length == 0) { |
| checked= null; |
| } |
| } else { |
| ArrayList<Object> res= new ArrayList<>(); |
| for (Object elem : checked) { |
| if (!fExisting.contains(elem)) { |
| res.add(elem); |
| } |
| } |
| if (!res.isEmpty()) { |
| checked= res.toArray(); |
| } else { |
| checked= null; |
| } |
| } |
| setSelectionResult(checked); |
| } |
| |
| private void access$superCreate() { |
| super.create(); |
| } |
| |
| /* |
| * @see Window#create() |
| */ |
| @Override |
| public void create() { |
| |
| BusyIndicator.showWhile(null, () -> { |
| access$superCreate(); |
| |
| fViewer.setCheckedElements( |
| getInitialElementSelections().toArray()); |
| |
| fViewer.expandToLevel(2); |
| if (fExisting != null) { |
| for (Object object : fExisting) { |
| fViewer.reveal(object); |
| } |
| } |
| |
| 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 (ViewerFilter filter : fFilters) |
| fViewer.addFilter(filter); |
| } |
| |
| 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(this::forceExistingChecked); |
| |
| 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= (IStructuredSelection) fViewer.getSelection(); |
| 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; |
| } |
| |
| |
| |
| } |