tmf: extract UpdateJob class and introduce TmfPieChartViewer
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / viewers / statistics / TmfStatisticsViewer.java
CommitLineData
cfd22ad0 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2012, 2015 Ericsson
cfd22ad0
MD
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 * Mathieu Denis <mathieu.denis@polymtl.ca> - Initial API and implementation
89c06060 11 * Alexandre Montplaisir - Port to ITmfStatistics provider
0fcf3b09 12 * Patrick Tasse - Support selection range
12d85f6c 13 * Bernd Hufmann - Fix range selection updates
cfd22ad0
MD
14 *******************************************************************************/
15
2bdf0193 16package org.eclipse.tracecompass.tmf.ui.viewers.statistics;
cfd22ad0 17
1d83ed07
AM
18import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
19
c14c0757 20import java.util.Collection;
de83d1ab 21import java.util.HashMap;
cfd22ad0 22import java.util.List;
89c06060 23import java.util.Map;
cfd22ad0 24
de83d1ab 25import org.eclipse.core.runtime.jobs.Job;
cfd22ad0
MD
26import org.eclipse.jface.viewers.TreeViewer;
27import org.eclipse.jface.viewers.TreeViewerColumn;
28import org.eclipse.jface.viewers.Viewer;
29import org.eclipse.jface.viewers.ViewerComparator;
cfd22ad0 30import org.eclipse.swt.SWT;
cdf994ef 31import org.eclipse.swt.custom.SashForm;
cfd22ad0
MD
32import org.eclipse.swt.events.SelectionAdapter;
33import org.eclipse.swt.events.SelectionEvent;
34import org.eclipse.swt.graphics.Color;
35import org.eclipse.swt.graphics.Cursor;
cfd22ad0
MD
36import org.eclipse.swt.widgets.Composite;
37import org.eclipse.swt.widgets.Control;
38import org.eclipse.swt.widgets.Display;
39import org.eclipse.swt.widgets.Event;
40import org.eclipse.swt.widgets.Listener;
2bdf0193
AM
41import org.eclipse.tracecompass.tmf.core.component.TmfComponent;
42import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
97c71024 43import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
cdf994ef 44import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
2bdf0193 45import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
2bdf0193
AM
46import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule;
47import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
48import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
49import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
21852dfa 50import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
2bdf0193 51import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
b8585c7c 52import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
5c5fa260 53import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
2bdf0193 54import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer;
cdf994ef
ACL
55import org.eclipse.tracecompass.tmf.ui.viewers.piecharts.TmfPieChartViewer;
56import org.eclipse.tracecompass.tmf.ui.viewers.piecharts.model.TmfPieChartStatisticsModel;
2bdf0193
AM
57import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnData;
58import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider;
59import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsFormatter;
60import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTree;
61import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager;
62import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode;
63import org.eclipse.tracecompass.tmf.ui.viewers.statistics.model.TmfTreeContentProvider;
cfd22ad0
MD
64
65/**
66 * A basic viewer to display statistics in the statistics view.
67 *
8b60cb37
MD
68 * It is linked to a single ITmfTrace until its disposal.
69 *
cfd22ad0 70 * @author Mathieu Denis
cfd22ad0 71 */
05627bda 72public class TmfStatisticsViewer extends TmfViewer {
cfd22ad0 73
87f83123
AM
74 /** The actual tree viewer to display */
75 private TreeViewer fTreeViewer;
05627bda 76
87f83123
AM
77 /** Update range synchronization object */
78 private final Object fStatisticsRangeUpdateSyncObj = new Object();
73fbf6be 79
cdf994ef
ACL
80 /** The statistics tree linked to this viewer */
81 private TmfStatisticsTree fStatisticsData;
82
87f83123
AM
83 /** The trace that is displayed by this viewer */
84 private ITmfTrace fTrace;
89c06060 85
87f83123 86 /** Indicates to process all events */
05627bda
MD
87 private boolean fProcessAll;
88
87f83123 89 /** View instance counter (for multiple statistics views) */
cfd22ad0
MD
90 private static int fCountInstance = 0;
91
87f83123 92 /** Number of this instance. Used as an instance ID. */
cfd22ad0
MD
93 private int fInstanceNb;
94
87f83123 95 /** Object to store the cursor while waiting for the trace to load */
cfd22ad0
MD
96 private Cursor fWaitCursor = null;
97
98 /**
05627bda
MD
99 * Counts the number of times waitCursor() has been called. It avoids
100 * removing the waiting cursor, since there may be multiple requests running
101 * at the same time.
102 */
103 private int fWaitCursorCount = 0;
104
87f83123 105 /** Tells to send a time range request when the trace gets updated. */
05627bda
MD
106 private boolean fSendRangeRequest = true;
107
de83d1ab
MAL
108 private final Map<ITmfTrace, Job> fUpdateJobsPartial = new HashMap<>();
109 private final Map<ITmfTrace, Job> fUpdateJobsGlobal = new HashMap<>();
110
cdf994ef
ACL
111 private TmfPieChartViewer fPieChartViewer;
112
113 private SashForm fSash;
de83d1ab 114
cdf994ef 115 private TmfPieChartStatisticsModel fPieChartModel;
de83d1ab 116
05627bda
MD
117 /**
118 * Create a basic statistics viewer. To be used in conjunction with
119 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
120 *
121 * @param parent
122 * The parent composite that will hold the viewer
123 * @param viewerName
124 * The name that will be assigned to this viewer
125 * @param trace
126 * The trace that is displayed by this viewer
127 * @see TmfComponent
128 */
129 public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) {
130 init(parent, viewerName, trace);
131 }
132
133 /**
134 * Initialize the statistics viewer.
cfd22ad0
MD
135 *
136 * @param parent
05627bda
MD
137 * The parent component of the viewer.
138 * @param viewerName
139 * The name to give to the viewer.
140 * @param trace
141 * The trace that will be displayed by the viewer.
cfd22ad0 142 */
05627bda
MD
143 public void init(Composite parent, String viewerName, ITmfTrace trace) {
144 super.init(parent, viewerName);
cfd22ad0
MD
145 // Increment a counter to make sure the tree ID is unique.
146 fCountInstance++;
147 fInstanceNb = fCountInstance;
05627bda
MD
148 fTrace = trace;
149
faa38350 150 // The viewer will process all events if he is assigned to an experiment
05627bda
MD
151 fProcessAll = (trace instanceof TmfExperiment);
152
153 initContent(parent);
8b60cb37 154 initInput();
05627bda
MD
155 }
156
05627bda
MD
157 @Override
158 public void dispose() {
159 super.dispose();
160 if (fWaitCursor != null) {
161 fWaitCursor.dispose();
162 }
8b60cb37 163
de83d1ab
MAL
164 for (Job j : fUpdateJobsGlobal.values()) {
165 j.cancel();
166 }
167
168 for (Job j : fUpdateJobsPartial.values()) {
169 j.cancel();
170 }
171
66792052 172 // Clean the model for this viewer
36033ff0 173 TmfStatisticsTreeManager.removeStatTreeRoot(getTreeID());
cdf994ef 174 fPieChartViewer.reinitializeCharts();
05627bda
MD
175 }
176
1c0de632
AM
177 // ------------------------------------------------------------------------
178 // Signal handlers
179 // ------------------------------------------------------------------------
89c06060 180
05627bda 181 /**
faa38350 182 * Handles the signal about new trace range.
05627bda
MD
183 *
184 * @param signal
faa38350 185 * The trace range updated signal
05627bda
MD
186 */
187 @TmfSignalHandler
faa38350
PT
188 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
189 ITmfTrace trace = signal.getTrace();
05627bda 190 // validate
faa38350 191 if (!isListeningTo(trace)) {
05627bda
MD
192 return;
193 }
194
3c934968
MD
195 synchronized (fStatisticsRangeUpdateSyncObj) {
196 // Sends the time range request only once from this method.
197 if (fSendRangeRequest) {
198 fSendRangeRequest = false;
21852dfa
AM
199
200 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
201 TmfTimeRange timeRange = ctx.getSelectionRange();
0fcf3b09 202 requestTimeRangeData(trace, timeRange);
3c934968 203 }
05627bda 204 }
faa38350 205 requestData(trace, signal.getRange());
05627bda
MD
206 }
207
0fcf3b09
PT
208 /**
209 * Handles the time synch updated signal. It updates the time range
210 * statistics.
211 *
212 * @param signal
213 * Contains the information about the new selected time range.
97c71024 214 * @since 1.0
0fcf3b09
PT
215 */
216 @TmfSignalHandler
97c71024 217 public void timeSynchUpdated(TmfSelectionRangeUpdatedSignal signal) {
faa38350
PT
218 if (fTrace == null) {
219 return;
220 }
0fcf3b09
PT
221 ITmfTimestamp begin = signal.getBeginTime();
222 ITmfTimestamp end = signal.getEndTime();
223 TmfTimeRange timeRange = new TmfTimeRange(begin, end);
224 requestTimeRangeData(fTrace, timeRange);
05627bda
MD
225 }
226
1c0de632
AM
227 // ------------------------------------------------------------------------
228 // Class methods
229 // ------------------------------------------------------------------------
230
05627bda
MD
231 /*
232 * Returns the primary control associated with this viewer.
233 *
234 * @return the SWT control which displays this viewer's content
235 */
236 @Override
237 public Control getControl() {
cdf994ef 238 return fSash;
05627bda
MD
239 }
240
241 /**
242 * Get the input of the viewer.
243 *
244 * @return an object representing the input of the statistics viewer.
245 */
246 public Object getInput() {
247 return fTreeViewer.getInput();
248 }
249
05627bda
MD
250 /**
251 * This method can be overridden to implement another way of representing
252 * the statistics data and to retrieve the information for display.
253 *
254 * @return a TmfStatisticsData object.
255 */
36033ff0 256 public TmfStatisticsTree getStatisticData() {
05627bda 257 if (fStatisticsData == null) {
36033ff0 258 fStatisticsData = new TmfStatisticsTree();
05627bda
MD
259 }
260 return fStatisticsData;
261 }
262
cdf994ef
ACL
263 /**
264 * @return the model of the piecharts in this viewer
265 * @since 2.0
266 */
267 public TmfPieChartStatisticsModel getPieChartModel(){
268 if (fPieChartModel == null) {
269 fPieChartModel = new TmfPieChartStatisticsModel();
270 }
271 return fPieChartModel;
272 }
273
05627bda
MD
274 /**
275 * Returns a unique ID based on name to be associated with the statistics
276 * tree for this viewer. For a same name, it will always return the same ID.
277 *
278 * @return a unique statistics tree ID.
279 */
280 public String getTreeID() {
281 return getName() + fInstanceNb;
282 }
283
284 @Override
285 public void refresh() {
286 final Control viewerControl = getControl();
287 // Ignore update if disposed
288 if (viewerControl.isDisposed()) {
289 return;
290 }
cdf994ef
ACL
291 refreshTree();
292 refreshPieCharts(true, true);
293 }
294
295 /**
296 * Only refreshes the Tree viewer
297 */
298 private void refreshTree(){
299 final Control viewerControl = getControl();
300 // Ignore update if disposed
301 if (viewerControl.isDisposed()) {
302 return;
303 }
05627bda 304
cdf994ef 305 Display.getDefault().asyncExec(new Runnable() {
05627bda
MD
306 @Override
307 public void run() {
308 if (!viewerControl.isDisposed()) {
309 fTreeViewer.refresh();
310 }
311 }
312 });
313 }
314
cdf994ef
ACL
315 /**
316 * Only refreshes the piecharts depending on the parameters
317 * @param refreshGlobal if we have to refresh the global piechart
318 * @param refreshSelection if we have to refresh the selection piechart
319 * @since 2.0
320 */
321 protected void refreshPieCharts(final boolean refreshGlobal, final boolean refreshSelection) {
322 final Control viewerControl = getControl();
323 // Ignore update if disposed
324 if (viewerControl.isDisposed()) {
325 return;
326 }
327
328 Display.getDefault().asyncExec(new Runnable() {
329 @Override
330 public void run() {
331 if (!viewerControl.isDisposed()) {
332 fPieChartViewer.refresh(refreshGlobal, refreshSelection);
333 }
334 }
335 });
336 }
337
3c934968
MD
338 /**
339 * Will force a request on the partial event count if one is needed.
340 */
341 public void sendPartialRequestOnNextUpdate() {
342 synchronized (fStatisticsRangeUpdateSyncObj) {
343 fSendRangeRequest = true;
344 }
345 }
346
05627bda
MD
347 /**
348 * Focus on the statistics tree of the viewer
349 */
350 public void setFocus() {
351 fTreeViewer.getTree().setFocus();
352 }
353
05627bda
MD
354 /**
355 * Cancels the request if it is not already completed
356 *
357 * @param request
358 * The request to be canceled
359 */
fd3f1eff 360 protected void cancelOngoingRequest(ITmfEventRequest request) {
05627bda
MD
361 if (request != null && !request.isCompleted()) {
362 request.cancel();
363 }
364 }
365
366 /**
367 * This method can be overridden to change the representation of the data in
368 * the columns.
369 *
b3a26928 370 * @return An object of type {@link TmfBaseColumnDataProvider}.
05627bda 371 */
b3a26928 372 protected TmfBaseColumnDataProvider getColumnDataProvider() {
05627bda
MD
373 return new TmfBaseColumnDataProvider();
374 }
cfd22ad0 375
05627bda
MD
376 /**
377 * Initialize the content that will be drawn in this viewer
378 *
379 * @param parent
380 * The parent of the control to create
381 */
382 protected void initContent(Composite parent) {
cdf994ef 383
cfd22ad0 384 final List<TmfBaseColumnData> columnDataList = getColumnDataProvider().getColumnData();
cfd22ad0 385
cdf994ef
ACL
386 fSash = new SashForm(parent, SWT.HORIZONTAL );
387
388 fTreeViewer = new TreeViewer(fSash, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
389 fPieChartViewer = new TmfPieChartViewer(fSash);
390 fSash.setWeights(new int[]{100,100});
391
cfd22ad0
MD
392 fTreeViewer.setContentProvider(new TmfTreeContentProvider());
393 fTreeViewer.getTree().setHeaderVisible(true);
394 fTreeViewer.setUseHashlookup(true);
395
396 // Creates the columns defined by the column data provider
397 for (final TmfBaseColumnData columnData : columnDataList) {
398 final TreeViewerColumn treeColumn = new TreeViewerColumn(fTreeViewer, columnData.getAlignment());
399 treeColumn.getColumn().setText(columnData.getHeader());
400 treeColumn.getColumn().setWidth(columnData.getWidth());
401 treeColumn.getColumn().setToolTipText(columnData.getTooltip());
402
df2b3dbb
VP
403 // If is dummy column
404 if (columnData == columnDataList.get(TmfBaseColumnDataProvider.StatsColumn.DUMMY.getIndex())) {
405 treeColumn.getColumn().setResizable(false);
406 }
407
408 // A comparator is defined.
409 if (columnData.getComparator() != null) {
cfd22ad0
MD
410 // Adds a listener on the columns header for sorting purpose.
411 treeColumn.getColumn().addSelectionListener(new SelectionAdapter() {
412
413 private ViewerComparator reverseComparator;
414
415 @Override
416 public void widgetSelected(SelectionEvent e) {
417 // Initializes the reverse comparator once.
418 if (reverseComparator == null) {
419 reverseComparator = new ViewerComparator() {
420 @Override
421 public int compare(Viewer viewer, Object e1, Object e2) {
422 return -1 * columnData.getComparator().compare(viewer, e1, e2);
423 }
424 };
425 }
426
427 if (fTreeViewer.getTree().getSortDirection() == SWT.UP
428 || fTreeViewer.getTree().getSortColumn() != treeColumn.getColumn()) {
429 /*
df2b3dbb
VP
430 * Puts the descendant order if the old order was up
431 * or if the selected column has changed.
cfd22ad0
MD
432 */
433 fTreeViewer.setComparator(columnData.getComparator());
434 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
435 } else {
436 /*
437 * Puts the ascendant ordering if the selected
438 * column hasn't changed.
439 */
440 fTreeViewer.setComparator(reverseComparator);
441 fTreeViewer.getTree().setSortDirection(SWT.UP);
442 }
443 fTreeViewer.getTree().setSortColumn(treeColumn.getColumn());
444 }
445 });
446 }
447 treeColumn.setLabelProvider(columnData.getLabelProvider());
448 }
449
df2b3dbb 450 // Handler that will draw the percentages and the bar charts.
cfd22ad0
MD
451 fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() {
452 @Override
453 public void handleEvent(Event event) {
454 if (columnDataList.get(event.index).getPercentageProvider() != null) {
df2b3dbb 455
cfd22ad0
MD
456 TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) event.item.getData();
457
df2b3dbb
VP
458 // If node is hidden, exit immediately.
459 if (TmfBaseColumnDataProvider.HIDDEN_FOLDER_LEVELS.contains(node.getName())) {
cfd22ad0
MD
460 return;
461 }
462
df2b3dbb
VP
463 // Otherwise, get percentage and draw bar and text if applicable.
464 double percentage = columnDataList.get(event.index).getPercentageProvider().getPercentage(node);
465
466 // The item is selected.
467 if ((event.detail & SWT.SELECTED) > 0) {
468 // Draws our own background to avoid overwriting the bar.
cfd22ad0
MD
469 event.gc.fillRectangle(event.x, event.y, event.width, event.height);
470 event.detail &= ~SWT.SELECTED;
471 }
472
df2b3dbb
VP
473 // Drawing the percentage text
474 // if events are present in top node
475 // and the current node is not the top node
476 // and if is total or partial events column.
477 // If not, exit the method.
478 if (!((event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() || event.index == TmfBaseColumnDataProvider.StatsColumn.PARTIAL.getIndex())
479 && node != node.getTop())) {
480 return;
481 }
482
483 long eventValue = event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() ?
484 node.getTop().getValues().getTotal() : node.getTop().getValues().getPartial();
485
486 if (eventValue != 0) {
487
488 int oldAlpha = event.gc.getAlpha();
489 Color oldForeground = event.gc.getForeground();
490 Color oldBackground = event.gc.getBackground();
491
492 // Bar to draw
493 if (percentage != 0) {
494 /*
495 * Draws a transparent gradient rectangle from the
496 * color of foreground and background.
497 */
498 int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage);
499 event.gc.setAlpha(64);
500 event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE));
501 event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
502 event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true);
503 event.gc.drawRectangle(event.x, event.y, barWidth, event.height);
504
505 // Restore old values
506 event.gc.setBackground(oldBackground);
507 event.gc.setAlpha(oldAlpha);
508 event.detail &= ~SWT.BACKGROUND;
509
510 }
511
512 String percentageText = TmfStatisticsFormatter.toPercentageText(percentage);
513 String absoluteNumberText = TmfStatisticsFormatter.toColumnData(node, TmfBaseColumnDataProvider.StatsColumn.getColumn(event.index));
514
515 if (event.width > event.gc.stringExtent(percentageText).x + event.gc.stringExtent(absoluteNumberText).x) {
516 int textHeight = event.gc.stringExtent(percentageText).y;
517 event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
518 event.gc.drawText(percentageText, event.x, event.y + (event.height - textHeight) / 2, true);
519 }
520
521 // Restores old values
522 event.gc.setForeground(oldForeground);
523
524 }
cfd22ad0
MD
525 }
526 }
df2b3dbb 527
cfd22ad0
MD
528 });
529
530 // Initializes the comparator parameters
531 fTreeViewer.setComparator(columnDataList.get(0).getComparator());
532 fTreeViewer.getTree().setSortColumn(fTreeViewer.getTree().getColumn(0));
533 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
534 }
535
8b60cb37
MD
536 /**
537 * Initializes the input for the tree viewer.
8b60cb37
MD
538 */
539 protected void initInput() {
540 String treeID = getTreeID();
faa38350 541 TmfStatisticsTreeNode statisticsTreeNode;
36033ff0 542 if (TmfStatisticsTreeManager.containsTreeRoot(treeID)) {
faa38350
PT
543 // The statistics root is already present
544 statisticsTreeNode = TmfStatisticsTreeManager.getStatTreeRoot(treeID);
8b60cb37
MD
545
546 // Checks if the trace is already in the statistics tree.
faa38350 547 int numNodeTraces = statisticsTreeNode.getNbChildren();
8b60cb37 548
c14c0757
GB
549 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
550 int numTraces = traces.size();
8b60cb37
MD
551
552 if (numTraces == numNodeTraces) {
553 boolean same = true;
554 /*
555 * Checks if the experiment contains the same traces as when
556 * previously selected.
557 */
c14c0757
GB
558 for (ITmfTrace trace : traces) {
559 String traceName = trace.getName();
faa38350 560 if (!statisticsTreeNode.containsChild(traceName)) {
8b60cb37
MD
561 same = false;
562 break;
563 }
564 }
565
566 if (same) {
567 // No need to reload data, all traces are already loaded
faa38350 568 fTreeViewer.setInput(statisticsTreeNode);
8b60cb37
MD
569 return;
570 }
571 // Clears the old content to start over
faa38350 572 statisticsTreeNode.reset();
8b60cb37
MD
573 }
574 } else {
575 // Creates a new tree
faa38350 576 statisticsTreeNode = TmfStatisticsTreeManager.addStatsTreeRoot(treeID, getStatisticData());
8b60cb37
MD
577 }
578
579 // Sets the input to a clean data model
faa38350 580 fTreeViewer.setInput(statisticsTreeNode);
cdf994ef
ACL
581 /* Set a new model for the piecharts and keep a reference */
582 fPieChartViewer.setInput(getPieChartModel());
8b60cb37
MD
583 }
584
cfd22ad0 585 /**
faa38350 586 * Tells if the viewer is listening to a trace.
cfd22ad0 587 *
1c0de632 588 * @param trace
05627bda
MD
589 * The trace that the viewer may be listening
590 * @return true if the viewer is listening to the trace, false otherwise
cfd22ad0 591 */
1c0de632
AM
592 protected boolean isListeningTo(ITmfTrace trace) {
593 if (fProcessAll || trace == fTrace) {
05627bda 594 return true;
cfd22ad0 595 }
05627bda 596 return false;
cfd22ad0
MD
597 }
598
599 /**
faa38350 600 * Called when an trace request has been completed successfully.
cfd22ad0 601 *
05627bda
MD
602 * @param global
603 * Tells if the request is a global or time range (partial)
604 * request.
cfd22ad0 605 */
05627bda 606 protected void modelComplete(boolean global) {
cdf994ef 607 refreshTree();
05627bda 608 waitCursor(false);
cfd22ad0
MD
609 }
610
611 /**
faa38350 612 * Sends the request to the trace for the whole trace
cfd22ad0 613 *
faa38350
PT
614 * @param trace
615 * The trace used to send the request
8b260d9f 616 * @param timeRange
faa38350 617 * The range to request to the trace
cfd22ad0 618 */
faa38350
PT
619 protected void requestData(final ITmfTrace trace, final TmfTimeRange timeRange) {
620 buildStatisticsTree(trace, timeRange, true);
cfd22ad0
MD
621 }
622
623 /**
faa38350 624 * Sends the time range request from the trace
cfd22ad0 625 *
faa38350
PT
626 * @param trace
627 * The trace used to send the request
8b260d9f 628 * @param timeRange
faa38350 629 * The range to request to the trace
cfd22ad0 630 */
faa38350 631 protected void requestTimeRangeData(final ITmfTrace trace, final TmfTimeRange timeRange) {
faa38350 632 buildStatisticsTree(trace, timeRange, false);
89c06060
AM
633 }
634
635 /**
df2b3dbb
VP
636 * Requests all the data of the trace to the state system which contains
637 * information about the statistics.
89c06060 638 *
df2b3dbb
VP
639 * Since the viewer may be listening to multiple traces, it may receive an
640 * experiment rather than a single trace. The filtering is done with the
89c06060
AM
641 * method {@link #isListeningTo(String trace)}.
642 *
faa38350
PT
643 * @param trace
644 * The trace for which a request must be done
89c06060
AM
645 * @param timeRange
646 * The time range that will be requested to the state system
647 * @param isGlobal
648 * Tells if the request is for the global event count or the
649 * partial one.
650 */
d6b46913 651 private void buildStatisticsTree(final ITmfTrace trace, final TmfTimeRange timeRange, final boolean isGlobal) {
36033ff0 652 final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID());
89c06060
AM
653 if (statsData == null) {
654 return;
655 }
656
de83d1ab
MAL
657 Map<ITmfTrace, Job> updateJobs;
658 if (isGlobal) {
659 updateJobs = fUpdateJobsGlobal;
de83d1ab
MAL
660 } else {
661 updateJobs = fUpdateJobsPartial;
de83d1ab 662 }
89c06060 663
1d83ed07
AM
664 for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) {
665 aTrace = checkNotNull(aTrace);
de83d1ab
MAL
666 if (!isListeningTo(aTrace)) {
667 continue;
668 }
d6b46913 669
de83d1ab 670 /* Retrieve the statistics object */
b8585c7c 671 final TmfStatisticsModule statsMod = TmfTraceUtils.getAnalysisModuleOfClass(aTrace, TmfStatisticsModule.class, TmfStatisticsModule.ID);
de83d1ab
MAL
672 if (statsMod == null) {
673 /* No statistics module available for this trace */
674 continue;
675 }
55954069 676
de83d1ab
MAL
677 Job job = updateJobs.get(aTrace);
678 if (job == null) {
cdf994ef 679 job = new StatisticsUpdateJob("Statistics update", aTrace, isGlobal, timeRange, statsMod, this); //$NON-NLS-1$
de83d1ab
MAL
680 updateJobs.put(aTrace, job);
681 job.setSystem(true);
682 job.schedule();
89c06060 683 }
89c06060 684 }
cfd22ad0
MD
685 }
686
687 /**
05627bda 688 * Resets the number of events within the time range
cfd22ad0 689 */
05627bda 690 protected void resetTimeRangeValue() {
36033ff0 691 TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID());
05627bda
MD
692 if (treeModelRoot != null && treeModelRoot.hasChildren()) {
693 treeModelRoot.resetTimeRangeValue();
694 }
cfd22ad0
MD
695 }
696
697 /**
df2b3dbb
VP
698 * When the trace is loading the cursor will be different so the user knows
699 * that the processing is not finished yet.
05627bda
MD
700 *
701 * Calls to this method are stacked.
cfd22ad0 702 *
05627bda 703 * @param waitRequested
cfd22ad0 704 * Indicates if we need to show the waiting cursor, or the
05627bda 705 * default one.
cfd22ad0 706 */
05627bda 707 protected void waitCursor(final boolean waitRequested) {
cfd22ad0
MD
708 if ((fTreeViewer == null) || (fTreeViewer.getTree().isDisposed())) {
709 return;
710 }
711
05627bda 712 boolean needsUpdate = false;
cfd22ad0 713 Display display = fTreeViewer.getControl().getDisplay();
05627bda
MD
714 if (waitRequested) {
715 fWaitCursorCount++;
716 if (fWaitCursor == null) { // The cursor hasn't been initialized yet
717 fWaitCursor = new Cursor(display, SWT.CURSOR_WAIT);
718 }
719 if (fWaitCursorCount == 1) { // The cursor is not in waiting mode
720 needsUpdate = true;
721 }
722 } else {
723 if (fWaitCursorCount > 0) { // The cursor is in waiting mode
724 fWaitCursorCount--;
725 if (fWaitCursorCount == 0) { // No more reason to wait
726 // Put back the default cursor
727 needsUpdate = true;
728 }
729 }
cfd22ad0
MD
730 }
731
05627bda
MD
732 if (needsUpdate) {
733 // Performs the updates on the UI thread
734 display.asyncExec(new Runnable() {
735 @Override
736 public void run() {
737 if ((fTreeViewer != null)
738 && (!fTreeViewer.getTree().isDisposed())) {
739 Cursor cursor = null; // indicates default
740 if (waitRequested) {
741 cursor = fWaitCursor;
742 }
743 fTreeViewer.getControl().setCursor(cursor);
cfd22ad0 744 }
cfd22ad0 745 }
05627bda
MD
746 });
747 }
cfd22ad0 748 }
cdf994ef
ACL
749
750 /**
751 * @param isGlobal if the job to remove is global or partial
752 * @param jobTrace The trace
753 */
754 void removeFromJobs(boolean isGlobal, ITmfTrace jobTrace) {
755 Map<ITmfTrace, Job> updateJobs = isGlobal ? fUpdateJobsGlobal : fUpdateJobsPartial;
756 Job job = updateJobs.remove(jobTrace);
757 if (job != null) {
758 job.cancel();
759 }
760 }
cfd22ad0 761}
This page took 0.153147 seconds and 5 git commands to generate.