KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > editors > text > SelectResourcesBlock


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.editors.text;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.custom.BusyIndicator;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.layout.GridLayout;
26 import org.eclipse.swt.widgets.Composite;
27 import org.eclipse.swt.widgets.Tree;
28
29 import org.eclipse.core.runtime.ListenerList;
30 import org.eclipse.core.runtime.SafeRunner;
31
32 import org.eclipse.jface.util.SafeRunnable;
33 import org.eclipse.jface.viewers.CheckStateChangedEvent;
34 import org.eclipse.jface.viewers.CheckboxTableViewer;
35 import org.eclipse.jface.viewers.CheckboxTreeViewer;
36 import org.eclipse.jface.viewers.ICheckStateListener;
37 import org.eclipse.jface.viewers.ILabelProvider;
38 import org.eclipse.jface.viewers.ISelectionChangedListener;
39 import org.eclipse.jface.viewers.IStructuredContentProvider;
40 import org.eclipse.jface.viewers.IStructuredSelection;
41 import org.eclipse.jface.viewers.ITreeContentProvider;
42 import org.eclipse.jface.viewers.ITreeViewerListener;
43 import org.eclipse.jface.viewers.SelectionChangedEvent;
44 import org.eclipse.jface.viewers.StructuredSelection;
45 import org.eclipse.jface.viewers.TreeExpansionEvent;
46 import org.eclipse.jface.viewers.ViewerComparator;
47
48 /*
49  * XXX: This is an copy of the internal ResourceTreeAndListGroup class, see:
50  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=147027
51  */

52
53 /**
54  * Workbench-level composite that combines a CheckboxTreeViewer and
55  * CheckboxListViewer. All viewer selection-driven interactions are handled
56  * within this object
57  */

58 class SelectResourcesBlock implements ICheckStateListener, ISelectionChangedListener, ITreeViewerListener {
59
60
61     /**
62      * The IElementFilter is a interface that defines
63      * the API for filtering the current selection of
64      * a ResourceTreeAndListGroup in order to find a
65      * subset to update as the result of a type filtering.
66      * This is meant as an internal class and is used exclusively
67      * by the import dialog.
68      */

69     interface IElementFilter {
70
71         void filterElements(Collection JavaDoc elements) throws InterruptedException JavaDoc;
72
73         void filterElements(Object JavaDoc[] elements) throws InterruptedException JavaDoc;
74     }
75
76
77     private Object JavaDoc root;
78
79     private Object JavaDoc currentTreeSelection;
80
81     private Collection JavaDoc expandedTreeNodes= new HashSet JavaDoc();
82
83     private Map JavaDoc checkedStateStore= new HashMap JavaDoc(9);
84
85     private Collection JavaDoc whiteCheckedTreeItems= new HashSet JavaDoc();
86
87     private ListenerList listeners= new ListenerList(ListenerList.IDENTITY);
88
89     private ITreeContentProvider treeContentProvider;
90
91     private IStructuredContentProvider listContentProvider;
92
93     private ILabelProvider treeLabelProvider;
94
95     private ILabelProvider listLabelProvider;
96
97     // widgets
98
private CheckboxTreeViewer treeViewer;
99
100     private CheckboxTableViewer listViewer;
101
102     //height hint for viewers
103
private static int PREFERRED_HEIGHT= 150;
104
105     /**
106      * Create an instance of this class. Use this constructor if you wish to
107      * specify the width and/or height of the combined widget (to only hard code
108      * one of the sizing dimensions, specify the other dimension's value as -1)
109      *
110      * @param parent
111      * @param rootObject
112      * @param treeContentProvider
113      * @param treeLabelProvider
114      * @param listContentProvider
115      * @param listLabelProvider
116      * @param style
117      * @param useHeightHint If true then use the height hint to make this group big enough
118      */

119     public SelectResourcesBlock(Composite parent, Object JavaDoc rootObject, ITreeContentProvider treeContentProvider, ILabelProvider treeLabelProvider, IStructuredContentProvider listContentProvider, ILabelProvider listLabelProvider, int style, boolean useHeightHint) {
120
121         root= rootObject;
122         this.treeContentProvider= treeContentProvider;
123         this.listContentProvider= listContentProvider;
124         this.treeLabelProvider= treeLabelProvider;
125         this.listLabelProvider= listLabelProvider;
126         createContents(parent, style, useHeightHint);
127     }
128
129     /**
130      * Add the passed listener to self's collection of clients that listen for
131      * changes to element checked states
132      *
133      * @param listener ICheckStateListener
134      */

135     public void addCheckStateListener(ICheckStateListener listener) {
136         listeners.add(listener);
137     }
138
139     /**
140      * Iterates over the passed elements which are being realized for the
141      * first time and check each one in the tree viewer as appropriate.
142      *
143      * @param elements the elements
144      */

145     private void checkNewTreeElements(Object JavaDoc[] elements) {
146         for (int i= 0; i < elements.length; ++i) {
147             Object JavaDoc currentElement= elements[i];
148             boolean checked= checkedStateStore.containsKey(currentElement);
149             treeViewer.setChecked(currentElement, checked);
150             treeViewer.setGrayed(currentElement, checked && !whiteCheckedTreeItems.contains(currentElement));
151         }
152     }
153
154     /**
155      * An item was checked in one of self's two views. Determine which view this
156      * occurred in and delegate appropriately
157      *
158      * @param event the check state event
159      * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
160      */

161     public void checkStateChanged(final CheckStateChangedEvent event) {
162
163         //Potentially long operation - show a busy cursor
164
BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable JavaDoc() {
165             public void run() {
166                 if (event.getCheckable().equals(treeViewer))
167                     treeItemChecked(event.getElement(), event.getChecked());
168                 else
169                     listItemChecked(event.getElement(), event.getChecked(), true);
170
171                 notifyCheckStateChangeListeners(event);
172             }
173         });
174     }
175
176     /**
177      * Lay out and initialize self's visual components.
178      *
179      * @param parent org.eclipse.swt.widgets.Composite
180      * @param style the style flags for the new Composite
181      * @param useHeightHint If true use the preferredHeight.
182      */

