Project

General

Profile

Download (8.78 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

    
101
        viewer = new CheckboxTreeViewer(tree);
102
        viewer.setContentProvider(contentProvider);
103
        viewer.setLabelProvider(labelProvider);
104
    }
105

    
106

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

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

    
155

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

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

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

    
178
    }
179

    
180
    /**
181
     * Grays the tree items corresponding to the given elements.<br>
182
     * @param elements
183
     */
184
    public void setGrayedElements(Object[] elements) {
185
        viewer.setGrayedElements(elements);
186
        for (Object element: elements) {
187
            viewer.reveal(element);
188
        }
189
        TreeItem[] rootItems = viewer.getTree().getItems();
190
        for (TreeItem rootItem : rootItems) {
191
            updateItem(rootItem);
192
        }
193

    
194
    }
195

    
196
    @Override
197
    public void widgetSelected(SelectionEvent e) {
198
        ITreeSelection structuredSelection = viewer.getStructuredSelection();
199
        Object firstElement = structuredSelection.getFirstElement();
200
        if(e.widget == btnCollapse){
201
            viewer.collapseAll();
202
        }
203
        else if(e.widget == btnExpand){
204
            viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
205
        }
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);
216
                updateItem(parent);
217
            }
218
        }
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);
225
                updateItem(parent);
226
                ((TreeItem) item).setChecked(false);
227
            }
228
        }
229
    }
230

    
231
    private TreeItem getRoot(TreeItem treeItem) {
232
        TreeItem parent = treeItem;
233
        while(parent.getParentItem()!=null){
234
            parent = parent.getParentItem();
235
        }
236
        return parent;
237
    }
238

    
239
    @Override
240
    public void widgetDefaultSelected(SelectionEvent e) {
241
    }
242

    
243
}
(13-13/18)