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