1 package net.sourceforge.phpdt.internal.ui.dialogs;
3 import java.util.ArrayList;
4 import java.util.Arrays;
7 import net.sourceforge.phpdt.internal.ui.viewsupport.ContainerCheckedTreeViewer;
9 import org.eclipse.core.runtime.IStatus;
10 import org.eclipse.jface.dialogs.IDialogConstants;
11 import org.eclipse.jface.viewers.CheckStateChangedEvent;
12 import org.eclipse.jface.viewers.CheckboxTreeViewer;
13 import org.eclipse.jface.viewers.ICheckStateListener;
14 import org.eclipse.jface.viewers.ILabelProvider;
15 import org.eclipse.jface.viewers.ITreeContentProvider;
16 import org.eclipse.jface.viewers.ViewerFilter;
17 import org.eclipse.jface.viewers.ViewerSorter;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.custom.BusyIndicator;
20 import org.eclipse.swt.events.SelectionAdapter;
21 import org.eclipse.swt.events.SelectionEvent;
22 import org.eclipse.swt.events.SelectionListener;
23 import org.eclipse.swt.layout.GridData;
24 import org.eclipse.swt.layout.GridLayout;
25 import org.eclipse.swt.widgets.Button;
26 import org.eclipse.swt.widgets.Composite;
27 import org.eclipse.swt.widgets.Control;
28 import org.eclipse.swt.widgets.Label;
29 import org.eclipse.swt.widgets.Shell;
30 import org.eclipse.swt.widgets.Tree;
33 * A class to select elements out of a tree structure.
35 public class CheckedTreeSelectionDialog extends SelectionStatusDialog {
37 private CheckboxTreeViewer fViewer;
39 private ILabelProvider fLabelProvider;
41 private ITreeContentProvider fContentProvider;
43 private ISelectionValidator fValidator = null;
45 private ViewerSorter fSorter;
47 private String fEmptyListMessage = "No entries available";
49 private IStatus fCurrStatus = new StatusInfo();
51 private List fFilters;
53 private Object fInput;
55 private boolean fIsEmpty;
57 private int fWidth = 60;
59 private int fHeight = 18;
61 private boolean fContainerMode;
63 private Object[] fExpandedElements;
66 * Constructs an instance of <code>ElementTreeSelectionDialog</code>.
68 * @param labelProvider
69 * the label provider to render the entries
70 * @param contentProvider
71 * the content provider to evaluate the tree structure
73 public CheckedTreeSelectionDialog(Shell parent,
74 ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
77 fLabelProvider = labelProvider;
78 fContentProvider = contentProvider;
80 setResult(new ArrayList(0));
81 setStatusLineAboveButtons(true);
83 fContainerMode = false;
84 fExpandedElements = null;
86 int shellStyle = getShellStyle();
87 setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
91 * If set, the checked /gray state of containers (inner nodes) is derived
92 * from the checked state of its leaf nodes.
94 * @param containerMode
95 * The containerMode to set
97 public void setContainerMode(boolean containerMode) {
98 fContainerMode = containerMode;
102 * Sets the initial selection. Convenience method.
105 * the initial selection.
107 public void setInitialSelection(Object selection) {
108 setInitialSelections(new Object[] { selection });
112 * Sets the message to be displayed if the list is empty.
115 * the message to be displayed.
117 public void setEmptyListMessage(String message) {
118 fEmptyListMessage = message;
122 * Sets the sorter used by the tree viewer.
124 public void setSorter(ViewerSorter sorter) {
129 * Adds a filter to the tree viewer.
134 public void addFilter(ViewerFilter filter) {
135 if (fFilters == null)
136 fFilters = new ArrayList(4);
138 fFilters.add(filter);
142 * Sets an optional validator to check if the selection is valid. The
143 * validator is invoked whenever the selection changes.
146 * the validator to validate the selection.
148 public void setValidator(ISelectionValidator validator) {
149 fValidator = validator;
153 * Sets the tree input.
158 public void setInput(Object input) {
165 public void setExpandedElements(Object[] elements) {
166 fExpandedElements = elements;
170 * Sets the size of the tree in unit of characters.
173 * the width of the tree.
175 * the height of the tree.
177 public void setSize(int width, int height) {
182 protected void updateOKStatus() {
184 if (fValidator != null) {
185 fCurrStatus = fValidator.validate(fViewer.getCheckedElements());
186 updateStatus(fCurrStatus);
187 } else if (!fCurrStatus.isOK()) {
188 fCurrStatus = new StatusInfo();
191 fCurrStatus = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
193 updateStatus(fCurrStatus);
200 fIsEmpty = evaluateIfTreeEmpty(fInput);
201 BusyIndicator.showWhile(null, new Runnable() {
207 return getReturnCode();
210 private void access$superOpen() {
215 * Handles cancel button pressed event.
217 protected void cancelPressed() {
219 super.cancelPressed();
223 * @see SelectionStatusDialog#computeResult()
225 protected void computeResult() {
226 setResult(Arrays.asList(fViewer.getCheckedElements()));
230 * @see Window#create()
232 public void create() {
235 List initialSelections = getInitialElementSelections();
236 if (initialSelections != null) {
237 fViewer.setCheckedElements(initialSelections.toArray());
240 if (fExpandedElements != null) {
241 fViewer.setExpandedElements(fExpandedElements);
248 * @see Dialog#createDialogArea(Composite)
250 protected Control createDialogArea(Composite parent) {
251 Composite composite = (Composite) super.createDialogArea(parent);
253 Label messageLabel = createMessageArea(composite);
254 Control treeWidget = createTreeViewer(composite);
255 Control buttonComposite = createSelectionButtons(composite);
257 GridData data = new GridData(GridData.FILL_BOTH);
258 data.widthHint = convertWidthInCharsToPixels(fWidth);
259 data.heightHint = convertHeightInCharsToPixels(fHeight);
260 treeWidget.setLayoutData(data);
263 messageLabel.setEnabled(false);
264 treeWidget.setEnabled(false);
265 buttonComposite.setEnabled(false);
271 private Tree createTreeViewer(Composite parent) {
272 if (fContainerMode) {
273 fViewer = new ContainerCheckedTreeViewer(parent, SWT.BORDER);
275 fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
278 fViewer.setContentProvider(fContentProvider);
279 fViewer.setLabelProvider(fLabelProvider);
280 fViewer.addCheckStateListener(new ICheckStateListener() {
281 public void checkStateChanged(CheckStateChangedEvent event) {
286 fViewer.setSorter(fSorter);
287 if (fFilters != null) {
288 for (int i = 0; i != fFilters.size(); i++)
289 fViewer.addFilter((ViewerFilter) fFilters.get(i));
292 fViewer.setInput(fInput);
294 return fViewer.getTree();
298 * Add the selection and deselection buttons to the dialog.
301 * org.eclipse.swt.widgets.Composite
303 private Composite createSelectionButtons(Composite composite) {
305 Composite buttonComposite = new Composite(composite, SWT.RIGHT);
306 GridLayout layout = new GridLayout();
307 layout.numColumns = 2;
308 buttonComposite.setLayout(layout);
309 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
310 | GridData.GRAB_HORIZONTAL);
311 data.grabExcessHorizontalSpace = true;
312 composite.setData(data);
314 Button selectButton = createButton(buttonComposite,
315 IDialogConstants.SELECT_ALL_ID, "Select &All", false);
317 SelectionListener listener = new SelectionAdapter() {
318 public void widgetSelected(SelectionEvent e) {
320 .setCheckedElements(fContentProvider
321 .getElements(fInput));
325 selectButton.addSelectionListener(listener);
327 Button deselectButton = createButton(buttonComposite,
328 IDialogConstants.DESELECT_ALL_ID, "&Deselect All", false);
330 listener = new SelectionAdapter() {
331 public void widgetSelected(SelectionEvent e) {
332 fViewer.setCheckedElements(new Object[0]);
336 deselectButton.addSelectionListener(listener);
337 return buttonComposite;
340 private boolean evaluateIfTreeEmpty(Object input) {
341 Object[] elements = fContentProvider.getElements(input);
342 if (elements.length > 0) {
343 if (fFilters != null) {
344 for (int i = 0; i < fFilters.size(); i++) {
345 ViewerFilter curr = (ViewerFilter) fFilters.get(i);
346 elements = curr.filter(fViewer, input, elements);
350 return elements.length == 0;