Project

General

Profile

Download (8.56 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2018 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
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.
8
 */
9
package eu.etaxonomy.taxeditor.preference.wizard;
10

    
11
import java.util.Arrays;
12
import java.util.List;
13

    
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;
31

    
32
import eu.etaxonomy.taxeditor.l10n.Messages;
33
import eu.etaxonomy.taxeditor.model.ImageResources;
34

    
35
/**
36
 * @author pplitzner
37
 * @since Oct 26, 2018
38
 *
39
 */
40
public class CheckBoxTreeComposite extends Composite implements SelectionListener {
41

    
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;
50

    
51
    public CheckBoxTreeComposite(Composite parent, ITreeContentProvider contentProvider, IBaseLabelProvider labelProvider, int style) {
52
        super(parent, style);
53
        GridLayout layout = new GridLayout();
54
        parent.setLayout(layout);
55
        Composite composite = new Composite(parent, SWT.NULL);
56
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
57

    
58
        GridLayout gl_composite = layout;
59
        gl_composite.marginHeight = 0;
60
        composite.setLayout(gl_composite);
61

    
62
        Composite toolbar = new Composite(composite, SWT.NONE);
63
        toolbar.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
64
        GridLayout gl_toolbar = new GridLayout(4, false);
65
        gl_toolbar.horizontalSpacing = 4;
66
        gl_toolbar.marginHeight = 0;
67
        gl_toolbar.verticalSpacing = 0;
68
        toolbar.setLayout(gl_toolbar);
69

    
70
        btnCollapse = new Button(toolbar, SWT.NONE);
71
        btnCollapse.addSelectionListener(this);
72
        btnCollapse.setImage(ImageResources.getImage(ImageResources.COLLAPSE_ALL));
73
        btnCollapse.setToolTipText(""); //$NON-NLS-1$
74

    
75
        btnExpand = new Button(toolbar, SWT.NONE);
76
        btnExpand.addSelectionListener(this);
77
        btnExpand.setImage(ImageResources.getImage(ImageResources.EXPAND));
78
        btnExpand.setToolTipText(""); //$NON-NLS-1$
79

    
80
        btnSelectDirectChildren = new Button(toolbar, SWT.NONE);
81
        btnSelectDirectChildren.addSelectionListener(this);
82
        btnSelectDirectChildren.setImage(ImageResources.getImage(ImageResources.FLAT));
83
        btnSelectDirectChildren.setToolTipText(Messages.CheckBoxTreeComposite_SELECT_DIRECT_CHILDREN);
84

    
85
                btnSelectAllChildren = new Button(toolbar, SWT.NONE);
86
                btnSelectAllChildren.addSelectionListener(this);
87
                btnSelectAllChildren.setImage(ImageResources.getImage(ImageResources.HIERARCHICAL));
88
                btnSelectAllChildren.setToolTipText(""); //$NON-NLS-1$
89

    
90
        Tree tree = new Tree(composite, SWT.BORDER | SWT.CHECK);
91
        tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
92
        tree.addListener(SWT.Selection, event -> {
93
            if (event.detail == SWT.CHECK) {
94
                TreeItem item = (TreeItem) event.item;
95
                updateItem(item);
96
            }
97
        });
98
        viewer = new CheckboxTreeViewer(tree);
99
        viewer.setContentProvider(contentProvider);
100
        viewer.setLabelProvider(labelProvider);
101
    }
102

    
103

    
104
    private void updateItem(TreeItem treeItem){
105
        TreeItem parentItem = treeItem.getParentItem();
106
        if(parentItem!=null){
107
            updateItem(parentItem);
108
        }
109
        else{
110
            updateChildItems(treeItem);
111
        }
112
    }
113

    
114
    private void updateChildItems(TreeItem treeItem){
115
        treeItem.setFont(FONT_DEFAULT);
116
        TreeItem[] children = treeItem.getItems();
117
        if(children.length==0){
118
            return;
119
        }
120
        int checkedCount = 0;
121
        for (TreeItem child : children) {
122
            updateChildItems(child);
123
            if(child.getChecked()){
124
                if ((child.getFont().equals(FONT_BOLD)) || (child.getItems().length == 0)) {
125
                    checkedCount++;
126
                }
127
                //some children are checked
128
                treeItem.setFont(FONT_ITALIC);
129
            }
130
            else if(child.getFont().equals(FONT_ITALIC)
131
                    || child.getFont().equals(FONT_BOLD)){
132
                //some children are checked
133
                treeItem.setFont(FONT_ITALIC);
134
            }
135
        }
136
        if(checkedCount==children.length){
137
            //all children are checked
138
            treeItem.setFont(FONT_BOLD);
139
        }
140
        else if(!treeItem.getFont().equals(FONT_ITALIC)){
141
            if(checkedCount>0){
142
                //some children are checked
143
                treeItem.setFont(FONT_ITALIC);
144
            }
145
            else{
146
                //no children are checked
147
                treeItem.setFont(FONT_DEFAULT);
148
            }
149
        }
150
    }
151

    
152

    
153
    public CheckboxTreeViewer getViewer() {
154
        return viewer;
155
    }
156

    
157
    /**
158
     * Checks the tree items corresponding to the given elements.<br>
159
     * @param elements
160
     */
161
    public void setCheckedElements(Object[] elements) {
162
        viewer.setCheckedElements(elements);
163
        for (Object element: elements) {
164
            viewer.reveal(element);
165
        }
166
        TreeItem[] rootItems = viewer.getTree().getItems();
167
        for (TreeItem rootItem : rootItems) {
168
            updateItem(rootItem);
169
        }
170
    }
171

    
172
    @Override
173
    public void widgetSelected(SelectionEvent e) {
174
        ITreeSelection structuredSelection = viewer.getStructuredSelection();
175
        Object firstElement = structuredSelection.getFirstElement();
176
        if(e.widget == btnCollapse){
177
            viewer.collapseAll();
178
        }
179
        else if(e.widget == btnExpand){
180
            viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
181
        }
182
        else if(e.widget == btnSelectDirectChildren){
183
            Widget item = viewer.testFindItem(firstElement);
184
            if(item instanceof TreeItem){
185
                viewer.expandToLevel(firstElement, 1);
186
                TreeItem treeItem = (TreeItem) item;
187
                TreeItem[] childItems = treeItem.getItems();
188
                List<TreeItem> childItemList = Arrays.asList(childItems);
189
                boolean allChecked = childItemList.stream().allMatch(childItem->childItem.getChecked());
190
                childItemList.stream().forEach(childItem->childItem.setChecked(!allChecked));
191
                TreeItem parent = getRoot(treeItem);
192
                updateItem(parent);
193
            }
194
        }
195
        else if(e.widget == btnSelectAllChildren){
196
            Widget item = viewer.testFindItem(firstElement);
197
            boolean checked = false;
198
            Object[] checkedElements = viewer.getCheckedElements();
199
            for (Object checkedElement : checkedElements) {
200
                if(checkedElement.equals(firstElement)){
201
                    checked = true;
202
                    break;
203
                }
204
            }
205
            if(item instanceof TreeItem){
206
                viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
207
                viewer.setSubtreeChecked(firstElement, !checked);
208
                TreeItem parent = getRoot((TreeItem) item);
209
                updateItem(parent);
210
            }
211
        }
212
    }
213

    
214

    
215
    /**
216
     * @param treeItem
217
     * @return
218
     */
219
    private TreeItem getRoot(TreeItem treeItem) {
220
        TreeItem parent = treeItem;
221
        while(parent.getParentItem()!=null){
222
            parent = parent.getParentItem();
223
        }
224
        return parent;
225
    }
226

    
227
    @Override
228
    public void widgetDefaultSelected(SelectionEvent e) {
229
    }
230

    
231
    private enum CheckState{
232
        CHECKED,
233
        GRAYED,
234
        NONE
235
    }
236

    
237
}
(11-11/14)