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;
40 private ITreeContentProvider fContentProvider;
42 private ISelectionValidator fValidator = null;
43 private ViewerSorter fSorter;
44 private String fEmptyListMessage = "No entries available";
46 private IStatus fCurrStatus = new StatusInfo();
47 private List fFilters;
48 private Object fInput;
49 private boolean fIsEmpty;
51 private int fWidth = 60;
52 private int fHeight = 18;
54 private boolean fContainerMode;
55 private Object[] fExpandedElements;
58 * Constructs an instance of <code>ElementTreeSelectionDialog</code>.
59 * @param labelProvider the label provider to render the entries
60 * @param contentProvider the content provider to evaluate the tree structure
62 public CheckedTreeSelectionDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
65 fLabelProvider = labelProvider;
66 fContentProvider = contentProvider;
68 setResult(new ArrayList(0));
69 setStatusLineAboveButtons(true);
71 fContainerMode = false;
72 fExpandedElements = null;
74 int shellStyle = getShellStyle();
75 setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
79 * If set, the checked /gray state of containers (inner nodes) is derived from the checked state of its
81 * @param containerMode The containerMode to set
83 public void setContainerMode(boolean containerMode) {
84 fContainerMode = containerMode;
88 * Sets the initial selection.
90 * @param selection the initial selection.
92 public void setInitialSelection(Object selection) {
93 setInitialSelections(new Object[] { selection });
97 * Sets the message to be displayed if the list is empty.
98 * @param message the message to be displayed.
100 public void setEmptyListMessage(String message) {
101 fEmptyListMessage = message;
105 * Sets the sorter used by the tree viewer.
107 public void setSorter(ViewerSorter sorter) {
112 * Adds a filter to the tree viewer.
113 * @param filter a filter.
115 public void addFilter(ViewerFilter filter) {
116 if (fFilters == null)
117 fFilters = new ArrayList(4);
119 fFilters.add(filter);
123 * Sets an optional validator to check if the selection is valid.
124 * The validator is invoked whenever the selection changes.
125 * @param validator the validator to validate the selection.
127 public void setValidator(ISelectionValidator validator) {
128 fValidator = validator;
132 * Sets the tree input.
133 * @param input the tree input.
135 public void setInput(Object input) {
142 public void setExpandedElements(Object[] elements) {
143 fExpandedElements = elements;
147 * Sets the size of the tree in unit of characters.
148 * @param width the width of the tree.
149 * @param height the height of the tree.
151 public void setSize(int width, int height) {
156 protected void updateOKStatus() {
158 if (fValidator != null) {
159 fCurrStatus = fValidator.validate(fViewer.getCheckedElements());
160 updateStatus(fCurrStatus);
161 } else if (!fCurrStatus.isOK()) {
162 fCurrStatus = new StatusInfo();
165 fCurrStatus = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
167 updateStatus(fCurrStatus);
174 fIsEmpty = evaluateIfTreeEmpty(fInput);
175 BusyIndicator.showWhile(null, new Runnable() {
181 return getReturnCode();
184 private void access$superOpen() {
189 * Handles cancel button pressed event.
191 protected void cancelPressed() {
193 super.cancelPressed();
197 * @see SelectionStatusDialog#computeResult()
199 protected void computeResult() {
200 setResult(Arrays.asList(fViewer.getCheckedElements()));
204 * @see Window#create()
206 public void create() {
209 List initialSelections = getInitialElementSelections();
210 if (initialSelections != null) {
211 fViewer.setCheckedElements(initialSelections.toArray());
214 if (fExpandedElements != null) {
215 fViewer.setExpandedElements(fExpandedElements);
222 * @see Dialog#createDialogArea(Composite)
224 protected Control createDialogArea(Composite parent) {
225 Composite composite = (Composite) super.createDialogArea(parent);
227 Label messageLabel = createMessageArea(composite);
228 Control treeWidget = createTreeViewer(composite);
229 Control buttonComposite = createSelectionButtons(composite);
231 GridData data = new GridData(GridData.FILL_BOTH);
232 data.widthHint = convertWidthInCharsToPixels(fWidth);
233 data.heightHint = convertHeightInCharsToPixels(fHeight);
234 treeWidget.setLayoutData(data);
237 messageLabel.setEnabled(false);
238 treeWidget.setEnabled(false);
239 buttonComposite.setEnabled(false);
245 private Tree createTreeViewer(Composite parent) {
246 if (fContainerMode) {
247 fViewer = new ContainerCheckedTreeViewer(parent, SWT.BORDER);
249 fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
252 fViewer.setContentProvider(fContentProvider);
253 fViewer.setLabelProvider(fLabelProvider);
254 fViewer.addCheckStateListener(new ICheckStateListener() {
255 public void checkStateChanged(CheckStateChangedEvent event) {
260 fViewer.setSorter(fSorter);
261 if (fFilters != null) {
262 for (int i = 0; i != fFilters.size(); i++)
263 fViewer.addFilter((ViewerFilter) fFilters.get(i));
266 fViewer.setInput(fInput);
268 return fViewer.getTree();
272 * Add the selection and deselection buttons to the dialog.
273 * @param composite org.eclipse.swt.widgets.Composite
275 private Composite createSelectionButtons(Composite composite) {
277 Composite buttonComposite = new Composite(composite, SWT.RIGHT);
278 GridLayout layout = new GridLayout();
279 layout.numColumns = 2;
280 buttonComposite.setLayout(layout);
281 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
282 data.grabExcessHorizontalSpace = true;
283 composite.setData(data);
285 Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, "Select &All", false);
287 SelectionListener listener = new SelectionAdapter() {
288 public void widgetSelected(SelectionEvent e) {
289 fViewer.setCheckedElements(fContentProvider.getElements(fInput));
293 selectButton.addSelectionListener(listener);
295 Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, "&Deselect All", false);
297 listener = new SelectionAdapter() {
298 public void widgetSelected(SelectionEvent e) {
299 fViewer.setCheckedElements(new Object[0]);
303 deselectButton.addSelectionListener(listener);
304 return buttonComposite;
307 private boolean evaluateIfTreeEmpty(Object input) {
308 Object[] elements = fContentProvider.getElements(input);
309 if (elements.length > 0) {
310 if (fFilters != null) {
311 for (int i = 0; i < fFilters.size(); i++) {
312 ViewerFilter curr = (ViewerFilter) fFilters.get(i);
313 elements = curr.filter(fViewer, input, elements);
317 return elements.length == 0;