1 /*******************************************************************************
2 * Copyright (c) 2014 Inria
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Generoso Pagano, Inria - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.dialogs
;
15 import java
.util
.HashSet
;
18 import org
.eclipse
.core
.runtime
.jobs
.IJobChangeEvent
;
19 import org
.eclipse
.core
.runtime
.jobs
.JobChangeAdapter
;
20 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
21 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
22 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
23 import org
.eclipse
.jface
.viewers
.ICheckable
;
24 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
25 import org
.eclipse
.jface
.viewers
.TreeViewer
;
26 import org
.eclipse
.swt
.widgets
.Composite
;
27 import org
.eclipse
.ui
.dialogs
.FilteredTree
;
28 import org
.eclipse
.ui
.dialogs
.PatternFilter
;
29 import org
.eclipse
.ui
.progress
.WorkbenchJob
;
32 * A <code>FilteredTree</code> wrapping a <code>CheckboxTreeViewer</code>.
34 * This tree keeps the check state of the nodes in sync, regardless of the fact
35 * that a node is filtered or not. This way, even if an node is filtered (not
36 * visible), the caller can get and set the check state.
38 * Note that all the "uncheck" operations act only on what is not filtered and
39 * what is child of something not filtered (even if such a child is filtered).
40 * On the contrary, all the "check" operations act only on what is not filtered.
42 * @author "Generoso Pagano <generoso.pagano@inria.fr>"
44 public class FilteredCheckboxTree
extends FilteredTree
implements ICheckable
{
47 * Set containing only the tree items that are checked
49 private Set
<Object
> fObjects
= new HashSet
<>();
52 * Handle to the tree viewer
54 private CheckboxTreeViewer fCheckboxTreeViewer
;
57 * Create a new instance of the receiver.
60 * the parent <code>Composite</code>
62 * the style bits for the <code>Tree</code>
64 * the filter to be used
66 * <code>true</code> if the new <code>FilteredTree</code> look
69 public FilteredCheckboxTree(Composite parent
, int treeStyle
, PatternFilter filter
,
71 super(parent
, treeStyle
, filter
, useNewLook
);
75 protected TreeViewer
doCreateTreeViewer(Composite parentComposite
, int style
) {
76 fCheckboxTreeViewer
= new CheckboxTreeViewer(parentComposite
, style
);
77 fCheckboxTreeViewer
.setUseHashlookup(true);
78 fCheckboxTreeViewer
.addCheckStateListener(new ICheckStateListener() {
80 public void checkStateChanged(CheckStateChangedEvent event
) {
81 if (event
.getChecked()) {
82 fObjects
.add(event
.getElement());
84 fObjects
.remove(event
.getElement());
88 return fCheckboxTreeViewer
;
92 protected WorkbenchJob
doCreateRefreshJob() {
93 WorkbenchJob job
= super.doCreateRefreshJob();
94 job
.addJobChangeListener(new JobChangeAdapter() {
96 public void done(IJobChangeEvent event
) {
97 fCheckboxTreeViewer
.expandAll();
98 fCheckboxTreeViewer
.setCheckedElements(getCheckedElements());
105 public boolean getChecked(Object element
) {
106 return fObjects
.contains(element
);
110 public boolean setChecked(Object element
, boolean state
) {
111 boolean checkable
= fCheckboxTreeViewer
.setChecked(element
, state
);
113 fObjects
.remove(element
);
114 } else if (checkable
) {
115 fObjects
.add(element
);
121 public void addCheckStateListener(ICheckStateListener listener
) {
122 fCheckboxTreeViewer
.addCheckStateListener(listener
);
126 public void removeCheckStateListener(ICheckStateListener listener
) {
127 fCheckboxTreeViewer
.addCheckStateListener(listener
);
131 * Returns all the checked elements of this tree, either visible or not.
133 * @return an array containing all the checked elements
135 public Object
[] getCheckedElements() {
136 return fObjects
.toArray();
140 * Checks all the passed elements and unchecks all the other.
143 * the elements to check
145 public void setCheckedElements(Object
[] elements
) {
146 fObjects
= new HashSet
<>();
147 for (Object element
: elements
) {
148 fObjects
.add(element
);
150 fCheckboxTreeViewer
.setCheckedElements(elements
);
154 * Sets the check state for the given element and its children in this
155 * viewer. The unchecked state is always set, while the checked state is set
156 * only on visible elements.
161 * the check state to set
162 * @return <code>true</code> if the check state could be set, and
163 * <code>false</code> otherwise
165 public boolean setSubtreeChecked(Object element
, boolean state
) {
166 checkSubtree(element
, state
);
167 return fCheckboxTreeViewer
.setSubtreeChecked(element
, state
);
171 * Recursively sets the check state on an element and its children, using
172 * the politic specified in {@link #setSubtreeChecked(Object, boolean)}
178 * the check state to set
180 private void checkSubtree(Object element
, boolean state
) {
181 if (!state
|| (fCheckboxTreeViewer
.testFindItem(element
) != null)) {
183 fObjects
.add(element
);
185 fObjects
.remove(element
);
187 for (Object o
: ((ITreeContentProvider
) fCheckboxTreeViewer
.getContentProvider()).getChildren(element
)) {
188 checkSubtree(o
, state
);