2 * Copyright (C) 2018 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.taxeditor
.preference
.wizard
;
11 import org
.eclipse
.jface
.resource
.JFaceResources
;
12 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
13 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
14 import org
.eclipse
.jface
.viewers
.IBaseLabelProvider
;
15 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
16 import org
.eclipse
.jface
.viewers
.ITreeSelection
;
17 import org
.eclipse
.swt
.SWT
;
18 import org
.eclipse
.swt
.events
.SelectionEvent
;
19 import org
.eclipse
.swt
.events
.SelectionListener
;
20 import org
.eclipse
.swt
.graphics
.Font
;
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
.Tree
;
26 import org
.eclipse
.swt
.widgets
.TreeItem
;
27 import org
.eclipse
.swt
.widgets
.Widget
;
29 import eu
.etaxonomy
.taxeditor
.model
.ImageResources
;
36 public class CheckBoxTreeComposite
extends Composite
implements SelectionListener
{
38 private static final Font FONT_DEFAULT
= JFaceResources
.getFontRegistry().get(JFaceResources
.DEFAULT_FONT
);
39 private static final Font FONT_ITALIC
= JFaceResources
.getFontRegistry().getItalic(JFaceResources
.DEFAULT_FONT
);
40 private static final Font FONT_BOLD
= JFaceResources
.getFontRegistry().getBold(JFaceResources
.DEFAULT_FONT
);
41 private CheckboxTreeViewer viewer
;
42 private Button btnCollapse
;
43 private Button btnExpand
;
44 private Button btnSelectAllChildren
;
46 public CheckBoxTreeComposite(Composite parent
, ITreeContentProvider contentProvider
, IBaseLabelProvider labelProvider
, int style
) {
48 Composite composite
= new Composite(parent
, SWT
.NULL
);
49 composite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
51 composite
.setLayout(new GridLayout());
53 Composite toolbar
= new Composite(composite
, SWT
.NONE
);
54 toolbar
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, true, false, 1, 1));
55 toolbar
.setLayout(new GridLayout(4, false));
57 btnCollapse
= new Button(toolbar
, SWT
.NONE
);
58 btnCollapse
.addSelectionListener(this);
59 btnCollapse
.setImage(ImageResources
.getImage(ImageResources
.COLLAPSE_ALL
));
60 btnCollapse
.setToolTipText("Collapse All");
62 btnExpand
= new Button(toolbar
, SWT
.NONE
);
63 btnExpand
.addSelectionListener(this);
64 btnExpand
.setImage(ImageResources
.getImage(ImageResources
.EXPAND
));
65 btnExpand
.setToolTipText("Expand Selected Node");
67 btnSelectAllChildren
= new Button(toolbar
, SWT
.NONE
);
68 btnSelectAllChildren
.addSelectionListener(this);
69 btnSelectAllChildren
.setImage(ImageResources
.getImage(ImageResources
.HIERARCHICAL
));
70 btnSelectAllChildren
.setToolTipText("Toggle Selection on all children");
72 Tree tree
= new Tree(composite
, SWT
.BORDER
| SWT
.CHECK
);
73 tree
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
74 tree
.addListener(SWT
.Selection
, event
-> {
75 if (event
.detail
== SWT
.CHECK
) {
76 TreeItem item
= (TreeItem
) event
.item
;
80 viewer
= new CheckboxTreeViewer(tree
);
81 viewer
.setContentProvider(contentProvider
);
82 viewer
.setLabelProvider(labelProvider
);
86 private void updateItem(TreeItem treeItem
){
87 TreeItem parentItem
= treeItem
.getParentItem();
89 updateItem(parentItem
);
91 updateChildItems(treeItem
);
94 private CheckState
updateChildItems(TreeItem treeItem
){
95 CheckState checkState
= CheckState
.NONE
;
96 TreeItem
[] children
= treeItem
.getItems();
97 if(children
.length
==0){
98 return treeItem
.getChecked()?CheckState
.CHECKED
:CheckState
.NONE
;
100 int checkedCount
= 0;
101 for (TreeItem child
: children
) {
102 CheckState childState
= updateChildItems(child
);
103 if(childState
.equals(CheckState
.CHECKED
)) {
106 else if(childState
.equals(CheckState
.GRAYED
)){
107 treeItem
.setFont(FONT_ITALIC
);
108 return CheckState
.GRAYED
;
111 if(checkedCount
==children
.length
){
112 //all children are checked
113 checkState
= CheckState
.CHECKED
;
114 treeItem
.setFont(FONT_BOLD
);
116 else if(checkedCount
>0){
117 //some children are checked
118 checkState
= CheckState
.GRAYED
;
119 treeItem
.setFont(FONT_ITALIC
);
122 //no children are checked
123 treeItem
.setFont(FONT_DEFAULT
);
124 if(treeItem
.getChecked()){
125 //no children but item itself is checked
126 checkState
= CheckState
.CHECKED
;
129 //neither children nor item itself is checked
130 checkState
= CheckState
.NONE
;
136 public CheckboxTreeViewer
getViewer() {
141 * Checks the tree items corresponding to the given elements.<br>
144 public void setCheckedElements(Object
[] elements
) {
145 viewer
.setCheckedElements(elements
);
146 for (Object element
: elements
) {
147 viewer
.reveal(element
);
149 TreeItem
[] rootItems
= viewer
.getTree().getItems();
150 for (TreeItem rootItem
: rootItems
) {
151 updateItem(rootItem
);
156 public void widgetSelected(SelectionEvent e
) {
157 ITreeSelection structuredSelection
= viewer
.getStructuredSelection();
158 Object firstElement
= structuredSelection
.getFirstElement();
159 if(e
.widget
== btnCollapse
){
160 viewer
.collapseAll();
162 else if(e
.widget
== btnExpand
){
163 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
165 else if(e
.widget
== btnSelectAllChildren
){
166 Widget item
= viewer
.testFindItem(firstElement
);
167 boolean checked
= false;
168 Object
[] checkedElements
= viewer
.getCheckedElements();
169 for (Object checkedElement
: checkedElements
) {
170 if(checkedElement
.equals(firstElement
)){
176 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
177 viewer
.setSubtreeChecked(firstElement
, !checked
);
178 TreeItem
[] rootItems
= viewer
.getTree().getItems();
179 for (TreeItem rootItem
: rootItems
) {
180 updateItem(rootItem
);
187 public void widgetDefaultSelected(SelectionEvent e
) {
190 private enum CheckState
{