183     private void createContents(Composite parent, int style, boolean useHeightHint) {
184         // group pane
185
Composite composite= new Composite(parent, style);
186         composite.setFont(parent.getFont());
187         GridLayout layout= new GridLayout();
188         layout.numColumns= 2;
189         layout.makeColumnsEqualWidth= true;
190         layout.marginHeight= 0;
191         layout.marginWidth= 0;
192         composite.setLayout(layout);
193         composite.setLayoutData(new GridData(GridData.FILL_BOTH));
194
195         createTreeViewer(composite, useHeightHint);
196         createListViewer(composite, useHeightHint);
197
198         initialize();
199     }
200
201     /**
202      * Creates this block's list viewer.
203      *
204      * @param parent the parent control
205      * @param useHeightHint if <code>true</code> use the height hints
206      */

207     private void createListViewer(Composite parent, boolean useHeightHint) {
208         listViewer= CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
209         GridData data= new GridData(GridData.FILL_BOTH);
210         if (useHeightHint)
211             data.heightHint= PREFERRED_HEIGHT;
212         listViewer.getTable().setLayoutData(data);
213         listViewer.getTable().setFont(parent.getFont());
214         listViewer.setContentProvider(listContentProvider);
215         listViewer.setLabelProvider(listLabelProvider);
216         listViewer.addCheckStateListener(this);
217     }
218
219     /**
220      * Create this block's tree viewer.
221      *
222      * @param parent the parent control
223      * @param useHeightHint if <code>true</code> use the height hints
224      */

225     private void createTreeViewer(Composite parent, boolean useHeightHint) {
226         Tree tree= new Tree(parent, SWT.CHECK | SWT.BORDER);
227         GridData data= new GridData(GridData.FILL_BOTH);
228         if (useHeightHint)
229             data.heightHint= PREFERRED_HEIGHT;
230         tree.setLayoutData(data);
231         tree.setFont(parent.getFont());
232
233         treeViewer= new CheckboxTreeViewer(tree);
234         treeViewer.setUseHashlookup(true);
235         treeViewer.setContentProvider(treeContentProvider);
236         treeViewer.setLabelProvider(treeLabelProvider);
237         treeViewer.addTreeListener(this);
238         treeViewer.addCheckStateListener(this);
239         treeViewer.addSelectionChangedListener(this);
240     }
241
242     /**
243      * Returns a boolean indicating whether the passed tree element should be at
244      * LEAST gray-checked. Note that this method does not consider whether it
245      * should be white-checked, so a specified tree item which should be
246      * white-checked will result in a <code>true</code> answer from this
247      * method.
248      *
249      * @param treeElement java.lang.Object
250      * @return boolean
251      */

