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 parent
.setLayout(layout
);
57 Composite composite
= new Composite(parent
, SWT
.NULL
);
58 composite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
60 GridLayout gl_composite
= layout
;
61 gl_composite
.marginHeight
= 0;
62 composite
.setLayout(gl_composite
);
64 Composite toolbar
= new Composite(composite
, SWT
.NONE
);
65 toolbar
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, true, false, 1, 1));
66 GridLayout gl_toolbar
= new GridLayout(4, false);
67 gl_toolbar
.horizontalSpacing
= 4;
68 gl_toolbar
.marginHeight
= 0;
69 gl_toolbar
.verticalSpacing
= 0;
70 toolbar
.setLayout(gl_toolbar
);
72 btnCollapse
= new Button(toolbar
, SWT
.NONE
);
73 btnCollapse
.addSelectionListener(this);
74 btnCollapse
.setImage(ImageResources
.getImage(ImageResources
.COLLAPSE_ALL
));
75 btnCollapse
.setToolTipText(""); //$NON-NLS-1$
77 btnExpand
= new Button(toolbar
, SWT
.NONE
);
78 btnExpand
.addSelectionListener(this);
79 btnExpand
.setImage(ImageResources
.getImage(ImageResources
.EXPAND
));
80 btnExpand
.setToolTipText(""); //$NON-NLS-1$
82 btnSelectDirectChildren
= new Button(toolbar
, SWT
.NONE
);
83 btnSelectDirectChildren
.addSelectionListener(this);
84 btnSelectDirectChildren
.setImage(ImageResources
.getImage(ImageResources
.FLAT
));
85 btnSelectDirectChildren
.setToolTipText(Messages
.CheckBoxTreeComposite_SELECT_DIRECT_CHILDREN
);
87 btnSelectAllChildren
= new Button(toolbar
, SWT
.NONE
);
88 btnSelectAllChildren
.addSelectionListener(this);
89 btnSelectAllChildren
.setImage(ImageResources
.getImage(ImageResources
.HIERARCHICAL
));
90 btnSelectAllChildren
.setToolTipText(""); //$NON-NLS-1$
92 Tree tree
= new Tree(composite
, SWT
.BORDER
| SWT
.CHECK
);
93 tree
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
94 tree
.addListener(SWT
.Selection
, event
-> {
95 if (event
.detail
== SWT
.CHECK
) {
96 TreeItem item
= (TreeItem
) event
.item
;
97 if(!allowTopLevelSelection
&& item
.getParentItem()==null){
98 // top level selection not allowed
99 item
.setChecked(false);
105 viewer
= new CheckboxTreeViewer(tree
);
106 viewer
.setContentProvider(contentProvider
);
107 viewer
.setLabelProvider(labelProvider
);
111 private void updateItem(TreeItem treeItem
){
112 TreeItem parentItem
= treeItem
.getParentItem();
113 if(parentItem
!=null){
114 updateItem(parentItem
);
117 updateChildItems(treeItem
);
121 private void updateChildItems(TreeItem treeItem
){
122 treeItem
.setFont(FONT_DEFAULT
);
123 TreeItem
[] children
= treeItem
.getItems();
124 if(children
.length
==0){
127 int checkedCount
= 0;
128 for (TreeItem child
: children
) {
129 updateChildItems(child
);
130 if(child
.getChecked()){
131 if ((child
.getFont().equals(FONT_BOLD
)) || (child
.getItems().length
== 0)) {
134 //some children are checked
135 treeItem
.setFont(FONT_ITALIC
);
137 else if(child
.getFont().equals(FONT_ITALIC
)
138 || child
.getFont().equals(FONT_BOLD
)){
139 //some children are checked
140 treeItem
.setFont(FONT_ITALIC
);
143 if(checkedCount
==children
.length
){
144 //all children are checked
145 treeItem
.setFont(FONT_BOLD
);
147 else if(!treeItem
.getFont().equals(FONT_ITALIC
)){
149 //some children are checked
150 treeItem
.setFont(FONT_ITALIC
);
153 //no children are checked
154 treeItem
.setFont(FONT_DEFAULT
);
160 public CheckboxTreeViewer
getViewer() {
164 public void setAllowTopLevelSelection(boolean allowTopLevelSelection
) {
165 this.allowTopLevelSelection
= allowTopLevelSelection
;
169 * Checks the tree items corresponding to the given elements.<br>
172 public void setCheckedElements(Object
[] elements
) {
173 viewer
.setCheckedElements(elements
);
174 for (Object element
: elements
) {
175 viewer
.reveal(element
);
177 TreeItem
[] rootItems
= viewer
.getTree().getItems();
178 for (TreeItem rootItem
: rootItems
) {
179 updateItem(rootItem
);
184 public void widgetSelected(SelectionEvent e
) {
185 ITreeSelection structuredSelection
= viewer
.getStructuredSelection();
186 Object firstElement
= structuredSelection
.getFirstElement();
187 if(e
.widget
== btnCollapse
){
188 viewer
.collapseAll();
190 else if(e
.widget
== btnExpand
){
191 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
193 else if(e
.widget
== btnSelectDirectChildren
){
194 Widget item
= viewer
.testFindItem(firstElement
);
195 if(item
instanceof TreeItem
){
196 viewer
.expandToLevel(firstElement
, 1);
197 TreeItem treeItem
= (TreeItem
) item
;
198 TreeItem
[] childItems
= treeItem
.getItems();
199 List
<TreeItem
> childItemList
= Arrays
.asList(childItems
);
200 boolean allChecked
= childItemList
.stream().allMatch(childItem
->childItem
.getChecked());
201 childItemList
.stream().forEach(childItem
->childItem
.setChecked(!allChecked
));
202 TreeItem parent
= getRoot(treeItem
);
206 else if(e
.widget
== btnSelectAllChildren
){
207 Widget item
= viewer
.testFindItem(firstElement
);
208 if(item
instanceof TreeItem
){
209 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
210 viewer
.setSubtreeChecked(firstElement
, !((TreeItem
) item
).getFont().equals(FONT_BOLD
));
211 TreeItem parent
= getRoot((TreeItem
) item
);
213 ((TreeItem
) item
).setChecked(false);
218 private TreeItem
getRoot(TreeItem treeItem
) {
219 TreeItem parent
= treeItem
;
220 while(parent
.getParentItem()!=null){
221 parent
= parent
.getParentItem();
227 public void widgetDefaultSelected(SelectionEvent e
) {