Project

General

Profile

Download (8.34 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
    private boolean allowTopLevelSelection = false;
52

    
53
    public CheckBoxTreeComposite(Composite parent, ITreeContentProvider contentProvider, IBaseLabelProvider labelProvider, int style) {
54
        super(parent, style);
55
        GridLayout layout = new GridLayout();
56
        layout.marginHeight = 0;
57
        setLayout(layout);
58

    
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);
66

    
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$
71

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

    
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);
81

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

    
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);
95
                    return;
96
                }
97
                updateItem(item);
98
            }
99
        });
100
        viewer = new CheckboxTreeViewer(tree);
101
        viewer.setContentProvider(contentProvider);
102
        viewer.setLabelProvider(labelProvider);
103
    }
104

    
105

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

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

    
154

    
155
    public CheckboxTreeViewer getViewer() {
156
        return viewer;
157
    }
158

    
159
    public void setAllowTopLevelSelection(boolean allowTopLevelSelection) {
160
        this.allowTopLevelSelection = allowTopLevelSelection;
161
    }
162

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

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

    
213
    private TreeItem getRoot(TreeItem treeItem) {
214
        TreeItem parent = treeItem;
215
        while(parent.getParentItem()!=null){
216
            parent = parent.getParentItem();
217
        }
218
        return parent;
219
    }
220

    
221
    @Override
222
    public void widgetDefaultSelected(SelectionEvent e) {
223
    }
224

    
225
}
(13-13/16)