252     private boolean determineShouldBeAtLeastGrayChecked(Object JavaDoc treeElement) {
253         // if any list items associated with treeElement are checked then it
254
// retains its gray-checked status regardless of its children
255
List JavaDoc checked= (List JavaDoc) checkedStateStore.get(treeElement);
256         if (checked != null && (!checked.isEmpty()))
257             return true;
258
259         // if any children of treeElement are still gray-checked then
260
// treeElement
261
// must remain gray-checked as well. Only ask expanded nodes
262
if (expandedTreeNodes.contains(treeElement)) {
263             Object JavaDoc[] children= treeContentProvider.getChildren(treeElement);
264             for (int i= 0; i < children.length; ++i) {
265                 if (checkedStateStore.containsKey(children[i]))
266                     return true;
267             }
268         }
269
270         return false;
271     }
272
273     /**
274      * Expands an element in a tree viewer.
275      *
276      * @param element the element to be expanded
277      */

278     private void expandTreeElement(final Object JavaDoc element) {
279         BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable JavaDoc() {
280             public void run() {
281
282                 // First see if the children need to be given their checked
283
// state at all. If they've
284
// already been realized then this won't be necessary
285
if (expandedTreeNodes.contains(element))
286                     checkNewTreeElements(treeContentProvider.getChildren(element));
287                 else {
288
289                     expandedTreeNodes.add(element);
290                     if (whiteCheckedTreeItems.contains(element)) {
291                         //If this is the first expansion and this is a white
292
// checked node then check the children
293
Object JavaDoc[] children= treeContentProvider.getChildren(element);
294                         for (int i= 0; i < children.length; ++i) {
295                             if (!whiteCheckedTreeItems.contains(children[i])) {
296                                 Object JavaDoc child= children[i];
297                                 setWhiteChecked(child, true);
298                                 treeViewer.setChecked(child, true);
299                                 checkedStateStore.put(child, new ArrayList JavaDoc());
300                             }
301                         }
302
303                         //Now be sure to select the list of items too
304
setListForWhiteSelection(element);
305                     }
306                 }
307
308             }
309         });
310     }
311
312     /**
313      * Adds all of the selected children of <code>treeElement</code> to result recursively. This
314      * does not set any values in the checked state.
315      *
316      * @param treeElement the tree element being queried
317      * @param parentLabel the parent label
318      * @param addAll a boolean to indicate if the checked state store needs to be queried
319      * @param filter the filter being used on the data
320      * @throws InterruptedException in case of interruption
321      */

322     private void findAllSelectedListElements(Object JavaDoc treeElement, String JavaDoc parentLabel, boolean addAll, IElementFilter filter) throws InterruptedException JavaDoc {
323
324         String JavaDoc fullLabel= null;
325     
326         if (addAll)
327             filter.filterElements(listContentProvider.getElements(treeElement));
328         else { //Add what we have stored
329
if (checkedStateStore.containsKey(treeElement))
330                 filter.filterElements((Collection JavaDoc) checkedStateStore.get(treeElement));
331         }
332
333         Object JavaDoc[] treeChildren= treeContentProvider.getChildren(treeElement);
334         for (int i= 0; i < treeChildren.length; i++) {
335             Object JavaDoc child= treeChildren[i];
336             if (addAll)
337                 findAllSelectedListElements(child, fullLabel, true, filter);
338             else { //Only continue for those with checked state
339
if (checkedStateStore.containsKey(child))
340                     findAllSelectedListElements(child, fullLabel, whiteCheckedTreeItems.contains(child), filter);
341             }
342
343         }
344     }
345
346     /**
347      * Find all of the white checked children of the treeElement and add them to
348      * the collection. If the element itself is white select add it. If not then
349      * add any selected list elements and recurse down to the children.
350      *
351      * @param treeElement java.lang.Object
352      * @param result java.util.Collection
353      */

