Commit | Line | Data |
---|---|---|
7692e512 AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2013 École Polytechnique de Montréal, Ericsson | |
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 | * Florian Wininger - Initial API and implementation | |
11 | * Alexandre Montplaisir - Refactoring, performance tweaks | |
fec1ac0b | 12 | * Bernd Hufmann - Updated signal handling |
c1cd9635 | 13 | * Marc-Andre Laperle - Add time zone preference |
7692e512 AM |
14 | *******************************************************************************/ |
15 | ||
16 | package org.eclipse.linuxtools.tmf.ui.views.statesystem; | |
17 | ||
278aa247 | 18 | import java.io.File; |
7692e512 AM |
19 | import java.util.LinkedHashMap; |
20 | import java.util.List; | |
21 | import java.util.Map; | |
22 | ||
278aa247 FW |
23 | import org.eclipse.jface.action.Action; |
24 | import org.eclipse.jface.action.IToolBarManager; | |
25 | import org.eclipse.jface.resource.ImageDescriptor; | |
26 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
7692e512 AM |
27 | import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; |
28 | import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException; | |
29 | import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; | |
30 | import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; | |
31 | import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; | |
32 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; | |
33 | import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; | |
c1cd9635 | 34 | import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; |
7692e512 | 35 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal; |
fec1ac0b | 36 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; |
7692e512 AM |
37 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal; |
38 | import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; | |
39 | import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; | |
40 | import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; | |
41 | import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; | |
42 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; | |
b9a5bf8f | 43 | import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; |
7692e512 AM |
44 | import org.eclipse.linuxtools.tmf.ui.views.TmfView; |
45 | import org.eclipse.swt.SWT; | |
278aa247 | 46 | import org.eclipse.swt.graphics.Image; |
7692e512 | 47 | import org.eclipse.swt.widgets.Composite; |
278aa247 | 48 | import org.eclipse.swt.widgets.Display; |
7692e512 AM |
49 | import org.eclipse.swt.widgets.Event; |
50 | import org.eclipse.swt.widgets.Listener; | |
51 | import org.eclipse.swt.widgets.Tree; | |
52 | import org.eclipse.swt.widgets.TreeColumn; | |
53 | import org.eclipse.swt.widgets.TreeItem; | |
278aa247 | 54 | import org.eclipse.ui.IActionBars; |
7692e512 AM |
55 | |
56 | /** | |
57 | * Displays the State System at a current time. | |
58 | * | |
59 | * @author Florian Wininger | |
60 | * @author Alexandre Montplaisir | |
61 | * @since 2.0 | |
62 | */ | |
63 | public class TmfStateSystemExplorer extends TmfView { | |
64 | ||
65 | /** The Environment View's ID */ | |
66 | public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.ssview"; //$NON-NLS-1$ | |
67 | ||
68 | private static final String emptyString = ""; //$NON-NLS-1$ | |
278aa247 FW |
69 | private static final String FS = File.separator; |
70 | private static final Image FILTER_IMAGE = | |
71 | Activator.getDefault().getImageFromPath(FS + "icons" + FS + "elcl16" + FS + "filter_items.gif"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
7692e512 AM |
72 | |
73 | /* Order of columns */ | |
74 | private static final int ATTRIBUTE_NAME_COL = 0; | |
75 | private static final int QUARK_COL = 1; | |
76 | private static final int VALUE_COL = 2; | |
278aa247 FW |
77 | private static final int TYPE_COL = 3; |
78 | private static final int START_TIME_COL = 4; | |
79 | private static final int END_TIME_COL = 5; | |
80 | private static final int ATTRIBUTE_FULLPATH_COL = 6; | |
7692e512 AM |
81 | |
82 | private ITmfTrace fTrace; | |
83 | private Tree fTree; | |
84 | private volatile long fCurrentTimestamp = -1L; | |
85 | ||
278aa247 FW |
86 | private boolean filterStatus = false ; |
87 | ||
7692e512 AM |
88 | /** |
89 | * Default constructor | |
90 | */ | |
91 | public TmfStateSystemExplorer() { | |
92 | super(ID); | |
93 | } | |
94 | ||
95 | // ------------------------------------------------------------------------ | |
96 | // ViewPart | |
97 | // ------------------------------------------------------------------------ | |
98 | ||
99 | @Override | |
100 | public void createPartControl(Composite parent) { | |
101 | fTree = new Tree(parent, SWT.NONE); | |
102 | TreeColumn nameCol = new TreeColumn(fTree, SWT.NONE, ATTRIBUTE_NAME_COL); | |
103 | TreeColumn quarkCol = new TreeColumn(fTree, SWT.NONE, QUARK_COL); | |
104 | TreeColumn valueCol = new TreeColumn(fTree, SWT.NONE, VALUE_COL); | |
278aa247 | 105 | TreeColumn typeCol = new TreeColumn(fTree, SWT.NONE, TYPE_COL); |
7692e512 AM |
106 | TreeColumn startCol = new TreeColumn(fTree, SWT.NONE, START_TIME_COL); |
107 | TreeColumn endCol = new TreeColumn(fTree, SWT.NONE, END_TIME_COL); | |
108 | TreeColumn pathCol = new TreeColumn(fTree, SWT.NONE, ATTRIBUTE_FULLPATH_COL); | |
109 | ||
110 | nameCol.setText(Messages.TreeNodeColumnLabel); | |
111 | quarkCol.setText(Messages.QuarkColumnLabel); | |
112 | valueCol.setText(Messages.ValueColumnLabel); | |
278aa247 | 113 | typeCol.setText(Messages.TypeColumnLabel); |
7692e512 AM |
114 | startCol.setText(Messages.StartTimeColumLabel); |
115 | endCol.setText(Messages.EndTimeColumLabel); | |
116 | pathCol.setText(Messages.AttributePathColumnLabel); | |
117 | ||
118 | fTree.setItemCount(0); | |
119 | ||
120 | fTree.setHeaderVisible(true); | |
121 | nameCol.pack(); | |
122 | valueCol.pack(); | |
123 | ||
124 | fTree.addListener(SWT.Expand, new Listener() { | |
125 | @Override | |
126 | public void handleEvent(Event e) { | |
127 | TreeItem item = (TreeItem) e.item; | |
128 | item.setExpanded(true); | |
129 | updateTable(); | |
130 | } | |
131 | }); | |
132 | ||
133 | ITmfTrace trace = getActiveTrace(); | |
134 | if (trace != null) { | |
135 | traceSelected(new TmfTraceSelectedSignal(this, trace)); | |
136 | } | |
278aa247 FW |
137 | |
138 | fillToolBar() ; | |
139 | ||
7692e512 AM |
140 | } |
141 | ||
142 | // ------------------------------------------------------------------------ | |
143 | // Operations | |
144 | // ------------------------------------------------------------------------ | |
145 | ||
146 | /** | |
147 | * Create the initial tree from a trace. | |
148 | */ | |
149 | private synchronized void createTable() { | |
278aa247 FW |
150 | |
151 | long ts = fCurrentTimestamp; | |
152 | ||
7692e512 AM |
153 | if (fTrace == null) { |
154 | return; | |
155 | } | |
156 | ||
157 | /* Clear the table, in case a trace was previously using it */ | |
158 | fTree.getDisplay().asyncExec(new Runnable() { | |
159 | @Override | |
160 | public void run() { | |
161 | fTree.setItemCount(0); | |
162 | } | |
163 | }); | |
164 | ||
b9a5bf8f | 165 | for (final ITmfTrace currentTrace : TmfTraceManager.getTraceSet(fTrace)) { |
7692e512 AM |
166 | /* |
167 | * We will first do all the queries for this trace, then update that | |
168 | * sub-tree in the UI thread. | |
169 | */ | |
170 | final Map<String, ITmfStateSystem> sss = currentTrace.getStateSystems(); | |
171 | final Map<String, List<ITmfStateInterval>> fullStates = | |
172 | new LinkedHashMap<String, List<ITmfStateInterval>>(); | |
173 | for (Map.Entry<String, ITmfStateSystem> entry : sss.entrySet()) { | |
174 | String ssName = entry.getKey(); | |
175 | ITmfStateSystem ss = entry.getValue(); | |
176 | ss.waitUntilBuilt(); | |
278aa247 FW |
177 | if (ts == -1 || ts < ss.getStartTime() || ts > ss.getCurrentEndTime()) { |
178 | ts = ss.getStartTime(); | |
179 | } | |
7692e512 | 180 | try { |
278aa247 | 181 | fullStates.put(ssName, ss.queryFullState(ts)); |
7692e512 | 182 | } catch (TimeRangeException e) { |
278aa247 | 183 | /* We already checked the limits ourselves */ |
7692e512 AM |
184 | throw new RuntimeException(); |
185 | } catch (StateSystemDisposedException e) { | |
186 | /* Probably shutting down, cancel and return */ | |
187 | return; | |
188 | } | |
189 | } | |
190 | ||
191 | /* Update the table (in the UI thread) */ | |
192 | fTree.getDisplay().asyncExec(new Runnable() { | |
193 | @Override | |
194 | public void run() { | |
195 | TreeItem traceRoot = new TreeItem(fTree, SWT.NONE); | |
196 | traceRoot.setText(ATTRIBUTE_NAME_COL, currentTrace.getName()); | |
197 | ||
198 | for (Map.Entry<String, ITmfStateSystem> entry : sss.entrySet()) { | |
199 | String ssName = entry.getKey(); | |
200 | ITmfStateSystem ss = entry.getValue(); | |
201 | List<ITmfStateInterval> fullState = fullStates.get(ssName); | |
202 | ||
203 | /* Root item of the current state system */ | |
204 | TreeItem item = new TreeItem(traceRoot, SWT.NONE); | |
205 | ||
206 | /* Name of the SS goes in the first column */ | |
207 | item.setText(ATTRIBUTE_NAME_COL, ssName); | |
208 | ||
209 | /* | |
210 | * Calling with quark '-1' here to start with the root | |
211 | * attribute, then it will be called recursively. | |
212 | */ | |
213 | addChildren(ss, fullState, -1, item); | |
214 | } | |
215 | ||
216 | /* Expand the first-level tree items */ | |
217 | for (TreeItem item : fTree.getItems()) { | |
218 | item.setExpanded(true); | |
219 | } | |
220 | packColumns(); | |
278aa247 FW |
221 | |
222 | if (filterStatus) { | |
223 | filterChildren(traceRoot); | |
224 | } | |
7692e512 AM |
225 | } |
226 | }); | |
227 | } | |
228 | } | |
229 | ||
230 | /** | |
231 | * Add children node to a newly-created tree. Should only be called by the | |
232 | * UI thread. | |
233 | */ | |
234 | private void addChildren(ITmfStateSystem ss, | |
235 | List<ITmfStateInterval> fullState, int rootQuark, TreeItem root) { | |
236 | try { | |
237 | for (int quark : ss.getSubAttributes(rootQuark, false)) { | |
238 | TreeItem subItem = new TreeItem(root, SWT.NONE); | |
239 | ||
240 | /* Write the info we already know */ | |
241 | subItem.setText(ATTRIBUTE_NAME_COL, ss.getAttributeName(quark)); | |
242 | subItem.setText(QUARK_COL, String.valueOf(quark)); | |
243 | subItem.setText(ATTRIBUTE_FULLPATH_COL, ss.getFullAttributePath(quark)); | |
244 | ||
245 | /* Populate the other columns */ | |
246 | ITmfStateInterval interval = fullState.get(quark); | |
247 | populateColumns(subItem, interval); | |
248 | ||
249 | /* Update this node's children recursively */ | |
250 | addChildren(ss, fullState, quark, subItem); | |
251 | } | |
252 | ||
253 | } catch (AttributeNotFoundException e) { | |
254 | /* Should not happen, we're iterating on known attributes */ | |
255 | throw new RuntimeException(); | |
256 | } | |
257 | } | |
258 | ||
259 | /** | |
260 | * Update the tree, which means keep the tree of attributes in the first | |
261 | * column as-is, but update the values to the ones at a new timestamp. | |
262 | */ | |
263 | private synchronized void updateTable() { | |
b9a5bf8f | 264 | ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace); |
7692e512 AM |
265 | long ts = fCurrentTimestamp; |
266 | ||
267 | /* For each trace... */ | |
268 | for (int traceNb = 0; traceNb < traces.length; traceNb++) { | |
269 | Map<String, ITmfStateSystem> sss = traces[traceNb].getStateSystems(); | |
270 | ||
271 | /* For each state system associated with this trace... */ | |
272 | int ssNb = 0; | |
273 | for (Map.Entry<String, ITmfStateSystem> entry : sss.entrySet()) { | |
274 | /* | |
275 | * Even though we only use the value, it just feels safer to | |
276 | * iterate the same way as before to keep the order the same. | |
277 | */ | |
278 | final ITmfStateSystem ss = entry.getValue(); | |
279 | final int traceNb1 = traceNb; | |
280 | final int ssNb1 = ssNb; | |
281 | ts = (ts == -1 ? ss.getStartTime() : ts); | |
282 | try { | |
283 | final List<ITmfStateInterval> fullState = ss.queryFullState(ts); | |
284 | fTree.getDisplay().asyncExec(new Runnable() { | |
285 | @Override | |
286 | public void run() { | |
287 | /* Get the tree item of the relevant state system */ | |
288 | TreeItem traceItem = fTree.getItem(traceNb1); | |
289 | TreeItem item = traceItem.getItem(ssNb1); | |
290 | /* Update it, then its children, recursively */ | |
291 | item.setText(VALUE_COL, emptyString); | |
292 | updateChildren(ss, fullState, -1, item); | |
293 | } | |
294 | }); | |
295 | ||
296 | } catch (TimeRangeException e) { | |
297 | /* | |
298 | * This can happen in an experiment, if the user selects a | |
299 | * range valid in the experiment, but this specific does not | |
300 | * exist. Print "out-of-range" into all the values. | |
301 | */ | |
302 | fTree.getDisplay().asyncExec(new Runnable() { | |
303 | @Override | |
304 | public void run() { | |
305 | TreeItem traceItem = fTree.getItem(traceNb1); | |
306 | TreeItem item = traceItem.getItem(ssNb1); | |
307 | markOutOfRange(item); | |
308 | } | |
309 | }); | |
310 | } catch (StateSystemDisposedException e) { | |
311 | return; | |
312 | } | |
313 | ||
314 | ssNb++; | |
315 | } | |
316 | } | |
317 | } | |
318 | ||
319 | /** | |
320 | * Update the values shown by a child row when doing an update. Should only | |
321 | * be called by the UI thread. | |
322 | */ | |
323 | private void updateChildren(ITmfStateSystem ss, | |
324 | List<ITmfStateInterval> state, int root_quark, TreeItem root) { | |
325 | try { | |
326 | for (TreeItem item : root.getItems()) { | |
327 | int quark = ss.getQuarkRelative(root_quark, item.getText(0)); | |
328 | ITmfStateInterval interval = state.get(quark); | |
329 | populateColumns(item, interval); | |
330 | ||
331 | /* Update children recursively */ | |
332 | updateChildren(ss, state, quark, item); | |
333 | } | |
334 | ||
335 | } catch (AttributeNotFoundException e) { | |
336 | /* We're iterating on known attributes, should not happen */ | |
337 | throw new RuntimeException(); | |
338 | } | |
339 | } | |
340 | ||
341 | /** | |
342 | * Populate an 'item' (a row in the tree) with the information found in the | |
343 | * interval. This method should only be called by the UI thread. | |
344 | */ | |
278aa247 | 345 | private void populateColumns(TreeItem item, ITmfStateInterval interval) { |
7692e512 AM |
346 | try { |
347 | ITmfStateValue state = interval.getStateValue(); | |
278aa247 | 348 | String value ; |
7692e512 AM |
349 | |
350 | // add the value in the 2nd column | |
351 | switch (state.getType()) { | |
352 | case INTEGER: | |
278aa247 FW |
353 | value = String.valueOf(state.unboxInt()); |
354 | item.setText(TYPE_COL, Messages.TypeInteger); | |
7692e512 AM |
355 | break; |
356 | case LONG: | |
278aa247 FW |
357 | value = String.valueOf(state.unboxLong()); |
358 | item.setText(TYPE_COL, Messages.TypeLong); | |
7692e512 AM |
359 | break; |
360 | case STRING: | |
278aa247 FW |
361 | value = state.unboxStr(); |
362 | item.setText(TYPE_COL, Messages.TypeString); | |
7692e512 AM |
363 | break; |
364 | case NULL: | |
365 | default: | |
278aa247 FW |
366 | value = emptyString ; |
367 | item.setText(TYPE_COL, emptyString); | |
7692e512 AM |
368 | break; |
369 | } | |
370 | ||
371 | TmfTimestamp startTime = new TmfTimestamp(interval.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE); | |
372 | item.setText(START_TIME_COL, startTime.toString()); | |
373 | ||
374 | TmfTimestamp endTime = new TmfTimestamp(interval.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE); | |
375 | item.setText(END_TIME_COL, endTime.toString()); | |
376 | ||
278aa247 FW |
377 | item.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)) ; |
378 | ||
31d773ed | 379 | if (!filterStatus && (!value.equals(item.getText(VALUE_COL)) || fCurrentTimestamp == startTime.getValue())) { |
278aa247 | 380 | item.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_YELLOW)); |
278aa247 FW |
381 | } |
382 | ||
383 | item.setText(VALUE_COL, value) ; | |
384 | ||
7692e512 AM |
385 | } catch (StateValueTypeException e) { |
386 | /* Should not happen, we're case-switching on the specific types */ | |
387 | throw new RuntimeException(); | |
388 | } | |
389 | } | |
390 | ||
391 | /** | |
392 | * Same concept as {@link updateChildren}, but instead of printing actual | |
393 | * values coming from the state system, we print "Out of range" into all | |
394 | * values. This is to indicate that this specific state system is not | |
395 | * currently defined at the selected timestamp. | |
396 | * | |
397 | * Guess by which thread this should be called? Hint: starts with a U, ends | |
398 | * with an I. | |
399 | */ | |
400 | private void markOutOfRange(TreeItem root) { | |
401 | root.setText(VALUE_COL, Messages.OutOfRangeMsg); | |
278aa247 | 402 | root.setText(TYPE_COL, emptyString); |
7692e512 AM |
403 | root.setText(START_TIME_COL, emptyString); |
404 | root.setText(END_TIME_COL, emptyString); | |
405 | for (TreeItem item : root.getItems()) { | |
406 | markOutOfRange(item); | |
407 | } | |
408 | } | |
409 | ||
410 | /** | |
411 | * Auto-pack all the columns in the display. Should only be called by the UI | |
412 | * thread. | |
413 | */ | |
414 | private void packColumns() { | |
415 | //FIXME should add a bit of padding | |
416 | for (TreeColumn column : fTree.getColumns()) { | |
417 | column.pack(); | |
418 | } | |
419 | } | |
420 | ||
421 | @Override | |
422 | public void setFocus() { | |
423 | fTree.setFocus(); | |
424 | } | |
425 | ||
426 | // ------------------------------------------------------------------------ | |
427 | // Signal handlers | |
428 | // ------------------------------------------------------------------------ | |
fec1ac0b BH |
429 | /** |
430 | * Handler for the trace opened signal. | |
431 | * @param signal | |
432 | * The incoming signal | |
433 | * @since 2.0 | |
434 | */ | |
435 | @TmfSignalHandler | |
436 | public void traceOpened(TmfTraceOpenedSignal signal) { | |
437 | fTrace = signal.getTrace(); | |
438 | loadTrace(); | |
439 | } | |
7692e512 AM |
440 | |
441 | /** | |
442 | * Handler for the trace selected signal. This will make the view display | |
443 | * the information for the newly-selected trace. | |
444 | * | |
445 | * @param signal | |
446 | * The incoming signal | |
447 | */ | |
448 | @TmfSignalHandler | |
449 | public void traceSelected(TmfTraceSelectedSignal signal) { | |
450 | ITmfTrace trace = signal.getTrace(); | |
451 | if (trace != fTrace) { | |
452 | fTrace = trace; | |
fec1ac0b | 453 | loadTrace(); |
7692e512 AM |
454 | } |
455 | } | |
456 | ||
457 | /** | |
458 | * Handler for the trace closed signal. This will clear the view. | |
459 | * | |
460 | * @param signal | |
461 | * the incoming signal | |
462 | */ | |
463 | @TmfSignalHandler | |
464 | public void traceClosed(TmfTraceClosedSignal signal) { | |
465 | // delete the tree at the trace closed | |
466 | if (signal.getTrace() == fTrace) { | |
467 | fTrace = null; | |
468 | fTree.setItemCount(0); | |
469 | } | |
470 | } | |
471 | ||
472 | /** | |
473 | * Handles the current time updated signal. This will update the view's | |
474 | * values to the newly-selected timestamp. | |
475 | * | |
476 | * @param signal | |
477 | * the signal to process | |
478 | */ | |
479 | @TmfSignalHandler | |
480 | public void currentTimeUpdated(final TmfTimeSynchSignal signal) { | |
481 | Thread thread = new Thread("State system visualizer update") { //$NON-NLS-1$ | |
482 | @Override | |
483 | public void run() { | |
0fcf3b09 | 484 | ITmfTimestamp currentTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE); |
7692e512 | 485 | fCurrentTimestamp = currentTime.getValue(); |
278aa247 FW |
486 | |
487 | if (filterStatus) { | |
488 | createTable(); | |
489 | } else { | |
490 | updateTable(); | |
491 | } | |
7692e512 AM |
492 | } |
493 | }; | |
494 | thread.start(); | |
495 | } | |
fec1ac0b BH |
496 | |
497 | private void loadTrace() { | |
498 | Thread thread = new Thread("State system visualizer construction") { //$NON-NLS-1$ | |
499 | @Override | |
500 | public void run() { | |
501 | createTable(); | |
502 | } | |
503 | }; | |
504 | thread.start(); | |
505 | } | |
c1cd9635 MAL |
506 | |
507 | /** | |
508 | * Update the display to use the updated timestamp format | |
509 | * | |
510 | * @param signal the incoming signal | |
511 | * @since 2.1 | |
512 | */ | |
513 | @TmfSignalHandler | |
514 | public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) { | |
515 | Thread thread = new Thread("State system visualizer update") { //$NON-NLS-1$ | |
516 | @Override | |
517 | public void run() { | |
518 | updateTable(); | |
519 | } | |
520 | }; | |
521 | thread.start(); | |
522 | } | |
fec1ac0b | 523 | |
278aa247 FW |
524 | /** |
525 | * Function for the delete TreeItem | |
526 | */ | |
527 | private boolean filterChildren(TreeItem root) { | |
528 | boolean valid = false ; | |
529 | TmfTimestamp startTime = new TmfTimestamp(fCurrentTimestamp, ITmfTimestamp.NANOSECOND_SCALE); | |
530 | valid = root.getText(START_TIME_COL).equals(startTime.toString()); | |
531 | root.setExpanded(true); | |
532 | ||
533 | for (TreeItem item : root.getItems()) { | |
534 | /* Update children recursively */ | |
535 | valid = filterChildren(item) || valid; | |
536 | } | |
537 | ||
538 | if (!valid) { | |
539 | root.dispose(); | |
540 | } | |
541 | return valid; | |
542 | } | |
543 | ||
544 | // ------------------------------------------------------------------------ | |
545 | // Part For Button Action | |
546 | // ------------------------------------------------------------------------ | |
547 | ||
548 | ||
549 | ||
550 | private void fillToolBar() { | |
551 | Action fFilterAction = new FilterAction(); | |
552 | fFilterAction.setImageDescriptor(ImageDescriptor.createFromImage(FILTER_IMAGE)); | |
553 | fFilterAction.setToolTipText(Messages.FilterButton) ; | |
554 | fFilterAction.setChecked(false); | |
555 | ||
556 | IActionBars bars = getViewSite().getActionBars(); | |
557 | IToolBarManager manager = bars.getToolBarManager(); | |
558 | manager.add(fFilterAction); | |
559 | } | |
560 | ||
561 | private class FilterAction extends Action { | |
562 | @Override | |
563 | public void run() { | |
564 | filterStatus = !filterStatus; | |
565 | if (!filterStatus) { | |
566 | createTable(); | |
567 | } | |
568 | } | |
569 | } | |
7692e512 | 570 | } |