Project

General

Profile

Download (9.77 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
public class CheckBoxTreeComposite extends Composite implements SelectionListener {
40

    
41
    private static final Font FONT_DEFAULT = JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT);
42
    private static final Font FONT_ITALIC = JFaceResources.getFontRegistry().getItalic(JFaceResources.DEFAULT_FONT);
43
    private static final Font FONT_BOLD = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
44
    private CheckboxTreeViewer viewer;
45
    private Button btnCollapse;
46
    private Button btnExpand;
47
    private Button btnSelectAllChildren;
48
    private Button btnSelectDirectChildren;
49

    
50
    protected Object[] checkedElements;
51

    
52
    private boolean allowTopLevelSelection = false;
53

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

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

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

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

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

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

    
88
        Tree tree = new Tree(this, SWT.BORDER | SWT.CHECK);
89
        tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
90
        tree.addListener(SWT.Selection, event -> {
91
            if (event.detail == SWT.CHECK) {
92
                TreeItem item = (TreeItem) event.item;
93
                if(!allowTopLevelSelection && item.getParentItem()==null){
94
                    // top level selection not allowed
95
                    item.setChecked(false);
96
                    return;
97
                }
98

    
99
                if (item.getChecked()){
100
                    if (checkedElements != null){
101
                        Object[] tempArray = Arrays.copyOf(checkedElements, checkedElements.length +1);
102
                        tempArray[checkedElements.length] = item.getData();
103
                        checkedElements = tempArray;
104
                    }
105
                }else{
106
                    
107
                    if (checkedElements != null){
108
                    	Object[] tempArray = new Object[checkedElements.length -1];
109
                    	int index = 0;
110
                        for (Object o:checkedElements){
111
                            if (o != null && !o.equals(item.getData())){
112
                            	tempArray[index] = o;
113
                            	index++;
114
                            }
115
                        }
116
                        checkedElements = tempArray;
117
                    }
118
                }
119

    
120
                updateItem(item);
121
            }
122
        });
123

    
124
        viewer = new CdmCheckBoxTreeViewer(tree);
125
        viewer.setContentProvider(contentProvider);
126
        viewer.setLabelProvider(labelProvider);
127
    }
128

    
129
    private void updateItem(TreeItem treeItem){
130
        TreeItem parentItem = treeItem.getParentItem();
131
        if(parentItem!=null){
132
            updateItem(parentItem);
133
        }
134
        else{
135
            updateChildItems(treeItem);
136
        }
137
    }
138

    
139
    private void updateChildItems(TreeItem treeItem){
140
        treeItem.setFont(FONT_DEFAULT);
141
        TreeItem[] children = treeItem.getItems();
142
        if(children.length==0){
143
            return;
144
        }
145
        int checkedCount = 0;
146
        for (TreeItem child : children) {
147
            updateChildItems(child);
148

    
149
            if(child.getChecked() ){
150
                if ((child.getFont().equals(FONT_BOLD)) || (child.getItems().length == 0)) {
151
                    checkedCount++;
152
                }
153
                //some children are checked
154
                treeItem.setFont(FONT_ITALIC);
155
            }
156
            else if(child.getFont().equals(FONT_ITALIC)
157
                    || child.getFont().equals(FONT_BOLD)){
158
                //some children are checked
159
                treeItem.setFont(FONT_ITALIC);
160
            }
161
        }
162
        if(checkedCount==children.length){
163
            //all children are checked
164
            treeItem.setFont(FONT_BOLD);
165
        }
166
        else if(!treeItem.getFont().equals(FONT_ITALIC)){
167
            if(checkedCount>0){
168
                //some children are checked
169
                treeItem.setFont(FONT_ITALIC);
170
            }
171
            else{
172
                //no children are checked
173
                treeItem.setFont(FONT_DEFAULT);
174
            }
175
        }
176
    }
177

    
178

    
179
    public CheckboxTreeViewer getViewer() {
180
        return viewer;
181
    }
182

    
183
    public void setAllowTopLevelSelection(boolean allowTopLevelSelection) {
184
        this.allowTopLevelSelection = allowTopLevelSelection;
185
    }
186

    
187
    /**
188
     * Checks the tree items corresponding to the given elements.<br>
189
     * @param elements
190
     */
191
    public void setCheckedElements(Object[] elements) {
192

    
193
        this.checkedElements = elements;
194
        viewer.setCheckedElements(elements);
195
        for (Object element: checkedElements) {
196
            viewer.reveal(element);
197
        }
198
        TreeItem[] rootItems = viewer.getTree().getItems();
199
        for (TreeItem rootItem : rootItems) {
200
            updateItem(rootItem);
201
        }
202
    }
203

    
204
    /**
205
     * Grays the tree items corresponding to the given elements.<br>
206
     * @param elements
207
     */
208
    public void setGrayedElements(Object[] elements) {
209
        viewer.setGrayedElements(elements);
210
        for (Object element: elements) {
211
            viewer.reveal(element);
212
        }
213
        TreeItem[] rootItems = viewer.getTree().getItems();
214
        for (TreeItem rootItem : rootItems) {
215
            updateItem(rootItem);
216
        }
217
    }
218

    
219
    @Override
220
    public void widgetSelected(SelectionEvent e) {
221
        ITreeSelection structuredSelection = viewer.getStructuredSelection();
222
        Object firstElement = structuredSelection.getFirstElement();
223
        if(e.widget == btnCollapse){
224
            viewer.collapseAll();
225
        }
226
        else if(e.widget == btnExpand){
227
            viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
228
        }
229
        else if(e.widget == btnSelectDirectChildren){
230
            Widget item = viewer.testFindItem(firstElement);
231
            if(item instanceof TreeItem){
232
                viewer.expandToLevel(firstElement, 1);
233
                TreeItem treeItem = (TreeItem) item;
234
                TreeItem[] childItems = treeItem.getItems();
235
                List<TreeItem> childItemList = Arrays.asList(childItems);
236
                boolean allChecked = childItemList.stream().allMatch(childItem->childItem.getChecked());
237
                childItemList.stream().forEach(childItem->childItem.setChecked(!allChecked));
238
                TreeItem parent = getRoot(treeItem);
239
                updateItem(parent);
240
            }
241
        }
242
        else if(e.widget == btnSelectAllChildren){
243
            Widget item = viewer.testFindItem(firstElement);
244
            if(item instanceof TreeItem){
245
                viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
246
                viewer.setSubtreeChecked(firstElement, !((TreeItem) item).getFont().equals(FONT_BOLD));
247
                TreeItem parent = getRoot((TreeItem) item);
248
                updateItem(parent);
249
                ((TreeItem) item).setChecked(false);
250
            }
251
        }
252
    }
253

    
254
    private TreeItem getRoot(TreeItem treeItem) {
255
        TreeItem parent = treeItem;
256
        while(parent.getParentItem()!=null){
257
            parent = parent.getParentItem();
258
        }
259
        return parent;
260
    }
261

    
262
    @Override
263
    public void widgetDefaultSelected(SelectionEvent e) {
264
    }
265
}
(14-14/19)