analysis: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / dialogs / FilteredCheckboxTree.java
CommitLineData
40b7b614
GP
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
2bdf0193 13package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs;
40b7b614
GP
14
15import java.util.HashSet;
16import java.util.Set;
17
18import org.eclipse.core.runtime.jobs.IJobChangeEvent;
19import org.eclipse.core.runtime.jobs.JobChangeAdapter;
20import org.eclipse.jface.viewers.CheckStateChangedEvent;
21import org.eclipse.jface.viewers.CheckboxTreeViewer;
22import org.eclipse.jface.viewers.ICheckStateListener;
23import org.eclipse.jface.viewers.ICheckable;
24import org.eclipse.jface.viewers.ITreeContentProvider;
25import org.eclipse.jface.viewers.TreeViewer;
26import org.eclipse.swt.widgets.Composite;
27import org.eclipse.ui.dialogs.FilteredTree;
28import org.eclipse.ui.dialogs.PatternFilter;
29import 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>"
40b7b614
GP
43 */
44public class FilteredCheckboxTree extends FilteredTree implements ICheckable {
45
46 /**
47 * Set containing only the tree items that are checked
48 */
49 private Set<Object> fObjects = new HashSet<>();
50
51 /**
52 * Handle to the tree viewer
53 */
54 private CheckboxTreeViewer fCheckboxTreeViewer;
55
56 /**
57 * Create a new instance of the receiver.
58 *
59 * @param parent
60 * the parent <code>Composite</code>
61 * @param treeStyle
62 * the style bits for the <code>Tree</code>
63 * @param filter
64 * the filter to be used
65 * @param useNewLook
66 * <code>true</code> if the new <code>FilteredTree</code> look
67 * should be used
68 */
69 public FilteredCheckboxTree(Composite parent, int treeStyle, PatternFilter filter,
70 boolean useNewLook) {
71 super(parent, treeStyle, filter, useNewLook);
72 }
73
74 @Override
75 protected TreeViewer doCreateTreeViewer(Composite parentComposite, int style) {
76 fCheckboxTreeViewer = new CheckboxTreeViewer(parentComposite, style);
ded8b718 77 fCheckboxTreeViewer.setUseHashlookup(true);
40b7b614
GP
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.061143 seconds and 5 git commands to generate.