1 package net.sourceforge.phpdt.internal.ui.dialog;
3 import java.util.ArrayList;
4 import java.util.Arrays;
7 import org.eclipse.core.runtime.IStatus;
8 import org.eclipse.jface.dialogs.IDialogConstants;
9 import org.eclipse.jface.viewers.CheckStateChangedEvent;
10 import org.eclipse.jface.viewers.CheckboxTreeViewer;
11 import org.eclipse.jface.viewers.ICheckStateListener;
12 import org.eclipse.jface.viewers.ILabelProvider;
13 import org.eclipse.jface.viewers.ITreeContentProvider;
14 import org.eclipse.jface.viewers.ViewerFilter;
15 import org.eclipse.jface.viewers.ViewerSorter;
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.custom.BusyIndicator;
18 import org.eclipse.swt.events.SelectionAdapter;
19 import org.eclipse.swt.events.SelectionEvent;
20 import org.eclipse.swt.events.SelectionListener;
21 import org.eclipse.swt.layout.GridData;
22 import org.eclipse.swt.layout.GridLayout;
23 import org.eclipse.swt.widgets.Button;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.swt.widgets.Control;
26 import org.eclipse.swt.widgets.Label;
27 import org.eclipse.swt.widgets.Shell;
28 import org.eclipse.swt.widgets.Tree;
29 import net.sourceforge.phpdt.internal.ui.viewsupport.ContainerCheckedTreeViewer;
32 * A class to select elements out of a tree structure.
34 public class CheckedTreeSelectionDialog extends SelectionStatusDialog {
36 private CheckboxTreeViewer fViewer;
38 private ILabelProvider fLabelProvider;
39 private ITreeContentProvider fContentProvider;
41 private ISelectionValidator fValidator = null;
42 private ViewerSorter fSorter;
43 private String fEmptyListMessage = "No entries available";
45 private IStatus fCurrStatus = new StatusInfo();
46 private List fFilters;
47 private Object fInput;
48 private boolean fIsEmpty;
50 private int fWidth = 60;
51 private int fHeight = 18;
53 private boolean fContainerMode;
54 private Object[] fExpandedElements;
57 * Constructs an instance of <code>ElementTreeSelectionDialog</code>.
58 * @param labelProvider the label provider to render the entries
59 * @param contentProvider the content provider to evaluate the tree structure
61 public CheckedTreeSelectionDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
64 fLabelProvider = labelProvider;
65 fContentProvider = contentProvider;
67 setResult(new ArrayList(0));
68 setStatusLineAboveButtons(true);
70 fContainerMode = false;
71 fExpandedElements = null;
73 int shellStyle = getShellStyle();
74 setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
78 * If set, the checked /gray state of containers (inner nodes) is derived from the checked state of its
80 * @param containerMode The containerMode to set
82 public void setContainerMode(boolean containerMode) {
83 fContainerMode = containerMode;
87 * Sets the initial selection.
89 * @param selection the initial selection.
91 public void setInitialSelection(Object selection) {
92 setInitialSelections(new Object[] { selection });
96 * Sets the message to be displayed if the list is empty.
97 * @param message the message to be displayed.
99 public void setEmptyListMessage(String message) {
100 fEmptyListMessage = message;
104 * Sets the sorter used by the tree viewer.
106 public void setSorter(ViewerSorter sorter) {
111 * Adds a filter to the tree viewer.
112 * @param filter a filter.
114 public void addFilter(ViewerFilter filter) {
115 if (fFilters == null)
116 fFilters = new ArrayList(4);
118 fFilters.add(filter);
122 * Sets an optional validator to check if the selection is valid.
123 * The validator is invoked whenever the selection changes.
124 * @param validator the validator to validate the selection.
126 public void setValidator(ISelectionValidator validator) {
127 fValidator = validator;
131 * Sets the tree input.
132 * @param input the tree input.
134 public void setInput(Object input) {
141 public void setExpandedElements(Object[] elements) {
142 fExpandedElements = elements;
146 * Sets the size of the tree in unit of characters.
147 * @param width the width of the tree.
148 * @param height the height of the tree.
150 public void setSize(int width, int height) {
155 protected void updateOKStatus() {
157 if (fValidator != null) {
158 fCurrStatus = fValidator.validate(fViewer.getCheckedElements());
159 updateStatus(fCurrStatus);
160 } else if (!fCurrStatus.isOK()) {
161 fCurrStatus = new StatusInfo();
164 fCurrStatus = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
166 updateStatus(fCurrStatus);
173 fIsEmpty = evaluateIfTreeEmpty(fInput);
174 BusyIndicator.showWhile(null, new Runnable() {
180 return getReturnCode();
183 private void access$superOpen() {
188 * Handles cancel button pressed event.
190 protected void cancelPressed() {
192 super.cancelPressed();
196 * @see SelectionStatusDialog#computeResult()
198 protected void computeResult() {
199 setResult(Arrays.asList(fViewer.getCheckedElements()));
203 * @see Window#create()
205 public void create() {
208 List initialSelections = getInitialSelections();
209 if (initialSelections != null) {
210 fViewer.setCheckedElements(initialSelections.toArray());
213 if (fExpandedElements != null) {
214 fViewer.setExpandedElements(fExpandedElements);
221 * @see Dialog#createDialogArea(Composite)
223 protected Control createDialogArea(Composite parent) {
224 Composite composite = (Composite) super.createDialogArea(parent);
226 Label messageLabel = createMessageArea(composite);
227 Control treeWidget = createTreeViewer(composite);
228 Control buttonComposite = createSelectionButtons(composite);
230 GridData data = new GridData(GridData.FILL_BOTH);
231 data.widthHint = convertWidthInCharsToPixels(fWidth);
232 data.heightHint = convertHeightInCharsToPixels(fHeight);
233 treeWidget.setLayoutData(data);
236 messageLabel.setEnabled(false);
237 treeWidget.setEnabled(false);
238 buttonComposite.setEnabled(false);
244 private Tree createTreeViewer(Composite parent) {
245 if (fContainerMode) {
246 fViewer = new ContainerCheckedTreeViewer(parent, SWT.BORDER);
248 fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
251 fViewer.setContentProvider(fContentProvider);
252 fViewer.setLabelProvider(fLabelProvider);
253 fViewer.addCheckStateListener(new ICheckStateListener() {
254 public void checkStateChanged(CheckStateChangedEvent event) {
259 fViewer.setSorter(fSorter);
260 if (fFilters != null) {
261 for (int i = 0; i != fFilters.size(); i++)
262 fViewer.addFilter((ViewerFilter) fFilters.get(i));
265 fViewer.setInput(fInput);
267 return fViewer.getTree();
271 * Add the selection and deselection buttons to the dialog.
272 * @param composite org.eclipse.swt.widgets.Composite
274 private Composite createSelectionButtons(Composite composite) {
276 Composite buttonComposite = new Composite(composite, SWT.RIGHT);
277 GridLayout layout = new GridLayout();
278 layout.numColumns = 2;
279 buttonComposite.setLayout(layout);
280 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
281 data.grabExcessHorizontalSpace = true;
282 composite.setData(data);
284 Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, "Select &All", false);
286 SelectionListener listener = new SelectionAdapter() {
287 public void widgetSelected(SelectionEvent e) {
288 fViewer.setCheckedElements(fContentProvider.getElements(fInput));
292 selectButton.addSelectionListener(listener);
294 Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, "&Deselect All", false);
296 listener = new SelectionAdapter() {
297 public void widgetSelected(SelectionEvent e) {
298 fViewer.setCheckedElements(new Object[0]);
302 deselectButton.addSelectionListener(listener);
303 return buttonComposite;
306 private boolean evaluateIfTreeEmpty(Object input) {
307 Object[] elements = fContentProvider.getElements(input);
308 if (elements.length > 0) {
309 if (fFilters != null) {
310 for (int i = 0; i < fFilters.size(); i++) {
311 ViewerFilter curr = (ViewerFilter) fFilters.get(i);
312 elements = curr.filter(fViewer, input, elements);
316 return elements.length == 0;