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 = getInitialSelections();
 
 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;