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 java
.util
.Arrays
;
12 import java
.util
.List
;
14 import org
.eclipse
.jface
.resource
.JFaceResources
;
15 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
16 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
17 import org
.eclipse
.jface
.viewers
.IBaseLabelProvider
;
18 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
19 import org
.eclipse
.jface
.viewers
.ITreeSelection
;
20 import org
.eclipse
.swt
.SWT
;
21 import org
.eclipse
.swt
.events
.SelectionEvent
;
22 import org
.eclipse
.swt
.events
.SelectionListener
;
23 import org
.eclipse
.swt
.graphics
.Font
;
24 import org
.eclipse
.swt
.layout
.GridData
;
25 import org
.eclipse
.swt
.layout
.GridLayout
;
26 import org
.eclipse
.swt
.widgets
.Button
;
27 import org
.eclipse
.swt
.widgets
.Composite
;
28 import org
.eclipse
.swt
.widgets
.Tree
;
29 import org
.eclipse
.swt
.widgets
.TreeItem
;
30 import org
.eclipse
.swt
.widgets
.Widget
;
32 import eu
.etaxonomy
.taxeditor
.l10n
.Messages
;
33 import eu
.etaxonomy
.taxeditor
.model
.ImageResources
;
40 public class CheckBoxTreeComposite
extends Composite
implements SelectionListener
{
42 private static final Font FONT_DEFAULT
= JFaceResources
.getFontRegistry().get(JFaceResources
.DEFAULT_FONT
);
43 private static final Font FONT_ITALIC
= JFaceResources
.getFontRegistry().getItalic(JFaceResources
.DEFAULT_FONT
);
44 private static final Font FONT_BOLD
= JFaceResources
.getFontRegistry().getBold(JFaceResources
.DEFAULT_FONT
);
45 private CheckboxTreeViewer viewer
;
46 private Button btnCollapse
;
47 private Button btnExpand
;
48 private Button btnSelectAllChildren
;
49 private Button btnSelectDirectChildren
;
51 private boolean allowTopLevelSelection
= false;
53 public CheckBoxTreeComposite(Composite parent
, ITreeContentProvider contentProvider
, IBaseLabelProvider labelProvider
, int style
) {
55 GridLayout layout
= new GridLayout();
56 layout
.marginHeight
= 0;
59 Composite toolbar
= new Composite(this, SWT
.NONE
);
60 toolbar
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, true, false, 1, 1));
61 GridLayout gl_toolbar
= new GridLayout(4, false);
62 gl_toolbar
.horizontalSpacing
= 4;
63 gl_toolbar
.marginHeight
= 0;
64 gl_toolbar
.verticalSpacing
= 0;
65 toolbar
.setLayout(gl_toolbar
);
67 btnCollapse
= new Button(toolbar
, SWT
.NONE
);
68 btnCollapse
.addSelectionListener(this);
69 btnCollapse
.setImage(ImageResources
.getImage(ImageResources
.COLLAPSE_ALL
));
70 btnCollapse
.setToolTipText(""); //$NON-NLS-1$
72 btnExpand
= new Button(toolbar
, SWT
.NONE
);
73 btnExpand
.addSelectionListener(this);
74 btnExpand
.setImage(ImageResources
.getImage(ImageResources
.EXPAND
));
75 btnExpand
.setToolTipText(""); //$NON-NLS-1$
77 btnSelectDirectChildren
= new Button(toolbar
, SWT
.NONE
);
78 btnSelectDirectChildren
.addSelectionListener(this);
79 btnSelectDirectChildren
.setImage(ImageResources
.getImage(ImageResources
.FLAT
));
80 btnSelectDirectChildren
.setToolTipText(Messages
.CheckBoxTreeComposite_SELECT_DIRECT_CHILDREN
);
82 btnSelectAllChildren
= new Button(toolbar
, SWT
.NONE
);
83 btnSelectAllChildren
.addSelectionListener(this);
84 btnSelectAllChildren
.setImage(ImageResources
.getImage(ImageResources
.HIERARCHICAL
));
85 btnSelectAllChildren
.setToolTipText(""); //$NON-NLS-1$
87 Tree tree
= new Tree(this, SWT
.BORDER
| SWT
.CHECK
);
88 tree
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
89 tree
.addListener(SWT
.Selection
, event
-> {
90 if (event
.detail
== SWT
.CHECK
) {
91 TreeItem item
= (TreeItem
) event
.item
;
92 if(!allowTopLevelSelection
&& item
.getParentItem()==null){
93 // top level selection not allowed
94 item
.setChecked(false);
101 viewer
= new CheckboxTreeViewer(tree
);
102 viewer
.setContentProvider(contentProvider
);
103 viewer
.setLabelProvider(labelProvider
);
107 private void updateItem(TreeItem treeItem
){
108 TreeItem parentItem
= treeItem
.getParentItem();
109 if(parentItem
!=null){
110 updateItem(parentItem
);
113 updateChildItems(treeItem
);
117 private void updateChildItems(TreeItem treeItem
){
118 treeItem
.setFont(FONT_DEFAULT
);
119 TreeItem
[] children
= treeItem
.getItems();
120 if(children
.length
==0){
123 int checkedCount
= 0;
124 for (TreeItem child
: children
) {
125 updateChildItems(child
);
126 if(child
.getChecked()){
127 if ((child
.getFont().equals(FONT_BOLD
)) || (child
.getItems().length
== 0)) {
130 //some children are checked
131 treeItem
.setFont(FONT_ITALIC
);
133 else if(child
.getFont().equals(FONT_ITALIC
)
134 || child
.getFont().equals(FONT_BOLD
)){
135 //some children are checked
136 treeItem
.setFont(FONT_ITALIC
);
139 if(checkedCount
==children
.length
){
140 //all children are checked
141 treeItem
.setFont(FONT_BOLD
);
143 else if(!treeItem
.getFont().equals(FONT_ITALIC
)){
145 //some children are checked
146 treeItem
.setFont(FONT_ITALIC
);
149 //no children are checked
150 treeItem
.setFont(FONT_DEFAULT
);
156 public CheckboxTreeViewer
getViewer() {
160 public void setAllowTopLevelSelection(boolean allowTopLevelSelection
) {
161 this.allowTopLevelSelection
= allowTopLevelSelection
;
165 * Checks the tree items corresponding to the given elements.<br>
168 public void setCheckedElements(Object
[] elements
) {
169 viewer
.setCheckedElements(elements
);
170 for (Object element
: elements
) {
171 viewer
.reveal(element
);
173 TreeItem
[] rootItems
= viewer
.getTree().getItems();
174 for (TreeItem rootItem
: rootItems
) {
175 updateItem(rootItem
);
181 * Grays the tree items corresponding to the given elements.<br>
184 public void setGrayedElements(Object
[] elements
) {
185 viewer
.setGrayedElements(elements
);
186 for (Object element
: elements
) {
187 viewer
.reveal(element
);
189 TreeItem
[] rootItems
= viewer
.getTree().getItems();
190 for (TreeItem rootItem
: rootItems
) {
191 updateItem(rootItem
);
197 public void widgetSelected(SelectionEvent e
) {
198 ITreeSelection structuredSelection
= viewer
.getStructuredSelection();
199 Object firstElement
= structuredSelection
.getFirstElement();
200 if(e
.widget
== btnCollapse
){
201 viewer
.collapseAll();
203 else if(e
.widget
== btnExpand
){
204 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
206 else if(e
.widget
== btnSelectDirectChildren
){
207 Widget item
= viewer
.testFindItem(firstElement
);
208 if(item
instanceof TreeItem
){
209 viewer
.expandToLevel(firstElement
, 1);
210 TreeItem treeItem
= (TreeItem
) item
;
211 TreeItem
[] childItems
= treeItem
.getItems();
212 List
<TreeItem
> childItemList
= Arrays
.asList(childItems
);
213 boolean allChecked
= childItemList
.stream().allMatch(childItem
->childItem
.getChecked());
214 childItemList
.stream().forEach(childItem
->childItem
.setChecked(!allChecked
));
215 TreeItem parent
= getRoot(treeItem
);
219 else if(e
.widget
== btnSelectAllChildren
){
220 Widget item
= viewer
.testFindItem(firstElement
);
221 if(item
instanceof TreeItem
){
222 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
223 viewer
.setSubtreeChecked(firstElement
, !((TreeItem
) item
).getFont().equals(FONT_BOLD
));
224 TreeItem parent
= getRoot((TreeItem
) item
);
226 ((TreeItem
) item
).setChecked(false);
231 private TreeItem
getRoot(TreeItem treeItem
) {
232 TreeItem parent
= treeItem
;
233 while(parent
.getParentItem()!=null){
234 parent
= parent
.getParentItem();
240 public void widgetDefaultSelected(SelectionEvent e
) {