354     private void findAllWhiteCheckedItems(Object JavaDoc treeElement, Collection JavaDoc result) {
355
356         if (whiteCheckedTreeItems.contains(treeElement))
357             result.add(treeElement);
358         else {
359             Collection JavaDoc listChildren= (Collection JavaDoc) checkedStateStore.get(treeElement);
360             //if it is not in the store then it and it's children are not
361
// interesting
362
if (listChildren == null)
363                 return;
364             result.addAll(listChildren);
365             Object JavaDoc[] children= treeContentProvider.getChildren(treeElement);
366             for (int i= 0; i < children.length; ++i) {
367                 findAllWhiteCheckedItems(children[i], result);
368             }
369         }
370     }
371
372     /**
373      * Returns a flat list of all of the leaf elements which are checked. Filter
374      * then based on the supplied ElementFilter. If monitor is canceled then
375      * return null
376      *
377      * @param filter - the filter for the data
378      * @throws InterruptedException in case of interruption
379      */

380     private void getAllCheckedListItems(IElementFilter filter) throws InterruptedException JavaDoc {
381         //Iterate through the children of the root as the root is not in the store
382
Object JavaDoc[] children= treeContentProvider.getChildren(root);
383         for (int i= 0; i < children.length; ++i) {
384             findAllSelectedListElements(children[i], null, whiteCheckedTreeItems.contains(children[i]), filter);
385         }
386     }
387
388     /**
389      * Returns a flat list of all of the leaf elements which are checked.
390      *
391      * @return all of the leaf elements which are checked. This API does not
392      * return null in order to keep backwards compatibility.
393      */

394     public List JavaDoc getAllCheckedListItems() {
395
396         final ArrayList JavaDoc returnValue= new ArrayList JavaDoc();
397
398         IElementFilter passThroughFilter= new IElementFilter() {
399
400             public void filterElements(Collection JavaDoc elements) throws InterruptedException JavaDoc {
401                 returnValue.addAll(elements);
402             }
403
404             public void filterElements(Object JavaDoc[] elements) throws InterruptedException JavaDoc {
405                 for (int i= 0; i < elements.length; i++) {
406                     returnValue.add(elements[i]);
407                 }
408             }
409         };
410
411         try {
412             getAllCheckedListItems(passThroughFilter);
413         } catch (InterruptedException JavaDoc exception) {
414             return new ArrayList JavaDoc();
415         }
416         return returnValue;
417
418     }
419
420     /**
421      * Returns a list of all of the items that are white checked. Any folders
422      * that are white checked are added and then any files from white checked
423      * folders are added.
424      *
425      * @return the list of all of the items that are white checked
426      */

427     public List JavaDoc getAllWhiteCheckedItems() {
428
429         List JavaDoc result= new ArrayList JavaDoc();
430
431         //Iterate through the children of the root as the root is not in the
432
// store
433
Object JavaDoc[] children= treeContentProvider.getChildren(root);
434         for (int i= 0; i < children.length; ++i) {
435             findAllWhiteCheckedItems(children[i], result);
436         }
437
438         return result;
439     }
440
441     /**
442      * Logically gray-check all ancestors of <code>treeElement</code> by ensuring that they
443      * appear in the checked table.
444      *
445      * @param treeElement the tree element
446      */

447     private void grayCheckHierarchy(Object JavaDoc treeElement) {
448
449         //expand the element first to make sure we have populated for it
450
expandTreeElement(treeElement);
451
452         // if this tree element is already gray then its ancestors all are as
453
// well
454
if (checkedStateStore.containsKey(treeElement))
455             return; // no need to proceed upwards from here
456

457         checkedStateStore.put(treeElement, new ArrayList JavaDoc());
458         Object JavaDoc parent= treeContentProvider.getParent(treeElement);
459         if (parent != null)
460             grayCheckHierarchy(parent);
461     }
462
463     /**
464      * Set the checked state of self and all ancestors appropriately. Do not
465      * white check anyone - this is only done down a hierarchy.
466      *
467      * @param treeElement the tree element
468      */

469     private void grayUpdateHierarchy(Object JavaDoc treeElement) {
470
471         boolean shouldBeAtLeastGray= determineShouldBeAtLeastGrayChecked(treeElement);
472
473         treeViewer.setGrayChecked(treeElement, shouldBeAtLeastGray);
474
475         if (whiteCheckedTreeItems.contains(treeElement))
476             whiteCheckedTreeItems.remove(treeElement);
477
478         // proceed up the tree element hierarchy
479
Object JavaDoc parent= treeContentProvider.getParent(treeElement);
480         if (parent != null) {
481             grayUpdateHierarchy(parent);
482         }
483     }
484
485     public void selectAndReveal(Object JavaDoc treeElement) {
486         treeViewer.reveal(treeElement);
487         IStructuredSelection selection= new StructuredSelection(treeElement);
488         treeViewer.setSelection(selection);
489     }
490
491     /**
492      * Initialize this group's viewers after they have been laid out.
493      */

