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 protected Object
[] checkedElements
;
53 private boolean allowTopLevelSelection
= false;
55 public CheckBoxTreeComposite(Composite parent
, ITreeContentProvider contentProvider
, IBaseLabelProvider labelProvider
, int style
) {
57 GridLayout layout
= new GridLayout();
58 layout
.marginHeight
= 0;
61 Composite toolbar
= new Composite(this, SWT
.NONE
);
62 toolbar
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, true, false, 1, 1));
63 GridLayout gl_toolbar
= new GridLayout(4, false);
64 gl_toolbar
.horizontalSpacing
= 4;
65 gl_toolbar
.marginHeight
= 0;
66 gl_toolbar
.verticalSpacing
= 0;
67 toolbar
.setLayout(gl_toolbar
);
69 btnCollapse
= new Button(toolbar
, SWT
.NONE
);
70 btnCollapse
.addSelectionListener(this);
71 btnCollapse
.setImage(ImageResources
.getImage(ImageResources
.COLLAPSE_ALL
));
72 btnCollapse
.setToolTipText(""); //$NON-NLS-1$
74 btnExpand
= new Button(toolbar
, SWT
.NONE
);
75 btnExpand
.addSelectionListener(this);
76 btnExpand
.setImage(ImageResources
.getImage(ImageResources
.EXPAND
));
77 btnExpand
.setToolTipText(""); //$NON-NLS-1$
79 btnSelectDirectChildren
= new Button(toolbar
, SWT
.NONE
);
80 btnSelectDirectChildren
.addSelectionListener(this);
81 btnSelectDirectChildren
.setImage(ImageResources
.getImage(ImageResources
.FLAT
));
82 btnSelectDirectChildren
.setToolTipText(Messages
.CheckBoxTreeComposite_SELECT_DIRECT_CHILDREN
);
84 btnSelectAllChildren
= new Button(toolbar
, SWT
.NONE
);
85 btnSelectAllChildren
.addSelectionListener(this);
86 btnSelectAllChildren
.setImage(ImageResources
.getImage(ImageResources
.HIERARCHICAL
));
87 btnSelectAllChildren
.setToolTipText(""); //$NON-NLS-1$
89 Tree tree
= new Tree(this, SWT
.BORDER
| SWT
.CHECK
);
90 tree
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
91 tree
.addListener(SWT
.Selection
, event
-> {
92 if (event
.detail
== SWT
.CHECK
) {
93 TreeItem item
= (TreeItem
) event
.item
;
94 if(!allowTopLevelSelection
&& item
.getParentItem()==null){
95 // top level selection not allowed
96 item
.setChecked(false);
100 if (item
.getChecked()){
101 if (checkedElements
!= null){
102 Object
[] tempArray
= Arrays
.copyOf(checkedElements
, checkedElements
.length
+1);
103 tempArray
[checkedElements
.length
] = item
.getData();
104 checkedElements
= tempArray
;
109 if (checkedElements
!= null){
110 for (Object o
:checkedElements
){
111 if (o
!= null && o
.equals(item
.getData())){
116 checkedElements
[index
] = null;
124 viewer
= new CdmCheckBoxTreeViewer(tree
);
125 viewer
.setContentProvider(contentProvider
);
126 viewer
.setLabelProvider(labelProvider
);
131 private void updateItem(TreeItem treeItem
){
132 TreeItem parentItem
= treeItem
.getParentItem();
133 if(parentItem
!=null){
134 updateItem(parentItem
);
137 updateChildItems(treeItem
);
141 private void updateChildItems(TreeItem treeItem
){
142 treeItem
.setFont(FONT_DEFAULT
);
143 TreeItem
[] children
= treeItem
.getItems();
144 if(children
.length
==0){
147 int checkedCount
= 0;
148 for (TreeItem child
: children
) {
149 updateChildItems(child
);
151 if(child
.getChecked() ){
152 if ((child
.getFont().equals(FONT_BOLD
)) || (child
.getItems().length
== 0)) {
155 //some children are checked
156 treeItem
.setFont(FONT_ITALIC
);
158 else if(child
.getFont().equals(FONT_ITALIC
)
159 || child
.getFont().equals(FONT_BOLD
)){
160 //some children are checked
161 treeItem
.setFont(FONT_ITALIC
);
164 if(checkedCount
==children
.length
){
165 //all children are checked
166 treeItem
.setFont(FONT_BOLD
);
168 else if(!treeItem
.getFont().equals(FONT_ITALIC
)){
170 //some children are checked
171 treeItem
.setFont(FONT_ITALIC
);
174 //no children are checked
175 treeItem
.setFont(FONT_DEFAULT
);
181 public CheckboxTreeViewer
getViewer() {
185 public void setAllowTopLevelSelection(boolean allowTopLevelSelection
) {
186 this.allowTopLevelSelection
= allowTopLevelSelection
;
190 * Checks the tree items corresponding to the given elements.<br>
193 public void setCheckedElements(Object
[] elements
) {
195 this.checkedElements
= elements
;
196 viewer
.setCheckedElements(elements
);
197 for (Object element
: checkedElements
) {
198 viewer
.reveal(element
);
200 TreeItem
[] rootItems
= viewer
.getTree().getItems();
201 for (TreeItem rootItem
: rootItems
) {
202 updateItem(rootItem
);
208 * Grays the tree items corresponding to the given elements.<br>
211 public void setGrayedElements(Object
[] elements
) {
212 viewer
.setGrayedElements(elements
);
213 for (Object element
: elements
) {
214 viewer
.reveal(element
);
216 TreeItem
[] rootItems
= viewer
.getTree().getItems();
217 for (TreeItem rootItem
: rootItems
) {
218 updateItem(rootItem
);
224 public void widgetSelected(SelectionEvent e
) {
225 ITreeSelection structuredSelection
= viewer
.getStructuredSelection();
226 Object firstElement
= structuredSelection
.getFirstElement();
227 if(e
.widget
== btnCollapse
){
228 viewer
.collapseAll();
230 else if(e
.widget
== btnExpand
){
231 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
233 else if(e
.widget
== btnSelectDirectChildren
){
234 Widget item
= viewer
.testFindItem(firstElement
);
235 if(item
instanceof TreeItem
){
236 viewer
.expandToLevel(firstElement
, 1);
237 TreeItem treeItem
= (TreeItem
) item
;
238 TreeItem
[] childItems
= treeItem
.getItems();
239 List
<TreeItem
> childItemList
= Arrays
.asList(childItems
);
240 boolean allChecked
= childItemList
.stream().allMatch(childItem
->childItem
.getChecked());
241 childItemList
.stream().forEach(childItem
->childItem
.setChecked(!allChecked
));
242 TreeItem parent
= getRoot(treeItem
);
246 else if(e
.widget
== btnSelectAllChildren
){
247 Widget item
= viewer
.testFindItem(firstElement
);
248 if(item
instanceof TreeItem
){
249 viewer
.expandToLevel(firstElement
, AbstractTreeViewer
.ALL_LEVELS
);
250 viewer
.setSubtreeChecked(firstElement
, !((TreeItem
) item
).getFont().equals(FONT_BOLD
));
251 TreeItem parent
= getRoot((TreeItem
) item
);
253 ((TreeItem
) item
).setChecked(false);
258 private TreeItem
getRoot(TreeItem treeItem
) {
259 TreeItem parent
= treeItem
;
260 while(parent
.getParentItem()!=null){
261 parent
= parent
.getParentItem();
267 public void widgetDefaultSelected(SelectionEvent e
) {