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