494     private void initialize() {
495         treeViewer.setInput(root);
496         this.expandedTreeNodes= new ArrayList JavaDoc();
497         this.expandedTreeNodes.add(root);
498
499     }
500
501     /**
502      * Callback that's invoked when the checked status of an item in the list is
503      * changed by the user. Do not try and update the hierarchy if we are
504      * building the initial list.
505      *
506      * @param listElement the list element
507      * @param state the checked state
508      * @param updatingFromSelection <code>true</code> if we are inside an
509      * update caused by selection
510      */

511     private void listItemChecked(Object JavaDoc listElement, boolean state, boolean updatingFromSelection) {
512         List JavaDoc checkedListItems= (List JavaDoc) checkedStateStore.get(currentTreeSelection);
513         //If it has not been expanded do so as the selection of list items will
514
// affect gray state
515
if (!expandedTreeNodes.contains(currentTreeSelection))
516             expandTreeElement(currentTreeSelection);
517
518         if (state) {
519             if (checkedListItems == null) {
520                 // since the associated tree item has gone from 0 -> 1 checked
521
// list items, tree checking may need to be updated
522
grayCheckHierarchy(currentTreeSelection);
523                 checkedListItems= (List JavaDoc) checkedStateStore.get(currentTreeSelection);
524             }
525             checkedListItems.add(listElement);
526         } else {
527             checkedListItems.remove(listElement);
528             if (checkedListItems.isEmpty()) {
529                 // since the associated tree item has gone from 1 -> 0 checked
530
// list items, tree checking may need to be updated
531
ungrayCheckHierarchy(currentTreeSelection);
532             }
533         }
534
535         //Update the list with the selections if there are any
536
if (checkedListItems.size() > 0)
537             checkedStateStore.put(currentTreeSelection, checkedListItems);
538         if (updatingFromSelection)
539             grayUpdateHierarchy(currentTreeSelection);
540     }
541
542     /**
543      * Notify all checked state listeners with the given event.
544      *
545      * @param event the event
546      */

547     private void notifyCheckStateChangeListeners(final CheckStateChangedEvent event) {
548         Object JavaDoc[] array= listeners.getListeners();
549         for (int i= 0; i < array.length; i++) {
550             final ICheckStateListener l= (ICheckStateListener) array[i];
551             SafeRunner.run(new SafeRunnable() {
552                 public void run() {
553                     l.checkStateChanged(event);
554                 }
555             });
556         }
557     }
558
559     /**
560      * Set the contents of the list viewer based upon the specified selected
561      * tree element. This also includes checking the appropriate list items.
562      *
563      * @param treeElement java.lang.Object
564      */

565     private void populateListViewer(final Object JavaDoc treeElement) {
566         listViewer.setInput(treeElement);
567
568         //If the element is white checked but not expanded we have not set up
569
// all of the children yet
570
if (!(expandedTreeNodes.contains(treeElement)) && whiteCheckedTreeItems.contains(treeElement)) {
571
572             //Potentially long operation - show a busy cursor
573
BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable JavaDoc() {
574                 public void run() {
575                     setListForWhiteSelection(treeElement);
576                     listViewer.setAllChecked(true);
577                 }
578             });
579
580         } else {
581             List JavaDoc listItemsToCheck= (List JavaDoc) checkedStateStore.get(treeElement);
582
583             if (listItemsToCheck != null) {
584                 Iterator JavaDoc listItemsEnum= listItemsToCheck.iterator();
585                 while (listItemsEnum.hasNext())
586                     listViewer.setChecked(listItemsEnum.next(), true);
587             }
588         }
589     }
590
591     /**
592      * Logically gray-check all ancestors of <code>item</code> by ensuring
593      * that they appear in the checked table. Add any elements to the
594      * <code>selectedNodes</code> so we can track that has been done.
595      *
596      * @param item the tree item
597      * @param selectedNodes the set of selected nodes
598      */

