1 /*******************************************************************************
2 * Copyright (c) 2012, 2016 Ericsson
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
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 *******************************************************************************/
16 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.viewers
.statistics
;
18 import java
.util
.Collection
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
22 import java
.util
.Map
.Entry
;
24 import org
.eclipse
.core
.runtime
.jobs
.Job
;
25 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
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
;
67 * A basic viewer to display statistics in the statistics view.
69 * It is linked to a single ITmfTrace until its disposal.
71 * @author Mathieu Denis
73 public class TmfStatisticsViewer
extends TmfViewer
{
75 /** The actual tree viewer to display */
76 private TreeViewer fTreeViewer
;
78 /** Update range synchronization object */
79 private final Object fStatisticsRangeUpdateSyncObj
= new Object();
81 /** The statistics tree linked to this viewer */
82 private TmfStatisticsTree fStatisticsData
;
84 /** The trace that is displayed by this viewer */
85 private ITmfTrace fTrace
;
87 /** Indicates to process all events */
88 private boolean fProcessAll
;
90 /** View instance counter (for multiple statistics views) */
91 private static int fCountInstance
= 0;
93 /** Number of this instance. Used as an instance ID. */
94 private int fInstanceNb
;
96 /** Object to store the cursor while waiting for the trace to load */
97 private Cursor fWaitCursor
= null;
100 * Counts the number of times waitCursor() has been called. It avoids
101 * removing the waiting cursor, since there may be multiple requests running
104 private int fWaitCursorCount
= 0;
106 /** Tells to send a time range request when the trace gets updated. */
107 private boolean fSendRangeRequest
= true;
109 private final Map
<ITmfTrace
, Job
> fUpdateJobsPartial
= new HashMap
<>();
110 private final Map
<ITmfTrace
, Job
> fUpdateJobsGlobal
= new HashMap
<>();
112 private TmfPieChartViewer fPieChartViewer
;
114 private SashForm fSash
;
116 private TmfPieChartStatisticsModel fPieChartModel
;
119 * Create a basic statistics viewer. To be used in conjunction with
120 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
123 * The parent composite that will hold the viewer
125 * The name that will be assigned to this viewer
127 * The trace that is displayed by this viewer
130 public TmfStatisticsViewer(Composite parent
, String viewerName
, ITmfTrace trace
) {
131 init(parent
, viewerName
, trace
);
135 * Initialize the statistics viewer.
138 * The parent component of the viewer.
140 * The name to give to the viewer.
142 * The trace that will be displayed by the viewer.
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.
148 fInstanceNb
= fCountInstance
;
151 // The viewer will process all events if he is assigned to an experiment
152 fProcessAll
= (trace
instanceof TmfExperiment
);
157 fSash
.addDisposeListener((e
) -> {
163 public void dispose() {
167 private void internalDispose() {
169 if (fWaitCursor
!= null) {
170 fWaitCursor
.dispose();
173 for (Job j
: fUpdateJobsGlobal
.values()) {
177 for (Job j
: fUpdateJobsPartial
.values()) {
181 // Clean the model for this viewer
182 TmfStatisticsTreeManager
.removeStatTreeRoot(getTreeID());
183 fPieChartViewer
.reinitializeCharts();
186 // ------------------------------------------------------------------------
188 // ------------------------------------------------------------------------
191 * Handles the signal about new trace range.
194 * The trace range updated signal
197 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal
) {
198 ITmfTrace trace
= signal
.getTrace();
200 if (!isListeningTo(trace
)) {
204 synchronized (fStatisticsRangeUpdateSyncObj
) {
205 // Sends the time range request only once from this method.
206 if (fSendRangeRequest
) {
207 fSendRangeRequest
= false;
209 TmfTraceContext ctx
= TmfTraceManager
.getInstance().getCurrentTraceContext();
210 TmfTimeRange timeRange
= ctx
.getSelectionRange();
211 requestTimeRangeData(trace
, timeRange
);
214 requestData(trace
, signal
.getRange());
218 * Handles the time synch updated signal. It updates the time range
222 * Contains the information about the new selected time range.
226 public void timeSynchUpdated(TmfSelectionRangeUpdatedSignal signal
) {
227 if (fTrace
== null) {
230 ITmfTimestamp begin
= signal
.getBeginTime();
231 ITmfTimestamp end
= signal
.getEndTime();
232 TmfTimeRange timeRange
;
233 if (begin
.compareTo(end
) <= 0) {
234 timeRange
= new TmfTimeRange(begin
, end
);
236 timeRange
= new TmfTimeRange(end
, begin
);
238 requestTimeRangeData(fTrace
, timeRange
);
241 // ------------------------------------------------------------------------
243 // ------------------------------------------------------------------------
246 * Returns the primary control associated with this viewer.
248 * @return the SWT control which displays this viewer's content
251 public Control
getControl() {
256 * Get the input of the viewer.
258 * @return an object representing the input of the statistics viewer.
260 public Object
getInput() {
261 return fTreeViewer
.getInput();
265 * This method can be overridden to implement another way of representing
266 * the statistics data and to retrieve the information for display.
268 * @return a TmfStatisticsData object.
270 public TmfStatisticsTree
getStatisticData() {
271 if (fStatisticsData
== null) {
272 fStatisticsData
= new TmfStatisticsTree();
274 return fStatisticsData
;
278 * @return the model of the piecharts in this viewer
281 public TmfPieChartStatisticsModel
getPieChartModel() {
282 if (fPieChartModel
== null) {
283 fPieChartModel
= new TmfPieChartStatisticsModel();
285 return fPieChartModel
;
289 * Returns a unique ID based on name to be associated with the statistics
290 * tree for this viewer. For a same name, it will always return the same ID.
292 * @return a unique statistics tree ID.
294 public String
getTreeID() {
295 return getName() + fInstanceNb
;
299 public void refresh() {
300 final Control viewerControl
= getControl();
301 // Ignore update if disposed
302 if (viewerControl
.isDisposed()) {
306 refreshPieCharts(true, true);
310 * Only refreshes the Tree viewer
312 private void refreshTree() {
313 final Control viewerControl
= getControl();
314 // Ignore update if disposed
315 if (viewerControl
.isDisposed()) {
319 Display
.getDefault().asyncExec(new Runnable() {
322 if (!viewerControl
.isDisposed()) {
323 fTreeViewer
.refresh();
330 * Only refreshes the piecharts depending on the parameters
332 * @param refreshGlobal
333 * if we have to refresh the global piechart
334 * @param refreshSelection
335 * if we have to refresh the selection piechart
338 protected void refreshPieCharts(final boolean refreshGlobal
, final boolean refreshSelection
) {
339 final Control viewerControl
= getControl();
340 // Ignore update if disposed
341 if (viewerControl
.isDisposed()) {
345 TmfPieChartStatisticsModel pieChartModel
= getPieChartModel();
346 if (pieChartModel
== null || pieChartModel
.getPieChartGlobalModel() == null) {
349 /* If there's only one event type, don't show any piechart */
350 boolean moreThanOne
= false;
351 for (Entry
<ITmfTrace
, Map
<String
, Long
>> entry
: pieChartModel
.getPieChartGlobalModel().entrySet()) {
352 if(entry
.getValue() != null && entry
.getValue().size() > 1) {
358 setPieChartsVisible(moreThanOne
);
360 Display
.getDefault().asyncExec(new Runnable() {
363 if (!viewerControl
.isDisposed()) {
364 fPieChartViewer
.refresh(refreshGlobal
, refreshSelection
);
371 * Will force a request on the partial event count if one is needed.
373 public void sendPartialRequestOnNextUpdate() {
374 synchronized (fStatisticsRangeUpdateSyncObj
) {
375 fSendRangeRequest
= true;
380 * Focus on the statistics tree of the viewer
382 public void setFocus() {
383 fTreeViewer
.getTree().setFocus();
387 * Cancels the request if it is not already completed
390 * The request to be canceled
392 protected void cancelOngoingRequest(ITmfEventRequest request
) {
393 if (request
!= null && !request
.isCompleted()) {
399 * This method can be overridden to change the representation of the data in
402 * @return An object of type {@link TmfBaseColumnDataProvider}.
404 protected TmfBaseColumnDataProvider
getColumnDataProvider() {
405 return new TmfBaseColumnDataProvider();
409 * Initialize the content that will be drawn in this viewer
412 * The parent of the control to create
414 protected void initContent(Composite parent
) {
416 final List
<TmfBaseColumnData
> columnDataList
= getColumnDataProvider().getColumnData();
418 fSash
= new SashForm(parent
, SWT
.HORIZONTAL
);
420 fTreeViewer
= new TreeViewer(fSash
, SWT
.BORDER
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
421 fPieChartViewer
= new TmfPieChartViewer(fSash
);
422 fPieChartViewer
.addEventTypeSelectionListener(new Listener() {
425 public void handleEvent(Event event
) {
426 String eventTypeName
= event
.text
;
427 if (getStatisticData().getRootNode() == null ||
428 fTreeViewer
.getTree() == null) {
431 /* Get all the nodes corresponding to the event name */
432 List
<TmfStatisticsTreeNode
> nodes
= (List
<TmfStatisticsTreeNode
>) getStatisticData().getRootNode().findChildren(eventTypeName
, true);
433 if (nodes
.isEmpty()) {
434 /* Shouldn't happen, except for when selecting "Others" */
437 /* Only select the first in the collection */
438 fTreeViewer
.setSelection(new StructuredSelection(nodes
.get(0)), true);
442 /* Make sure the sash is split in 2 equal parts */
443 fSash
.setWeights(new int[] { 100, 100 });
445 fTreeViewer
.setContentProvider(new TmfTreeContentProvider());
446 fTreeViewer
.getTree().setHeaderVisible(true);
447 fTreeViewer
.setUseHashlookup(true);
449 // Creates the columns defined by the column data provider
450 for (final TmfBaseColumnData columnData
: columnDataList
) {
451 final TreeViewerColumn treeColumn
= new TreeViewerColumn(fTreeViewer
, columnData
.getAlignment());
452 treeColumn
.getColumn().setText(columnData
.getHeader());
453 treeColumn
.getColumn().setWidth(columnData
.getWidth());
454 treeColumn
.getColumn().setToolTipText(columnData
.getTooltip());
456 // If is dummy column
457 if (columnData
== columnDataList
.get(TmfBaseColumnDataProvider
.StatsColumn
.DUMMY
.getIndex())) {
458 treeColumn
.getColumn().setResizable(false);
461 // A comparator is defined.
462 if (columnData
.getComparator() != null) {
463 // Adds a listener on the columns header for sorting purpose.
464 treeColumn
.getColumn().addSelectionListener(new SelectionAdapter() {
466 private ViewerComparator reverseComparator
;
469 public void widgetSelected(SelectionEvent e
) {
470 // Initializes the reverse comparator once.
471 if (reverseComparator
== null) {
472 reverseComparator
= new ViewerComparator() {
474 public int compare(Viewer viewer
, Object e1
, Object e2
) {
475 return -1 * columnData
.getComparator().compare(viewer
, e1
, e2
);
480 if (fTreeViewer
.getTree().getSortDirection() == SWT
.UP
481 || fTreeViewer
.getTree().getSortColumn() != treeColumn
.getColumn()) {
483 * Puts the descendant order if the old order was up
484 * or if the selected column has changed.
486 fTreeViewer
.setComparator(columnData
.getComparator());
487 fTreeViewer
.getTree().setSortDirection(SWT
.DOWN
);
490 * Puts the ascendant ordering if the selected
491 * column hasn't changed.
493 fTreeViewer
.setComparator(reverseComparator
);
494 fTreeViewer
.getTree().setSortDirection(SWT
.UP
);
496 fTreeViewer
.getTree().setSortColumn(treeColumn
.getColumn());
500 treeColumn
.setLabelProvider(columnData
.getLabelProvider());
503 // Handler that will draw the percentages and the bar charts.
504 fTreeViewer
.getTree().addListener(SWT
.EraseItem
, new Listener() {
506 public void handleEvent(Event event
) {
507 if (columnDataList
.get(event
.index
).getPercentageProvider() != null) {
509 TmfStatisticsTreeNode node
= (TmfStatisticsTreeNode
) event
.item
.getData();
511 // If node is hidden, exit immediately.
512 if (TmfBaseColumnDataProvider
.HIDDEN_FOLDER_LEVELS
.contains(node
.getName())) {
516 // Otherwise, get percentage and draw bar and text if
518 double percentage
= columnDataList
.get(event
.index
).getPercentageProvider().getPercentage(node
);
520 // The item is selected.
521 if ((event
.detail
& SWT
.SELECTED
) > 0) {
522 // Draws our own background to avoid overwriting the
524 event
.gc
.fillRectangle(event
.x
, event
.y
, event
.width
, event
.height
);
525 event
.detail
&= ~SWT
.SELECTED
;
528 // Drawing the percentage text
529 // if events are present in top node
530 // and the current node is not the top node
531 // and if is total or partial events column.
532 // If not, exit the method.
533 if (!((event
.index
== TmfBaseColumnDataProvider
.StatsColumn
.TOTAL
.getIndex() || event
.index
== TmfBaseColumnDataProvider
.StatsColumn
.PARTIAL
.getIndex())
534 && node
!= node
.getTop())) {
538 long eventValue
= event
.index
== TmfBaseColumnDataProvider
.StatsColumn
.TOTAL
.getIndex() ?
539 node
.getTop().getValues().getTotal() : node
.getTop().getValues().getPartial();
541 if (eventValue
!= 0) {
543 int oldAlpha
= event
.gc
.getAlpha();
544 Color oldForeground
= event
.gc
.getForeground();
545 Color oldBackground
= event
.gc
.getBackground();
548 if (percentage
!= 0) {
550 * Draws a transparent gradient rectangle from the
551 * color of foreground and background.
553 int barWidth
= (int) ((fTreeViewer
.getTree().getColumn(event
.index
).getWidth() - 8) * percentage
);
554 event
.gc
.setAlpha(64);
555 event
.gc
.setForeground(event
.item
.getDisplay().getSystemColor(SWT
.COLOR_BLUE
));
556 event
.gc
.setBackground(event
.item
.getDisplay().getSystemColor(SWT
.COLOR_LIST_BACKGROUND
));
557 event
.gc
.fillGradientRectangle(event
.x
, event
.y
, barWidth
, event
.height
, true);
558 event
.gc
.drawRectangle(event
.x
, event
.y
, barWidth
, event
.height
);
560 // Restore old values
561 event
.gc
.setBackground(oldBackground
);
562 event
.gc
.setAlpha(oldAlpha
);
563 event
.detail
&= ~SWT
.BACKGROUND
;
567 String percentageText
= TmfStatisticsFormatter
.toPercentageText(percentage
);
568 String absoluteNumberText
= TmfStatisticsFormatter
.toColumnData(node
, TmfBaseColumnDataProvider
.StatsColumn
.getColumn(event
.index
));
570 if (event
.width
> event
.gc
.stringExtent(percentageText
).x
+ event
.gc
.stringExtent(absoluteNumberText
).x
) {
571 int textHeight
= event
.gc
.stringExtent(percentageText
).y
;
572 event
.gc
.setForeground(event
.item
.getDisplay().getSystemColor(SWT
.COLOR_DARK_GRAY
));
573 event
.gc
.drawText(percentageText
, event
.x
, event
.y
+ (event
.height
- textHeight
) / 2, true);
576 // Restores old values
577 event
.gc
.setForeground(oldForeground
);
585 // Initializes the comparator parameters
586 fTreeViewer
.setComparator(columnDataList
.get(0).getComparator());
587 fTreeViewer
.getTree().setSortColumn(fTreeViewer
.getTree().getColumn(0));
588 fTreeViewer
.getTree().setSortDirection(SWT
.DOWN
);
592 * Initializes the input for the tree viewer.
594 protected void initInput() {
595 String treeID
= getTreeID();
596 TmfStatisticsTreeNode statisticsTreeNode
;
597 if (TmfStatisticsTreeManager
.containsTreeRoot(treeID
)) {
598 // The statistics root is already present
599 statisticsTreeNode
= TmfStatisticsTreeManager
.getStatTreeRoot(treeID
);
601 // Checks if the trace is already in the statistics tree.
602 int numNodeTraces
= statisticsTreeNode
.getNbChildren();
604 Collection
<ITmfTrace
> traces
= TmfTraceManager
.getTraceSet(fTrace
);
605 int numTraces
= traces
.size();
607 if (numTraces
== numNodeTraces
) {
610 * Checks if the experiment contains the same traces as when
611 * previously selected.
613 for (ITmfTrace trace
: traces
) {
614 String traceName
= trace
.getName();
615 if (!statisticsTreeNode
.containsChild(traceName
)) {
622 // No need to reload data, all traces are already loaded
623 fTreeViewer
.setInput(statisticsTreeNode
);
626 // Clears the old content to start over
627 statisticsTreeNode
.reset();
630 // Creates a new tree
631 statisticsTreeNode
= TmfStatisticsTreeManager
.addStatsTreeRoot(treeID
, getStatisticData());
634 // Sets the input to a clean data model
635 fTreeViewer
.setInput(statisticsTreeNode
);
636 /* Set a new model for the piecharts and keep a reference */
637 fPieChartViewer
.setInput(getPieChartModel());
641 * Tells if the viewer is listening to a trace.
644 * The trace that the viewer may be listening
645 * @return true if the viewer is listening to the trace, false otherwise
647 protected boolean isListeningTo(ITmfTrace trace
) {
648 if (fProcessAll
|| trace
== fTrace
) {
655 * Called when an trace request has been completed successfully.
658 * Tells if the request is a global or time range (partial)
661 protected void modelComplete(boolean global
) {
667 * Sends the request to the trace for the whole trace
670 * The trace used to send the request
672 * The range to request to the trace
674 protected void requestData(final ITmfTrace trace
, final TmfTimeRange timeRange
) {
675 buildStatisticsTree(trace
, timeRange
, true);
679 * Sends the time range request from the trace
682 * The trace used to send the request
684 * The range to request to the trace
686 protected void requestTimeRangeData(final ITmfTrace trace
, final TmfTimeRange timeRange
) {
687 buildStatisticsTree(trace
, timeRange
, false);
691 * Requests all the data of the trace to the state system which contains
692 * information about the statistics.
694 * Since the viewer may be listening to multiple traces, it may receive an
695 * experiment rather than a single trace. The filtering is done with the
696 * method {@link #isListeningTo(String trace)}.
699 * The trace for which a request must be done
701 * The time range that will be requested to the state system
703 * Tells if the request is for the global event count or the
706 private void buildStatisticsTree(final ITmfTrace trace
, final TmfTimeRange timeRange
, final boolean isGlobal
) {
707 final TmfStatisticsTree statsData
= TmfStatisticsTreeManager
.getStatTree(getTreeID());
708 if (statsData
== null) {
712 Map
<ITmfTrace
, Job
> updateJobs
;
714 updateJobs
= fUpdateJobsGlobal
;
716 updateJobs
= fUpdateJobsPartial
;
719 for (ITmfTrace aTrace
: TmfTraceManager
.getTraceSet(trace
)) {
720 if (!isListeningTo(aTrace
)) {
724 /* Retrieve the statistics object */
725 final TmfStatisticsModule statsMod
= TmfTraceUtils
.getAnalysisModuleOfClass(aTrace
, TmfStatisticsModule
.class, TmfStatisticsModule
.ID
);
726 if (statsMod
== null) {
727 /* No statistics module available for this trace */
731 Job job
= updateJobs
.get(aTrace
);
733 job
= new StatisticsUpdateJob("Statistics update", aTrace
, isGlobal
, timeRange
, statsMod
, this); //$NON-NLS-1$
734 updateJobs
.put(aTrace
, job
);
741 private void setPieChartsVisible(final boolean visible
) {
742 if (fPieChartViewer
.isDisposed()) {
745 TmfUiRefreshHandler
.getInstance().queueUpdate(fPieChartViewer
, new Runnable() {
748 if (!fPieChartViewer
.isDisposed()) {
749 fPieChartViewer
.setVisible(visible
);
750 fPieChartViewer
.getParent().layout();
757 * Resets the number of events within the time range
759 protected void resetTimeRangeValue() {
760 TmfStatisticsTreeNode treeModelRoot
= TmfStatisticsTreeManager
.getStatTreeRoot(getTreeID());
761 if (treeModelRoot
!= null && treeModelRoot
.hasChildren()) {
762 treeModelRoot
.resetTimeRangeValue();
767 * When the trace is loading the cursor will be different so the user knows
768 * that the processing is not finished yet.
770 * Calls to this method are stacked.
772 * @param waitRequested
773 * Indicates if we need to show the waiting cursor, or the
776 protected void waitCursor(final boolean waitRequested
) {
777 if ((fTreeViewer
== null) || (fTreeViewer
.getTree().isDisposed())) {
781 boolean needsUpdate
= false;
782 Display display
= fTreeViewer
.getControl().getDisplay();
785 if (fWaitCursor
== null) { // The cursor hasn't been initialized yet
786 fWaitCursor
= new Cursor(display
, SWT
.CURSOR_WAIT
);
788 if (fWaitCursorCount
== 1) { // The cursor is not in waiting mode
792 if (fWaitCursorCount
> 0) { // The cursor is in waiting mode
794 if (fWaitCursorCount
== 0) { // No more reason to wait
795 // Put back the default cursor
802 // Performs the updates on the UI thread
803 display
.asyncExec(new Runnable() {
806 if ((fTreeViewer
!= null)
807 && (!fTreeViewer
.getTree().isDisposed())) {
808 Cursor cursor
= null; // indicates default
810 cursor
= fWaitCursor
;
812 fTreeViewer
.getControl().setCursor(cursor
);
821 * if the job to remove is global or partial
825 void removeFromJobs(boolean isGlobal
, ITmfTrace jobTrace
) {
826 Map
<ITmfTrace
, Job
> updateJobs
= isGlobal ? fUpdateJobsGlobal
: fUpdateJobsPartial
;
827 Job job
= updateJobs
.remove(jobTrace
);