1 /*******************************************************************************
2 * Copyright (c) 2009, 2013 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
.linuxtools
.tmf
.ui
.views
.histogram
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.jface
.action
.Action
;
24 import org
.eclipse
.jface
.action
.IAction
;
25 import org
.eclipse
.jface
.action
.Separator
;
26 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
27 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.ITmfImageConstants
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
.ExecutionType
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalThrottler
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceClosedSignal
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceRangeUpdatedSignal
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceUpdatedSignal
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTraceManager
;
44 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
45 import org
.eclipse
.swt
.SWT
;
46 import org
.eclipse
.swt
.custom
.CLabel
;
47 import org
.eclipse
.swt
.events
.MouseAdapter
;
48 import org
.eclipse
.swt
.events
.MouseEvent
;
49 import org
.eclipse
.swt
.events
.MouseWheelListener
;
50 import org
.eclipse
.swt
.events
.PaintEvent
;
51 import org
.eclipse
.swt
.events
.PaintListener
;
52 import org
.eclipse
.swt
.graphics
.GC
;
53 import org
.eclipse
.swt
.graphics
.Image
;
54 import org
.eclipse
.swt
.graphics
.Rectangle
;
55 import org
.eclipse
.swt
.layout
.GridData
;
56 import org
.eclipse
.swt
.layout
.GridLayout
;
57 import org
.eclipse
.swt
.layout
.RowLayout
;
58 import org
.eclipse
.swt
.widgets
.Composite
;
59 import org
.eclipse
.swt
.widgets
.Control
;
60 import org
.eclipse
.swt
.widgets
.Display
;
61 import org
.eclipse
.swt
.widgets
.Label
;
62 import org
.eclipse
.ui
.IActionBars
;
65 * The purpose of this view is to provide graphical time distribution statistics about the trace events.
67 * The view is composed of two histograms and two controls:
69 * <li>an event distribution histogram for the whole trace;
70 * <li>an event distribution histogram for current time window (window span);
71 * <li>the timestamp of the currently selected event;
72 * <li>the window span (size of the time window of the smaller histogram).
74 * The histograms x-axis show their respective time range.
77 * @author Francois Chouinard
79 public class HistogramView
extends TmfView
{
81 // ------------------------------------------------------------------------
83 // ------------------------------------------------------------------------
86 * The view ID as defined in plugin.xml
88 public static final @NonNull String ID
= "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
90 private static final Image LINK_IMG
= Activator
.getDefault().getImageFromPath("/icons/etool16/link.gif"); //$NON-NLS-1$
92 // ------------------------------------------------------------------------
94 // ------------------------------------------------------------------------
97 private Composite fParent
;
100 private ITmfTrace fTrace
;
102 // Current timestamp/time window - everything in the TIME_SCALE
103 private long fTraceStartTime
;
104 private long fTraceEndTime
;
105 private long fWindowStartTime
;
106 private long fWindowEndTime
;
107 private long fWindowSpan
;
108 private long fSelectionBeginTime
;
109 private long fSelectionEndTime
;
112 private HistogramTextControl fSelectionStartControl
;
113 private HistogramTextControl fSelectionEndControl
;
114 private HistogramTextControl fTimeSpanControl
;
117 private Label fLinkButton
;
118 private boolean fLinkState
;
120 // Histogram/request for the full trace range
121 private static FullTraceHistogram fFullTraceHistogram
;
122 private HistogramRequest fFullTraceRequest
;
124 // Histogram/request for the selected time range
125 private static TimeRangeHistogram fTimeRangeHistogram
;
126 private HistogramRequest fTimeRangeRequest
;
129 private Composite fLegendArea
;
130 private Image
[] fLegendImages
;
132 // Throttlers for the time sync and time-range sync signals
133 private final TmfSignalThrottler fTimeSyncThrottle
;
134 private final TmfSignalThrottler fTimeRangeSyncThrottle
;
136 // Action for toggle showing the lost events
137 private Action hideLostEventsAction
;
138 // Action for toggle showing the traces
139 private Action showTraceAction
;
141 // ------------------------------------------------------------------------
143 // ------------------------------------------------------------------------
146 * Default constructor
148 public HistogramView() {
150 fTimeSyncThrottle
= new TmfSignalThrottler(this, 200);
151 fTimeRangeSyncThrottle
= new TmfSignalThrottler(this, 200);
155 public void dispose() {
156 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
157 fTimeRangeRequest
.cancel();
159 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
160 fFullTraceRequest
.cancel();
162 fFullTraceHistogram
.dispose();
163 fTimeRangeHistogram
.dispose();
164 fSelectionStartControl
.dispose();
165 fSelectionEndControl
.dispose();
166 fTimeSpanControl
.dispose();
170 // ------------------------------------------------------------------------
172 // ------------------------------------------------------------------------
175 public void createPartControl(Composite parent
) {
180 final String selectionStartLabel
= Messages
.HistogramView_selectionStartLabel
;
181 final String selectionEndLabel
= Messages
.HistogramView_selectionEndLabel
;
182 final String windowSpanLabel
= Messages
.HistogramView_windowSpanLabel
;
184 // --------------------------------------------------------------------
185 // Set the HistogramView layout
186 // --------------------------------------------------------------------
188 Composite viewComposite
= new Composite(fParent
, SWT
.FILL
);
189 GridLayout gridLayout
= new GridLayout();
190 gridLayout
.numColumns
= 2;
191 gridLayout
.horizontalSpacing
= 5;
192 gridLayout
.verticalSpacing
= 0;
193 gridLayout
.marginHeight
= 0;
194 gridLayout
.marginWidth
= 0;
195 viewComposite
.setLayout(gridLayout
);
197 // --------------------------------------------------------------------
199 // --------------------------------------------------------------------
201 Composite controlsComposite
= new Composite(viewComposite
, SWT
.NONE
);
202 gridLayout
= new GridLayout();
203 gridLayout
.numColumns
= 2;
204 gridLayout
.marginHeight
= 0;
205 gridLayout
.marginWidth
= 0;
206 gridLayout
.horizontalSpacing
= 5;
207 gridLayout
.verticalSpacing
= 1;
208 gridLayout
.makeColumnsEqualWidth
= false;
209 controlsComposite
.setLayout(gridLayout
);
210 GridData gridData
= new GridData(SWT
.FILL
, SWT
.CENTER
, false, false);
211 controlsComposite
.setLayoutData(gridData
);
213 Composite selectionGroup
= new Composite(controlsComposite
, SWT
.BORDER
);
214 gridLayout
= new GridLayout();
215 gridLayout
.marginHeight
= 0;
216 gridLayout
.marginWidth
= 0;
217 gridLayout
.horizontalSpacing
= 0;
218 gridLayout
.verticalSpacing
= 0;
219 selectionGroup
.setLayout(gridLayout
);
221 // Selection start control
222 gridData
= new GridData();
223 gridData
.horizontalAlignment
= SWT
.FILL
;
224 gridData
.verticalAlignment
= SWT
.CENTER
;
225 fSelectionStartControl
= new HistogramSelectionStartControl(this, selectionGroup
, selectionStartLabel
, 0L);
226 fSelectionStartControl
.setLayoutData(gridData
);
227 fSelectionStartControl
.setValue(Long
.MIN_VALUE
);
229 // Selection end control
230 gridData
= new GridData();
231 gridData
.horizontalAlignment
= SWT
.FILL
;
232 gridData
.verticalAlignment
= SWT
.CENTER
;
233 fSelectionEndControl
= new HistogramSelectionEndControl(this, selectionGroup
, selectionEndLabel
, 0L);
234 fSelectionEndControl
.setLayoutData(gridData
);
235 fSelectionEndControl
.setValue(Long
.MIN_VALUE
);
238 gridData
= new GridData();
239 fLinkButton
= new Label(controlsComposite
, SWT
.NONE
);
240 fLinkButton
.setImage(LINK_IMG
);
241 fLinkButton
.setLayoutData(gridData
);
242 addLinkButtonListeners();
244 // Window span time control
245 gridData
= new GridData();
246 gridData
.horizontalAlignment
= SWT
.FILL
;
247 gridData
.verticalAlignment
= SWT
.CENTER
;
248 fTimeSpanControl
= new HistogramTimeRangeControl(this, controlsComposite
, windowSpanLabel
, 0L);
249 fTimeSpanControl
.setLayoutData(gridData
);
250 fTimeSpanControl
.setValue(Long
.MIN_VALUE
);
252 // --------------------------------------------------------------------
253 // Time range histogram
254 // --------------------------------------------------------------------
256 Composite timeRangeComposite
= new Composite(viewComposite
, SWT
.NONE
);
257 gridLayout
= new GridLayout();
258 gridLayout
.numColumns
= 1;
259 gridLayout
.marginHeight
= 0;
260 gridLayout
.marginWidth
= 0;
261 gridLayout
.marginTop
= 5;
262 gridLayout
.horizontalSpacing
= 0;
263 gridLayout
.verticalSpacing
= 0;
264 gridLayout
.marginLeft
= 5;
265 gridLayout
.marginRight
= 5;
266 timeRangeComposite
.setLayout(gridLayout
);
268 // Use remaining horizontal space
269 gridData
= new GridData();
270 gridData
.horizontalAlignment
= SWT
.FILL
;
271 gridData
.verticalAlignment
= SWT
.FILL
;
272 gridData
.grabExcessHorizontalSpace
= true;
273 gridData
.grabExcessVerticalSpace
= true;
274 timeRangeComposite
.setLayoutData(gridData
);
277 fTimeRangeHistogram
= new TimeRangeHistogram(this, timeRangeComposite
);
279 // --------------------------------------------------------------------
280 // Full range histogram
281 // --------------------------------------------------------------------
283 Composite fullRangeComposite
= new Composite(viewComposite
, SWT
.FILL
);
284 gridLayout
= new GridLayout();
285 gridLayout
.numColumns
= 1;
286 gridLayout
.marginHeight
= 0;
287 gridLayout
.marginWidth
= 0;
288 gridLayout
.marginTop
= 5;
289 gridLayout
.horizontalSpacing
= 0;
290 gridLayout
.verticalSpacing
= 0;
291 gridLayout
.marginLeft
= 5;
292 gridLayout
.marginRight
= 5;
293 fullRangeComposite
.setLayout(gridLayout
);
295 // Use remaining horizontal space
296 gridData
= new GridData();
297 gridData
.horizontalAlignment
= SWT
.FILL
;
298 gridData
.verticalAlignment
= SWT
.FILL
;
299 gridData
.horizontalSpan
= 2;
300 gridData
.grabExcessHorizontalSpace
= true;
301 gridData
.grabExcessVerticalSpace
= true;
302 fullRangeComposite
.setLayoutData(gridData
);
305 fFullTraceHistogram
= new FullTraceHistogram(this, fullRangeComposite
);
307 fLegendArea
= new Composite(viewComposite
, SWT
.FILL
);
308 fLegendArea
.setLayoutData(new GridData(SWT
.BEGINNING
, SWT
.BEGINNING
, true, false, 2, 1));
309 fLegendArea
.setLayout(new RowLayout());
311 // Add mouse wheel listener to time span control
312 MouseWheelListener listener
= fFullTraceHistogram
.getZoom();
313 fTimeSpanControl
.addMouseWheelListener(listener
);
316 // View Action Handling
317 contributeToActionBars();
319 ITmfTrace trace
= getActiveTrace();
321 traceSelected(new TmfTraceSelectedSignal(this, trace
));
326 public void setFocus() {
327 fFullTraceHistogram
.fCanvas
.setFocus();
331 fParent
.layout(true);
334 // ------------------------------------------------------------------------
336 // ------------------------------------------------------------------------
339 * Returns the current trace handled by the view
341 * @return the current trace
344 public ITmfTrace
getTrace() {
349 * Returns the time range of the current selected window (base on default time scale).
351 * @return the time range of current selected window.
354 public TmfTimeRange
getTimeRange() {
355 return new TmfTimeRange(
356 new TmfTimestamp(fWindowStartTime
, ITmfTimestamp
.NANOSECOND_SCALE
),
357 new TmfTimestamp(fWindowEndTime
, ITmfTimestamp
.NANOSECOND_SCALE
));
361 * get the show lost events action
363 * @return The action object
366 public Action
getShowLostEventsAction() {
367 if (hideLostEventsAction
== null) {
368 /* show lost events */
369 hideLostEventsAction
= new Action(Messages
.HistogramView_hideLostEvents
, IAction
.AS_CHECK_BOX
) {
372 HistogramScaledData
.hideLostEvents
= hideLostEventsAction
.isChecked();
373 long maxNbEvents
= HistogramScaledData
.hideLostEvents ? fFullTraceHistogram
.fScaledData
.fMaxValue
: fFullTraceHistogram
.fScaledData
.fMaxCombinedValue
;
374 fFullTraceHistogram
.setMaxNbEvents(maxNbEvents
);
375 maxNbEvents
= HistogramScaledData
.hideLostEvents ? fTimeRangeHistogram
.fScaledData
.fMaxValue
: fTimeRangeHistogram
.fScaledData
.fMaxCombinedValue
;
376 fTimeRangeHistogram
.setMaxNbEvents(maxNbEvents
);
379 hideLostEventsAction
.setText(Messages
.HistogramView_hideLostEvents
);
380 hideLostEventsAction
.setToolTipText(Messages
.HistogramView_hideLostEvents
);
381 hideLostEventsAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_LOST_EVENTS
));
383 return hideLostEventsAction
;
387 * get the show trace action
389 * @return The action object
392 public Action
getShowTraceAction() {
393 if (showTraceAction
== null) {
394 /* show lost events */
395 showTraceAction
= new Action(Messages
.HistogramView_showTraces
, IAction
.AS_CHECK_BOX
) {
398 Histogram
.showTraces
= showTraceAction
.isChecked();
399 fFullTraceHistogram
.fCanvas
.redraw();
400 fTimeRangeHistogram
.fCanvas
.redraw();
404 showTraceAction
.setChecked(true);
405 showTraceAction
.setText(Messages
.HistogramView_showTraces
);
406 showTraceAction
.setToolTipText(Messages
.HistogramView_showTraces
);
407 showTraceAction
.setImageDescriptor(Activator
.getDefault().getImageDescripterFromPath(ITmfImageConstants
.IMG_UI_SHOW_HIST_TRACES
));
409 return showTraceAction
;
412 // ------------------------------------------------------------------------
414 // ------------------------------------------------------------------------
417 * Broadcast TmfSignal about new current selection time range.
418 * @param beginTime the begin time of current selection.
419 * @param endTime the end time of current selection.
421 void updateSelectionTime(long beginTime
, long endTime
) {
422 updateDisplayedSelectionTime(beginTime
, endTime
);
423 TmfTimestamp beginTs
= new TmfTimestamp(beginTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
424 TmfTimestamp endTs
= new TmfTimestamp(endTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
425 TmfTimeSynchSignal signal
= new TmfTimeSynchSignal(this, beginTs
, endTs
);
426 fTimeSyncThrottle
.queue(signal
);
430 * Get selection begin time
431 * @return the begin time of current selection
433 long getSelectionBegin() {
434 return fSelectionBeginTime
;
438 * Get selection end time
439 * @return the end time of current selection
441 long getSelectionEnd() {
442 return fSelectionEndTime
;
447 * @return true if begin and end selection time should be linked
449 boolean getLinkState() {
454 * Broadcast TmfSignal about new selection time range.
455 * @param startTime the new start time
456 * @param endTime the new end time
458 void updateTimeRange(long startTime
, long endTime
) {
459 if (fTrace
!= null) {
460 // Build the new time range; keep the current time
461 TmfTimeRange timeRange
= new TmfTimeRange(
462 new TmfTimestamp(startTime
, ITmfTimestamp
.NANOSECOND_SCALE
),
463 new TmfTimestamp(endTime
, ITmfTimestamp
.NANOSECOND_SCALE
));
464 fTimeSpanControl
.setValue(endTime
- startTime
);
466 updateDisplayedTimeRange(startTime
, endTime
);
468 // Send the FW signal
469 TmfRangeSynchSignal signal
= new TmfRangeSynchSignal(this, timeRange
);
470 fTimeRangeSyncThrottle
.queue(signal
);
475 * Broadcast TmfSignal about new selected time range.
476 * @param newDuration new duration (relative to current start time)
478 public synchronized void updateTimeRange(long newDuration
) {
479 if (fTrace
!= null) {
480 long delta
= newDuration
- fWindowSpan
;
481 long newStartTime
= fWindowStartTime
- (delta
/ 2);
482 setNewRange(newStartTime
, newDuration
);
486 private void setNewRange(long startTime
, long duration
) {
487 long realStart
= startTime
;
489 if (realStart
< fTraceStartTime
) {
490 realStart
= fTraceStartTime
;
493 long endTime
= realStart
+ duration
;
494 if (endTime
> fTraceEndTime
) {
495 endTime
= fTraceEndTime
;
496 if ((endTime
- duration
) > fTraceStartTime
) {
497 realStart
= endTime
- duration
;
499 realStart
= fTraceStartTime
;
502 updateTimeRange(realStart
, endTime
);
505 // ------------------------------------------------------------------------
507 // ------------------------------------------------------------------------
510 * Handles trace opened signal. Loads histogram if new trace time range is not
511 * equal <code>TmfTimeRange.NULL_RANGE</code>
512 * @param signal the trace opened signal
516 public void traceOpened(TmfTraceOpenedSignal signal
) {
517 assert (signal
!= null);
518 fTrace
= signal
.getTrace();
523 * Handles trace selected signal. Loads histogram if new trace time range is not
524 * equal <code>TmfTimeRange.NULL_RANGE</code>
525 * @param signal the trace selected signal
529 public void traceSelected(TmfTraceSelectedSignal signal
) {
530 assert (signal
!= null);
531 if (fTrace
!= signal
.getTrace()) {
532 fTrace
= signal
.getTrace();
537 private void loadTrace() {
538 initializeHistograms();
543 * Handles trace closed signal. Clears the view and data model and cancels requests.
544 * @param signal the trace closed signal
548 public void traceClosed(TmfTraceClosedSignal signal
) {
550 if (signal
.getTrace() != fTrace
) {
554 // Kill any running request
555 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
556 fTimeRangeRequest
.cancel();
558 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
559 fFullTraceRequest
.cancel();
562 // Initialize the internal data
564 fTraceStartTime
= 0L;
566 fWindowStartTime
= 0L;
569 fSelectionBeginTime
= 0L;
570 fSelectionEndTime
= 0L;
572 // Clear the UI widgets
573 fFullTraceHistogram
.clear();
574 fTimeRangeHistogram
.clear();
575 fSelectionStartControl
.setValue(Long
.MIN_VALUE
);
576 fSelectionEndControl
.setValue(Long
.MIN_VALUE
);
578 fTimeSpanControl
.setValue(Long
.MIN_VALUE
);
580 for (Control c
: fLegendArea
.getChildren()) {
583 if (fLegendImages
!= null) {
584 for (Image i
: fLegendImages
) {
588 fLegendImages
= null;
589 fLegendArea
.layout();
590 fLegendArea
.getParent().layout();
594 * Handles trace range updated signal. Extends histogram according to the new time range. If a
595 * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range
598 * @param signal the trace range updated signal
602 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal
) {
604 if (signal
.getTrace() != fTrace
) {
608 TmfTimeRange fullRange
= signal
.getRange();
610 fTraceStartTime
= fullRange
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
611 fTraceEndTime
= fullRange
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
613 fFullTraceHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
614 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
616 sendFullRangeRequest(fullRange
);
620 * Handles the trace updated signal. Used to update time limits (start and end time)
621 * @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();
713 long selectionBeginTime
= fTraceManager
.getSelectionBeginTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
714 long selectionEndTime
= fTraceManager
.getSelectionEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
715 long startTime
= fTraceManager
.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
716 long duration
= fTraceManager
.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue() - startTime
;
718 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
719 fTimeRangeRequest
.cancel();
721 fTimeRangeHistogram
.clear();
722 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
723 fTimeRangeHistogram
.setTimeRange(startTime
, duration
);
724 fTimeRangeHistogram
.setSelection(selectionBeginTime
, selectionEndTime
);
725 fTimeRangeHistogram
.fDataModel
.setTrace(fTrace
);
727 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
728 fFullTraceRequest
.cancel();
730 fFullTraceHistogram
.clear();
731 fFullTraceHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
732 fFullTraceHistogram
.setTimeRange(startTime
, duration
);
733 fFullTraceHistogram
.setSelection(selectionBeginTime
, selectionEndTime
);
734 fFullTraceHistogram
.fDataModel
.setTrace(fTrace
);
736 fWindowStartTime
= startTime
;
737 fWindowSpan
= duration
;
738 fWindowEndTime
= startTime
+ duration
;
740 fSelectionBeginTime
= selectionBeginTime
;
741 fSelectionEndTime
= selectionEndTime
;
742 fSelectionStartControl
.setValue(fSelectionBeginTime
);
743 fSelectionEndControl
.setValue(fSelectionEndTime
);
745 fTimeSpanControl
.setValue(duration
);
747 ITmfTrace
[] traces
= TmfTraceManager
.getTraceSet(fTrace
);
748 if (traces
!= null) {
749 this.showTraceAction
.setEnabled(traces
.length
< fFullTraceHistogram
.getMaxNbTraces());
753 if (!fullRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
754 sendTimeRangeRequest(startTime
, startTime
+ duration
);
755 sendFullRangeRequest(fullRange
);
759 private void updateLegendArea() {
760 for (Control c
: fLegendArea
.getChildren()) {
763 if (fLegendImages
!= null) {
764 for (Image i
: fLegendImages
) {
768 fLegendImages
= null;
769 if (fFullTraceHistogram
.showTraces()) {
770 ITmfTrace
[] traces
= TmfTraceManager
.getTraceSet(fTrace
);
771 fLegendImages
= new Image
[traces
.length
];
773 for (ITmfTrace trace
: traces
) {
774 fLegendImages
[traceIndex
] = new Image(fLegendArea
.getDisplay(), 16, 16);
775 GC gc
= new GC(fLegendImages
[traceIndex
]);
776 gc
.setBackground(fFullTraceHistogram
.getTraceColor(traceIndex
));
777 gc
.fillRectangle(0, 0, 15, 15);
778 gc
.setForeground(fLegendArea
.getDisplay().getSystemColor(SWT
.COLOR_BLACK
));
779 gc
.drawRectangle(0, 0, 15, 15);
782 CLabel label
= new CLabel(fLegendArea
, SWT
.NONE
);
783 label
.setText(trace
.getName());
784 label
.setImage(fLegendImages
[traceIndex
]);
788 fLegendArea
.layout();
789 fLegendArea
.getParent().layout();
792 private void updateDisplayedSelectionTime(long beginTime
, long endTime
) {
793 fSelectionBeginTime
= beginTime
;
794 fSelectionEndTime
= endTime
;
796 fFullTraceHistogram
.setSelection(fSelectionBeginTime
, fSelectionEndTime
);
797 fTimeRangeHistogram
.setSelection(fSelectionBeginTime
, fSelectionEndTime
);
798 fSelectionStartControl
.setValue(fSelectionBeginTime
);
799 fSelectionEndControl
.setValue(fSelectionEndTime
);
802 private void updateDisplayedTimeRange(long start
, long end
) {
803 fWindowStartTime
= start
;
804 fWindowEndTime
= end
;
805 fWindowSpan
= fWindowEndTime
- fWindowStartTime
;
806 fFullTraceHistogram
.setTimeRange(fWindowStartTime
, fWindowSpan
);
809 private TmfTimeRange
updateTraceTimeRange() {
810 fTraceStartTime
= 0L;
813 TmfTimeRange timeRange
= fTrace
.getTimeRange();
814 if (!timeRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
815 fTraceStartTime
= timeRange
.getStartTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
816 fTraceEndTime
= timeRange
.getEndTime().normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
).getValue();
821 private void sendTimeRangeRequest(long startTime
, long endTime
) {
822 if ((fTimeRangeRequest
!= null) && !fTimeRangeRequest
.isCompleted()) {
823 fTimeRangeRequest
.cancel();
825 TmfTimestamp startTS
= new TmfTimestamp(startTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
826 TmfTimestamp endTS
= new TmfTimestamp(endTime
, ITmfTimestamp
.NANOSECOND_SCALE
);
827 TmfTimeRange timeRange
= new TmfTimeRange(startTS
, endTS
);
829 fTimeRangeHistogram
.clear();
830 fTimeRangeHistogram
.setFullRange(fTraceStartTime
, fTraceEndTime
);
831 fTimeRangeHistogram
.setTimeRange(startTime
, endTime
- startTime
);
833 int cacheSize
= fTrace
.getCacheSize();
834 fTimeRangeRequest
= new HistogramRequest(fTimeRangeHistogram
.getDataModel(),
835 timeRange
, 0, ITmfEventRequest
.ALL_DATA
, cacheSize
, ExecutionType
.FOREGROUND
, false);
836 fTrace
.sendRequest(fTimeRangeRequest
);
839 private void sendFullRangeRequest(TmfTimeRange fullRange
) {
840 if ((fFullTraceRequest
!= null) && !fFullTraceRequest
.isCompleted()) {
841 fFullTraceRequest
.cancel();
843 int cacheSize
= fTrace
.getCacheSize();
844 fFullTraceRequest
= new HistogramRequest(fFullTraceHistogram
.getDataModel(),
846 (int) fFullTraceHistogram
.fDataModel
.getNbEvents(),
847 ITmfEventRequest
.ALL_DATA
,
849 ExecutionType
.BACKGROUND
, true);
850 fTrace
.sendRequest(fFullTraceRequest
);
853 private void contributeToActionBars() {
854 IActionBars bars
= getViewSite().getActionBars();
855 bars
.getToolBarManager().add(getShowLostEventsAction());
856 bars
.getToolBarManager().add(getShowTraceAction());
857 bars
.getToolBarManager().add(new Separator());
860 private void addLinkButtonListeners() {
861 fLinkButton
.addMouseListener(new MouseAdapter() {
863 public void mouseDown(MouseEvent e
) {
864 fSelectionEndControl
.setEnabled(fLinkState
);
865 fLinkState
= !fLinkState
;
866 fLinkButton
.redraw();
870 fLinkButton
.addPaintListener(new PaintListener() {
872 public void paintControl(PaintEvent e
) {
874 Rectangle r
= fLinkButton
.getBounds();
877 e
.gc
.setForeground(e
.display
.getSystemColor(SWT
.COLOR_WIDGET_NORMAL_SHADOW
));
878 e
.gc
.drawRectangle(r
);
881 e
.gc
.setForeground(e
.display
.getSystemColor(SWT
.COLOR_DARK_GRAY
));
882 e
.gc
.drawRectangle(r
);