Commit | Line | Data |
---|---|---|
6e512b93 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 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: | |
dfaf8391 FC |
10 | * Yann N. Dauphin (dhaemon@gmail.com) - Implementation |
11 | * Francois Chouinard (fchouinard@gmail.com) - Initial API | |
6e512b93 ASL |
12 | *******************************************************************************/ |
13 | ||
14 | package org.eclipse.linuxtools.lttng.ui.views.statistics; | |
15 | ||
dfaf8391 FC |
16 | import java.text.DecimalFormat; |
17 | import java.util.Arrays; | |
18 | import java.util.HashSet; | |
19 | import java.util.Set; | |
20 | ||
21 | import org.eclipse.jface.viewers.ColumnLabelProvider; | |
22 | import org.eclipse.jface.viewers.ITreeContentProvider; | |
23 | import org.eclipse.jface.viewers.TreeViewer; | |
24 | import org.eclipse.jface.viewers.TreeViewerColumn; | |
25 | import org.eclipse.jface.viewers.Viewer; | |
26 | import org.eclipse.jface.viewers.ViewerComparator; | |
8827c197 FC |
27 | import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest; |
28 | import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver; | |
29 | import org.eclipse.linuxtools.lttng.ui.TraceDebug; | |
30 | import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer; | |
31 | import org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView; | |
32 | import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater; | |
dfaf8391 | 33 | import org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor.StatsTimeCountHandlerFactory; |
dfaf8391 | 34 | import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeNode; |
8827c197 FC |
35 | import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeRootFactory; |
36 | import org.eclipse.linuxtools.tmf.event.TmfEvent; | |
37 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; | |
38 | import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; | |
39 | import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal; | |
dfaf8391 | 40 | import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler; |
8827c197 FC |
41 | import org.eclipse.linuxtools.tmf.trace.ITmfTrace; |
42 | import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry; | |
dfaf8391 FC |
43 | import org.eclipse.swt.SWT; |
44 | import org.eclipse.swt.events.SelectionAdapter; | |
45 | import org.eclipse.swt.events.SelectionEvent; | |
46 | import org.eclipse.swt.graphics.Color; | |
8827c197 | 47 | import org.eclipse.swt.graphics.Cursor; |
dfaf8391 FC |
48 | import org.eclipse.swt.graphics.Image; |
49 | import org.eclipse.swt.layout.FillLayout; | |
6e512b93 | 50 | import org.eclipse.swt.widgets.Composite; |
8827c197 | 51 | import org.eclipse.swt.widgets.Display; |
dfaf8391 FC |
52 | import org.eclipse.swt.widgets.Event; |
53 | import org.eclipse.swt.widgets.Listener; | |
54 | import org.eclipse.ui.ISharedImages; | |
55 | import org.eclipse.ui.PlatformUI; | |
6e512b93 ASL |
56 | |
57 | /** | |
58 | * <b><u>StatisticsView</u></b> | |
59 | * <p> | |
dfaf8391 FC |
60 | * The Statistics View displays statistics for traces. |
61 | * | |
62 | * It is implemented according to the MVC pattern. - The model is a | |
63 | * StatisticsTreeNode built by the State Manager. - The view is built with a | |
64 | * TreeViewer. - The controller that keeps model and view synchronised is an | |
65 | * observer of the model. | |
6e512b93 | 66 | */ |
8827c197 | 67 | public class StatisticsView extends AbsTimeUpdateView { |
dfaf8391 | 68 | public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.statistics"; |
dfaf8391 FC |
69 | private TreeViewer treeViewer; |
70 | ||
71 | // Table column names | |
72 | private final String LEVEL_COLUMN = "Level"; | |
73 | private final String EVENTS_COUNT_COLUMN = "Number of Events"; | |
74 | private final String CPU_TIME_COLUMN = "CPU Time"; | |
75 | private final String CUMULATIVE_CPU_TIME_COLUMN = "Cumulative CPU Time"; | |
76 | private final String ELAPSED_TIME_COLUMN = "Elapsed Time"; | |
77 | ||
78 | // Table column tooltips | |
79 | private final String LEVEL_COLUMN_TIP = "Level at which statistics apply."; | |
80 | private final String EVENTS_COUNT_COLUMN_TIP = "Total amount of events that are tied to given resource."; | |
81 | private final String CPU_TIME_COLUMN_TIP = "Total amount of time the CPU was used excluding wait times(I/O, etc.) at that level."; | |
82 | private final String CUMULATIVE_CPU_TIME_COLUMN_TIP = "Total amount of time between the first and last event excluding wait times in a level."; | |
83 | private final String ELAPSED_TIME_COLUMN_TIP = "Total amount of time the CPU was used including wait times(I/O, etc.) at that level."; | |
6e512b93 | 84 | |
dfaf8391 FC |
85 | // Level for which statistics should not be displayed. |
86 | private Set<String> folderLevels = new HashSet<String>(Arrays | |
87 | .asList(new String[] { "Event Types", "Modes", "Submodes", "CPUs", | |
88 | "Processes", "Functions" })); | |
6e512b93 | 89 | |
dfaf8391 FC |
90 | // Levels for which sub-levels should not contain time-related statistics. |
91 | private Set<String> levelsWithEmptyTime = new HashSet<String>(Arrays | |
92 | .asList(new String[] { "Event Types" })); | |
93 | ||
94 | private DecimalFormat decimalFormat = new DecimalFormat("0.#########"); | |
8827c197 | 95 | private Cursor fwaitCursor = null; |
dfaf8391 FC |
96 | |
97 | // Used to draw bar charts in columns. | |
98 | private interface ColumnPercentageProvider { | |
99 | public double getPercentage(StatisticsTreeNode node); | |
100 | } | |
101 | ||
102 | /** | |
103 | * Contains all the information necessary to build a column of the table. | |
104 | */ | |
105 | private class ColumnData { | |
106 | // Name of the column. | |
107 | public final String header; | |
108 | // Width of the column. | |
109 | public final int width; | |
110 | // Alignment of the column. | |
111 | public final int alignment; | |
112 | // Tooltip of the column. | |
113 | public final String tooltip; | |
114 | // Adapts a StatisticsTreeNode into the content of it's corresponding | |
115 | // cell for that column. | |
116 | public final ColumnLabelProvider labelProvider; | |
117 | // Used to sort elements of this column. Can be null. | |
118 | public final ViewerComparator comparator; | |
119 | // Used to draw bar charts in this column. Can be null. | |
120 | public final ColumnPercentageProvider percentageProvider; | |
121 | ||
122 | public ColumnData(String h, int w, int a, String t, | |
123 | ColumnLabelProvider l, ViewerComparator c, | |
124 | ColumnPercentageProvider p) { | |
125 | header = h; | |
126 | width = w; | |
127 | alignment = a; | |
128 | tooltip = t; | |
129 | labelProvider = l; | |
130 | comparator = c; | |
131 | percentageProvider = p; | |
132 | } | |
133 | }; | |
134 | ||
135 | // List that will be used to create the table. | |
136 | private ColumnData[] columnDataList = new ColumnData[] { | |
137 | new ColumnData(LEVEL_COLUMN, 200, SWT.LEFT, LEVEL_COLUMN_TIP, | |
138 | new ColumnLabelProvider() { | |
139 | @Override | |
140 | public String getText(Object element) { | |
141 | return ((StatisticsTreeNode) element).getKey(); | |
142 | } | |
143 | ||
144 | @Override | |
145 | public Image getImage(Object element) { | |
146 | StatisticsTreeNode node = (StatisticsTreeNode) element; | |
147 | if (folderLevels.contains(node.getKey())) { | |
148 | return PlatformUI.getWorkbench() | |
149 | .getSharedImages().getImage( | |
150 | ISharedImages.IMG_OBJ_FOLDER); | |
151 | } else { | |
152 | return PlatformUI.getWorkbench() | |
153 | .getSharedImages().getImage( | |
154 | ISharedImages.IMG_OBJ_ELEMENT); | |
155 | } | |
156 | } | |
157 | }, new ViewerComparator() { | |
158 | @Override | |
159 | public int compare(Viewer viewer, Object e1, Object e2) { | |
160 | StatisticsTreeNode n1 = (StatisticsTreeNode) e1; | |
161 | StatisticsTreeNode n2 = (StatisticsTreeNode) e2; | |
162 | ||
163 | return n1.getKey().compareTo(n2.getKey()); | |
164 | } | |
165 | }, null), | |
166 | new ColumnData(EVENTS_COUNT_COLUMN, 125, SWT.LEFT, | |
167 | EVENTS_COUNT_COLUMN_TIP, new ColumnLabelProvider() { | |
168 | @Override | |
169 | public String getText(Object element) { | |
170 | StatisticsTreeNode node = (StatisticsTreeNode) element; | |
171 | if (!folderLevels.contains(node.getKey())) { | |
172 | return Long.toString(node.getValue().nbEvents); | |
173 | } else { | |
174 | return ""; | |
175 | } | |
176 | } | |
177 | }, new ViewerComparator() { | |
178 | @Override | |
179 | public int compare(Viewer viewer, Object e1, Object e2) { | |
180 | StatisticsTreeNode n1 = (StatisticsTreeNode) e1; | |
181 | StatisticsTreeNode n2 = (StatisticsTreeNode) e2; | |
182 | ||
183 | return (int) (n1.getValue().nbEvents - n2 | |
184 | .getValue().nbEvents); | |
185 | } | |
186 | }, new ColumnPercentageProvider() { | |
187 | public double getPercentage(StatisticsTreeNode node) { | |
188 | StatisticsTreeNode parent = node; | |
189 | do { | |
190 | parent = parent.getParent(); | |
191 | } while (parent != null | |
192 | && parent.getValue().nbEvents == 0); | |
193 | ||
194 | if (parent == null) { | |
195 | return 0; | |
196 | } else { | |
197 | return (double) node.getValue().nbEvents | |
198 | / parent.getValue().nbEvents; | |
199 | } | |
200 | } | |
201 | }), | |
202 | new ColumnData(CPU_TIME_COLUMN, 125, SWT.LEFT, CPU_TIME_COLUMN_TIP, | |
203 | new ColumnLabelProvider() { | |
204 | @Override | |
205 | public String getText(Object element) { | |
206 | StatisticsTreeNode node = (StatisticsTreeNode) element; | |
207 | ||
208 | if (folderLevels.contains(node.getKey())) { | |
209 | return ""; | |
210 | } else if (node.getParent() != null | |
211 | && levelsWithEmptyTime.contains(node | |
212 | .getParent().getKey())) { | |
213 | return ""; | |
214 | } else { | |
215 | return decimalFormat | |
216 | .format(node.getValue().cpuTime | |
217 | / Math.pow(10, 9)); | |
218 | } | |
219 | } | |
220 | }, null, null), | |
221 | new ColumnData(CUMULATIVE_CPU_TIME_COLUMN, 155, SWT.LEFT, | |
222 | CUMULATIVE_CPU_TIME_COLUMN_TIP, new ColumnLabelProvider() { | |
223 | @Override | |
224 | public String getText(Object element) { | |
225 | StatisticsTreeNode node = (StatisticsTreeNode) element; | |
226 | if (folderLevels.contains(node.getKey())) { | |
227 | return ""; | |
228 | } else if (node.getParent() != null | |
229 | && levelsWithEmptyTime.contains(node | |
230 | .getParent().getKey())) { | |
231 | return ""; | |
232 | } else { | |
233 | return decimalFormat | |
234 | .format(node.getValue().cumulativeCpuTime | |
235 | / Math.pow(10, 9)); | |
236 | } | |
237 | } | |
238 | }, null, null), | |
239 | new ColumnData(ELAPSED_TIME_COLUMN, 100, SWT.LEFT, | |
240 | ELAPSED_TIME_COLUMN_TIP, new ColumnLabelProvider() { | |
241 | @Override | |
242 | public String getText(Object element) { | |
243 | StatisticsTreeNode node = (StatisticsTreeNode) element; | |
244 | if (folderLevels.contains(node.getKey())) { | |
245 | return ""; | |
246 | } else if (node.getParent() != null | |
247 | && levelsWithEmptyTime.contains(node | |
248 | .getParent().getKey())) { | |
249 | return ""; | |
250 | } else { | |
251 | return decimalFormat | |
252 | .format(node.getValue().elapsedTime | |
253 | / Math.pow(10, 9)); | |
254 | } | |
255 | } | |
256 | }, null, null) }; | |
257 | ||
258 | /** | |
259 | * Adapter TreeViewers can use to interact with StatisticsTreeNode objects. | |
6e512b93 | 260 | * |
dfaf8391 | 261 | * @see org.eclipse.jface.viewers.ITreeContentProvider |
6e512b93 | 262 | */ |
dfaf8391 FC |
263 | class TreeContentProvider implements ITreeContentProvider { |
264 | /* | |
265 | * (non-Javadoc) | |
266 | * | |
267 | * @see | |
268 | * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang | |
269 | * .Object) | |
270 | */ | |
271 | public Object[] getChildren(Object parentElement) { | |
272 | return ((StatisticsTreeNode) parentElement).getChildren().toArray(); | |
273 | } | |
274 | ||
275 | /* | |
276 | * (non-Javadoc) | |
277 | * | |
278 | * @see | |
279 | * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang | |
280 | * .Object) | |
281 | */ | |
282 | public Object getParent(Object element) { | |
283 | return ((StatisticsTreeNode) element).getParent(); | |
284 | } | |
285 | ||
286 | /* | |
287 | * (non-Javadoc) | |
288 | * | |
289 | * @see | |
290 | * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang | |
291 | * .Object) | |
292 | */ | |
293 | public boolean hasChildren(Object element) { | |
294 | return ((StatisticsTreeNode) element).hasChildren(); | |
295 | } | |
296 | ||
297 | /* | |
298 | * (non-Javadoc) | |
299 | * | |
300 | * @see | |
301 | * org.eclipse.jface.viewers.IStructuredContentProvider#getElements( | |
302 | * java.lang.Object) | |
303 | */ | |
304 | public Object[] getElements(Object inputElement) { | |
305 | return getChildren(inputElement); | |
306 | } | |
307 | ||
308 | /* | |
309 | * (non-Javadoc) | |
310 | * | |
311 | * @see org.eclipse.jface.viewers.IContentProvider#dispose() | |
312 | */ | |
313 | public void dispose() { | |
314 | } | |
315 | ||
316 | /* | |
317 | * (non-Javadoc) | |
318 | * | |
319 | * @see | |
320 | * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse | |
321 | * .jface.viewers.Viewer, java.lang.Object, java.lang.Object) | |
322 | */ | |
323 | // @Override | |
324 | public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { | |
325 | } | |
6e512b93 ASL |
326 | } |
327 | ||
fc6ccf6f | 328 | public StatisticsView(String viewName) { |
951d134a FC |
329 | super(viewName); |
330 | } | |
331 | ||
332 | public StatisticsView() { | |
333 | this("StatisticsView"); | |
fc6ccf6f FC |
334 | } |
335 | ||
dfaf8391 FC |
336 | /* |
337 | * (non-Javadoc) | |
338 | * | |
339 | * @see | |
340 | * org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets | |
341 | * .Composite) | |
6e512b93 ASL |
342 | */ |
343 | @Override | |
344 | public void createPartControl(Composite parent) { | |
dfaf8391 FC |
345 | parent.setLayout(new FillLayout()); |
346 | ||
347 | treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | |
348 | | SWT.V_SCROLL); | |
349 | treeViewer.setContentProvider(new TreeContentProvider()); | |
350 | treeViewer.getTree().setHeaderVisible(true); | |
351 | treeViewer.setUseHashlookup(true); | |
352 | ||
353 | for (final ColumnData columnData : columnDataList) { | |
354 | final TreeViewerColumn treeColumn = new TreeViewerColumn( | |
355 | treeViewer, columnData.alignment); | |
356 | treeColumn.getColumn().setText(columnData.header); | |
357 | treeColumn.getColumn().setWidth(columnData.width); | |
358 | treeColumn.getColumn().setToolTipText(columnData.tooltip); | |
359 | if (columnData.comparator != null) { | |
360 | treeColumn.getColumn().addSelectionListener( | |
361 | new SelectionAdapter() { | |
362 | @Override | |
363 | public void widgetSelected(SelectionEvent e) { | |
364 | if (treeViewer.getTree().getSortDirection() == SWT.UP | |
365 | || treeViewer.getTree().getSortColumn() != treeColumn | |
366 | .getColumn()) { | |
367 | treeViewer | |
368 | .setComparator(columnData.comparator); | |
369 | treeViewer.getTree().setSortDirection( | |
370 | SWT.DOWN); | |
371 | } else { | |
372 | treeViewer | |
373 | .setComparator(new ViewerComparator() { | |
374 | @Override | |
375 | public int compare( | |
376 | Viewer viewer, | |
377 | Object e1, Object e2) { | |
378 | return -1 | |
379 | * columnData.comparator | |
380 | .compare( | |
381 | viewer, | |
382 | e1, | |
383 | e2); | |
384 | } | |
385 | }); | |
386 | treeViewer.getTree().setSortDirection( | |
387 | SWT.UP); | |
388 | } | |
389 | treeViewer.getTree().setSortColumn( | |
390 | treeColumn.getColumn()); | |
391 | } | |
392 | }); | |
393 | } | |
394 | treeColumn.setLabelProvider(columnData.labelProvider); | |
395 | } | |
396 | ||
397 | // Handler that will draw the bar charts. | |
398 | treeViewer.getTree().addListener(SWT.EraseItem, new Listener() { | |
399 | // @Override | |
400 | public void handleEvent(Event event) { | |
401 | if (columnDataList[event.index].percentageProvider != null) { | |
402 | StatisticsTreeNode node = (StatisticsTreeNode) event.item | |
403 | .getData(); | |
404 | ||
405 | double percentage = columnDataList[event.index].percentageProvider | |
406 | .getPercentage(node); | |
407 | if (percentage == 0) { | |
408 | return; | |
409 | } | |
410 | ||
411 | if ((event.detail & SWT.SELECTED) > 0) { | |
412 | Color oldForeground = event.gc.getForeground(); | |
413 | event.gc.setForeground(event.item.getDisplay() | |
414 | .getSystemColor(SWT.COLOR_LIST_SELECTION)); | |
415 | event.gc.fillRectangle(event.x, event.y, event.width, | |
416 | event.height); | |
417 | event.gc.setForeground(oldForeground); | |
418 | event.detail &= ~SWT.SELECTED; | |
419 | } | |
420 | ||
421 | int barWidth = (int) ((treeViewer.getTree().getColumn(1) | |
422 | .getWidth() - 8) * percentage); | |
423 | int oldAlpha = event.gc.getAlpha(); | |
424 | Color oldForeground = event.gc.getForeground(); | |
425 | Color oldBackground = event.gc.getBackground(); | |
426 | event.gc.setAlpha(64); | |
427 | event.gc.setForeground(event.item.getDisplay() | |
428 | .getSystemColor(SWT.COLOR_BLUE)); | |
429 | event.gc.setBackground(event.item.getDisplay() | |
430 | .getSystemColor(SWT.COLOR_LIST_BACKGROUND)); | |
431 | event.gc.fillGradientRectangle(event.x, event.y, barWidth, | |
432 | event.height, true); | |
433 | event.gc.drawRectangle(event.x, event.y, barWidth, | |
434 | event.height); | |
435 | event.gc.setForeground(oldForeground); | |
436 | event.gc.setBackground(oldBackground); | |
437 | event.gc.setAlpha(oldAlpha); | |
438 | event.detail &= ~SWT.BACKGROUND; | |
439 | } | |
440 | } | |
441 | }); | |
442 | ||
443 | treeViewer.setComparator(columnDataList[0].comparator); | |
444 | treeViewer.getTree().setSortColumn(treeViewer.getTree().getColumn(0)); | |
445 | treeViewer.getTree().setSortDirection(SWT.DOWN); | |
446 | ||
dfaf8391 | 447 | // Read current data if any available |
8827c197 FC |
448 | TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment(); |
449 | if (experiment != null) { | |
450 | requestData(experiment); | |
451 | } else { | |
452 | TraceDebug.debug("No selected experiment information available"); | |
453 | } | |
dfaf8391 | 454 | } |
8827c197 | 455 | |
dfaf8391 FC |
456 | @Override |
457 | public void dispose() { | |
458 | super.dispose(); | |
8827c197 FC |
459 | if (fwaitCursor != null) { |
460 | fwaitCursor.dispose(); | |
461 | } | |
6e512b93 | 462 | |
8827c197 FC |
463 | // clean the model |
464 | StatisticsTreeRootFactory.removeAll(); | |
6e512b93 ASL |
465 | } |
466 | ||
dfaf8391 FC |
467 | /* |
468 | * (non-Javadoc) | |
469 | * | |
6e512b93 ASL |
470 | * @see org.eclipse.ui.part.WorkbenchPart#setFocus() |
471 | */ | |
472 | @Override | |
473 | public void setFocus() { | |
dfaf8391 FC |
474 | treeViewer.getTree().setFocus(); |
475 | } | |
476 | ||
6e512b93 | 477 | |
8827c197 FC |
478 | /** |
479 | * @return | |
480 | */ | |
550d787e | 481 | @Override |
8827c197 FC |
482 | public AbsEventToHandlerResolver getEventProcessor() { |
483 | return StatsTimeCountHandlerFactory.getInstance(); | |
6e512b93 ASL |
484 | } |
485 | ||
8827c197 FC |
486 | /* |
487 | * (non-Javadoc) | |
488 | * | |
489 | * @see | |
490 | * org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#waitCursor | |
491 | * (boolean) | |
492 | */ | |
550d787e | 493 | @Override |
8827c197 FC |
494 | protected void waitCursor(final boolean waitInd) { |
495 | if (treeViewer == null) { | |
496 | return; | |
497 | } | |
498 | ||
499 | Display display = treeViewer.getControl().getDisplay(); | |
500 | if (fwaitCursor == null) { | |
501 | fwaitCursor = new Cursor(display, SWT.CURSOR_WAIT); | |
502 | } | |
503 | ||
504 | // Perform the updates on the UI thread | |
505 | display.asyncExec(new Runnable() { | |
506 | public void run() { | |
507 | Cursor cursor = null; /* indicates default */ | |
508 | if (waitInd) { | |
509 | cursor = fwaitCursor; | |
510 | } | |
511 | treeViewer.getControl().setCursor(cursor); | |
512 | } | |
513 | }); | |
514 | } | |
515 | ||
516 | @Override | |
517 | public void ModelUpdatePrep(TmfTimeRange timeRange, boolean clearAllData) { | |
518 | Object input = treeViewer.getInput(); | |
519 | if (input != null && input instanceof StatisticsTreeNode) { | |
520 | ((StatisticsTreeNode) input).reset(); | |
521 | treeViewer.getTree().getDisplay().asyncExec(new Runnable() { | |
522 | // @Override | |
523 | public void run() { | |
524 | treeViewer.refresh(); | |
525 | } | |
526 | }); | |
527 | } | |
528 | } | |
529 | ||
530 | @Override | |
531 | public void modelInputChanged(ILttngSyntEventRequest request, boolean complete) { | |
dfaf8391 FC |
532 | treeViewer.getTree().getDisplay().asyncExec(new Runnable() { |
533 | // @Override | |
534 | public void run() { | |
535 | treeViewer.refresh(); | |
536 | } | |
537 | }); | |
538 | } | |
8827c197 FC |
539 | |
540 | /* | |
541 | * (non-Javadoc) | |
542 | * | |
543 | * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView# | |
544 | * modelIncomplete | |
545 | * (org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest) | |
546 | */ | |
547 | @Override | |
548 | public void modelIncomplete(ILttngSyntEventRequest request) { | |
549 | Object input = treeViewer.getInput(); | |
550 | if (input != null && input instanceof StatisticsTreeNode) { | |
551 | // The data from this experiment is invalid and shall be removed to | |
552 | // refresh upon next selection | |
553 | String name = ((StatisticsTreeNode) input).getKey(); | |
554 | StatisticsTreeRootFactory.removeStatTreeRoot(name); | |
555 | } | |
556 | } | |
557 | ||
558 | /** | |
559 | * @param signal | |
560 | */ | |
561 | @TmfSignalHandler | |
562 | public void experimentSelected(TmfExperimentSelectedSignal<? extends TmfEvent> signal) { | |
563 | if (signal != null) { | |
564 | TmfExperiment<?> experiment = signal.getExperiment(); | |
565 | String experimentName = experiment.getName(); | |
566 | ||
567 | if (StatisticsTreeRootFactory.containsTreeRoot(experimentName)) { | |
568 | // The experiment root is already present | |
569 | StatisticsTreeNode experimentTreeNode = StatisticsTreeRootFactory.getStatTreeRoot(experimentName); | |
570 | ||
571 | ITmfTrace[] traces = experiment.getTraces(); | |
572 | ||
573 | // check if there is partial data loaded in the experiment | |
574 | int numTraces = experiment.getTraces().length; | |
575 | int numNodeTraces = experimentTreeNode.getNbChildren(); | |
576 | ||
577 | if (numTraces == numNodeTraces) { | |
578 | boolean same = true; | |
579 | // Detect if the experiment contains the same traces as when | |
580 | // previously selected | |
581 | for (int i = 0; i < numTraces; i++) { | |
582 | String traceName = traces[i].getName(); | |
583 | if (!experimentTreeNode.containsChild(traceName)) { | |
584 | same = false; | |
585 | break; | |
586 | } | |
587 | } | |
588 | ||
589 | if (same) { | |
590 | // no need to reload data, all traces are already loaded | |
591 | treeViewer.setInput(experimentTreeNode); | |
592 | return; | |
593 | } | |
594 | } | |
595 | } | |
596 | ||
597 | // if the data is not available or has changed, reload it | |
598 | requestData(experiment); | |
599 | } | |
600 | } | |
601 | ||
602 | /** | |
603 | * @param experiment | |
604 | */ | |
605 | private void requestData(TmfExperiment<?> experiment) { | |
606 | if (experiment != null) { | |
607 | StatisticsTreeNode treeModelRoot = StatisticsTreeRootFactory.getStatTreeRoot(experiment.getName()); | |
608 | ||
609 | // if the model has contents, clear to start over | |
610 | if (treeModelRoot.hasChildren()) { | |
611 | treeModelRoot.reset(); | |
612 | } | |
613 | ||
614 | // set input to a clean data model | |
615 | treeViewer.setInput(treeModelRoot); | |
616 | TmfTimeRange experimentTRange = experiment.getTimeRange(); | |
617 | ||
618 | // send the initial request, to start filling up model | |
619 | dataRequest(experimentTRange, experimentTRange, true); | |
620 | } else { | |
621 | TraceDebug.debug("No selected experiment information available"); | |
622 | } | |
623 | } | |
624 | ||
625 | /* | |
626 | * (non-Javadoc) | |
627 | * | |
628 | * @see | |
629 | * org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#displayModel | |
630 | * (org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model. | |
631 | * ITmfTimeAnalysisEntry[], long, long, boolean, long, long, | |
632 | * java.lang.Object) | |
633 | */ | |
634 | @Override | |
635 | protected void displayModel(ITmfTimeAnalysisEntry[] items, long startBoundTime, long endBoundTime, | |
636 | boolean updateTimeBounds, long startVisibleWindow, long endVisibleWindow, Object source) { | |
637 | // No applicable to statistics view | |
638 | } | |
639 | ||
640 | /* | |
641 | * (non-Javadoc) | |
642 | * | |
643 | * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView# | |
644 | * getParamsUpdater() | |
645 | */ | |
646 | @Override | |
647 | protected ParamsUpdater getParamsUpdater() { | |
648 | // Not applicable to statistics view | |
649 | return null; | |
650 | } | |
651 | ||
652 | @Override | |
653 | protected ItemContainer<?> getItemContainer() { | |
654 | // Not applicable to statistics view | |
655 | return null; | |
656 | } | |
6e512b93 | 657 | } |