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