599     private void primeHierarchyForSelection(Object JavaDoc item, Set JavaDoc selectedNodes) {
600
601         //Only prime it if we haven't visited yet
602
if (selectedNodes.contains(item))
603             return;
604
605         checkedStateStore.put(item, new ArrayList JavaDoc());
606
607         //mark as expanded as we are going to populate it after this
608
expandedTreeNodes.add(item);
609         selectedNodes.add(item);
610
611         Object JavaDoc parent= treeContentProvider.getParent(item);
612         if (parent != null)
613             primeHierarchyForSelection(parent, selectedNodes);
614     }
615
616     /**
617      * Remove the passed listener from self's collection of clients that listen
618      * for changes to element checked states
619      *
620      * @param listener ICheckStateListener
621      */

622     public void removeCheckStateListener(ICheckStateListener listener) {
623         listeners.remove(listener);
624     }
625
626     /**
627      * Handle the selection of an item in the tree viewer
628      *
629      * @param event SelectionChangedEvent
630      */

631     public void selectionChanged(SelectionChangedEvent event) {
632         IStructuredSelection selection= (IStructuredSelection) event.getSelection();
633         Object JavaDoc selectedElement= selection.getFirstElement();
634         if (selectedElement == null) {
635             currentTreeSelection= null;
636             listViewer.setInput(currentTreeSelection);
637             return;
638         }
639
640         // i.e.- if not an item deselection
641
if (selectedElement != currentTreeSelection)
642             populateListViewer(selectedElement);
643
644         currentTreeSelection= selectedElement;
645     }
646
647     /**
648      * Select or deselect all of the elements in the tree depending on the value
649      * of <code>selection</code>. Be sure to update the displayed files as
650      * well.
651      *
652      * @param selection <code>true</code> if selection should be set,
653      * <code>false</code> if it should be removed
654      */

655     public void setAllSelections(final boolean selection) {
656
657         //If there is no root there is nothing to select
658
if (root == null)
659             return;
660
661         //Potentially long operation - show a busy cursor
662
BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable JavaDoc() {
663             public void run() {
664                 setTreeChecked(root, selection);
665                 listViewer.setAllChecked(selection);
666             }
667         });
668     }
669
670     /**
671      * The treeElement has been white selected. Get the list for the element and
672      * set it in the checked state store.
673      *
674      * @param treeElement the element being updated
675      */

676     private void setListForWhiteSelection(Object JavaDoc treeElement) {
677
678         Object JavaDoc[] listItems= listContentProvider.getElements(treeElement);
679         List JavaDoc listItemsChecked= new ArrayList JavaDoc();
680         for (int i= 0; i < listItems.length; ++i) {
681             listItemsChecked.add(listItems[i]);
682         }
683
684         checkedStateStore.put(treeElement, listItemsChecked);
685     }
686
687     /**
688      * Set the <code>comparator</code> that is to be applied to self's list viewer
689      *
690      * @param comparator the comparator to be set
691      */

692     public void setListComparator(ViewerComparator comparator) {
693         listViewer.setComparator(comparator);
694     }
695
696     /**
697      * Set the checked state of the passed <code>treeElement</code>
698      * appropriately, and do so recursively to all of its child tree elements as
699      * well.
700      *
701      * @param treeElement the root of the subtree
702      * @param state <code>true</code> if checked, <code>false</code> otherwise
703      */

704     private void setTreeChecked(Object JavaDoc treeElement, boolean state) {
705
706         if (treeElement.equals(currentTreeSelection)) {
707             listViewer.setAllChecked(state);
708         }
709
710         if (state) {
711             setListForWhiteSelection(treeElement);
712         } else
713             checkedStateStore.remove(treeElement);
714
715         setWhiteChecked(treeElement, state);
716         treeViewer.setChecked(treeElement, state);
717         treeViewer.setGrayed(treeElement, false);
718
719         // now logically check/uncheck all children as well if it has been
720
// expanded
721
if (expandedTreeNodes.contains(treeElement)) {
722             Object JavaDoc[] children= treeContentProvider.getChildren(treeElement);
723             for (int i= 0; i < children.length; ++i) {
724                 setTreeChecked(children[i], state);
725             }
726         }
727     }
728
729     /**
730      * Set the comparator that is to be applied to self's tree viewer.
731      *
732      * @param comparator the comparator to be set
733      */

