1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 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 * William Bourque - Initial API and implementation
11 * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements.
12 * Yuriy Vashchuk - Histograms optimisation.
13 * Yuriy Vashchuk - Histogram Canvas Heritage correction
14 * Francois Chouinard - Cleanup and refactoring
15 * Francois Chouinard - Moved from LTTng to TMF
16 * Patrick Tasse - Update for mouse wheel zoom
17 * Xavier Raynaud - Support multi-trace coloring
18 *******************************************************************************/
20 package org
.eclipse
.tracecompass
.tmf
.ui
.views
.histogram
;
22 import java
.util
.Collection
;
24 import org
.eclipse
.jdt
.annotation
.NonNull
;
25 import org
.eclipse
.jface
.action
.Action
;
26 import org
.eclipse
.jface
.action
.IAction
;
27 import org
.eclipse
.jface
.action
.Separator
;
28 import org
.eclipse
.swt
.SWT
;
29 import org
.eclipse
.swt
.custom
.CLabel
;
30 import org
.eclipse
.swt
.events
.MouseAdapter
;
31 import org
.eclipse
.swt
.events
.MouseEvent
;
32 import org
.eclipse
.swt
.events
.MouseWheelListener
;
33 import org
.eclipse
.swt
.events
.PaintEvent
;
34 import org
.eclipse
.swt
.events
.PaintListener
;
35 import org
.eclipse
.swt
.graphics
.GC
;
36 import org
.eclipse
.swt
.graphics
.Image
;
37 import org
.eclipse
.swt
.graphics
.Rectangle
;
38 import org
.eclipse
.swt
.layout
.GridData
;
39 import org
.eclipse
.swt
.layout
.GridLayout
;
40 import org
.eclipse
.swt
.layout
.RowLayout
;
41 import org
.eclipse
.swt
.widgets
.Composite
;
42 import org
.eclipse
.swt
.widgets
.Control
;
43 import org
.eclipse
.swt
.widgets
.Display
;
44 import org
.eclipse
.swt
.widgets
.Label
;
45 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
46 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.ITmfImageConstants
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.request
.ITmfEventRequest
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.request
.ITmfEventRequest
.ExecutionType
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfRangeSynchSignal
;
50 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalHandler
;
51 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalThrottler
;
52 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTimeSynchSignal
;
53 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceClosedSignal
;
54 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
55 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceRangeUpdatedSignal
;
56 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
57 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceUpdatedSignal
;
58 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
59 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
60 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
61 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
62 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceContext
;
63 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
64 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.TmfView
;
65 import org
.eclipse
.ui
.IActionBars
;
68 * The purpose of this view is to provide graphical time distribution statistics about the trace events.
70 * The view is composed of two histograms and two controls:
72 * <li>an event distribution histogram for the whole trace;
73 * <li>an event distribution histogram for current time window (window span);
74 * <li>the timestamp of the currently selected event;
75 * <li>the window span (size of the time window of the smaller histogram).
77 * The histograms x-axis show their respective time range.
80 * @author Francois Chouinard
82 public class HistogramView
extends TmfView
{
84 // ------------------------------------------------------------------------
86 // ------------------------------------------------------------------------
89 * The view ID as defined in plugin.xml
91 public static final @NonNull String ID
= "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
93 private static final Image LINK_IMG
= Activator
.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$
95 // ------------------------------------------------------------------------
97 // ------------------------------------------------------------------------
100 private Composite fParent
;
103 private ITmfTrace fTrace
;
105 // Current timestamp/time window - everything in the TIME_SCALE
106 private long fTraceStartTime
;
107 private long fTraceEndTime
;
108 private long fWindowStartTime
;
109 private long fWindowEndTime
;
110 private long fWindowSpan
;
111 private long fSelectionBeginTime
;
112 private long fSelectionEndTime
;
115 private HistogramTextControl fSelectionStartControl
;
116 private HistogramTextControl fSelectionEndControl
;
117 private HistogramTextControl fTimeSpanControl
;
120 private Label fLinkButton
;
121 private boolean fLinkState
;
123 // Histogram/request for the full trace range
124 private static FullTraceHistogram fFullTraceHistogram
;
125 private HistogramRequest fFullTraceRequest
;
127 // Histogram/request for the selected time range
128 private static TimeRangeHistogram fTimeRangeHistogram
;
129 private HistogramRequest fTimeRangeRequest
;
132 private Composite fLegendArea
;
133 private Image
[] fLegendImages
;
135 // Throttlers for the time sync and time-range sync signals
136 private final TmfSignalThrottler fTimeSyncThrottle
;
137 private final TmfSignalThrottler fTimeRangeSyncThrottle
;
139 // Action for toggle showing the lost events
140 private Action hideLostEventsAction
;
141 // Action for toggle showing the traces
142 private Action showTraceAction
;
144 // ------------------------------------------------------------------------
146 // ------------------------------------------------------------------------
149 * Default constructor
151 public HistogramView() {
153 fTimeSyncThrottle
= new TmfSignalThrottler(this, 200);
154 fTimeRangeSyncThrottle
= new TmfSignalThrottler(this, 200);
158 public void dispose() {
159 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
160 fTimeRangeRequest
.cancel();
162 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
163 fFullTraceRequest
.cancel();
165 fFullTraceHistogram
.dispose();
166 fTimeRangeHistogram
.dispose();
167 fSelectionStartControl
.dispose();
168 fSelectionEndControl
.dispose();
169 fTimeSpanControl
.dispose();
170 disposeLegendImages();
175 private void disposeLegendImages() {
176 if (fLegendImages
!= null) {
177 for (Image i
: fLegendImages
) {
181 fLegendImages
= null;
184 // ------------------------------------------------------------------------
186 // ------------------------------------------------------------------------
189 public void createPartControl(Composite parent
) {
194 final String selectionStartLabel
= Messages
.HistogramView_selectionStartLabel
;
195 final String selectionEndLabel
= Messages
.HistogramView_selectionEndLabel
;
196 final String windowSpanLabel
= Messages
.HistogramView_windowSpanLabel
;
198 // --------------------------------------------------------------------
199 // Set the HistogramView layout
200 // --------------------------------------------------------------------
202 Composite viewComposite
= new Composite(fParent
, SWT
.FILL
);
203 GridLayout gridLayout
= new GridLayout();
204 gridLayout
.numColumns
= 2;
205 gridLayout
.horizontalSpacing
= 5;
206 gridLayout
.verticalSpacing
= 0;
207 gridLayout
.marginHeight
= 0;
208 gridLayout
.marginWidth
= 0;
209 viewComposite
.setLayout(gridLayout
);
211 // --------------------------------------------------------------------
213 // --------------------------------------------------------------------
215 Composite controlsComposite
= new Composite(viewComposite
, SWT
.NONE
);
216 gridLayout
= new GridLayout();
217 gridLayout
.numColumns
= 2;
218 gridLayout
.marginHeight
= 0;
219 gridLayout
.marginWidth
= 0;
220 gridLayout
.horizontalSpacing
= 5;
221 gridLayout
.verticalSpacing
= 1;
222 gridLayout
.makeColumnsEqualWidth
= false;
223 controlsComposite
.setLayout(gridLayout
);
224 GridData gridData
= new GridData(SWT
.FILL
, SWT
.CENTER
, false, false);
225 controlsComposite
.setLayoutData(gridData
);
227 Composite selectionGroup
= new Composite(controlsComposite
, SWT
.BORDER
);
228 gridLayout
= new GridLayout();
229 gridLayout
.marginHeight
= 0;
230 gridLayout
.marginWidth
= 0;
231 gridLayout
.horizontalSpacing
= 0;
232 gridLayout
.verticalSpacing
= 0;
233 selectionGroup
.setLayout(gridLayout
);
235 // Selection start control
236 gridData
= new GridData();
237 gridData
.horizontalAlignment
= SWT
.FILL
;
238 gridData
.verticalAlignment
= SWT
.CENTER
;
239 fSelectionStartControl
= new HistogramSelectionStartControl(this, selectionGroup
, selectionStartLabel
, 0L);
240 fSelectionStartControl
.setLayoutData(gridData
);
241 fSelectionStartControl
.setValue(Long
.MIN_VALUE
);
243 // Selection end control
244 gridData
= new GridData();
245 gridData
.horizontalAlignment
= SWT
.FILL
;
246 gridData
.verticalAlignment
= SWT
.CENTER
;
247 fSelectionEndControl
= new HistogramSelectionEndControl(this, selectionGroup
, selectionEndLabel
, 0L);
248 fSelectionEndControl
.setLayoutData(gridData
);
249 fSelectionEndControl
.setValue(Long
.MIN_VALUE
);
252 gridData
= new GridData();
253 fLinkButton
= new Label(controlsComposite
, SWT
.NONE
);
254 fLinkButton
.setImage(LINK_IMG
);
255 fLinkButton
.setLayoutData(gridData
);
256 addLinkButtonListeners();
258 // Window span time control
259 gridData
= new GridData();
260 gridData
.horizontalAlignment
= SWT
.FILL
;
261 gridData
.verticalAlignment
= SWT
.CENTER
;
262 fTimeSpanControl
= new HistogramTimeRangeControl(this, controlsComposite
, windowSpanLabel
, 0L);
263 fTimeSpanControl
.setLayoutData(gridData
);
264 fTimeSpanControl
.setValue(Long
.MIN_VALUE
);
266 // --------------------------------------------------------------------
267 // Time range histogram
268 // --------------------------------------------------------------------
270 Composite timeRangeComposite
= new Composite(viewComposite
, SWT
.NONE
);
271 gridLayout
= new GridLayout();
272 gridLayout
.numColumns
= 1;
273 gridLayout
.marginHeight
= 0;
274 gridLayout
.marginWidth
= 0;
275 gridLayout
.marginTop
= 5;
276 gridLayout
.horizontalSpacing
= 0;
277 gridLayout
.verticalSpacing
= 0;
278 gridLayout
.marginLeft
= 5;
279 gridLayout
.marginRight
= 5;
280 timeRangeComposite
.setLayout(gridLayout
);
282 // Use remaining horizontal space
283 gridData
= new GridData();
284 gridData
.horizontalAlignment
= SWT
.FILL
;
285 gridData
.verticalAlignment
= SWT
.FILL
;
286 gridData
.grabExcessHorizontalSpace
= true;
287 gridData
.grabExcessVerticalSpace
= true;
288 timeRangeComposite
.setLayoutData(gridData
);
291 fTimeRangeHistogram
= new TimeRangeHistogram(this, timeRangeComposite
);
293 // --------------------------------------------------------------------
294 // Full range histogram
295 // --------------------------------------------------------------------
297 Composite fullRangeComposite
= new Composite(viewComposite
, SWT
.FILL
);
298 gridLayout
= new GridLayout();
299 gridLayout
.numColumns
= 1;
300 gridLayout
.marginHeight
= 0;
301 gridLayout
.marginWidth
= 0;
302 gridLayout
.marginTop
= 5;
303 gridLayout
.horizontalSpacing
= 0;
304 gridLayout
.verticalSpacing
= 0;
305 gridLayout
.marginLeft
= 5;
306 gridLayout
.marginRight
= 5;
307 fullRangeComposite
.setLayout(gridLayout
);
309 // Use remaining horizontal space
310 gridData
= new GridData();
311 gridData
.horizontalAlignment
= SWT
.FILL
;
312 gridData
.verticalAlignment
= SWT
.FILL
;
313 gridData
.horizontalSpan
= 2;
314 gridData
.grabExcessHorizontalSpace
= true;
315 gridData
.grabExcessVerticalSpace
= true;
316 fullRangeComposite
.setLayoutData(gridData
);
319 fFullTraceHistogram
= new FullTraceHistogram(this, fullRangeComposite
);
321 fLegendArea
= new Composite(viewComposite
, SWT
.FILL
);
322 fLegendArea
.setLayoutData(new GridData(SWT
.BEGINNING
, SWT
.BEGINNING
, true, false, 2, 1));
323 fLegendArea
.setLayout(new RowLayout());
325 // Add mouse wheel listener to time span control
326 MouseWheelListener listener
= fFullTraceHistogram
.getZoom();
327 fTimeSpanControl
.addMouseWheelListener(listener
);
330 // View Action Handling
331 contributeToActionBars();
333 ITmfTrace trace
= TmfTraceManager
.getInstance().getActiveTrace();
335 traceSelected(new TmfTraceSelectedSignal(this, trace
));
340 public void setFocus() {
341 fFullTraceHistogram
.fCanvas
.setFocus();
345 fParent
.layout(true);
348 // ------------------------------------------------------------------------
350 // ------------------------------------------------------------------------
353 * Returns the current trace handled by the view
355 * @return the current trace
357 public ITmfTrace
getTrace() {
362 * Returns the time range of the current selected window (base on default time scale).
364 * @return the time range of current selected window.
366 public TmfTimeRange
getTimeRange() {
367 return new TmfTimeRange(
368 new TmfTimestamp(fWindowStartTime
, ITmfTimestamp
.NANOSECOND_SCALE
),
369 new TmfTimestamp(fWindowEndTime
, ITmfTimestamp
.NANOSECOND_SCALE
));
373 * get the show lost events action
375 * @return The action object
377 public Action
getShowLostEventsAction() {
378 if (hideLostEventsAction
== null) {
379 /* show lost events */
380 hideLostEventsAction
= new Action(Messages
.HistogramView_hideLostEvents
, IAction
.AS_CHECK_BOX
) {
383 HistogramScaledData
.hideLostEvents
= hideLostEventsAction
.isChecked();
384 long maxNbEvents
= HistogramScaledData
.hideLostEvents ? fFullTraceHistogram
.fScaledData
.fMaxValue
: fFullTraceHistogram
.fScaledData
.fMaxCombinedValue
;
385 fFullTraceHistogram
.setMaxNbEvents(maxNbEvents
);
386 maxNbEvents
= HistogramScaledData
.hideLostEvents ? fTimeRangeHistogram
.fScaledData
.fMaxValue
: fTimeRangeHistogram
.fScaledData
.fMaxCombinedValue
;
387 fTimeRangeHistogram
.setMaxNbEvents(maxNbEvents
);
390 hideLostEventsAction
.setText(Messages
.HistogramView_hideLostEvents
);
391 hideLostEventsAction
.setToolTipText(Messages
.HistogramView_hideLostEvents
);
392 hideLostEventsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LOST_EVENTS
));
394 return hideLostEventsAction
;
398 * get the show trace action
400 * @return The action object
402 public Action
getShowTraceAction() {
403 if (showTraceAction
== null) {
404 /* show lost events */
405 showTraceAction
= new Action(Messages
.HistogramView_showTraces
, IAction
.AS_CHECK_BOX
) {
408 Histogram
.showTraces
= showTraceAction
.isChecked();
409 fFullTraceHistogram
.fCanvas
.redraw();
410 fTimeRangeHistogram
.fCanvas
.redraw();
414 showTraceAction
.setChecked(true);
415 showTraceAction
.setText(Messages
.HistogramView_showTraces
);
416 showTraceAction
.setToolTipText(Messages
.HistogramView_showTraces
);
417 showTraceAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_HIST_TRACES
));
419 return showTraceAction
;
422 // ------------------------------------------------------------------------
424 // ------------------------------------------------------------------------
427 * Broadcast TmfSignal about new current selection time range.
428 * @param beginTime the begin time of current selection.
429 * @param endTime the end time of current selection.
431 void updateSelectionTime(long beginTime
, long endTime
) {
432 updateDisplayedSelectionTime(beginTime
, endTime
);
433 TmfTimestamp beginTs
= new TmfTimestamp(beginTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
434 TmfTimestamp endTs
= new TmfTimestamp(endTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
435 TmfTimeSynchSignal signal
= new TmfTimeSynchSignal(this, beginTs
, endTs
);
436 fTimeSyncThrottle
.queue(signal
);
440 * Get selection begin time
441 * @return the begin time of current selection
443 long getSelectionBegin() {
444 return fSelectionBeginTime
;
448 * Get selection end time
449 * @return the end time of current selection
451 long getSelectionEnd() {
452 return fSelectionEndTime
;
457 * @return true if begin and end selection time should be linked
459 boolean getLinkState() {
464 * Broadcast TmfSignal about new selection time range.
465 * @param startTime the new start time
466 * @param endTime the new end time
468 void updateTimeRange(long startTime
, long endTime
) {
469 if (fTrace
!= null) {
470 // Build the new time range; keep the current time
471 TmfTimeRange timeRange
= new TmfTimeRange(
472 new TmfTimestamp(startTime
, ITmfTimestamp
.NANOSECOND_SCALE
),
473 new TmfTimestamp(endTime
, ITmfTimestamp
.NANOSECOND_SCALE
));
474 fTimeSpanControl
.setValue(endTime
- startTime
);
476 updateDisplayedTimeRange(startTime
, endTime
);
478 // Send the FW signal
479 TmfRangeSynchSignal signal
= new TmfRangeSynchSignal(this, timeRange
);
480 fTimeRangeSyncThrottle
.queue(signal
);
485 * Broadcast TmfSignal about new selected time range.
486 * @param newDuration new duration (relative to current start time)
488 public synchronized void updateTimeRange(long newDuration
) {
489 if (fTrace
!= null) {
490 long delta
= newDuration
- fWindowSpan
;
491 long newStartTime
= fWindowStartTime
- (delta
/ 2);
492 setNewRange(newStartTime
, newDuration
);
496 private void setNewRange(long startTime
, long duration
) {
497 long realStart
= startTime
;
499 if (realStart
< fTraceStartTime
) {
500 realStart
= fTraceStartTime
;
503 long endTime
= realStart
+ duration
;
504 if (endTime
> fTraceEndTime
) {
505 endTime
= fTraceEndTime
;
506 if ((endTime
- duration
) > fTraceStartTime
) {
507 realStart
= endTime
- duration
;
509 realStart
= fTraceStartTime
;
512 updateTimeRange(realStart
, endTime
);
515 // ------------------------------------------------------------------------
517 // ------------------------------------------------------------------------
520 * Handles trace opened signal. Loads histogram if new trace time range is not
521 * equal <code>TmfTimeRange.NULL_RANGE</code>
522 * @param signal the trace opened signal
525 public void traceOpened(TmfTraceOpenedSignal signal
) {
526 assert (signal
!= null);
527 fTrace
= signal
.getTrace();
532 * Handles trace selected signal. Loads histogram if new trace time range is not
533 * equal <code>TmfTimeRange.NULL_RANGE</code>
534 * @param signal the trace selected signal
537 public void traceSelected(TmfTraceSelectedSignal signal
) {
538 assert (signal
!= null);
539 if (fTrace
!= signal
.getTrace()) {
540 fTrace
= signal
.getTrace();
545 private void loadTrace() {
546 initializeHistograms();
551 * Handles trace closed signal. Clears the view and data model and cancels requests.
552 * @param signal the trace closed signal
555 public void traceClosed(TmfTraceClosedSignal signal
) {
557 if (signal
.getTrace() != fTrace
) {
561 // Kill any running request
562 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
563 fTimeRangeRequest
.cancel();
565 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
566 fFullTraceRequest
.cancel();
569 // Initialize the internal data
571 fTraceStartTime
= 0L;
573 fWindowStartTime
= 0L;
576 fSelectionBeginTime
= 0L;
577 fSelectionEndTime
= 0L;
579 // Clear the UI widgets
580 fFullTraceHistogram
.clear();
581 fTimeRangeHistogram
.clear();
582 fSelectionStartControl
.setValue(Long
.MIN_VALUE
);
583 fSelectionEndControl
.setValue(Long
.MIN_VALUE
);
585 fTimeSpanControl
.setValue(Long
.MIN_VALUE
);
587 for (Control c
: fLegendArea
.getChildren()) {
590 disposeLegendImages();
591 fLegendArea
.layout();
592 fLegendArea
.getParent().layout();
596 * Handles trace range updated signal. Extends histogram according to the new time range. If a
597 * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range
600 * @param signal the trace range updated signal
603 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal
) {
605 if (signal
.getTrace() != fTrace
) {
609 TmfTimeRange fullRange
= signal
.getRange();
611 fTraceStartTime
= fullRange
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
612 fTraceEndTime
= fullRange
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
614 fFullTraceHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
615 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
617 sendFullRangeRequest(fullRange
);
621 * Handles the trace updated signal. Used to update time limits (start and end time)
622 * @param signal the trace updated signal
625 public void traceUpdated(TmfTraceUpdatedSignal signal
) {
626 if (signal
.getTrace() != fTrace
) {
629 TmfTimeRange fullRange
= signal
.getTrace().getTimeRange();
630 fTraceStartTime
= fullRange
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
631 fTraceEndTime
= fullRange
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
633 fFullTraceHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
634 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
636 if ((fFullTraceRequest
!= null) && fFullTraceRequest
.getRange().getEndTime().compareTo(signal
.getRange().getEndTime()) < 0) {
637 sendFullRangeRequest(fullRange
);
642 * Handles the current time updated signal. Sets the current time in the time range
643 * histogram as well as the full histogram.
645 * @param signal the signal to process
648 public void currentTimeUpdated(final TmfTimeSynchSignal signal
) {
649 if (Display
.getCurrent() == null) {
650 // Make sure the signal is handled in the UI thread
651 Display
.getDefault().asyncExec(new Runnable() {
654 if (fParent
.isDisposed()) {
657 currentTimeUpdated(signal
);
663 // Update the selected time range
664 ITmfTimestamp beginTime
= signal
.getBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
);
665 ITmfTimestamp endTime
= signal
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
);
666 updateDisplayedSelectionTime(beginTime
.getValue(), endTime
.getValue());
670 * Updates the current time range in the time range histogram and full range histogram.
671 * @param signal the signal to process
674 public void timeRangeUpdated(final TmfRangeSynchSignal signal
) {
675 if (Display
.getCurrent() == null) {
676 // Make sure the signal is handled in the UI thread
677 Display
.getDefault().asyncExec(new Runnable() {
680 if (fParent
.isDisposed()) {
683 timeRangeUpdated(signal
);
689 if (fTrace
!= null) {
690 // Validate the time range
691 TmfTimeRange range
= signal
.getCurrentRange().getIntersection(fTrace
.getTimeRange());
696 updateDisplayedTimeRange(
697 range
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue(),
698 range
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue());
700 // Send the event request to populate the small histogram
701 sendTimeRangeRequest(fWindowStartTime
, fWindowEndTime
);
703 fTimeSpanControl
.setValue(fWindowSpan
);
707 // ------------------------------------------------------------------------
709 // ------------------------------------------------------------------------
711 private void initializeHistograms() {
712 TmfTimeRange fullRange
= updateTraceTimeRange();
714 TmfTraceContext ctx
= TmfTraceManager
.getInstance().getCurrentTraceContext();
715 long selectionBeginTime
= ctx
.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
716 long selectionEndTime
= ctx
.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
717 long startTime
= ctx
.getWindowRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
718 long duration
= ctx
.getWindowRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue() - startTime
;
720 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
721 fTimeRangeRequest
.cancel();
723 fTimeRangeHistogram
.clear();
724 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
725 fTimeRangeHistogram
.setTimeRange(startTime
, duration
);
726 fTimeRangeHistogram
.setSelection(selectionBeginTime
, selectionEndTime
);
727 fTimeRangeHistogram
.fDataModel
.setTrace(fTrace
);
729 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
730 fFullTraceRequest
.cancel();
732 fFullTraceHistogram
.clear();
733 fFullTraceHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
734 fFullTraceHistogram
.setTimeRange(startTime
, duration
);
735 fFullTraceHistogram
.setSelection(selectionBeginTime
, selectionEndTime
);
736 fFullTraceHistogram
.fDataModel
.setTrace(fTrace
);
738 fWindowStartTime
= startTime
;
739 fWindowSpan
= duration
;
740 fWindowEndTime
= startTime
+ duration
;
742 fSelectionBeginTime
= selectionBeginTime
;
743 fSelectionEndTime
= selectionEndTime
;
744 fSelectionStartControl
.setValue(fSelectionBeginTime
);
745 fSelectionEndControl
.setValue(fSelectionEndTime
);
747 fTimeSpanControl
.setValue(duration
);
749 Collection
<ITmfTrace
> traces
= TmfTraceManager
.getTraceSet(fTrace
);
750 if (!traces
.isEmpty()) {
751 this.showTraceAction
.setEnabled(traces
.size() < fFullTraceHistogram
.getMaxNbTraces());
755 if (!fullRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
756 sendTimeRangeRequest(startTime
, startTime
+ duration
);
757 sendFullRangeRequest(fullRange
);
761 private void updateLegendArea() {
762 for (Control c
: fLegendArea
.getChildren()) {
765 disposeLegendImages();
766 if (fFullTraceHistogram
.showTraces()) {
767 Collection
<ITmfTrace
> traces
= TmfTraceManager
.getTraceSet(fTrace
);
768 fLegendImages
= new Image
[traces
.size()];
770 for (ITmfTrace trace
: traces
) {
771 fLegendImages
[traceIndex
] = new Image(fLegendArea
.getDisplay(), 16, 16);
772 GC gc
= new GC(fLegendImages
[traceIndex
]);
773 gc
.setBackground(fFullTraceHistogram
.getTraceColor(traceIndex
));
774 gc
.fillRectangle(0, 0, 15, 15);
775 gc
.setForeground(fLegendArea
.getDisplay().getSystemColor(SWT
.COLOR_BLACK
));
776 gc
.drawRectangle(0, 0, 15, 15);
779 CLabel label
= new CLabel(fLegendArea
, SWT
.NONE
);
780 label
.setText(trace
.getName());
781 label
.setImage(fLegendImages
[traceIndex
]);
785 fLegendArea
.layout();
786 fLegendArea
.getParent().layout();
789 private void updateDisplayedSelectionTime(long beginTime
, long endTime
) {
790 fSelectionBeginTime
= beginTime
;
791 fSelectionEndTime
= endTime
;
793 fFullTraceHistogram
.setSelection(fSelectionBeginTime
, fSelectionEndTime
);
794 fTimeRangeHistogram
.setSelection(fSelectionBeginTime
, fSelectionEndTime
);
795 fSelectionStartControl
.setValue(fSelectionBeginTime
);
796 fSelectionEndControl
.setValue(fSelectionEndTime
);
799 private void updateDisplayedTimeRange(long start
, long end
) {
800 fWindowStartTime
= start
;
801 fWindowEndTime
= end
;
802 fWindowSpan
= fWindowEndTime
- fWindowStartTime
;
803 fFullTraceHistogram
.setTimeRange(fWindowStartTime
, fWindowSpan
);
806 private TmfTimeRange
updateTraceTimeRange() {
807 fTraceStartTime
= 0L;
810 TmfTimeRange timeRange
= fTrace
.getTimeRange();
811 if (!timeRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
812 fTraceStartTime
= timeRange
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
813 fTraceEndTime
= timeRange
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
818 private void sendTimeRangeRequest(long startTime
, long endTime
) {
819 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
820 fTimeRangeRequest
.cancel();
822 TmfTimestamp startTS
= new TmfTimestamp(startTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
823 TmfTimestamp endTS
= new TmfTimestamp(endTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
824 TmfTimeRange timeRange
= new TmfTimeRange(startTS
, endTS
);
826 fTimeRangeHistogram
.clear();
827 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
828 fTimeRangeHistogram
.setTimeRange(startTime
, endTime
- startTime
);
830 int cacheSize
= fTrace
.getCacheSize();
831 fTimeRangeRequest
= new HistogramRequest(fTimeRangeHistogram
.getDataModel(),
832 timeRange
, 0, ITmfEventRequest
.ALL_DATA
, cacheSize
, ExecutionType
.FOREGROUND
, false);
833 fTrace
.sendRequest(fTimeRangeRequest
);
836 private void sendFullRangeRequest(TmfTimeRange fullRange
) {
837 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
838 fFullTraceRequest
.cancel();
840 int cacheSize
= fTrace
.getCacheSize();
841 fFullTraceRequest
= new HistogramRequest(fFullTraceHistogram
.getDataModel(),
843 (int) fFullTraceHistogram
.fDataModel
.getNbEvents(),
844 ITmfEventRequest
.ALL_DATA
,
846 ExecutionType
.BACKGROUND
, true);
847 fTrace
.sendRequest(fFullTraceRequest
);
850 private void contributeToActionBars() {
851 IActionBars bars
= getViewSite().getActionBars();
852 bars
.getToolBarManager().add(getShowLostEventsAction());
853 bars
.getToolBarManager().add(getShowTraceAction());
854 bars
.getToolBarManager().add(new Separator());
857 private void addLinkButtonListeners() {
858 fLinkButton
.addMouseListener(new MouseAdapter() {
860 public void mouseDown(MouseEvent e
) {
861 fSelectionEndControl
.setEnabled(fLinkState
);
862 fLinkState
= !fLinkState
;
863 fLinkButton
.redraw();
867 fLinkButton
.addPaintListener(new PaintListener() {
869 public void paintControl(PaintEvent e
) {
871 Rectangle r
= fLinkButton
.getBounds();
874 e
.gc
.setForeground(e
.display
.getSystemColor(SWT
.COLOR_WIDGET_NORMAL_SHADOW
));
875 e
.gc
.drawRectangle(r
);
878 e
.gc
.setForeground(e
.display
.getSystemColor(SWT
.COLOR_DARK_GRAY
));
879 e
.gc
.drawRectangle(r
);