tmf: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / dialogs / FilteredCheckboxTree.java
1 /*******************************************************************************
2 * Copyright (c) 2014 Inria
3 *
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
8 *
9 * Contributors:
10 * Generoso Pagano, Inria - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs;
14
15 import java.util.HashSet;
16 import java.util.Set;
17
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;
30
31 /**
32 * A <code>FilteredTree</code> wrapping a <code>CheckboxTreeViewer</code>.
33 *
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.
37 *
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.
41 *
42 * @author "Generoso Pagano <generoso.pagano@inria.fr>"
43 * @since 3.2
44 */
45 public class FilteredCheckboxTree extends FilteredTree implements ICheckable {
46
47 /**
48 * Set containing only the tree items that are checked
49 */
50 private Set<Object> fObjects = new HashSet<>();
51
52 /**
53 * Handle to the tree viewer
54 */
55 private CheckboxTreeViewer fCheckboxTreeViewer;
56
57 /**
58 * Create a new instance of the receiver.
59 *
60 * @param parent
61 * the parent <code>Composite</code>
62 * @param treeStyle
63 * the style bits for the <code>Tree</code>
64 * @param filter
65 * the filter to be used
66 * @param useNewLook
67 * <code>true</code> if the new <code>FilteredTree</code> look
68 * should be used
69 */
70 public FilteredCheckboxTree(Composite parent, int treeStyle, PatternFilter filter,
71 boolean useNewLook) {
72 super(parent, treeStyle, filter, useNewLook);
73 }
74
75 @Override
76 protected TreeViewer doCreateTreeViewer(Composite parentComposite, int style) {
77 fCheckboxTreeViewer = new CheckboxTreeViewer(parentComposite, style);
78 fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() {
79 @Override
80 public void checkStateChanged(CheckStateChangedEvent event) {
81 if (event.getChecked()) {
82 fObjects.add(event.getElement());
83 } else {
84 fObjects.remove(event.getElement());
85 }
86 }
87 });
88 return fCheckboxTreeViewer;
89 }
90
91 @Override
92 protected WorkbenchJob doCreateRefreshJob() {
93 WorkbenchJob job = super.doCreateRefreshJob();
94 job.addJobChangeListener(new JobChangeAdapter() {
95 @Override
96 public void done(IJobChangeEvent event) {
97 fCheckboxTreeViewer.expandAll();
98 fCheckboxTreeViewer.setCheckedElements(getCheckedElements());
99 }
100 });
101 return job;
102 }
103
104 @Override
105 public boolean getChecked(Object element) {
106 return fObjects.contains(element);
107 }
108
109 @Override
110 public boolean setChecked(Object element, boolean state) {
111 boolean checkable = fCheckboxTreeViewer.setChecked(element, state);
112 if (!state) {
113 fObjects.remove(element);
114 } else if (checkable) {
115 fObjects.add(element);
116 }
117 return checkable;
118 }
119
120 @Override
121 public void addCheckStateListener(ICheckStateListener listener) {
122 fCheckboxTreeViewer.addCheckStateListener(listener);
123 }
124
125 @Override
126 public void removeCheckStateListener(ICheckStateListener listener) {
127 fCheckboxTreeViewer.addCheckStateListener(listener);
128 }
129
130 /**
131 * Returns all the checked elements of this tree, either visible or not.
132 *
133 * @return an array containing all the checked elements
134 */
135 public Object[] getCheckedElements() {
136 return fObjects.toArray();
137 }
138
139 /**
140 * Checks all the passed elements and unchecks all the other.
141 *
142 * @param elements
143 * the elements to check
144 */
145 public void setCheckedElements(Object[] elements) {
146 fObjects = new HashSet<>();
147 for (Object element : elements) {
148 fObjects.add(element);
149 }
150 fCheckboxTreeViewer.setCheckedElements(elements);
151 }
152
153 /**
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.
157 *
158 * @param element
159 * the element
160 * @param state
161 * the check state to set
162 * @return <code>true</code> if the check state could be set, and
163 * <code>false</code> otherwise
164 */
165 public boolean setSubtreeChecked(Object element, boolean state) {
166 checkSubtree(element, state);
167 return fCheckboxTreeViewer.setSubtreeChecked(element, state);
168 }
169
170 /**
171 * Recursively sets the check state on an element and its children, using
172 * the politic specified in {@link #setSubtreeChecked(Object, boolean)}
173 * documentation.
174 *
175 * @param element
176 * the element
177 * @param state
178 * the check state to set
179 */
180 private void checkSubtree(Object element, boolean state) {
181 if (!state || (fCheckboxTreeViewer.testFindItem(element) != null)) {
182 if (state) {
183 fObjects.add(element);
184 } else {
185 fObjects.remove(element);
186 }
187 for (Object o : ((ITreeContentProvider) fCheckboxTreeViewer.getContentProvider()).getChildren(element)) {
188 checkSubtree(o, state);
189 }
190 }
191 }
192
193 }
This page took 0.040421 seconds and 5 git commands to generate.