734     public void setTreeComparator(ViewerComparator comparator) {
735         treeViewer.setComparator(comparator);
736     }
737
738     /**
739      * Adjust the collection of references to white-checked tree elements
740      * appropriately.
741      *
742      * @param treeElement the root of the subtree
743      * @param isWhiteChecked <code>true</code> if white checked,
744      * <code>false</code> otherwise
745      */

746     private void setWhiteChecked(Object JavaDoc treeElement, boolean isWhiteChecked) {
747         if (isWhiteChecked) {
748             if (!whiteCheckedTreeItems.contains(treeElement))
749                 whiteCheckedTreeItems.add(treeElement);
750         } else
751             whiteCheckedTreeItems.remove(treeElement);
752     }
753
754     /**
755      * Handle the collapsing of an element in a tree viewer.
756      *
757      * @param event the collapse event
758      */

759     public void treeCollapsed(TreeExpansionEvent event) {
760         // We don't need to do anything with this
761
}
762
763     /**
764      * Handle the expansion of an element in a tree viewer.
765      *
766      * @param event the expansion event
767      */

768     public void treeExpanded(TreeExpansionEvent event) {
769         expandTreeElement(event.getElement());
770     }
771
772     /**
773      * Callback that's invoked when the checked status of an item in the tree is
774      * changed by the user.
775      *
776      * @param treeElement the tree element that has been checked/unchecked
777      * @param state <code>true</code> if checked, <code>false</code> if
778      * unchecked
779      */

780     private void treeItemChecked(Object JavaDoc treeElement, boolean state) {
781
782         // recursively adjust all child tree elements appropriately
783
setTreeChecked(treeElement, state);
784
785         Object JavaDoc parent= treeContentProvider.getParent(treeElement);
786         if (parent == null)
787             return;
788
789         // now update upwards in the tree hierarchy
790
if (state)
791             grayCheckHierarchy(parent);
792         else
793             ungrayCheckHierarchy(parent);
794
795         //Update the hierarchy but do not white select the parent
796
grayUpdateHierarchy(parent);
797     }
798
799     /**
800      * Logically un-gray-check all ancestors of <code>treeElement</code> if
801      * appropriate.
802      *
803      * @param treeElement the root of the subtree
804      */

805     private void ungrayCheckHierarchy(Object JavaDoc treeElement) {
806         if (!determineShouldBeAtLeastGrayChecked(treeElement))
807             checkedStateStore.remove(treeElement);
808
809         Object JavaDoc parent= treeContentProvider.getParent(treeElement);
810         if (parent != null)
811             ungrayCheckHierarchy(parent);
812     }
813
814     /**
815      * Update the selections of the tree elements in items to reflect the new
816      * selections provided.
817      *
818      * @param items Map with keys of Object (the tree element) and values of
819      * List (the selected list elements). NOTE: This method does not
820      * special case keys with no values (i.e., a tree element with an
821      * empty list). If a tree element does not have any selected
822      * items, do not include the element in the Map.
823      */

824     public void updateSelections(Map JavaDoc items) {
825         // We are replacing all selected items with the given selected items,
826
// so reinitialize everything.
827
this.listViewer.setAllChecked(false);
828         this.treeViewer.setCheckedElements(new Object JavaDoc[0]);
829         this.whiteCheckedTreeItems= new HashSet JavaDoc();
830         Set JavaDoc selectedNodes= new HashSet JavaDoc();
831         checkedStateStore= new HashMap JavaDoc();
832
833         //Update the store before the hierarchy to prevent updating parents
834
// before all of the children are done
835
Iterator JavaDoc keyIterator= items.keySet().iterator();
836         while (keyIterator.hasNext()) {
837             Object JavaDoc key= keyIterator.next();
838             primeHierarchyForSelection(key, selectedNodes);
839             checkedStateStore.put(key, items.get(key));
840         }
841
842         // Update the checked tree items. Since each tree item has a selected
843
// item, all the tree items will be gray checked.
844
treeViewer.setCheckedElements(checkedStateStore.keySet().toArray());
845         treeViewer.setGrayedElements(checkedStateStore.keySet().toArray());
846
847         // Update the listView of the currently selected tree item.
848
if (currentTreeSelection != null) {
849             Object JavaDoc displayItems= items.get(currentTreeSelection);
850             if (displayItems != null)
851                 listViewer.setCheckedElements(((List JavaDoc) displayItems).toArray());
852         }
853     }
854 }
855
Popular Tags